]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
mt76x2: move mt76x2 source files to mt76x2 folder
authorLorenzo Bianconi <lorenzo.bianconi@redhat.com>
Mon, 1 Oct 2018 08:18:42 +0000 (10:18 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 5 Oct 2018 18:05:44 +0000 (20:05 +0200)
Move mt76x2 and mt76x2u drivers to mt76x2 subfolder and
leave just shared code in mt76 root folder

Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
71 files changed:
drivers/net/wireless/mediatek/mt76/Kconfig
drivers/net/wireless/mediatek/mt76/Makefile
drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/Makefile [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/common.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/debugfs.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/dfs.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/init.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mac.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mac.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mcu.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_core.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_dma.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_trace.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/phy.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/trace.h [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/tx.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_core.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c [new file with mode: 0644]
drivers/net/wireless/mediatek/mt76/mt76x2_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_core.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_dma.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_init.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mac.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mac.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_main.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_pci.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_phy.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_trace.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_trace.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_tx.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2_usb.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u.h [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_core.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_init.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_main.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c [deleted file]
drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c [deleted file]

index 7f24aad94efd93268abc79ca8f1ba879c3882473..0ccbcd7e887d67d1352886736411e13c0813ccfb 100644 (file)
@@ -13,44 +13,5 @@ config MT76x02_USB
        tristate
        select MT76_USB
 
-config MT76x0_COMMON
-       tristate
-       select MT76x02_LIB
-
-config MT76x2_COMMON
-       tristate
-       select MT76x02_LIB
-
-config MT76x0U
-       tristate "MediaTek MT76x0U (USB) support"
-       select MT76x0_COMMON
-       select MT76x02_USB
-       depends on MAC80211
-       depends on USB
-       help
-         This adds support for MT7610U-based wireless USB dongles.
-
-config MT76x0E
-       tristate "MediaTek MT76x0E (PCIe) support"
-       select MT76x0_COMMON
-       depends on MAC80211
-       depends on PCI
-       help
-         This adds support for MT7610/MT7630-based wireless PCIe devices.
-
-config MT76x2E
-       tristate "MediaTek MT76x2E (PCIe) support"
-       select MT76x2_COMMON
-       depends on MAC80211
-       depends on PCI
-       ---help---
-         This adds support for MT7612/MT7602/MT7662-based wireless PCIe devices.
-
-config MT76x2U
-       tristate "MediaTek MT76x2U (USB) support"
-       select MT76x2_COMMON
-       select MT76x02_USB
-       depends on MAC80211
-       depends on USB
-       help
-         This adds support for MT7612U-based wireless USB dongles.
+source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig"
+source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig"
index 2346a1b768bcb605f8c6fe49a23884505a0316fb..907b9e2d704449af78f5a25a7a3ec77869a018db 100644 (file)
@@ -1,11 +1,7 @@
 obj-$(CONFIG_MT76_CORE) += mt76.o
 obj-$(CONFIG_MT76_USB) += mt76-usb.o
-obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
 obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o
 obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o
-obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o
-obj-$(CONFIG_MT76x2E) += mt76x2e.o
-obj-$(CONFIG_MT76x2U) += mt76x2u.o
 
 mt76-y := \
        mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o tx.o agg-rx.o
@@ -20,19 +16,5 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \
 
 mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
 
-mt76x2-common-y := \
-       mt76x2_eeprom.o mt76x2_tx_common.o mt76x2_mac_common.o \
-       mt76x2_init_common.o mt76x2_common.o mt76x2_phy_common.o \
-       mt76x2_debugfs.o mt76x2_mcu_common.o
-
-mt76x2e-y := \
-       mt76x2_pci.o mt76x2_dma.o \
-       mt76x2_main.o mt76x2_init.o mt76x2_tx.o \
-       mt76x2_core.o mt76x2_mac.o mt76x2_mcu.o mt76x2_phy.o \
-       mt76x2_dfs.o mt76x2_trace.o
-
-mt76x2u-y := \
-       mt76x2_usb.o mt76x2u_init.o mt76x2u_main.o mt76x2u_mac.o \
-       mt76x2u_mcu.o mt76x2u_phy.o mt76x2u_core.o
-
-CFLAGS_mt76x2_trace.o := -I$(src)
+obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
+obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig b/drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig
new file mode 100644 (file)
index 0000000..9a6157d
--- /dev/null
@@ -0,0 +1,20 @@
+config MT76x0_COMMON
+       tristate
+       select MT76x02_LIB
+
+config MT76x0U
+       tristate "MediaTek MT76x0U (USB) support"
+       select MT76x0_COMMON
+       select MT76x02_USB
+       depends on MAC80211
+       depends on USB
+       help
+         This adds support for MT7610U-based wireless USB dongles.
+
+config MT76x0E
+       tristate "MediaTek MT76x0E (PCIe) support"
+       select MT76x0_COMMON
+       depends on MAC80211
+       depends on PCI
+       help
+         This adds support for MT7610/MT7630-based wireless PCIe devices.
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2.h
deleted file mode 100644 (file)
index d6ccab0..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2_H
-#define __MT76x2_H
-
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/spinlock.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/mutex.h>
-#include <linux/bitops.h>
-#include <linux/kfifo.h>
-
-#define MT7662_FIRMWARE                "mt7662.bin"
-#define MT7662_ROM_PATCH       "mt7662_rom_patch.bin"
-#define MT7662_EEPROM_SIZE     512
-
-#define MT7662U_FIRMWARE       "mediatek/mt7662u.bin"
-#define MT7662U_ROM_PATCH      "mediatek/mt7662u_rom_patch.bin"
-
-#define MT_MAX_CHAINS          2
-
-#define MT_CALIBRATE_INTERVAL  HZ
-
-#include "mt76.h"
-#include "mt76x02_regs.h"
-#include "mt76x2_mac.h"
-#include "mt76x2_dfs.h"
-
-struct mt76x2_rx_freq_cal {
-       s8 high_gain[MT_MAX_CHAINS];
-       s8 rssi_offset[MT_MAX_CHAINS];
-       s8 lna_gain;
-       u32 mcu_gain;
-};
-
-struct mt76x2_calibration {
-       struct mt76x2_rx_freq_cal rx;
-
-       u8 agc_gain_init[MT_MAX_CHAINS];
-       u8 agc_gain_cur[MT_MAX_CHAINS];
-
-       u16 false_cca;
-       s8 avg_rssi_all;
-       s8 agc_gain_adjust;
-       s8 low_gain;
-
-       u8 temp;
-
-       bool init_cal_done;
-       bool tssi_cal_done;
-       bool tssi_comp_pending;
-       bool dpd_cal_done;
-       bool channel_cal_done;
-};
-
-struct mt76x2_dev {
-       struct mt76_dev mt76; /* must be first */
-
-       struct mac_address macaddr_list[8];
-
-       struct mutex mutex;
-
-       u8 txdone_seq;
-       DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
-
-       struct sk_buff *rx_head;
-
-       struct tasklet_struct tx_tasklet;
-       struct tasklet_struct pre_tbtt_tasklet;
-       struct delayed_work cal_work;
-       struct delayed_work mac_work;
-
-       u32 aggr_stats[32];
-
-       struct sk_buff *beacons[8];
-       u8 beacon_mask;
-       u8 beacon_data_mask;
-
-       u8 tbtt_count;
-       u16 beacon_int;
-
-       struct mt76x2_calibration cal;
-
-       s8 target_power;
-       s8 target_power_delta[2];
-       bool enable_tpc;
-
-       u8 coverage_class;
-       u8 slottime;
-
-       struct mt76x2_dfs_pattern_detector dfs_pd;
-};
-
-static inline bool is_mt7612(struct mt76x2_dev *dev)
-{
-       return mt76_chip(&dev->mt76) == 0x7612;
-}
-
-static inline bool mt76x2_channel_silent(struct mt76x2_dev *dev)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-
-       return ((chan->flags & IEEE80211_CHAN_RADAR) &&
-               chan->dfs_state != NL80211_DFS_AVAILABLE);
-}
-
-extern const struct ieee80211_ops mt76x2_ops;
-
-struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev);
-int mt76x2_register_device(struct mt76x2_dev *dev);
-void mt76x2_init_debugfs(struct mt76x2_dev *dev);
-void mt76x2_init_device(struct mt76x2_dev *dev);
-
-irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance);
-void mt76x2_phy_power_on(struct mt76x2_dev *dev);
-int mt76x2_init_hardware(struct mt76x2_dev *dev);
-void mt76x2_stop_hardware(struct mt76x2_dev *dev);
-int mt76x2_eeprom_init(struct mt76x2_dev *dev);
-int mt76x2_apply_calibration_data(struct mt76x2_dev *dev, int channel);
-void mt76x2_set_tx_ackto(struct mt76x2_dev *dev);
-
-void mt76x2_phy_set_antenna(struct mt76x2_dev *dev);
-int mt76x2_phy_start(struct mt76x2_dev *dev);
-int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
-                        struct cfg80211_chan_def *chandef);
-int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain);
-void mt76x2_phy_calibrate(struct work_struct *work);
-void mt76x2_phy_set_txpower(struct mt76x2_dev *dev);
-
-int mt76x2_mcu_init(struct mt76x2_dev *dev);
-int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw,
-                          u8 bw_index, bool scan);
-int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level,
-                      u8 channel);
-
-void mt76x2_tx_tasklet(unsigned long data);
-void mt76x2_dma_cleanup(struct mt76x2_dev *dev);
-
-void mt76x2_cleanup(struct mt76x2_dev *dev);
-
-void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
-              struct sk_buff *skb);
-int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
-                         struct sk_buff *skb, struct mt76_queue *q,
-                         struct mt76_wcid *wcid, struct ieee80211_sta *sta,
-                         u32 *tx_info);
-void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
-                           struct mt76_queue_entry *e, bool flush);
-void mt76x2_mac_set_tx_protection(struct mt76x2_dev *dev, u32 val);
-
-void mt76x2_pre_tbtt_tasklet(unsigned long arg);
-
-void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
-void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
-                        struct sk_buff *skb);
-
-void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
-
-void mt76x2_update_channel(struct mt76_dev *mdev);
-
-s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *dev,
-                              const struct ieee80211_tx_rate *rate);
-s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj);
-void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr);
-
-
-void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable);
-void mt76x2_init_txpower(struct mt76x2_dev *dev,
-                        struct ieee80211_supported_band *sband);
-void mt76_write_mac_initvals(struct mt76x2_dev *dev);
-
-int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                  struct ieee80211_sta *sta);
-int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                     struct ieee80211_sta *sta);
-void mt76x2_remove_interface(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif);
-int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                  u16 queue, const struct ieee80211_tx_queue_params *params);
-void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq);
-
-void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait);
-void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev,
-                                enum nl80211_band band);
-void mt76x2_configure_tx_delay(struct mt76x2_dev *dev,
-                              enum nl80211_band band, u8 bw);
-void mt76x2_phy_set_bw(struct mt76x2_dev *dev, int width, u8 ctrl);
-void mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper);
-int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev);
-void mt76x2_apply_gain_adj(struct mt76x2_dev *dev);
-
-#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig b/drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig
new file mode 100644 (file)
index 0000000..2b414a0
--- /dev/null
@@ -0,0 +1,20 @@
+config MT76x2_COMMON
+       tristate
+       select MT76x02_LIB
+
+config MT76x2E
+       tristate "MediaTek MT76x2E (PCIe) support"
+       select MT76x2_COMMON
+       depends on MAC80211
+       depends on PCI
+       ---help---
+         This adds support for MT7612/MT7602/MT7662-based wireless PCIe devices.
+
+config MT76x2U
+       tristate "MediaTek MT76x2U (USB) support"
+       select MT76x2_COMMON
+       select MT76x02_USB
+       depends on MAC80211
+       depends on USB
+       help
+         This adds support for MT7612U-based wireless USB dongles.
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile b/drivers/net/wireless/mediatek/mt76/mt76x2/Makefile
new file mode 100644 (file)
index 0000000..2b5a316
--- /dev/null
@@ -0,0 +1,18 @@
+obj-$(CONFIG_MT76x2_COMMON) += mt76x2-common.o
+obj-$(CONFIG_MT76x2E) += mt76x2e.o
+obj-$(CONFIG_MT76x2U) += mt76x2u.o
+
+mt76x2-common-y := \
+       eeprom.o tx.o mac.o init.o common.o phy.o \
+       debugfs.o mcu.o
+
+mt76x2e-y := \
+       pci.o pci_dma.o pci_main.o pci_init.o pci_tx.o \
+       pci_core.o pci_mac.o pci_mcu.o pci_phy.o \
+       pci_dfs.o pci_trace.o
+
+mt76x2u-y := \
+       usb.o usb_init.o usb_main.o usb_mac.o usb_mcu.o \
+       usb_phy.o usb_core.o
+
+CFLAGS_pci_trace.o := -I$(src)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/common.c b/drivers/net/wireless/mediatek/mt76/mt76x2/common.c
new file mode 100644 (file)
index 0000000..fa6bad3
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_mac.h"
+
+void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+                        struct sk_buff *skb)
+{
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+       void *rxwi = skb->data;
+
+       if (q == MT_RXQ_MCU) {
+               /* this is used just by mmio code */
+               skb_queue_tail(&mdev->mmio.mcu.res_q, skb);
+               wake_up(&mdev->mmio.mcu.wait);
+               return;
+       }
+
+       skb_pull(skb, sizeof(struct mt76x02_rxwi));
+       if (mt76x2_mac_process_rx(dev, skb, rxwi)) {
+               dev_kfree_skb(skb);
+               return;
+       }
+
+       mt76_rx(&dev->mt76, q, skb);
+}
+EXPORT_SYMBOL_GPL(mt76x2_queue_rx_skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2/debugfs.c
new file mode 100644 (file)
index 0000000..ea373ba
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/debugfs.h>
+#include "mt76x2.h"
+
+static int
+mt76x2_ampdu_stat_read(struct seq_file *file, void *data)
+{
+       struct mt76x2_dev *dev = file->private;
+       int i, j;
+
+       for (i = 0; i < 4; i++) {
+               seq_puts(file, "Length: ");
+               for (j = 0; j < 8; j++)
+                       seq_printf(file, "%8d | ", i * 8 + j + 1);
+               seq_puts(file, "\n");
+               seq_puts(file, "Count:  ");
+               for (j = 0; j < 8; j++)
+                       seq_printf(file, "%8d | ", dev->aggr_stats[i * 8 + j]);
+               seq_puts(file, "\n");
+               seq_puts(file, "--------");
+               for (j = 0; j < 8; j++)
+                       seq_puts(file, "-----------");
+               seq_puts(file, "\n");
+       }
+
+       return 0;
+}
+
+static int
+mt76x2_ampdu_stat_open(struct inode *inode, struct file *f)
+{
+       return single_open(f, mt76x2_ampdu_stat_read, inode->i_private);
+}
+
+static int read_txpower(struct seq_file *file, void *data)
+{
+       struct mt76x2_dev *dev = dev_get_drvdata(file->private);
+
+       seq_printf(file, "Target power: %d\n", dev->target_power);
+
+       mt76_seq_puts_array(file, "Delta", dev->target_power_delta,
+                           ARRAY_SIZE(dev->target_power_delta));
+       return 0;
+}
+
+static const struct file_operations fops_ampdu_stat = {
+       .open = mt76x2_ampdu_stat_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int
+mt76x2_dfs_stat_read(struct seq_file *file, void *data)
+{
+       int i;
+       struct mt76x2_dev *dev = file->private;
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       seq_printf(file, "allocated sequences:\t%d\n",
+                  dfs_pd->seq_stats.seq_pool_len);
+       seq_printf(file, "used sequences:\t\t%d\n",
+                  dfs_pd->seq_stats.seq_len);
+       seq_puts(file, "\n");
+
+       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
+               seq_printf(file, "engine: %d\n", i);
+               seq_printf(file, "  hw pattern detected:\t%d\n",
+                          dfs_pd->stats[i].hw_pattern);
+               seq_printf(file, "  hw pulse discarded:\t%d\n",
+                          dfs_pd->stats[i].hw_pulse_discarded);
+               seq_printf(file, "  sw pattern detected:\t%d\n",
+                          dfs_pd->stats[i].sw_pattern);
+       }
+
+       return 0;
+}
+
+static int
+mt76x2_dfs_stat_open(struct inode *inode, struct file *f)
+{
+       return single_open(f, mt76x2_dfs_stat_read, inode->i_private);
+}
+
+static const struct file_operations fops_dfs_stat = {
+       .open = mt76x2_dfs_stat_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int read_agc(struct seq_file *file, void *data)
+{
+       struct mt76x2_dev *dev = dev_get_drvdata(file->private);
+
+       seq_printf(file, "avg_rssi: %d\n", dev->cal.avg_rssi_all);
+       seq_printf(file, "low_gain: %d\n", dev->cal.low_gain);
+       seq_printf(file, "false_cca: %d\n", dev->cal.false_cca);
+       seq_printf(file, "agc_gain_adjust: %d\n", dev->cal.agc_gain_adjust);
+
+       return 0;
+}
+
+void mt76x2_init_debugfs(struct mt76x2_dev *dev)
+{
+       struct dentry *dir;
+
+       dir = mt76_register_debugfs(&dev->mt76);
+       if (!dir)
+               return;
+
+       debugfs_create_u8("temperature", 0400, dir, &dev->cal.temp);
+       debugfs_create_bool("tpc", 0600, dir, &dev->enable_tpc);
+
+       debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat);
+       debugfs_create_file("dfs_stats", 0400, dir, dev, &fops_dfs_stat);
+       debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir,
+                                   read_txpower);
+
+       debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc);
+}
+EXPORT_SYMBOL_GPL(mt76x2_init_debugfs);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/dfs.h b/drivers/net/wireless/mediatek/mt76/mt76x2/dfs.h
new file mode 100644 (file)
index 0000000..693f421
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2_DFS_H
+#define __MT76x2_DFS_H
+
+#include <linux/types.h>
+#include <linux/nl80211.h>
+
+#define MT_DFS_GP_INTERVAL             (10 << 4) /* 64 us unit */
+#define MT_DFS_NUM_ENGINES             4
+
+/* bbp params */
+#define MT_DFS_SYM_ROUND               0
+#define MT_DFS_DELTA_DELAY             2
+#define MT_DFS_VGA_MASK                        0
+#define MT_DFS_PWR_GAIN_OFFSET         3
+#define MT_DFS_PWR_DOWN_TIME           0xf
+#define MT_DFS_RX_PE_MASK              0xff
+#define MT_DFS_PKT_END_MASK            0
+#define MT_DFS_CH_EN                   0xf
+
+/* sw detector params */
+#define MT_DFS_EVENT_LOOP              64
+#define MT_DFS_SW_TIMEOUT              (HZ / 20)
+#define MT_DFS_EVENT_WINDOW            (HZ / 5)
+#define MT_DFS_SEQUENCE_WINDOW         (200 * (1 << 20))
+#define MT_DFS_EVENT_TIME_MARGIN       2000
+#define MT_DFS_PRI_MARGIN              4
+#define MT_DFS_SEQUENCE_TH             6
+
+#define MT_DFS_FCC_MAX_PRI             ((28570 << 1) + 1000)
+#define MT_DFS_FCC_MIN_PRI             (3000 - 2)
+#define MT_DFS_JP_MAX_PRI              ((80000 << 1) + 1000)
+#define MT_DFS_JP_MIN_PRI              (28500 - 2)
+#define MT_DFS_ETSI_MAX_PRI            (133333 + 125000 + 117647 + 1000)
+#define MT_DFS_ETSI_MIN_PRI            (4500 - 20)
+
+struct mt76x2_radar_specs {
+       u8 mode;
+       u16 avg_len;
+       u16 e_low;
+       u16 e_high;
+       u16 w_low;
+       u16 w_high;
+       u16 w_margin;
+       u32 t_low;
+       u32 t_high;
+       u16 t_margin;
+       u32 b_low;
+       u32 b_high;
+       u32 event_expiration;
+       u16 pwr_jmp;
+};
+
+#define MT_DFS_CHECK_EVENT(x)          ((x) != GENMASK(31, 0))
+#define MT_DFS_EVENT_ENGINE(x)         (((x) & BIT(31)) ? 2 : 0)
+#define MT_DFS_EVENT_TIMESTAMP(x)      ((x) & GENMASK(21, 0))
+#define MT_DFS_EVENT_WIDTH(x)          ((x) & GENMASK(11, 0))
+struct mt76x2_dfs_event {
+       unsigned long fetch_ts;
+       u32 ts;
+       u16 width;
+       u8 engine;
+};
+
+#define MT_DFS_EVENT_BUFLEN            256
+struct mt76x2_dfs_event_rb {
+       struct mt76x2_dfs_event data[MT_DFS_EVENT_BUFLEN];
+       int h_rb, t_rb;
+};
+
+struct mt76x2_dfs_sequence {
+       struct list_head head;
+       u32 first_ts;
+       u32 last_ts;
+       u32 pri;
+       u16 count;
+       u8 engine;
+};
+
+struct mt76x2_dfs_hw_pulse {
+       u8 engine;
+       u32 period;
+       u32 w1;
+       u32 w2;
+       u32 burst;
+};
+
+struct mt76x2_dfs_sw_detector_params {
+       u32 min_pri;
+       u32 max_pri;
+       u32 pri_margin;
+};
+
+struct mt76x2_dfs_engine_stats {
+       u32 hw_pattern;
+       u32 hw_pulse_discarded;
+       u32 sw_pattern;
+};
+
+struct mt76x2_dfs_seq_stats {
+       u32 seq_pool_len;
+       u32 seq_len;
+};
+
+struct mt76x2_dfs_pattern_detector {
+       enum nl80211_dfs_regions region;
+
+       u8 chirp_pulse_cnt;
+       u32 chirp_pulse_ts;
+
+       struct mt76x2_dfs_sw_detector_params sw_dpd_params;
+       struct mt76x2_dfs_event_rb event_rb[2];
+
+       struct list_head sequences;
+       struct list_head seq_pool;
+       struct mt76x2_dfs_seq_stats seq_stats;
+
+       unsigned long last_sw_check;
+       u32 last_event_ts;
+
+       struct mt76x2_dfs_engine_stats stats[MT_DFS_NUM_ENGINES];
+       struct tasklet_struct dfs_tasklet;
+};
+
+void mt76x2_dfs_init_params(struct mt76x2_dev *dev);
+void mt76x2_dfs_init_detector(struct mt76x2_dev *dev);
+void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev);
+void mt76x2_dfs_set_domain(struct mt76x2_dev *dev,
+                          enum nl80211_dfs_regions region);
+
+#endif /* __MT76x2_DFS_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c
new file mode 100644 (file)
index 0000000..55eda67
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include "mt76x2.h"
+#include "eeprom.h"
+
+#define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
+
+static int
+mt76x2_eeprom_copy(struct mt76x2_dev *dev, enum mt76x02_eeprom_field field,
+                  void *dest, int len)
+{
+       if (field + len > dev->mt76.eeprom.size)
+               return -1;
+
+       memcpy(dest, dev->mt76.eeprom.data + field, len);
+       return 0;
+}
+
+static int
+mt76x2_eeprom_get_macaddr(struct mt76x2_dev *dev)
+{
+       void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR;
+
+       memcpy(dev->mt76.macaddr, src, ETH_ALEN);
+       return 0;
+}
+
+static bool
+mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
+{
+       u16 *efuse_w = (u16 *) efuse;
+
+       if (efuse_w[MT_EE_NIC_CONF_0] != 0)
+               return false;
+
+       if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff)
+               return false;
+
+       if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0)
+               return false;
+
+       if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff)
+               return false;
+
+       if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0)
+               return false;
+
+       if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff)
+               return false;
+
+       return true;
+}
+
+static void
+mt76x2_apply_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
+{
+#define GROUP_5G(_id)                                                     \
+       MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
+       MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
+       MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
+       MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
+
+       static const u8 cal_free_bytes[] = {
+               MT_EE_XTAL_TRIM_1,
+               MT_EE_TX_POWER_EXT_PA_5G + 1,
+               MT_EE_TX_POWER_0_START_2G,
+               MT_EE_TX_POWER_0_START_2G + 1,
+               MT_EE_TX_POWER_1_START_2G,
+               MT_EE_TX_POWER_1_START_2G + 1,
+               GROUP_5G(0),
+               GROUP_5G(1),
+               GROUP_5G(2),
+               GROUP_5G(3),
+               GROUP_5G(4),
+               GROUP_5G(5),
+               MT_EE_RF_2G_TSSI_OFF_TXPOWER,
+               MT_EE_RF_2G_RX_HIGH_GAIN + 1,
+               MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN,
+               MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1,
+               MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN,
+               MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1,
+               MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN,
+               MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1,
+       };
+       u8 *eeprom = dev->mt76.eeprom.data;
+       u8 prev_grp0[4] = {
+               eeprom[MT_EE_TX_POWER_0_START_5G],
+               eeprom[MT_EE_TX_POWER_0_START_5G + 1],
+               eeprom[MT_EE_TX_POWER_1_START_5G],
+               eeprom[MT_EE_TX_POWER_1_START_5G + 1]
+       };
+       u16 val;
+       int i;
+
+       if (!mt76x2_has_cal_free_data(dev, efuse))
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) {
+               int offset = cal_free_bytes[i];
+
+               eeprom[offset] = efuse[offset];
+       }
+
+       if (!(efuse[MT_EE_TX_POWER_0_START_5G] |
+             efuse[MT_EE_TX_POWER_0_START_5G + 1]))
+               memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2);
+       if (!(efuse[MT_EE_TX_POWER_1_START_5G] |
+             efuse[MT_EE_TX_POWER_1_START_5G + 1]))
+               memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2);
+
+       val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT);
+       if (val != 0xffff)
+               eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff;
+
+       val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION);
+       if (val != 0xffff)
+               eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8;
+
+       val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG);
+       if (val != 0xffff)
+               eeprom[MT_EE_BT_PMUCFG] = val & 0xff;
+}
+
+static int mt76x2_check_eeprom(struct mt76x2_dev *dev)
+{
+       u16 val = get_unaligned_le16(dev->mt76.eeprom.data);
+
+       if (!val)
+               val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID);
+
+       switch (val) {
+       case 0x7662:
+       case 0x7612:
+               return 0;
+       default:
+               dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val);
+               return -EINVAL;
+       }
+}
+
+static int
+mt76x2_eeprom_load(struct mt76x2_dev *dev)
+{
+       void *efuse;
+       bool found;
+       int ret;
+
+       ret = mt76_eeprom_init(&dev->mt76, MT7662_EEPROM_SIZE);
+       if (ret < 0)
+               return ret;
+
+       found = ret;
+       if (found)
+               found = !mt76x2_check_eeprom(dev);
+
+       dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, MT7662_EEPROM_SIZE,
+                                         GFP_KERNEL);
+       dev->mt76.otp.size = MT7662_EEPROM_SIZE;
+       if (!dev->mt76.otp.data)
+               return -ENOMEM;
+
+       efuse = dev->mt76.otp.data;
+
+       if (mt76x02_get_efuse_data(&dev->mt76, 0, efuse,
+                                  MT7662_EEPROM_SIZE, MT_EE_READ))
+               goto out;
+
+       if (found) {
+               mt76x2_apply_cal_free_data(dev, efuse);
+       } else {
+               /* FIXME: check if efuse data is complete */
+               found = true;
+               memcpy(dev->mt76.eeprom.data, efuse, MT7662_EEPROM_SIZE);
+       }
+
+out:
+       if (!found)
+               return -ENOENT;
+
+       return 0;
+}
+
+static void
+mt76x2_set_rx_gain_group(struct mt76x2_dev *dev, u8 val)
+{
+       s8 *dest = dev->cal.rx.high_gain;
+
+       if (!mt76x02_field_valid(val)) {
+               dest[0] = 0;
+               dest[1] = 0;
+               return;
+       }
+
+       dest[0] = mt76x02_sign_extend(val, 4);
+       dest[1] = mt76x02_sign_extend(val >> 4, 4);
+}
+
+static void
+mt76x2_set_rssi_offset(struct mt76x2_dev *dev, int chain, u8 val)
+{
+       s8 *dest = dev->cal.rx.rssi_offset;
+
+       if (!mt76x02_field_valid(val)) {
+               dest[chain] = 0;
+               return;
+       }
+
+       dest[chain] = mt76x02_sign_extend_optional(val, 7);
+}
+
+static enum mt76x2_cal_channel_group
+mt76x2_get_cal_channel_group(int channel)
+{
+       if (channel >= 184 && channel <= 196)
+               return MT_CH_5G_JAPAN;
+       if (channel <= 48)
+               return MT_CH_5G_UNII_1;
+       if (channel <= 64)
+               return MT_CH_5G_UNII_2;
+       if (channel <= 114)
+               return MT_CH_5G_UNII_2E_1;
+       if (channel <= 144)
+               return MT_CH_5G_UNII_2E_2;
+       return MT_CH_5G_UNII_3;
+}
+
+static u8
+mt76x2_get_5g_rx_gain(struct mt76x2_dev *dev, u8 channel)
+{
+       enum mt76x2_cal_channel_group group;
+
+       group = mt76x2_get_cal_channel_group(channel);
+       switch (group) {
+       case MT_CH_5G_JAPAN:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN);
+       case MT_CH_5G_UNII_1:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8;
+       case MT_CH_5G_UNII_2:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN);
+       case MT_CH_5G_UNII_2E_1:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8;
+       case MT_CH_5G_UNII_2E_2:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN);
+       default:
+               return mt76x02_eeprom_get(&dev->mt76,
+                                         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8;
+       }
+}
+
+void mt76x2_read_rx_gain(struct mt76x2_dev *dev)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       int channel = chan->hw_value;
+       s8 lna_5g[3], lna_2g;
+       u8 lna;
+       u16 val;
+
+       if (chan->band == NL80211_BAND_2GHZ)
+               val = mt76x02_eeprom_get(&dev->mt76,
+                                        MT_EE_RF_2G_RX_HIGH_GAIN) >> 8;
+       else
+               val = mt76x2_get_5g_rx_gain(dev, channel);
+
+       mt76x2_set_rx_gain_group(dev, val);
+
+       mt76x02_get_rx_gain(&dev->mt76, chan->band, &val, &lna_2g, lna_5g);
+       mt76x2_set_rssi_offset(dev, 0, val);
+       mt76x2_set_rssi_offset(dev, 1, val >> 8);
+
+       dev->cal.rx.mcu_gain =  (lna_2g & 0xff);
+       dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8;
+       dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
+       dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
+
+       lna = mt76x02_get_lna_gain(&dev->mt76, &lna_2g, lna_5g, chan);
+       dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8);
+}
+EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
+
+void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
+                          struct ieee80211_channel *chan)
+{
+       bool is_5ghz;
+       u16 val;
+
+       is_5ghz = chan->band == NL80211_BAND_5GHZ;
+
+       memset(t, 0, sizeof(*t));
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_CCK);
+       t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val);
+       t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8);
+
+       if (is_5ghz)
+               val = mt76x02_eeprom_get(&dev->mt76,
+                                        MT_EE_TX_POWER_OFDM_5G_6M);
+       else
+               val = mt76x02_eeprom_get(&dev->mt76,
+                                        MT_EE_TX_POWER_OFDM_2G_6M);
+       t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val);
+       t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8);
+
+       if (is_5ghz)
+               val = mt76x02_eeprom_get(&dev->mt76,
+                                        MT_EE_TX_POWER_OFDM_5G_24M);
+       else
+               val = mt76x02_eeprom_get(&dev->mt76,
+                                        MT_EE_TX_POWER_OFDM_2G_24M);
+       t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val);
+       t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS0);
+       t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val);
+       t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS4);
+       t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val);
+       t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS8);
+       t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val);
+       t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS12);
+       t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val);
+       t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS0);
+       t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val);
+       t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS4);
+       t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val);
+       t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS8);
+       if (!is_5ghz)
+               val >>= 8;
+       t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8);
+
+       memcpy(t->stbc, t->ht, sizeof(t->stbc[0]) * 8);
+       t->stbc[8] = t->vht[8];
+       t->stbc[9] = t->vht[9];
+}
+EXPORT_SYMBOL_GPL(mt76x2_get_rate_power);
+
+static void
+mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
+                        struct ieee80211_channel *chan, int chain, int offset)
+{
+       int channel = chan->hw_value;
+       int delta_idx;
+       u8 data[6];
+       u16 val;
+
+       if (channel < 6)
+               delta_idx = 3;
+       else if (channel < 11)
+               delta_idx = 4;
+       else
+               delta_idx = 5;
+
+       mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
+
+       t->chain[chain].tssi_slope = data[0];
+       t->chain[chain].tssi_offset = data[1];
+       t->chain[chain].target_power = data[2];
+       t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
+       t->target_power = val >> 8;
+}
+
+static void
+mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
+                        struct ieee80211_channel *chan, int chain, int offset)
+{
+       int channel = chan->hw_value;
+       enum mt76x2_cal_channel_group group;
+       int delta_idx;
+       u16 val;
+       u8 data[5];
+
+       group = mt76x2_get_cal_channel_group(channel);
+       offset += group * MT_TX_POWER_GROUP_SIZE_5G;
+
+       if (channel >= 192)
+               delta_idx = 4;
+       else if (channel >= 184)
+               delta_idx = 3;
+       else if (channel < 44)
+               delta_idx = 3;
+       else if (channel < 52)
+               delta_idx = 4;
+       else if (channel < 58)
+               delta_idx = 3;
+       else if (channel < 98)
+               delta_idx = 4;
+       else if (channel < 106)
+               delta_idx = 3;
+       else if (channel < 116)
+               delta_idx = 4;
+       else if (channel < 130)
+               delta_idx = 3;
+       else if (channel < 149)
+               delta_idx = 4;
+       else if (channel < 157)
+               delta_idx = 3;
+       else
+               delta_idx = 4;
+
+       mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
+
+       t->chain[chain].tssi_slope = data[0];
+       t->chain[chain].tssi_offset = data[1];
+       t->chain[chain].target_power = data[2];
+       t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_RX_HIGH_GAIN);
+       t->target_power = val & 0xff;
+}
+
+void mt76x2_get_power_info(struct mt76x2_dev *dev,
+                          struct mt76x2_tx_power_info *t,
+                          struct ieee80211_channel *chan)
+{
+       u16 bw40, bw80;
+
+       memset(t, 0, sizeof(*t));
+
+       bw40 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW40);
+       bw80 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW80);
+
+       if (chan->band == NL80211_BAND_5GHZ) {
+               bw40 >>= 8;
+               mt76x2_get_power_info_5g(dev, t, chan, 0,
+                                        MT_EE_TX_POWER_0_START_5G);
+               mt76x2_get_power_info_5g(dev, t, chan, 1,
+                                        MT_EE_TX_POWER_1_START_5G);
+       } else {
+               mt76x2_get_power_info_2g(dev, t, chan, 0,
+                                        MT_EE_TX_POWER_0_START_2G);
+               mt76x2_get_power_info_2g(dev, t, chan, 1,
+                                        MT_EE_TX_POWER_1_START_2G);
+       }
+
+       if (mt76x02_tssi_enabled(&dev->mt76) ||
+           !mt76x02_field_valid(t->target_power))
+               t->target_power = t->chain[0].target_power;
+
+       t->delta_bw40 = mt76x02_rate_power_val(bw40);
+       t->delta_bw80 = mt76x02_rate_power_val(bw80);
+}
+EXPORT_SYMBOL_GPL(mt76x2_get_power_info);
+
+int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t)
+{
+       enum nl80211_band band = dev->mt76.chandef.chan->band;
+       u16 val, slope;
+       u8 bounds;
+
+       memset(t, 0, sizeof(*t));
+
+       if (!mt76x02_temp_tx_alc_enabled(&dev->mt76))
+               return -EINVAL;
+
+       if (!mt76x02_ext_pa_enabled(&dev->mt76, band))
+               return -EINVAL;
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_EXT_PA_5G) >> 8;
+       t->temp_25_ref = val & 0x7f;
+       if (band == NL80211_BAND_5GHZ) {
+               slope = mt76x02_eeprom_get(&dev->mt76,
+                                          MT_EE_RF_TEMP_COMP_SLOPE_5G);
+               bounds = mt76x02_eeprom_get(&dev->mt76,
+                                           MT_EE_TX_POWER_EXT_PA_5G);
+       } else {
+               slope = mt76x02_eeprom_get(&dev->mt76,
+                                          MT_EE_RF_TEMP_COMP_SLOPE_2G);
+               bounds = mt76x02_eeprom_get(&dev->mt76,
+                                           MT_EE_TX_POWER_DELTA_BW80) >> 8;
+       }
+
+       t->high_slope = slope & 0xff;
+       t->low_slope = slope >> 8;
+       t->lower_bound = 0 - (bounds & 0xf);
+       t->upper_bound = (bounds >> 4) & 0xf;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp);
+
+int mt76x2_eeprom_init(struct mt76x2_dev *dev)
+{
+       int ret;
+
+       ret = mt76x2_eeprom_load(dev);
+       if (ret)
+               return ret;
+
+       mt76x02_eeprom_parse_hw_cap(&dev->mt76);
+       mt76x2_eeprom_get_macaddr(dev);
+       mt76_eeprom_override(&dev->mt76);
+       dev->mt76.macaddr[0] &= ~BIT(1);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mt76x2_eeprom_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.h
new file mode 100644 (file)
index 0000000..33277c7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2_EEPROM_H
+#define __MT76x2_EEPROM_H
+
+#include "../mt76x02_eeprom.h"
+
+enum mt76x2_cal_channel_group {
+       MT_CH_5G_JAPAN,
+       MT_CH_5G_UNII_1,
+       MT_CH_5G_UNII_2,
+       MT_CH_5G_UNII_2E_1,
+       MT_CH_5G_UNII_2E_2,
+       MT_CH_5G_UNII_3,
+       __MT_CH_MAX
+};
+
+struct mt76x2_tx_power_info {
+       u8 target_power;
+
+       s8 delta_bw40;
+       s8 delta_bw80;
+
+       struct {
+               s8 tssi_slope;
+               s8 tssi_offset;
+               s8 target_power;
+               s8 delta;
+       } chain[MT_MAX_CHAINS];
+};
+
+struct mt76x2_temp_comp {
+       u8 temp_25_ref;
+       int lower_bound; /* J */
+       int upper_bound; /* J */
+       unsigned int high_slope; /* J / dB */
+       unsigned int low_slope; /* J / dB */
+};
+
+void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
+                          struct ieee80211_channel *chan);
+void mt76x2_get_power_info(struct mt76x2_dev *dev,
+                          struct mt76x2_tx_power_info *t,
+                          struct ieee80211_channel *chan);
+int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t);
+void mt76x2_read_rx_gain(struct mt76x2_dev *dev);
+
+static inline bool
+mt76x2_has_ext_lna(struct mt76x2_dev *dev)
+{
+       u32 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_1);
+
+       if (dev->mt76.chandef.chan->band == NL80211_BAND_2GHZ)
+               return val & MT_EE_NIC_CONF_1_LNA_EXT_2G;
+       else
+               return val & MT_EE_NIC_CONF_1_LNA_EXT_5G;
+}
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/init.c
new file mode 100644 (file)
index 0000000..d672771
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "eeprom.h"
+#include "../mt76x02_phy.h"
+
+static void
+mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable)
+{
+       u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
+
+       if (enable)
+               val |= (MT_WLAN_FUN_CTRL_WLAN_EN |
+                       MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
+       else
+               val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN |
+                        MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
+
+       mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
+       udelay(20);
+}
+
+void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable)
+{
+       u32 val;
+
+       if (!enable)
+               goto out;
+
+       val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
+
+       val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL;
+
+       if (val & MT_WLAN_FUN_CTRL_WLAN_EN) {
+               val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
+               mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
+               udelay(20);
+
+               val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
+       }
+
+       mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
+       udelay(20);
+
+out:
+       mt76x2_set_wlan_state(dev, enable);
+}
+EXPORT_SYMBOL_GPL(mt76x2_reset_wlan);
+
+void mt76_write_mac_initvals(struct mt76x2_dev *dev)
+{
+#define DEFAULT_PROT_CFG_CCK                           \
+       (FIELD_PREP(MT_PROT_CFG_RATE, 0x3) |            \
+        FIELD_PREP(MT_PROT_CFG_NAV, 1) |               \
+        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |     \
+        MT_PROT_CFG_RTS_THRESH)
+
+#define DEFAULT_PROT_CFG_OFDM                          \
+       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |         \
+        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
+        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |     \
+        MT_PROT_CFG_RTS_THRESH)
+
+#define DEFAULT_PROT_CFG_20                            \
+       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |         \
+        FIELD_PREP(MT_PROT_CFG_CTRL, 1) |              \
+        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
+        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17))
+
+#define DEFAULT_PROT_CFG_40                            \
+       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) |         \
+        FIELD_PREP(MT_PROT_CFG_CTRL, 1) |              \
+        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
+        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f))
+
+       static const struct mt76_reg_pair vals[] = {
+               /* Copied from MediaTek reference source */
+               { MT_PBF_SYS_CTRL,              0x00080c00 },
+               { MT_PBF_CFG,                   0x1efebcff },
+               { MT_FCE_PSE_CTRL,              0x00000001 },
+               { MT_MAC_SYS_CTRL,              0x0000000c },
+               { MT_MAX_LEN_CFG,               0x003e3f00 },
+               { MT_AMPDU_MAX_LEN_20M1S,       0xaaa99887 },
+               { MT_AMPDU_MAX_LEN_20M2S,       0x000000aa },
+               { MT_XIFS_TIME_CFG,             0x33a40d0a },
+               { MT_BKOFF_SLOT_CFG,            0x00000209 },
+               { MT_TBTT_SYNC_CFG,             0x00422010 },
+               { MT_PWR_PIN_CFG,               0x00000000 },
+               { 0x1238,                       0x001700c8 },
+               { MT_TX_SW_CFG0,                0x00101001 },
+               { MT_TX_SW_CFG1,                0x00010000 },
+               { MT_TX_SW_CFG2,                0x00000000 },
+               { MT_TXOP_CTRL_CFG,             0x0400583f },
+               { MT_TX_RTS_CFG,                0x00100020 },
+               { MT_TX_TIMEOUT_CFG,            0x000a2290 },
+               { MT_TX_RETRY_CFG,              0x47f01f0f },
+               { MT_EXP_ACK_TIME,              0x002c00dc },
+               { MT_TX_PROT_CFG6,              0xe3f42004 },
+               { MT_TX_PROT_CFG7,              0xe3f42084 },
+               { MT_TX_PROT_CFG8,              0xe3f42104 },
+               { MT_PIFS_TX_CFG,               0x00060fff },
+               { MT_RX_FILTR_CFG,              0x00015f97 },
+               { MT_LEGACY_BASIC_RATE,         0x0000017f },
+               { MT_HT_BASIC_RATE,             0x00004003 },
+               { MT_PN_PAD_MODE,               0x00000003 },
+               { MT_TXOP_HLDR_ET,              0x00000002 },
+               { 0xa44,                        0x00000000 },
+               { MT_HEADER_TRANS_CTRL_REG,     0x00000000 },
+               { MT_TSO_CTRL,                  0x00000000 },
+               { MT_AUX_CLK_CFG,               0x00000000 },
+               { MT_DACCLK_EN_DLY_CFG,         0x00000000 },
+               { MT_TX_ALC_CFG_4,              0x00000000 },
+               { MT_TX_ALC_VGA3,               0x00000000 },
+               { MT_TX_PWR_CFG_0,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_1,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_2,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_3,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_4,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_7,              0x3a3a3a3a },
+               { MT_TX_PWR_CFG_8,              0x0000003a },
+               { MT_TX_PWR_CFG_9,              0x0000003a },
+               { MT_EFUSE_CTRL,                0x0000d000 },
+               { MT_PAUSE_ENABLE_CONTROL1,     0x0000000a },
+               { MT_FCE_WLAN_FLOW_CONTROL1,    0x60401c18 },
+               { MT_WPDMA_DELAY_INT_CFG,       0x94ff0000 },
+               { MT_TX_SW_CFG3,                0x00000004 },
+               { MT_HT_FBK_TO_LEGACY,          0x00001818 },
+               { MT_VHT_HT_FBK_CFG1,           0xedcba980 },
+               { MT_PROT_AUTO_TX_CFG,          0x00830083 },
+               { MT_HT_CTRL_CFG,               0x000001ff },
+       };
+       struct mt76_reg_pair prot_vals[] = {
+               { MT_CCK_PROT_CFG,              DEFAULT_PROT_CFG_CCK },
+               { MT_OFDM_PROT_CFG,             DEFAULT_PROT_CFG_OFDM },
+               { MT_MM20_PROT_CFG,             DEFAULT_PROT_CFG_20 },
+               { MT_MM40_PROT_CFG,             DEFAULT_PROT_CFG_40 },
+               { MT_GF20_PROT_CFG,             DEFAULT_PROT_CFG_20 },
+               { MT_GF40_PROT_CFG,             DEFAULT_PROT_CFG_40 },
+       };
+
+       mt76_wr_rp(dev, 0, vals, ARRAY_SIZE(vals));
+       mt76_wr_rp(dev, 0, prot_vals, ARRAY_SIZE(prot_vals));
+}
+EXPORT_SYMBOL_GPL(mt76_write_mac_initvals);
+
+void mt76x2_init_device(struct mt76x2_dev *dev)
+{
+       struct ieee80211_hw *hw = mt76_hw(dev);
+
+       hw->queues = 4;
+       hw->max_rates = 1;
+       hw->max_report_rates = 7;
+       hw->max_rate_tries = 1;
+       hw->extra_tx_headroom = 2;
+
+       hw->sta_data_size = sizeof(struct mt76x02_sta);
+       hw->vif_data_size = sizeof(struct mt76x02_vif);
+
+       ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
+       ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
+
+       dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
+       dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
+
+       dev->mt76.chainmask = 0x202;
+       dev->mt76.global_wcid.idx = 255;
+       dev->mt76.global_wcid.hw_key_idx = -1;
+       dev->slottime = 9;
+
+       /* init antenna configuration */
+       dev->mt76.antenna_mask = 3;
+}
+EXPORT_SYMBOL_GPL(mt76x2_init_device);
+
+void mt76x2_init_txpower(struct mt76x2_dev *dev,
+                        struct ieee80211_supported_band *sband)
+{
+       struct ieee80211_channel *chan;
+       struct mt76x2_tx_power_info txp;
+       struct mt76_rate_power t = {};
+       int target_power;
+       int i;
+
+       for (i = 0; i < sband->n_channels; i++) {
+               chan = &sband->channels[i];
+
+               mt76x2_get_power_info(dev, &txp, chan);
+
+               target_power = max_t(int, (txp.chain[0].target_power +
+                                          txp.chain[0].delta),
+                                         (txp.chain[1].target_power +
+                                          txp.chain[1].delta));
+
+               mt76x2_get_rate_power(dev, &t, chan);
+
+               chan->max_power = mt76x02_get_max_rate_power(&t) +
+                                 target_power;
+               chan->max_power /= 2;
+
+               /* convert to combined output power on 2x2 devices */
+               chan->max_power += 3;
+       }
+}
+EXPORT_SYMBOL_GPL(mt76x2_init_txpower);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
new file mode 100644 (file)
index 0000000..568bac7
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_util.h"
+
+void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force)
+{
+       bool stopped = false;
+       u32 rts_cfg;
+       int i;
+
+       mt76_wr(dev, MT_MAC_SYS_CTRL, 0);
+
+       rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
+       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
+
+       /* Wait for MAC to become idle */
+       for (i = 0; i < 300; i++) {
+               if ((mt76_rr(dev, MT_MAC_STATUS) &
+                    (MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) ||
+                   mt76_rr(dev, MT_BBP(IBI, 12))) {
+                       udelay(1);
+                       continue;
+               }
+
+               stopped = true;
+               break;
+       }
+
+       if (force && !stopped) {
+               mt76_set(dev, MT_BBP(CORE, 4), BIT(1));
+               mt76_clear(dev, MT_BBP(CORE, 4), BIT(1));
+
+               mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
+               mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
+       }
+
+       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mac_stop);
+
+void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi,
+                          struct sk_buff *skb, struct mt76_wcid *wcid,
+                          struct ieee80211_sta *sta, int len)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rate = &info->control.rates[0];
+       struct ieee80211_key_conf *key = info->control.hw_key;
+       u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
+       u8 nss;
+       s8 txpwr_adj, max_txpwr_adj;
+       u8 ccmp_pn[8];
+
+       memset(txwi, 0, sizeof(*txwi));
+
+       if (wcid)
+               txwi->wcid = wcid->idx;
+       else
+               txwi->wcid = 0xff;
+
+       txwi->pktid = 1;
+
+       if (wcid && wcid->sw_iv && key) {
+               u64 pn = atomic64_inc_return(&key->tx_pn);
+               ccmp_pn[0] = pn;
+               ccmp_pn[1] = pn >> 8;
+               ccmp_pn[2] = 0;
+               ccmp_pn[3] = 0x20 | (key->keyidx << 6);
+               ccmp_pn[4] = pn >> 16;
+               ccmp_pn[5] = pn >> 24;
+               ccmp_pn[6] = pn >> 32;
+               ccmp_pn[7] = pn >> 40;
+               txwi->iv = *((__le32 *)&ccmp_pn[0]);
+               txwi->eiv = *((__le32 *)&ccmp_pn[1]);
+       }
+
+       spin_lock_bh(&dev->mt76.lock);
+       if (wcid && (rate->idx < 0 || !rate->count)) {
+               txwi->rate = wcid->tx_rate;
+               max_txpwr_adj = wcid->max_txpwr_adj;
+               nss = wcid->tx_rate_nss;
+       } else {
+               txwi->rate = mt76x02_mac_tx_rate_val(&dev->mt76, rate, &nss);
+               max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(&dev->mt76, rate);
+       }
+       spin_unlock_bh(&dev->mt76.lock);
+
+       txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf,
+                                           max_txpwr_adj);
+       txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj);
+
+       if (mt76xx_rev(dev) >= MT76XX_REV_E4)
+               txwi->txstream = 0x13;
+       else if (mt76xx_rev(dev) >= MT76XX_REV_E3 &&
+                !(txwi->rate & cpu_to_le16(rate_ht_mask)))
+               txwi->txstream = 0x93;
+
+       mt76x02_mac_fill_txwi(txwi, skb, sta, len, nss);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi);
+
+int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain)
+{
+       struct mt76x2_rx_freq_cal *cal = &dev->cal.rx;
+
+       rssi += cal->rssi_offset[chain];
+       rssi -= cal->lna_gain;
+
+       return rssi;
+}
+
+static struct mt76x02_sta *
+mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx)
+{
+       struct mt76_wcid *wcid;
+
+       if (idx >= ARRAY_SIZE(dev->mt76.wcid))
+               return NULL;
+
+       wcid = rcu_dereference(dev->mt76.wcid[idx]);
+       if (!wcid)
+               return NULL;
+
+       return container_of(wcid, struct mt76x02_sta, wcid);
+}
+
+static struct mt76_wcid *
+mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x02_sta *sta,
+                      bool unicast)
+{
+       if (!sta)
+               return NULL;
+
+       if (unicast)
+               return &sta->wcid;
+       else
+               return &sta->vif->group_wcid;
+}
+
+int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
+                         void *rxi)
+{
+       struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
+       struct mt76x02_rxwi *rxwi = rxi;
+       struct mt76x02_sta *sta;
+       u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
+       u32 ctl = le32_to_cpu(rxwi->ctl);
+       u16 rate = le16_to_cpu(rxwi->rate);
+       u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
+       bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
+       int pad_len = 0;
+       u8 pn_len;
+       u8 wcid;
+       int len;
+
+       if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
+               return -EINVAL;
+
+       if (rxinfo & MT_RXINFO_L2PAD)
+               pad_len += 2;
+
+       if (rxinfo & MT_RXINFO_DECRYPT) {
+               status->flag |= RX_FLAG_DECRYPTED;
+               status->flag |= RX_FLAG_MMIC_STRIPPED;
+               status->flag |= RX_FLAG_MIC_STRIPPED;
+               status->flag |= RX_FLAG_IV_STRIPPED;
+       }
+
+       wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
+       sta = mt76x2_rx_get_sta(dev, wcid);
+       status->wcid = mt76x2_rx_get_sta_wcid(dev, sta, unicast);
+
+       len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
+       pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
+       if (pn_len) {
+               int offset = ieee80211_get_hdrlen_from_skb(skb) + pad_len;
+               u8 *data = skb->data + offset;
+
+               status->iv[0] = data[7];
+               status->iv[1] = data[6];
+               status->iv[2] = data[5];
+               status->iv[3] = data[4];
+               status->iv[4] = data[1];
+               status->iv[5] = data[0];
+
+               /*
+                * Driver CCMP validation can't deal with fragments.
+                * Let mac80211 take care of it.
+                */
+               if (rxinfo & MT_RXINFO_FRAG) {
+                       status->flag &= ~RX_FLAG_IV_STRIPPED;
+               } else {
+                       pad_len += pn_len << 2;
+                       len -= pn_len << 2;
+               }
+       }
+
+       mt76x02_remove_hdr_pad(skb, pad_len);
+
+       if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
+               status->aggr = true;
+
+       if (WARN_ON_ONCE(len > skb->len))
+               return -EINVAL;
+
+       pskb_trim(skb, len);
+       status->chains = BIT(0) | BIT(1);
+       status->chain_signal[0] = mt76x2_mac_get_rssi(dev, rxwi->rssi[0], 0);
+       status->chain_signal[1] = mt76x2_mac_get_rssi(dev, rxwi->rssi[1], 1);
+       status->signal = max(status->chain_signal[0], status->chain_signal[1]);
+       status->freq = dev->mt76.chandef.chan->center_freq;
+       status->band = dev->mt76.chandef.chan->band;
+
+       status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
+       status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
+
+       if (sta) {
+               ewma_signal_add(&sta->rssi, status->signal);
+               sta->inactive_count = 0;
+       }
+
+       return mt76x02_mac_process_rate(status, rate);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mac_process_rx);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mac.h
new file mode 100644 (file)
index 0000000..b2176f9
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2_MAC_H
+#define __MT76x2_MAC_H
+
+#include "../mt76.h"
+#include "../mt76x02_mac.h"
+
+struct mt76x2_dev;
+struct mt76x2_sta;
+struct mt76x02_vif;
+
+struct mt76x2_tx_info {
+       unsigned long jiffies;
+       u8 tries;
+
+       u8 wcid;
+       u8 pktid;
+       u8 retry;
+};
+
+static inline struct mt76x2_tx_info *
+mt76x2_skb_tx_info(struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
+       return (void *) info->status.status_driver_data;
+}
+
+int mt76x2_mac_start(struct mt76x2_dev *dev);
+void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force);
+void mt76x2_mac_resume(struct mt76x2_dev *dev);
+void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr);
+
+int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
+                         void *rxi);
+void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi,
+                          struct sk_buff *skb, struct mt76_wcid *wcid,
+                          struct ieee80211_sta *sta, int len);
+
+int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx,
+                         struct sk_buff *skb);
+void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val);
+
+void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq);
+void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev);
+
+void mt76x2_mac_work(struct work_struct *work);
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.c
new file mode 100644 (file)
index 0000000..86b0953
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+
+#include "mt76x2.h"
+#include "mcu.h"
+#include "eeprom.h"
+#include "../mt76x02_dma.h"
+
+int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw,
+                          u8 bw_index, bool scan)
+{
+       struct sk_buff *skb;
+       struct {
+               u8 idx;
+               u8 scan;
+               u8 bw;
+               u8 _pad0;
+
+               __le16 chainmask;
+               u8 ext_chan;
+               u8 _pad1;
+
+       } __packed __aligned(4) msg = {
+               .idx = channel,
+               .scan = scan,
+               .bw = bw,
+               .chainmask = cpu_to_le16(dev->mt76.chainmask),
+       };
+
+       /* first set the channel without the extension channel info */
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true);
+
+       usleep_range(5000, 10000);
+
+       msg.ext_chan = 0xe0 + bw_index;
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel);
+
+int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level,
+                      u8 channel)
+{
+       struct mt76_dev *mdev = &dev->mt76;
+       struct sk_buff *skb;
+       struct {
+               u8 cr_mode;
+               u8 temp;
+               u8 ch;
+               u8 _pad0;
+
+               __le32 cfg;
+       } __packed __aligned(4) msg = {
+               .cr_mode = type,
+               .temp = temp_level,
+               .ch = channel,
+       };
+       u32 val;
+
+       val = BIT(31);
+       val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
+       val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
+       msg.cfg = cpu_to_le32(val);
+
+       /* first set the channel without the extension channel info */
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr);
+
+int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain,
+                        bool force)
+{
+       struct sk_buff *skb;
+       struct {
+               __le32 channel;
+               __le32 gain_val;
+       } __packed __aligned(4) msg = {
+               .channel = cpu_to_le32(channel),
+               .gain_val = cpu_to_le32(gain),
+       };
+
+       if (force)
+               msg.channel |= cpu_to_le32(BIT(31));
+
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain);
+
+int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev,
+                        struct mt76x2_tssi_comp *tssi_data)
+{
+       struct sk_buff *skb;
+       struct {
+               __le32 id;
+               struct mt76x2_tssi_comp data;
+       } __packed __aligned(4) msg = {
+               .id = cpu_to_le32(MCU_CAL_TSSI_COMP),
+               .data = *tssi_data,
+       };
+
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true);
+}
+EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mcu.h
new file mode 100644 (file)
index 0000000..98a73e2
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2_MCU_H
+#define __MT76x2_MCU_H
+
+#include "../mt76x02_mcu.h"
+
+/* Register definitions */
+#define MT_MCU_CPU_CTL                 0x0704
+#define MT_MCU_CLOCK_CTL               0x0708
+#define MT_MCU_PCIE_REMAP_BASE1                0x0740
+#define MT_MCU_PCIE_REMAP_BASE2                0x0744
+#define MT_MCU_PCIE_REMAP_BASE3                0x0748
+
+#define MT_LED_CTRL                    0x0770
+#define MT_LED_CTRL_REPLAY(_n)         BIT(0 + (8 * (_n)))
+#define MT_LED_CTRL_POLARITY(_n)       BIT(1 + (8 * (_n)))
+#define MT_LED_CTRL_TX_BLINK_MODE(_n)  BIT(2 + (8 * (_n)))
+#define MT_LED_CTRL_KICK(_n)           BIT(7 + (8 * (_n)))
+
+#define MT_LED_TX_BLINK_0              0x0774
+#define MT_LED_TX_BLINK_1              0x0778
+
+#define MT_LED_S0_BASE                 0x077C
+#define MT_LED_S0(_n)                  (MT_LED_S0_BASE + 8 * (_n))
+#define MT_LED_S1_BASE                 0x0780
+#define MT_LED_S1(_n)                  (MT_LED_S1_BASE + 8 * (_n))
+#define MT_LED_STATUS_OFF_MASK         GENMASK(31, 24)
+#define MT_LED_STATUS_OFF(_v)          (((_v) << __ffs(MT_LED_STATUS_OFF_MASK)) & \
+                                        MT_LED_STATUS_OFF_MASK)
+#define MT_LED_STATUS_ON_MASK          GENMASK(23, 16)
+#define MT_LED_STATUS_ON(_v)           (((_v) << __ffs(MT_LED_STATUS_ON_MASK)) & \
+                                        MT_LED_STATUS_ON_MASK)
+#define MT_LED_STATUS_DURATION_MASK    GENMASK(15, 8)
+#define MT_LED_STATUS_DURATION(_v)     (((_v) << __ffs(MT_LED_STATUS_DURATION_MASK)) & \
+                                        MT_LED_STATUS_DURATION_MASK)
+
+#define MT_MCU_ROM_PATCH_OFFSET                0x80000
+#define MT_MCU_ROM_PATCH_ADDR          0x90000
+
+#define MT_MCU_ILM_OFFSET              0x80000
+
+#define MT_MCU_DLM_OFFSET              0x100000
+#define MT_MCU_DLM_ADDR                        0x90000
+#define MT_MCU_DLM_ADDR_E3             0x90800
+
+enum mcu_calibration {
+       MCU_CAL_R = 1,
+       MCU_CAL_TEMP_SENSOR,
+       MCU_CAL_RXDCOC,
+       MCU_CAL_RC,
+       MCU_CAL_SX_LOGEN,
+       MCU_CAL_LC,
+       MCU_CAL_TX_LOFT,
+       MCU_CAL_TXIQ,
+       MCU_CAL_TSSI,
+       MCU_CAL_TSSI_COMP,
+       MCU_CAL_DPD,
+       MCU_CAL_RXIQC_FI,
+       MCU_CAL_RXIQC_FD,
+       MCU_CAL_PWRON,
+       MCU_CAL_TX_SHAPING,
+};
+
+enum mt76x2_mcu_cr_mode {
+       MT_RF_CR,
+       MT_BBP_CR,
+       MT_RF_BBP_CR,
+       MT_HL_TEMP_CR_UPDATE,
+};
+
+struct mt76x2_tssi_comp {
+       u8 pa_mode;
+       u8 cal_mode;
+       u16 pad;
+
+       u8 slope0;
+       u8 slope1;
+       u8 offset0;
+       u8 offset1;
+} __packed __aligned(4);
+
+int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, struct mt76x2_tssi_comp *tssi_data);
+int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain,
+                        bool force);
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h
new file mode 100644 (file)
index 0000000..ecbb9e4
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2_H
+#define __MT76x2_H
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mutex.h>
+#include <linux/bitops.h>
+#include <linux/kfifo.h>
+
+#define MT7662_FIRMWARE                "mt7662.bin"
+#define MT7662_ROM_PATCH       "mt7662_rom_patch.bin"
+#define MT7662_EEPROM_SIZE     512
+
+#define MT7662U_FIRMWARE       "mediatek/mt7662u.bin"
+#define MT7662U_ROM_PATCH      "mediatek/mt7662u_rom_patch.bin"
+
+#define MT_MAX_CHAINS          2
+
+#define MT_CALIBRATE_INTERVAL  HZ
+
+#include "../mt76.h"
+#include "../mt76x02_regs.h"
+#include "mac.h"
+#include "dfs.h"
+
+struct mt76x2_rx_freq_cal {
+       s8 high_gain[MT_MAX_CHAINS];
+       s8 rssi_offset[MT_MAX_CHAINS];
+       s8 lna_gain;
+       u32 mcu_gain;
+};
+
+struct mt76x2_calibration {
+       struct mt76x2_rx_freq_cal rx;
+
+       u8 agc_gain_init[MT_MAX_CHAINS];
+       u8 agc_gain_cur[MT_MAX_CHAINS];
+
+       u16 false_cca;
+       s8 avg_rssi_all;
+       s8 agc_gain_adjust;
+       s8 low_gain;
+
+       u8 temp;
+
+       bool init_cal_done;
+       bool tssi_cal_done;
+       bool tssi_comp_pending;
+       bool dpd_cal_done;
+       bool channel_cal_done;
+};
+
+struct mt76x2_dev {
+       struct mt76_dev mt76; /* must be first */
+
+       struct mac_address macaddr_list[8];
+
+       struct mutex mutex;
+
+       u8 txdone_seq;
+       DECLARE_KFIFO_PTR(txstatus_fifo, struct mt76x02_tx_status);
+
+       struct sk_buff *rx_head;
+
+       struct tasklet_struct tx_tasklet;
+       struct tasklet_struct pre_tbtt_tasklet;
+       struct delayed_work cal_work;
+       struct delayed_work mac_work;
+
+       u32 aggr_stats[32];
+
+       struct sk_buff *beacons[8];
+       u8 beacon_mask;
+       u8 beacon_data_mask;
+
+       u8 tbtt_count;
+       u16 beacon_int;
+
+       struct mt76x2_calibration cal;
+
+       s8 target_power;
+       s8 target_power_delta[2];
+       bool enable_tpc;
+
+       u8 coverage_class;
+       u8 slottime;
+
+       struct mt76x2_dfs_pattern_detector dfs_pd;
+};
+
+static inline bool is_mt7612(struct mt76x2_dev *dev)
+{
+       return mt76_chip(&dev->mt76) == 0x7612;
+}
+
+static inline bool mt76x2_channel_silent(struct mt76x2_dev *dev)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+
+       return ((chan->flags & IEEE80211_CHAN_RADAR) &&
+               chan->dfs_state != NL80211_DFS_AVAILABLE);
+}
+
+extern const struct ieee80211_ops mt76x2_ops;
+
+struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev);
+int mt76x2_register_device(struct mt76x2_dev *dev);
+void mt76x2_init_debugfs(struct mt76x2_dev *dev);
+void mt76x2_init_device(struct mt76x2_dev *dev);
+
+irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance);
+void mt76x2_phy_power_on(struct mt76x2_dev *dev);
+int mt76x2_init_hardware(struct mt76x2_dev *dev);
+void mt76x2_stop_hardware(struct mt76x2_dev *dev);
+int mt76x2_eeprom_init(struct mt76x2_dev *dev);
+int mt76x2_apply_calibration_data(struct mt76x2_dev *dev, int channel);
+void mt76x2_set_tx_ackto(struct mt76x2_dev *dev);
+
+void mt76x2_phy_set_antenna(struct mt76x2_dev *dev);
+int mt76x2_phy_start(struct mt76x2_dev *dev);
+int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
+                        struct cfg80211_chan_def *chandef);
+int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain);
+void mt76x2_phy_calibrate(struct work_struct *work);
+void mt76x2_phy_set_txpower(struct mt76x2_dev *dev);
+
+int mt76x2_mcu_init(struct mt76x2_dev *dev);
+int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw,
+                          u8 bw_index, bool scan);
+int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level,
+                      u8 channel);
+
+void mt76x2_tx_tasklet(unsigned long data);
+void mt76x2_dma_cleanup(struct mt76x2_dev *dev);
+
+void mt76x2_cleanup(struct mt76x2_dev *dev);
+
+void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
+              struct sk_buff *skb);
+int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
+                         struct sk_buff *skb, struct mt76_queue *q,
+                         struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+                         u32 *tx_info);
+void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+                           struct mt76_queue_entry *e, bool flush);
+void mt76x2_mac_set_tx_protection(struct mt76x2_dev *dev, u32 val);
+
+void mt76x2_pre_tbtt_tasklet(unsigned long arg);
+
+void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q);
+void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+                        struct sk_buff *skb);
+
+void mt76x2_sta_ps(struct mt76_dev *dev, struct ieee80211_sta *sta, bool ps);
+
+void mt76x2_update_channel(struct mt76_dev *mdev);
+
+s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *dev,
+                              const struct ieee80211_tx_rate *rate);
+s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj);
+void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr);
+
+
+void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable);
+void mt76x2_init_txpower(struct mt76x2_dev *dev,
+                        struct ieee80211_supported_band *sband);
+void mt76_write_mac_initvals(struct mt76x2_dev *dev);
+
+int mt76x2_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                  struct ieee80211_sta *sta);
+int mt76x2_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                     struct ieee80211_sta *sta);
+void mt76x2_remove_interface(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif);
+int mt76x2_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                  u16 queue, const struct ieee80211_tx_queue_params *params);
+void mt76x2_txq_init(struct mt76x2_dev *dev, struct ieee80211_txq *txq);
+
+void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait);
+void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev,
+                                enum nl80211_band band);
+void mt76x2_configure_tx_delay(struct mt76x2_dev *dev,
+                              enum nl80211_band band, u8 bw);
+void mt76x2_phy_set_bw(struct mt76x2_dev *dev, int width, u8 ctrl);
+void mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper);
+int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev);
+void mt76x2_apply_gain_adj(struct mt76x2_dev *dev);
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2u.h
new file mode 100644 (file)
index 0000000..969e8e1
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __MT76x2U_H
+#define __MT76x2U_H
+
+#include <linux/device.h>
+
+#include "mt76x2.h"
+#include "mcu.h"
+#include "../mt76x02_dma.h"
+
+#define MT7612U_EEPROM_SIZE            512
+
+#define MT_USB_AGGR_SIZE_LIMIT         21 /* 1024B unit */
+#define MT_USB_AGGR_TIMEOUT            0x80 /* 33ns unit */
+
+extern const struct ieee80211_ops mt76x2u_ops;
+
+struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev);
+int mt76x2u_register_device(struct mt76x2_dev *dev);
+int mt76x2u_init_hardware(struct mt76x2_dev *dev);
+void mt76x2u_cleanup(struct mt76x2_dev *dev);
+void mt76x2u_stop_hw(struct mt76x2_dev *dev);
+
+int mt76x2u_mac_reset(struct mt76x2_dev *dev);
+void mt76x2u_mac_resume(struct mt76x2_dev *dev);
+int mt76x2u_mac_start(struct mt76x2_dev *dev);
+int mt76x2u_mac_stop(struct mt76x2_dev *dev);
+
+int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
+                           struct cfg80211_chan_def *chandef);
+void mt76x2u_phy_calibrate(struct work_struct *work);
+void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev);
+
+void mt76x2u_mcu_complete_urb(struct urb *urb);
+int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap,
+                               bool ext, int rssi, u32 false_cca);
+int mt76x2u_mcu_init(struct mt76x2_dev *dev);
+int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev);
+
+int mt76x2u_alloc_queues(struct mt76x2_dev *dev);
+void mt76x2u_queues_deinit(struct mt76x2_dev *dev);
+void mt76x2u_stop_queues(struct mt76x2_dev *dev);
+int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
+                          struct sk_buff *skb, struct mt76_queue *q,
+                          struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+                          u32 *tx_info);
+int mt76x2u_skb_dma_info(struct sk_buff *skb, enum dma_msg_port port,
+                        u32 flags);
+
+#endif /* __MT76x2U_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
new file mode 100644 (file)
index 0000000..49556be
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "mt76x2.h"
+#include "trace.h"
+
+static const struct pci_device_id mt76pci_device_table[] = {
+       { PCI_DEVICE(0x14c3, 0x7662) },
+       { PCI_DEVICE(0x14c3, 0x7612) },
+       { PCI_DEVICE(0x14c3, 0x7602) },
+       { },
+};
+
+static int
+mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       struct mt76x2_dev *dev;
+       int ret;
+
+       ret = pcim_enable_device(pdev);
+       if (ret)
+               return ret;
+
+       ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
+       if (ret)
+               return ret;
+
+       pci_set_master(pdev);
+
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret)
+               return ret;
+
+       dev = mt76x2_alloc_device(&pdev->dev);
+       if (!dev)
+               return -ENOMEM;
+
+       mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
+       mt76x2_reset_wlan(dev, false);
+
+       dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION);
+       dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev);
+
+       ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x2_irq_handler,
+                              IRQF_SHARED, KBUILD_MODNAME, dev);
+       if (ret)
+               goto error;
+
+       ret = mt76x2_register_device(dev);
+       if (ret)
+               goto error;
+
+       /* Fix up ASPM configuration */
+
+       /* RG_SSUSB_G1_CDR_BIR_LTR = 0x9 */
+       mt76_rmw_field(dev, 0x15a10, 0x1f << 16, 0x9);
+
+       /* RG_SSUSB_G1_CDR_BIC_LTR = 0xf */
+       mt76_rmw_field(dev, 0x15a0c, 0xf << 28, 0xf);
+
+       /* RG_SSUSB_CDR_BR_PE1D = 0x3 */
+       mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3);
+
+       return 0;
+
+error:
+       ieee80211_free_hw(mt76_hw(dev));
+       return ret;
+}
+
+static void
+mt76pci_remove(struct pci_dev *pdev)
+{
+       struct mt76_dev *mdev = pci_get_drvdata(pdev);
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+
+       mt76_unregister_device(mdev);
+       mt76x2_cleanup(dev);
+       ieee80211_free_hw(mdev->hw);
+}
+
+MODULE_DEVICE_TABLE(pci, mt76pci_device_table);
+MODULE_FIRMWARE(MT7662_FIRMWARE);
+MODULE_FIRMWARE(MT7662_ROM_PATCH);
+MODULE_LICENSE("Dual BSD/GPL");
+
+static struct pci_driver mt76pci_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = mt76pci_device_table,
+       .probe          = mt76pci_probe,
+       .remove         = mt76pci_remove,
+};
+
+module_pci_driver(mt76pci_driver);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_core.c
new file mode 100644 (file)
index 0000000..b343742
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include "mt76x2.h"
+#include "trace.h"
+#include "../mt76x02_util.h"
+
+void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
+{
+       mt76x02_irq_enable(mdev, MT_INT_RX_DONE(q));
+}
+
+irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance)
+{
+       struct mt76x2_dev *dev = dev_instance;
+       u32 intr;
+
+       intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
+       mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
+
+       if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state))
+               return IRQ_NONE;
+
+       trace_dev_irq(dev, intr, dev->mt76.mmio.irqmask);
+
+       intr &= dev->mt76.mmio.irqmask;
+
+       if (intr & MT_INT_TX_DONE_ALL) {
+               mt76x02_irq_disable(&dev->mt76, MT_INT_TX_DONE_ALL);
+               tasklet_schedule(&dev->tx_tasklet);
+       }
+
+       if (intr & MT_INT_RX_DONE(0)) {
+               mt76x02_irq_disable(&dev->mt76, MT_INT_RX_DONE(0));
+               napi_schedule(&dev->mt76.napi[0]);
+       }
+
+       if (intr & MT_INT_RX_DONE(1)) {
+               mt76x02_irq_disable(&dev->mt76, MT_INT_RX_DONE(1));
+               napi_schedule(&dev->mt76.napi[1]);
+       }
+
+       if (intr & MT_INT_PRE_TBTT)
+               tasklet_schedule(&dev->pre_tbtt_tasklet);
+
+       /* send buffered multicast frames now */
+       if (intr & MT_INT_TBTT)
+               mt76_queue_kick(dev, &dev->mt76.q_tx[MT_TXQ_PSD]);
+
+       if (intr & MT_INT_TX_STAT) {
+               mt76x2_mac_poll_tx_status(dev, true);
+               tasklet_schedule(&dev->tx_tasklet);
+       }
+
+       if (intr & MT_INT_GPTIMER) {
+               mt76x02_irq_disable(&dev->mt76, MT_INT_GPTIMER);
+               tasklet_schedule(&dev->dfs_pd.dfs_tasklet);
+       }
+
+       return IRQ_HANDLED;
+}
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dfs.c
new file mode 100644 (file)
index 0000000..18926a6
--- /dev/null
@@ -0,0 +1,878 @@
+/*
+ * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_util.h"
+
+#define RADAR_SPEC(m, len, el, eh, wl, wh,             \
+                  w_tolerance, tl, th, t_tolerance,    \
+                  bl, bh, event_exp, power_jmp)        \
+{                                                      \
+       .mode = m,                                      \
+       .avg_len = len,                                 \
+       .e_low = el,                                    \
+       .e_high = eh,                                   \
+       .w_low = wl,                                    \
+       .w_high = wh,                                   \
+       .w_margin = w_tolerance,                        \
+       .t_low = tl,                                    \
+       .t_high = th,                                   \
+       .t_margin = t_tolerance,                        \
+       .b_low = bl,                                    \
+       .b_high = bh,                                   \
+       .event_expiration = event_exp,                  \
+       .pwr_jmp = power_jmp                            \
+}
+
+static const struct mt76x2_radar_specs etsi_radar_specs[] = {
+       /* 20MHz */
+       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
+                  0x7fffffff, 0x155cc0, 0x19dd),
+       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
+                  0x7fffffff, 0x2191c0, 0x15cc),
+       /* 40MHz */
+       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
+                  0x7fffffff, 0x155cc0, 0x19dd),
+       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
+                  0x7fffffff, 0x2191c0, 0x15cc),
+       /* 80MHz */
+       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
+                  0x7fffffff, 0x155cc0, 0x19cc),
+       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
+                  0x7fffffff, 0x155cc0, 0x19dd),
+       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
+                  0x7fffffff, 0x2191c0, 0x15cc)
+};
+
+static const struct mt76x2_radar_specs fcc_radar_specs[] = {
+       /* 20MHz */
+       RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0,
+                  0x7fffffff, 0xfe808, 0x13dc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0xfe808, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0xfe808, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0x57bcf00, 0x1289),
+       /* 40MHz */
+       RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0,
+                  0x7fffffff, 0xfe808, 0x13dc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0xfe808, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0xfe808, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0x57bcf00, 0x1289),
+       /* 80MHz */
+       RADAR_SPEC(0, 8, 2, 14, 106, 150, 15, 2900, 80100, 15, 0,
+                  0x7fffffff, 0xfe808, 0x16cc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0xfe808, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0xfe808, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0x57bcf00, 0x1289)
+};
+
+static const struct mt76x2_radar_specs jp_w56_radar_specs[] = {
+       /* 20MHz */
+       RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0,
+                  0x7fffffff, 0x14c080, 0x13dc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0x14c080, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0x14c080, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0X57bcf00, 0x1289),
+       /* 40MHz */
+       RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0,
+                  0x7fffffff, 0x14c080, 0x13dc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0x14c080, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0x14c080, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0X57bcf00, 0x1289),
+       /* 80MHz */
+       RADAR_SPEC(0, 8, 2, 9, 106, 150, 15, 2900, 80100, 15, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
+                  0x7fffffff, 0x14c080, 0x19dd),
+       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
+                  0x7fffffff, 0x14c080, 0x12cc),
+       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
+                  0x3938700, 0X57bcf00, 0x1289)
+};
+
+static const struct mt76x2_radar_specs jp_w53_radar_specs[] = {
+       /* 20MHz */
+       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 },
+       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 },
+       /* 40MHz */
+       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 },
+       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 },
+       /* 80MHz */
+       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 },
+       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
+                  0x7fffffff, 0x14c080, 0x16cc),
+       { 0 }
+};
+
+static void mt76x2_dfs_set_capture_mode_ctrl(struct mt76x2_dev *dev,
+                                            u8 enable)
+{
+       u32 data;
+
+       data = (1 << 1) | enable;
+       mt76_wr(dev, MT_BBP(DFS, 36), data);
+}
+
+static void mt76x2_dfs_seq_pool_put(struct mt76x2_dev *dev,
+                                   struct mt76x2_dfs_sequence *seq)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       list_add(&seq->head, &dfs_pd->seq_pool);
+
+       dfs_pd->seq_stats.seq_pool_len++;
+       dfs_pd->seq_stats.seq_len--;
+}
+
+static
+struct mt76x2_dfs_sequence *mt76x2_dfs_seq_pool_get(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_sequence *seq;
+
+       if (list_empty(&dfs_pd->seq_pool)) {
+               seq = devm_kzalloc(dev->mt76.dev, sizeof(*seq), GFP_ATOMIC);
+       } else {
+               seq = list_first_entry(&dfs_pd->seq_pool,
+                                      struct mt76x2_dfs_sequence,
+                                      head);
+               list_del(&seq->head);
+               dfs_pd->seq_stats.seq_pool_len--;
+       }
+       if (seq)
+               dfs_pd->seq_stats.seq_len++;
+
+       return seq;
+}
+
+static int mt76x2_dfs_get_multiple(int val, int frac, int margin)
+{
+       int remainder, factor;
+
+       if (!frac)
+               return 0;
+
+       if (abs(val - frac) <= margin)
+               return 1;
+
+       factor = val / frac;
+       remainder = val % frac;
+
+       if (remainder > margin) {
+               if ((frac - remainder) <= margin)
+                       factor++;
+               else
+                       factor = 0;
+       }
+       return factor;
+}
+
+static void mt76x2_dfs_detector_reset(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_sequence *seq, *tmp_seq;
+       int i;
+
+       /* reset hw detector */
+       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
+
+       /* reset sw detector */
+       for (i = 0; i < ARRAY_SIZE(dfs_pd->event_rb); i++) {
+               dfs_pd->event_rb[i].h_rb = 0;
+               dfs_pd->event_rb[i].t_rb = 0;
+       }
+
+       list_for_each_entry_safe(seq, tmp_seq, &dfs_pd->sequences, head) {
+               list_del_init(&seq->head);
+               mt76x2_dfs_seq_pool_put(dev, seq);
+       }
+}
+
+static bool mt76x2_dfs_check_chirp(struct mt76x2_dev *dev)
+{
+       bool ret = false;
+       u32 current_ts, delta_ts;
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       current_ts = mt76_rr(dev, MT_PBF_LIFE_TIMER);
+       delta_ts = current_ts - dfs_pd->chirp_pulse_ts;
+       dfs_pd->chirp_pulse_ts = current_ts;
+
+       /* 12 sec */
+       if (delta_ts <= (12 * (1 << 20))) {
+               if (++dfs_pd->chirp_pulse_cnt > 8)
+                       ret = true;
+       } else {
+               dfs_pd->chirp_pulse_cnt = 1;
+       }
+
+       return ret;
+}
+
+static void mt76x2_dfs_get_hw_pulse(struct mt76x2_dev *dev,
+                                   struct mt76x2_dfs_hw_pulse *pulse)
+{
+       u32 data;
+
+       /* select channel */
+       data = (MT_DFS_CH_EN << 16) | pulse->engine;
+       mt76_wr(dev, MT_BBP(DFS, 0), data);
+
+       /* reported period */
+       pulse->period = mt76_rr(dev, MT_BBP(DFS, 19));
+
+       /* reported width */
+       pulse->w1 = mt76_rr(dev, MT_BBP(DFS, 20));
+       pulse->w2 = mt76_rr(dev, MT_BBP(DFS, 23));
+
+       /* reported burst number */
+       pulse->burst = mt76_rr(dev, MT_BBP(DFS, 22));
+}
+
+static bool mt76x2_dfs_check_hw_pulse(struct mt76x2_dev *dev,
+                                     struct mt76x2_dfs_hw_pulse *pulse)
+{
+       bool ret = false;
+
+       if (!pulse->period || !pulse->w1)
+               return false;
+
+       switch (dev->dfs_pd.region) {
+       case NL80211_DFS_FCC:
+               if (pulse->engine > 3)
+                       break;
+
+               if (pulse->engine == 3) {
+                       ret = mt76x2_dfs_check_chirp(dev);
+                       break;
+               }
+
+               /* check short pulse*/
+               if (pulse->w1 < 120)
+                       ret = (pulse->period >= 2900 &&
+                              (pulse->period <= 4700 ||
+                               pulse->period >= 6400) &&
+                              (pulse->period <= 6800 ||
+                               pulse->period >= 10200) &&
+                              pulse->period <= 61600);
+               else if (pulse->w1 < 130) /* 120 - 130 */
+                       ret = (pulse->period >= 2900 &&
+                              pulse->period <= 61600);
+               else
+                       ret = (pulse->period >= 3500 &&
+                              pulse->period <= 10100);
+               break;
+       case NL80211_DFS_ETSI:
+               if (pulse->engine >= 3)
+                       break;
+
+               ret = (pulse->period >= 4900 &&
+                      (pulse->period <= 10200 ||
+                       pulse->period >= 12400) &&
+                      pulse->period <= 100100);
+               break;
+       case NL80211_DFS_JP:
+               if (dev->mt76.chandef.chan->center_freq >= 5250 &&
+                   dev->mt76.chandef.chan->center_freq <= 5350) {
+                       /* JPW53 */
+                       if (pulse->w1 <= 130)
+                               ret = (pulse->period >= 28360 &&
+                                      (pulse->period <= 28700 ||
+                                       pulse->period >= 76900) &&
+                                      pulse->period <= 76940);
+                       break;
+               }
+
+               if (pulse->engine > 3)
+                       break;
+
+               if (pulse->engine == 3) {
+                       ret = mt76x2_dfs_check_chirp(dev);
+                       break;
+               }
+
+               /* check short pulse*/
+               if (pulse->w1 < 120)
+                       ret = (pulse->period >= 2900 &&
+                              (pulse->period <= 4700 ||
+                               pulse->period >= 6400) &&
+                              (pulse->period <= 6800 ||
+                               pulse->period >= 27560) &&
+                              (pulse->period <= 27960 ||
+                               pulse->period >= 28360) &&
+                              (pulse->period <= 28700 ||
+                               pulse->period >= 79900) &&
+                              pulse->period <= 80100);
+               else if (pulse->w1 < 130) /* 120 - 130 */
+                       ret = (pulse->period >= 2900 &&
+                              (pulse->period <= 10100 ||
+                               pulse->period >= 27560) &&
+                              (pulse->period <= 27960 ||
+                               pulse->period >= 28360) &&
+                              (pulse->period <= 28700 ||
+                               pulse->period >= 79900) &&
+                              pulse->period <= 80100);
+               else
+                       ret = (pulse->period >= 3900 &&
+                              pulse->period <= 10100);
+               break;
+       case NL80211_DFS_UNSET:
+       default:
+               return false;
+       }
+
+       return ret;
+}
+
+static bool mt76x2_dfs_fetch_event(struct mt76x2_dev *dev,
+                                  struct mt76x2_dfs_event *event)
+{
+       u32 data;
+
+       /* 1st: DFS_R37[31]: 0 (engine 0) - 1 (engine 2)
+        * 2nd: DFS_R37[21:0]: pulse time
+        * 3rd: DFS_R37[11:0]: pulse width
+        * 3rd: DFS_R37[25:16]: phase
+        * 4th: DFS_R37[12:0]: current pwr
+        * 4th: DFS_R37[21:16]: pwr stable counter
+        *
+        * 1st: DFS_R37[31:0] set to 0xffffffff means no event detected
+        */
+       data = mt76_rr(dev, MT_BBP(DFS, 37));
+       if (!MT_DFS_CHECK_EVENT(data))
+               return false;
+
+       event->engine = MT_DFS_EVENT_ENGINE(data);
+       data = mt76_rr(dev, MT_BBP(DFS, 37));
+       event->ts = MT_DFS_EVENT_TIMESTAMP(data);
+       data = mt76_rr(dev, MT_BBP(DFS, 37));
+       event->width = MT_DFS_EVENT_WIDTH(data);
+
+       return true;
+}
+
+static bool mt76x2_dfs_check_event(struct mt76x2_dev *dev,
+                                  struct mt76x2_dfs_event *event)
+{
+       if (event->engine == 2) {
+               struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+               struct mt76x2_dfs_event_rb *event_buff = &dfs_pd->event_rb[1];
+               u16 last_event_idx;
+               u32 delta_ts;
+
+               last_event_idx = mt76_decr(event_buff->t_rb,
+                                          MT_DFS_EVENT_BUFLEN);
+               delta_ts = event->ts - event_buff->data[last_event_idx].ts;
+               if (delta_ts < MT_DFS_EVENT_TIME_MARGIN &&
+                   event_buff->data[last_event_idx].width >= 200)
+                       return false;
+       }
+       return true;
+}
+
+static void mt76x2_dfs_queue_event(struct mt76x2_dev *dev,
+                                  struct mt76x2_dfs_event *event)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_event_rb *event_buff;
+
+       /* add radar event to ring buffer */
+       event_buff = event->engine == 2 ? &dfs_pd->event_rb[1]
+                                       : &dfs_pd->event_rb[0];
+       event_buff->data[event_buff->t_rb] = *event;
+       event_buff->data[event_buff->t_rb].fetch_ts = jiffies;
+
+       event_buff->t_rb = mt76_incr(event_buff->t_rb, MT_DFS_EVENT_BUFLEN);
+       if (event_buff->t_rb == event_buff->h_rb)
+               event_buff->h_rb = mt76_incr(event_buff->h_rb,
+                                            MT_DFS_EVENT_BUFLEN);
+}
+
+static int mt76x2_dfs_create_sequence(struct mt76x2_dev *dev,
+                                     struct mt76x2_dfs_event *event,
+                                     u16 cur_len)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_sw_detector_params *sw_params;
+       u32 width_delta, with_sum, factor, cur_pri;
+       struct mt76x2_dfs_sequence seq, *seq_p;
+       struct mt76x2_dfs_event_rb *event_rb;
+       struct mt76x2_dfs_event *cur_event;
+       int i, j, end, pri;
+
+       event_rb = event->engine == 2 ? &dfs_pd->event_rb[1]
+                                     : &dfs_pd->event_rb[0];
+
+       i = mt76_decr(event_rb->t_rb, MT_DFS_EVENT_BUFLEN);
+       end = mt76_decr(event_rb->h_rb, MT_DFS_EVENT_BUFLEN);
+
+       while (i != end) {
+               cur_event = &event_rb->data[i];
+               with_sum = event->width + cur_event->width;
+
+               sw_params = &dfs_pd->sw_dpd_params;
+               switch (dev->dfs_pd.region) {
+               case NL80211_DFS_FCC:
+               case NL80211_DFS_JP:
+                       if (with_sum < 600)
+                               width_delta = 8;
+                       else
+                               width_delta = with_sum >> 3;
+                       break;
+               case NL80211_DFS_ETSI:
+                       if (event->engine == 2)
+                               width_delta = with_sum >> 6;
+                       else if (with_sum < 620)
+                               width_delta = 24;
+                       else
+                               width_delta = 8;
+                       break;
+               case NL80211_DFS_UNSET:
+               default:
+                       return -EINVAL;
+               }
+
+               pri = event->ts - cur_event->ts;
+               if (abs(event->width - cur_event->width) > width_delta ||
+                   pri < sw_params->min_pri)
+                       goto next;
+
+               if (pri > sw_params->max_pri)
+                       break;
+
+               seq.pri = event->ts - cur_event->ts;
+               seq.first_ts = cur_event->ts;
+               seq.last_ts = event->ts;
+               seq.engine = event->engine;
+               seq.count = 2;
+
+               j = mt76_decr(i, MT_DFS_EVENT_BUFLEN);
+               while (j != end) {
+                       cur_event = &event_rb->data[j];
+                       cur_pri = event->ts - cur_event->ts;
+                       factor = mt76x2_dfs_get_multiple(cur_pri, seq.pri,
+                                               sw_params->pri_margin);
+                       if (factor > 0) {
+                               seq.first_ts = cur_event->ts;
+                               seq.count++;
+                       }
+
+                       j = mt76_decr(j, MT_DFS_EVENT_BUFLEN);
+               }
+               if (seq.count <= cur_len)
+                       goto next;
+
+               seq_p = mt76x2_dfs_seq_pool_get(dev);
+               if (!seq_p)
+                       return -ENOMEM;
+
+               *seq_p = seq;
+               INIT_LIST_HEAD(&seq_p->head);
+               list_add(&seq_p->head, &dfs_pd->sequences);
+next:
+               i = mt76_decr(i, MT_DFS_EVENT_BUFLEN);
+       }
+       return 0;
+}
+
+static u16 mt76x2_dfs_add_event_to_sequence(struct mt76x2_dev *dev,
+                                           struct mt76x2_dfs_event *event)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_sw_detector_params *sw_params;
+       struct mt76x2_dfs_sequence *seq, *tmp_seq;
+       u16 max_seq_len = 0;
+       u32 factor, pri;
+
+       sw_params = &dfs_pd->sw_dpd_params;
+       list_for_each_entry_safe(seq, tmp_seq, &dfs_pd->sequences, head) {
+               if (event->ts > seq->first_ts + MT_DFS_SEQUENCE_WINDOW) {
+                       list_del_init(&seq->head);
+                       mt76x2_dfs_seq_pool_put(dev, seq);
+                       continue;
+               }
+
+               if (event->engine != seq->engine)
+                       continue;
+
+               pri = event->ts - seq->last_ts;
+               factor = mt76x2_dfs_get_multiple(pri, seq->pri,
+                                                sw_params->pri_margin);
+               if (factor > 0) {
+                       seq->last_ts = event->ts;
+                       seq->count++;
+                       max_seq_len = max_t(u16, max_seq_len, seq->count);
+               }
+       }
+       return max_seq_len;
+}
+
+static bool mt76x2_dfs_check_detection(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_sequence *seq;
+
+       if (list_empty(&dfs_pd->sequences))
+               return false;
+
+       list_for_each_entry(seq, &dfs_pd->sequences, head) {
+               if (seq->count > MT_DFS_SEQUENCE_TH) {
+                       dfs_pd->stats[seq->engine].sw_pattern++;
+                       return true;
+               }
+       }
+       return false;
+}
+
+static void mt76x2_dfs_add_events(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_event event;
+       int i, seq_len;
+
+       /* disable debug mode */
+       mt76x2_dfs_set_capture_mode_ctrl(dev, false);
+       for (i = 0; i < MT_DFS_EVENT_LOOP; i++) {
+               if (!mt76x2_dfs_fetch_event(dev, &event))
+                       break;
+
+               if (dfs_pd->last_event_ts > event.ts)
+                       mt76x2_dfs_detector_reset(dev);
+               dfs_pd->last_event_ts = event.ts;
+
+               if (!mt76x2_dfs_check_event(dev, &event))
+                       continue;
+
+               seq_len = mt76x2_dfs_add_event_to_sequence(dev, &event);
+               mt76x2_dfs_create_sequence(dev, &event, seq_len);
+
+               mt76x2_dfs_queue_event(dev, &event);
+       }
+       mt76x2_dfs_set_capture_mode_ctrl(dev, true);
+}
+
+static void mt76x2_dfs_check_event_window(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       struct mt76x2_dfs_event_rb *event_buff;
+       struct mt76x2_dfs_event *event;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dfs_pd->event_rb); i++) {
+               event_buff = &dfs_pd->event_rb[i];
+
+               while (event_buff->h_rb != event_buff->t_rb) {
+                       event = &event_buff->data[event_buff->h_rb];
+
+                       /* sorted list */
+                       if (time_is_after_jiffies(event->fetch_ts +
+                                                 MT_DFS_EVENT_WINDOW))
+                               break;
+                       event_buff->h_rb = mt76_incr(event_buff->h_rb,
+                                                    MT_DFS_EVENT_BUFLEN);
+               }
+       }
+}
+
+static void mt76x2_dfs_tasklet(unsigned long arg)
+{
+       struct mt76x2_dev *dev = (struct mt76x2_dev *)arg;
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+       u32 engine_mask;
+       int i;
+
+       if (test_bit(MT76_SCANNING, &dev->mt76.state))
+               goto out;
+
+       if (time_is_before_jiffies(dfs_pd->last_sw_check +
+                                  MT_DFS_SW_TIMEOUT)) {
+               bool radar_detected;
+
+               dfs_pd->last_sw_check = jiffies;
+
+               mt76x2_dfs_add_events(dev);
+               radar_detected = mt76x2_dfs_check_detection(dev);
+               if (radar_detected) {
+                       /* sw detector rx radar pattern */
+                       ieee80211_radar_detected(dev->mt76.hw);
+                       mt76x2_dfs_detector_reset(dev);
+
+                       return;
+               }
+               mt76x2_dfs_check_event_window(dev);
+       }
+
+       engine_mask = mt76_rr(dev, MT_BBP(DFS, 1));
+       if (!(engine_mask & 0xf))
+               goto out;
+
+       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
+               struct mt76x2_dfs_hw_pulse pulse;
+
+               if (!(engine_mask & (1 << i)))
+                       continue;
+
+               pulse.engine = i;
+               mt76x2_dfs_get_hw_pulse(dev, &pulse);
+
+               if (!mt76x2_dfs_check_hw_pulse(dev, &pulse)) {
+                       dfs_pd->stats[i].hw_pulse_discarded++;
+                       continue;
+               }
+
+               /* hw detector rx radar pattern */
+               dfs_pd->stats[i].hw_pattern++;
+               ieee80211_radar_detected(dev->mt76.hw);
+               mt76x2_dfs_detector_reset(dev);
+
+               return;
+       }
+
+       /* reset hw detector */
+       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
+
+out:
+       mt76x02_irq_enable(&dev->mt76, MT_INT_GPTIMER);
+}
+
+static void mt76x2_dfs_init_sw_detector(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       switch (dev->dfs_pd.region) {
+       case NL80211_DFS_FCC:
+               dfs_pd->sw_dpd_params.max_pri = MT_DFS_FCC_MAX_PRI;
+               dfs_pd->sw_dpd_params.min_pri = MT_DFS_FCC_MIN_PRI;
+               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN;
+               break;
+       case NL80211_DFS_ETSI:
+               dfs_pd->sw_dpd_params.max_pri = MT_DFS_ETSI_MAX_PRI;
+               dfs_pd->sw_dpd_params.min_pri = MT_DFS_ETSI_MIN_PRI;
+               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN << 2;
+               break;
+       case NL80211_DFS_JP:
+               dfs_pd->sw_dpd_params.max_pri = MT_DFS_JP_MAX_PRI;
+               dfs_pd->sw_dpd_params.min_pri = MT_DFS_JP_MIN_PRI;
+               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN;
+               break;
+       case NL80211_DFS_UNSET:
+       default:
+               break;
+       }
+}
+
+static void mt76x2_dfs_set_bbp_params(struct mt76x2_dev *dev)
+{
+       u32 data;
+       u8 i, shift;
+       const struct mt76x2_radar_specs *radar_specs;
+
+       switch (dev->mt76.chandef.width) {
+       case NL80211_CHAN_WIDTH_40:
+               shift = MT_DFS_NUM_ENGINES;
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               shift = 2 * MT_DFS_NUM_ENGINES;
+               break;
+       default:
+               shift = 0;
+               break;
+       }
+
+       switch (dev->dfs_pd.region) {
+       case NL80211_DFS_FCC:
+               radar_specs = &fcc_radar_specs[shift];
+               break;
+       case NL80211_DFS_ETSI:
+               radar_specs = &etsi_radar_specs[shift];
+               break;
+       case NL80211_DFS_JP:
+               if (dev->mt76.chandef.chan->center_freq >= 5250 &&
+                   dev->mt76.chandef.chan->center_freq <= 5350)
+                       radar_specs = &jp_w53_radar_specs[shift];
+               else
+                       radar_specs = &jp_w56_radar_specs[shift];
+               break;
+       case NL80211_DFS_UNSET:
+       default:
+               return;
+       }
+
+       data = (MT_DFS_VGA_MASK << 16) |
+              (MT_DFS_PWR_GAIN_OFFSET << 12) |
+              (MT_DFS_PWR_DOWN_TIME << 8) |
+              (MT_DFS_SYM_ROUND << 4) |
+              (MT_DFS_DELTA_DELAY & 0xf);
+       mt76_wr(dev, MT_BBP(DFS, 2), data);
+
+       data = (MT_DFS_RX_PE_MASK << 16) | MT_DFS_PKT_END_MASK;
+       mt76_wr(dev, MT_BBP(DFS, 3), data);
+
+       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
+               /* configure engine */
+               mt76_wr(dev, MT_BBP(DFS, 0), i);
+
+               /* detection mode + avg_len */
+               data = ((radar_specs[i].avg_len & 0x1ff) << 16) |
+                      (radar_specs[i].mode & 0xf);
+               mt76_wr(dev, MT_BBP(DFS, 4), data);
+
+               /* dfs energy */
+               data = ((radar_specs[i].e_high & 0x0fff) << 16) |
+                      (radar_specs[i].e_low & 0x0fff);
+               mt76_wr(dev, MT_BBP(DFS, 5), data);
+
+               /* dfs period */
+               mt76_wr(dev, MT_BBP(DFS, 7), radar_specs[i].t_low);
+               mt76_wr(dev, MT_BBP(DFS, 9), radar_specs[i].t_high);
+
+               /* dfs burst */
+               mt76_wr(dev, MT_BBP(DFS, 11), radar_specs[i].b_low);
+               mt76_wr(dev, MT_BBP(DFS, 13), radar_specs[i].b_high);
+
+               /* dfs width */
+               data = ((radar_specs[i].w_high & 0x0fff) << 16) |
+                      (radar_specs[i].w_low & 0x0fff);
+               mt76_wr(dev, MT_BBP(DFS, 14), data);
+
+               /* dfs margins */
+               data = (radar_specs[i].w_margin << 16) |
+                      radar_specs[i].t_margin;
+               mt76_wr(dev, MT_BBP(DFS, 15), data);
+
+               /* dfs event expiration */
+               mt76_wr(dev, MT_BBP(DFS, 17), radar_specs[i].event_expiration);
+
+               /* dfs pwr adj */
+               mt76_wr(dev, MT_BBP(DFS, 30), radar_specs[i].pwr_jmp);
+       }
+
+       /* reset status */
+       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
+       mt76_wr(dev, MT_BBP(DFS, 36), 0x3);
+
+       /* enable detection*/
+       mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16);
+       mt76_wr(dev, 0x212c, 0x0c350001);
+}
+
+void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev)
+{
+       u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
+
+       agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
+       agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
+
+       val_r8 = (agc_r8 & 0x00007e00) >> 9;
+       val_r4 = agc_r4 & ~0x1f000000;
+       val_r4 += (((val_r8 + 1) >> 1) << 24);
+       mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
+
+       dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
+       dfs_r31 += val_r8;
+       dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
+       dfs_r31 = (dfs_r31 << 16) | 0x00000307;
+       mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
+
+       mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
+}
+
+void mt76x2_dfs_init_params(struct mt76x2_dev *dev)
+{
+       struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+
+       if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
+           dev->dfs_pd.region != NL80211_DFS_UNSET) {
+               mt76x2_dfs_init_sw_detector(dev);
+               mt76x2_dfs_set_bbp_params(dev);
+               /* enable debug mode */
+               mt76x2_dfs_set_capture_mode_ctrl(dev, true);
+
+               mt76x02_irq_enable(&dev->mt76, MT_INT_GPTIMER);
+               mt76_rmw_field(dev, MT_INT_TIMER_EN,
+                              MT_INT_TIMER_EN_GP_TIMER_EN, 1);
+       } else {
+               /* disable hw detector */
+               mt76_wr(dev, MT_BBP(DFS, 0), 0);
+               /* clear detector status */
+               mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
+               mt76_wr(dev, 0x212c, 0);
+
+               mt76x02_irq_disable(&dev->mt76, MT_INT_GPTIMER);
+               mt76_rmw_field(dev, MT_INT_TIMER_EN,
+                              MT_INT_TIMER_EN_GP_TIMER_EN, 0);
+       }
+}
+
+void mt76x2_dfs_init_detector(struct mt76x2_dev *dev)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       INIT_LIST_HEAD(&dfs_pd->sequences);
+       INIT_LIST_HEAD(&dfs_pd->seq_pool);
+       dfs_pd->region = NL80211_DFS_UNSET;
+       dfs_pd->last_sw_check = jiffies;
+       tasklet_init(&dfs_pd->dfs_tasklet, mt76x2_dfs_tasklet,
+                    (unsigned long)dev);
+}
+
+void mt76x2_dfs_set_domain(struct mt76x2_dev *dev,
+                          enum nl80211_dfs_regions region)
+{
+       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
+
+       if (dfs_pd->region != region) {
+               tasklet_disable(&dfs_pd->dfs_tasklet);
+               dfs_pd->region = region;
+               mt76x2_dfs_init_params(dev);
+               tasklet_enable(&dfs_pd->dfs_tasklet);
+       }
+}
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_dma.c
new file mode 100644 (file)
index 0000000..fdd5103
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_dma.h"
+#include "../mt76x02_util.h"
+
+void mt76x2_tx_tasklet(unsigned long data)
+{
+       struct mt76x2_dev *dev = (struct mt76x2_dev *) data;
+       int i;
+
+       mt76x2_mac_process_tx_status_fifo(dev);
+
+       for (i = MT_TXQ_MCU; i >= 0; i--)
+               mt76_queue_tx_cleanup(dev, i, false);
+
+       mt76x2_mac_poll_tx_status(dev, false);
+       mt76x02_irq_enable(&dev->mt76, MT_INT_TX_DONE_ALL);
+}
+
+void mt76x2_dma_cleanup(struct mt76x2_dev *dev)
+{
+       tasklet_kill(&dev->tx_tasklet);
+       mt76_dma_cleanup(&dev->mt76);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
new file mode 100644 (file)
index 0000000..7036f4c
--- /dev/null
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include "mt76x2.h"
+#include "eeprom.h"
+#include "mcu.h"
+#include "../mt76x02_util.h"
+#include "../mt76x02_dma.h"
+
+static void
+mt76x2_mac_pbf_init(struct mt76x2_dev *dev)
+{
+       u32 val;
+
+       val = MT_PBF_SYS_CTRL_MCU_RESET |
+             MT_PBF_SYS_CTRL_DMA_RESET |
+             MT_PBF_SYS_CTRL_MAC_RESET |
+             MT_PBF_SYS_CTRL_PBF_RESET |
+             MT_PBF_SYS_CTRL_ASY_RESET;
+
+       mt76_set(dev, MT_PBF_SYS_CTRL, val);
+       mt76_clear(dev, MT_PBF_SYS_CTRL, val);
+
+       mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f);
+       mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf);
+}
+
+static void
+mt76x2_fixup_xtal(struct mt76x2_dev *dev)
+{
+       u16 eep_val;
+       s8 offset = 0;
+
+       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2);
+
+       offset = eep_val & 0x7f;
+       if ((eep_val & 0xff) == 0xff)
+               offset = 0;
+       else if (eep_val & 0x80)
+               offset = 0 - offset;
+
+       eep_val >>= 8;
+       if (eep_val == 0x00 || eep_val == 0xff) {
+               eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1);
+               eep_val &= 0xff;
+
+               if (eep_val == 0x00 || eep_val == 0xff)
+                       eep_val = 0x14;
+       }
+
+       eep_val &= 0x7f;
+       mt76_rmw_field(dev, MT_XO_CTRL5, MT_XO_CTRL5_C2_VAL, eep_val + offset);
+       mt76_set(dev, MT_XO_CTRL6, MT_XO_CTRL6_C2_CTRL);
+
+       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
+       switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) {
+       case 0:
+               mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80);
+               break;
+       case 1:
+               mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0);
+               break;
+       default:
+               break;
+       }
+}
+
+static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
+{
+       static const u8 null_addr[ETH_ALEN] = {};
+       const u8 *macaddr = dev->mt76.macaddr;
+       u32 val;
+       int i, k;
+
+       if (!mt76x02_wait_for_mac(&dev->mt76))
+               return -ETIMEDOUT;
+
+       val = mt76_rr(dev, MT_WPDMA_GLO_CFG);
+
+       val &= ~(MT_WPDMA_GLO_CFG_TX_DMA_EN |
+                MT_WPDMA_GLO_CFG_TX_DMA_BUSY |
+                MT_WPDMA_GLO_CFG_RX_DMA_EN |
+                MT_WPDMA_GLO_CFG_RX_DMA_BUSY |
+                MT_WPDMA_GLO_CFG_DMA_BURST_SIZE);
+       val |= FIELD_PREP(MT_WPDMA_GLO_CFG_DMA_BURST_SIZE, 3);
+
+       mt76_wr(dev, MT_WPDMA_GLO_CFG, val);
+
+       mt76x2_mac_pbf_init(dev);
+       mt76_write_mac_initvals(dev);
+       mt76x2_fixup_xtal(dev);
+
+       mt76_clear(dev, MT_MAC_SYS_CTRL,
+                  MT_MAC_SYS_CTRL_RESET_CSR |
+                  MT_MAC_SYS_CTRL_RESET_BBP);
+
+       if (is_mt7612(dev))
+               mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN);
+
+       mt76_set(dev, MT_EXT_CCA_CFG, 0x0000f000);
+       mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31));
+
+       mt76_wr(dev, MT_RF_BYPASS_0, 0x06000000);
+       mt76_wr(dev, MT_RF_SETTING_0, 0x08800000);
+       usleep_range(5000, 10000);
+       mt76_wr(dev, MT_RF_BYPASS_0, 0x00000000);
+
+       mt76_wr(dev, MT_MCU_CLOCK_CTL, 0x1401);
+       mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
+
+       mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr));
+       mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(macaddr + 4));
+
+       mt76_wr(dev, MT_MAC_BSSID_DW0, get_unaligned_le32(macaddr));
+       mt76_wr(dev, MT_MAC_BSSID_DW1, get_unaligned_le16(macaddr + 4) |
+               FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */
+               MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
+
+       /* Fire a pre-TBTT interrupt 8 ms before TBTT */
+       mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
+                      8 << 4);
+       mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
+                      MT_DFS_GP_INTERVAL);
+       mt76_wr(dev, MT_INT_TIMER_EN, 0);
+
+       mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
+       if (!hard)
+               return 0;
+
+       for (i = 0; i < 256 / 32; i++)
+               mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0);
+
+       for (i = 0; i < 256; i++)
+               mt76x02_mac_wcid_setup(&dev->mt76, i, 0, NULL);
+
+       for (i = 0; i < MT_MAX_VIFS; i++)
+               mt76x02_mac_wcid_setup(&dev->mt76, MT_VIF_WCID(i), i, NULL);
+
+       for (i = 0; i < 16; i++)
+               for (k = 0; k < 4; k++)
+                       mt76x02_mac_shared_key_setup(&dev->mt76, i, k, NULL);
+
+       for (i = 0; i < 8; i++) {
+               mt76x2_mac_set_bssid(dev, i, null_addr);
+               mt76x2_mac_set_beacon(dev, i, NULL);
+       }
+
+       for (i = 0; i < 16; i++)
+               mt76_rr(dev, MT_TX_STAT_FIFO);
+
+       mt76_wr(dev, MT_CH_TIME_CFG,
+               MT_CH_TIME_CFG_TIMER_EN |
+               MT_CH_TIME_CFG_TX_AS_BUSY |
+               MT_CH_TIME_CFG_RX_AS_BUSY |
+               MT_CH_TIME_CFG_NAV_AS_BUSY |
+               MT_CH_TIME_CFG_EIFS_AS_BUSY |
+               FIELD_PREP(MT_CH_TIME_CFG_CH_TIMER_CLR, 1));
+
+       mt76x02_set_beacon_offsets(&dev->mt76);
+
+       mt76x2_set_tx_ackto(dev);
+
+       return 0;
+}
+
+int mt76x2_mac_start(struct mt76x2_dev *dev)
+{
+       int i;
+
+       for (i = 0; i < 16; i++)
+               mt76_rr(dev, MT_TX_AGG_CNT(i));
+
+       for (i = 0; i < 16; i++)
+               mt76_rr(dev, MT_TX_STAT_FIFO);
+
+       memset(dev->aggr_stats, 0, sizeof(dev->aggr_stats));
+       mt76x02_mac_start(&dev->mt76);
+
+       return 0;
+}
+
+void mt76x2_mac_resume(struct mt76x2_dev *dev)
+{
+       mt76_wr(dev, MT_MAC_SYS_CTRL,
+               MT_MAC_SYS_CTRL_ENABLE_TX |
+               MT_MAC_SYS_CTRL_ENABLE_RX);
+}
+
+static void
+mt76x2_power_on_rf_patch(struct mt76x2_dev *dev)
+{
+       mt76_set(dev, 0x10130, BIT(0) | BIT(16));
+       udelay(1);
+
+       mt76_clear(dev, 0x1001c, 0xff);
+       mt76_set(dev, 0x1001c, 0x30);
+
+       mt76_wr(dev, 0x10014, 0x484f);
+       udelay(1);
+
+       mt76_set(dev, 0x10130, BIT(17));
+       udelay(125);
+
+       mt76_clear(dev, 0x10130, BIT(16));
+       udelay(50);
+
+       mt76_set(dev, 0x1014c, BIT(19) | BIT(20));
+}
+
+static void
+mt76x2_power_on_rf(struct mt76x2_dev *dev, int unit)
+{
+       int shift = unit ? 8 : 0;
+
+       /* Enable RF BG */
+       mt76_set(dev, 0x10130, BIT(0) << shift);
+       udelay(10);
+
+       /* Enable RFDIG LDO/AFE/ABB/ADDA */
+       mt76_set(dev, 0x10130, (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift);
+       udelay(10);
+
+       /* Switch RFDIG power to internal LDO */
+       mt76_clear(dev, 0x10130, BIT(2) << shift);
+       udelay(10);
+
+       mt76x2_power_on_rf_patch(dev);
+
+       mt76_set(dev, 0x530, 0xf);
+}
+
+static void
+mt76x2_power_on(struct mt76x2_dev *dev)
+{
+       u32 val;
+
+       /* Turn on WL MTCMOS */
+       mt76_set(dev, MT_WLAN_MTC_CTRL, MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP);
+
+       val = MT_WLAN_MTC_CTRL_STATE_UP |
+             MT_WLAN_MTC_CTRL_PWR_ACK |
+             MT_WLAN_MTC_CTRL_PWR_ACK_S;
+
+       mt76_poll(dev, MT_WLAN_MTC_CTRL, val, val, 1000);
+
+       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0x7f << 16);
+       udelay(10);
+
+       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xf << 24);
+       udelay(10);
+
+       mt76_set(dev, MT_WLAN_MTC_CTRL, 0xf << 24);
+       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xfff);
+
+       /* Turn on AD/DA power down */
+       mt76_clear(dev, 0x11204, BIT(3));
+
+       /* WLAN function enable */
+       mt76_set(dev, 0x10080, BIT(0));
+
+       /* Release BBP software reset */
+       mt76_clear(dev, 0x10064, BIT(18));
+
+       mt76x2_power_on_rf(dev, 0);
+       mt76x2_power_on_rf(dev, 1);
+}
+
+void mt76x2_set_tx_ackto(struct mt76x2_dev *dev)
+{
+       u8 ackto, sifs, slottime = dev->slottime;
+
+       /* As defined by IEEE 802.11-2007 17.3.8.6 */
+       slottime += 3 * dev->coverage_class;
+       mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
+                      MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
+
+       sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
+                             MT_XIFS_TIME_CFG_OFDM_SIFS);
+
+       ackto = slottime + sifs;
+       mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG,
+                      MT_TX_TIMEOUT_CFG_ACKTO, ackto);
+}
+
+int mt76x2_init_hardware(struct mt76x2_dev *dev)
+{
+       int ret;
+
+       tasklet_init(&dev->pre_tbtt_tasklet, mt76x2_pre_tbtt_tasklet,
+                    (unsigned long) dev);
+
+       mt76x02_dma_disable(&dev->mt76);
+       mt76x2_reset_wlan(dev, true);
+       mt76x2_power_on(dev);
+
+       ret = mt76x2_eeprom_init(dev);
+       if (ret)
+               return ret;
+
+       ret = mt76x2_mac_reset(dev, true);
+       if (ret)
+               return ret;
+
+       dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
+
+       ret = mt76x02_dma_init(&dev->mt76);
+       if (ret)
+               return ret;
+
+       set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
+       ret = mt76x2_mac_start(dev);
+       if (ret)
+               return ret;
+
+       ret = mt76x2_mcu_init(dev);
+       if (ret)
+               return ret;
+
+       mt76x2_mac_stop(dev, false);
+
+       return 0;
+}
+
+void mt76x2_stop_hardware(struct mt76x2_dev *dev)
+{
+       cancel_delayed_work_sync(&dev->cal_work);
+       cancel_delayed_work_sync(&dev->mac_work);
+       mt76x02_mcu_set_radio_state(&dev->mt76, false, true);
+       mt76x2_mac_stop(dev, false);
+}
+
+void mt76x2_cleanup(struct mt76x2_dev *dev)
+{
+       tasklet_disable(&dev->dfs_pd.dfs_tasklet);
+       tasklet_disable(&dev->pre_tbtt_tasklet);
+       mt76x2_stop_hardware(dev);
+       mt76x2_dma_cleanup(dev);
+       mt76x02_mcu_cleanup(&dev->mt76);
+}
+
+struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
+{
+       static const struct mt76_driver_ops drv_ops = {
+               .txwi_size = sizeof(struct mt76x02_txwi),
+               .update_survey = mt76x2_update_channel,
+               .tx_prepare_skb = mt76x2_tx_prepare_skb,
+               .tx_complete_skb = mt76x2_tx_complete_skb,
+               .rx_skb = mt76x2_queue_rx_skb,
+               .rx_poll_complete = mt76x2_rx_poll_complete,
+               .sta_ps = mt76x2_sta_ps,
+               .get_max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj,
+       };
+       struct mt76x2_dev *dev;
+       struct mt76_dev *mdev;
+
+       mdev = mt76_alloc_device(sizeof(*dev), &mt76x2_ops);
+       if (!mdev)
+               return NULL;
+
+       dev = container_of(mdev, struct mt76x2_dev, mt76);
+       mdev->dev = pdev;
+       mdev->drv = &drv_ops;
+
+       return dev;
+}
+
+static void mt76x2_regd_notifier(struct wiphy *wiphy,
+                                struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct mt76x2_dev *dev = hw->priv;
+
+       mt76x2_dfs_set_domain(dev, request->dfs_region);
+}
+
+static const struct ieee80211_iface_limit if_limits[] = {
+       {
+               .max = 1,
+               .types = BIT(NL80211_IFTYPE_ADHOC)
+       }, {
+               .max = 8,
+               .types = BIT(NL80211_IFTYPE_STATION) |
+#ifdef CONFIG_MAC80211_MESH
+                        BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+                        BIT(NL80211_IFTYPE_AP)
+        },
+};
+
+static const struct ieee80211_iface_combination if_comb[] = {
+       {
+               .limits = if_limits,
+               .n_limits = ARRAY_SIZE(if_limits),
+               .max_interfaces = 8,
+               .num_different_channels = 1,
+               .beacon_int_infra_match = true,
+               .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+                                      BIT(NL80211_CHAN_WIDTH_20) |
+                                      BIT(NL80211_CHAN_WIDTH_40) |
+                                      BIT(NL80211_CHAN_WIDTH_80),
+       }
+};
+
+static void mt76x2_led_set_config(struct mt76_dev *mt76, u8 delay_on,
+                                 u8 delay_off)
+{
+       struct mt76x2_dev *dev = container_of(mt76, struct mt76x2_dev,
+                                             mt76);
+       u32 val;
+
+       val = MT_LED_STATUS_DURATION(0xff) |
+             MT_LED_STATUS_OFF(delay_off) |
+             MT_LED_STATUS_ON(delay_on);
+
+       mt76_wr(dev, MT_LED_S0(mt76->led_pin), val);
+       mt76_wr(dev, MT_LED_S1(mt76->led_pin), val);
+
+       val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
+             MT_LED_CTRL_KICK(mt76->led_pin);
+       if (mt76->led_al)
+               val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
+       mt76_wr(dev, MT_LED_CTRL, val);
+}
+
+static int mt76x2_led_set_blink(struct led_classdev *led_cdev,
+                               unsigned long *delay_on,
+                               unsigned long *delay_off)
+{
+       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
+                                            led_cdev);
+       u8 delta_on, delta_off;
+
+       delta_off = max_t(u8, *delay_off / 10, 1);
+       delta_on = max_t(u8, *delay_on / 10, 1);
+
+       mt76x2_led_set_config(mt76, delta_on, delta_off);
+       return 0;
+}
+
+static void mt76x2_led_set_brightness(struct led_classdev *led_cdev,
+                                     enum led_brightness brightness)
+{
+       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
+                                            led_cdev);
+
+       if (!brightness)
+               mt76x2_led_set_config(mt76, 0, 0xff);
+       else
+               mt76x2_led_set_config(mt76, 0xff, 0);
+}
+
+int mt76x2_register_device(struct mt76x2_dev *dev)
+{
+       struct ieee80211_hw *hw = mt76_hw(dev);
+       struct wiphy *wiphy = hw->wiphy;
+       void *status_fifo;
+       int fifo_size;
+       int i, ret;
+
+       fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status));
+       status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL);
+       if (!status_fifo)
+               return -ENOMEM;
+
+       tasklet_init(&dev->tx_tasklet, mt76x2_tx_tasklet, (unsigned long)dev);
+       kfifo_init(&dev->txstatus_fifo, status_fifo, fifo_size);
+       INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate);
+       INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work);
+
+       mt76x2_init_device(dev);
+
+       ret = mt76x2_init_hardware(dev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
+               u8 *addr = dev->macaddr_list[i].addr;
+
+               memcpy(addr, dev->mt76.macaddr, ETH_ALEN);
+
+               if (!i)
+                       continue;
+
+               addr[0] |= BIT(1);
+               addr[0] ^= ((i - 1) << 2);
+       }
+       wiphy->addresses = dev->macaddr_list;
+       wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
+
+       wiphy->iface_combinations = if_comb;
+       wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+
+       wiphy->reg_notifier = mt76x2_regd_notifier;
+
+       wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_AP) |
+#ifdef CONFIG_MAC80211_MESH
+               BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+               BIT(NL80211_IFTYPE_ADHOC);
+
+       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+
+       mt76x2_dfs_init_detector(dev);
+
+       /* init led callbacks */
+       dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
+       dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
+
+       ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,
+                                  ARRAY_SIZE(mt76x02_rates));
+       if (ret)
+               goto fail;
+
+       mt76x2_init_debugfs(dev);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
+
+       return 0;
+
+fail:
+       mt76x2_stop_hardware(dev);
+       return ret;
+}
+
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mac.c
new file mode 100644 (file)
index 0000000..c1be3fe
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include "mt76x2.h"
+#include "mcu.h"
+#include "eeprom.h"
+#include "trace.h"
+#include "../mt76x02_util.h"
+
+void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr)
+{
+       idx &= 7;
+       mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
+       mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
+                      get_unaligned_le16(addr + 4));
+}
+
+void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq)
+{
+       struct mt76x02_tx_status stat = {};
+       unsigned long flags;
+       u8 update = 1;
+       bool ret;
+
+       if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
+               return;
+
+       trace_mac_txstat_poll(dev);
+
+       while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) {
+               spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags);
+               ret = mt76x02_mac_load_tx_status(&dev->mt76, &stat);
+               spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags);
+
+               if (!ret)
+                       break;
+
+               trace_mac_txstat_fetch(dev, &stat);
+
+               if (!irq) {
+                       mt76x02_send_tx_status(&dev->mt76, &stat, &update);
+                       continue;
+               }
+
+               kfifo_put(&dev->txstatus_fifo, stat);
+       }
+}
+
+static void
+mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb,
+                       void *txwi_ptr)
+{
+       struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb);
+       struct mt76x02_txwi *txwi = txwi_ptr;
+
+       mt76x2_mac_poll_tx_status(dev, false);
+
+       txi->tries = 0;
+       txi->jiffies = jiffies;
+       txi->wcid = txwi->wcid;
+       txi->pktid = txwi->pktid;
+       trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);
+       mt76x02_tx_complete(&dev->mt76, skb);
+}
+
+void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev)
+{
+       struct mt76x02_tx_status stat;
+       u8 update = 1;
+
+       while (kfifo_get(&dev->txstatus_fifo, &stat))
+               mt76x02_send_tx_status(&dev->mt76, &stat, &update);
+}
+
+void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
+                           struct mt76_queue_entry *e, bool flush)
+{
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+
+       if (e->txwi)
+               mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi);
+       else
+               dev_kfree_skb_any(e->skb);
+}
+
+static int
+mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb)
+{
+       int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+       struct mt76x02_txwi txwi;
+
+       if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
+               return -ENOSPC;
+
+       mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
+
+       mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
+       offset += sizeof(txwi);
+
+       mt76_wr_copy(dev, offset, skb->data, skb->len);
+       return 0;
+}
+
+static int
+__mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 bcn_idx, struct sk_buff *skb)
+{
+       int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+       int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
+       int ret = 0;
+       int i;
+
+       /* Prevent corrupt transmissions during update */
+       mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
+
+       if (skb) {
+               ret = mt76_write_beacon(dev, beacon_addr, skb);
+               if (!ret)
+                       dev->beacon_data_mask |= BIT(bcn_idx);
+       } else {
+               dev->beacon_data_mask &= ~BIT(bcn_idx);
+               for (i = 0; i < beacon_len; i += 4)
+                       mt76_wr(dev, beacon_addr + i, 0);
+       }
+
+       mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
+
+       return ret;
+}
+
+int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx,
+                         struct sk_buff *skb)
+{
+       bool force_update = false;
+       int bcn_idx = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
+               if (vif_idx == i) {
+                       force_update = !!dev->beacons[i] ^ !!skb;
+
+                       if (dev->beacons[i])
+                               dev_kfree_skb(dev->beacons[i]);
+
+                       dev->beacons[i] = skb;
+                       __mt76x2_mac_set_beacon(dev, bcn_idx, skb);
+               } else if (force_update && dev->beacons[i]) {
+                       __mt76x2_mac_set_beacon(dev, bcn_idx, dev->beacons[i]);
+               }
+
+               bcn_idx += !!dev->beacons[i];
+       }
+
+       for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
+               if (!(dev->beacon_data_mask & BIT(i)))
+                       break;
+
+               __mt76x2_mac_set_beacon(dev, i, NULL);
+       }
+
+       mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
+                      bcn_idx - 1);
+       return 0;
+}
+
+void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val)
+{
+       u8 old_mask = dev->beacon_mask;
+       bool en;
+       u32 reg;
+
+       if (val) {
+               dev->beacon_mask |= BIT(vif_idx);
+       } else {
+               dev->beacon_mask &= ~BIT(vif_idx);
+               mt76x2_mac_set_beacon(dev, vif_idx, NULL);
+       }
+
+       if (!!old_mask == !!dev->beacon_mask)
+               return;
+
+       en = dev->beacon_mask;
+
+       mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
+       reg = MT_BEACON_TIME_CFG_BEACON_TX |
+             MT_BEACON_TIME_CFG_TBTT_EN |
+             MT_BEACON_TIME_CFG_TIMER_EN;
+       mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
+
+       if (en)
+               mt76x02_irq_enable(&dev->mt76, MT_INT_PRE_TBTT | MT_INT_TBTT);
+       else
+               mt76x02_irq_disable(&dev->mt76, MT_INT_PRE_TBTT | MT_INT_TBTT);
+}
+
+void mt76x2_update_channel(struct mt76_dev *mdev)
+{
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+       struct mt76_channel_state *state;
+       u32 active, busy;
+
+       state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan);
+
+       busy = mt76_rr(dev, MT_CH_BUSY);
+       active = busy + mt76_rr(dev, MT_CH_IDLE);
+
+       spin_lock_bh(&dev->mt76.cc_lock);
+       state->cc_busy += busy;
+       state->cc_active += active;
+       spin_unlock_bh(&dev->mt76.cc_lock);
+}
+
+void mt76x2_mac_work(struct work_struct *work)
+{
+       struct mt76x2_dev *dev = container_of(work, struct mt76x2_dev,
+                                           mac_work.work);
+       int i, idx;
+
+       mt76x2_update_channel(&dev->mt76);
+       for (i = 0, idx = 0; i < 16; i++) {
+               u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
+
+               dev->aggr_stats[idx++] += val & 0xffff;
+               dev->aggr_stats[idx++] += val >> 16;
+       }
+
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+                                    MT_CALIBRATE_INTERVAL);
+}
+
+void mt76x2_mac_set_tx_protection(struct mt76x2_dev *dev, u32 val)
+{
+       u32 data = 0;
+
+       if (val != ~0)
+               data = FIELD_PREP(MT_PROT_CFG_CTRL, 1) |
+                      MT_PROT_CFG_RTS_THRESH;
+
+       mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, val);
+
+       mt76_rmw(dev, MT_CCK_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_OFDM_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_MM20_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_MM40_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_GF20_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_GF40_PROT_CFG,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_TX_PROT_CFG6,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_TX_PROT_CFG7,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+       mt76_rmw(dev, MT_TX_PROT_CFG8,
+                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
new file mode 100644 (file)
index 0000000..521c926
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_util.h"
+
+static int
+mt76x2_start(struct ieee80211_hw *hw)
+{
+       struct mt76x2_dev *dev = hw->priv;
+       int ret;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       ret = mt76x2_mac_start(dev);
+       if (ret)
+               goto out;
+
+       ret = mt76x2_phy_start(dev);
+       if (ret)
+               goto out;
+
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+                                    MT_CALIBRATE_INTERVAL);
+
+       set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
+
+out:
+       mutex_unlock(&dev->mt76.mutex);
+       return ret;
+}
+
+static void
+mt76x2_stop(struct ieee80211_hw *hw)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       mutex_lock(&dev->mt76.mutex);
+       clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
+       mt76x2_stop_hardware(dev);
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+static int
+mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef)
+{
+       int ret;
+
+       cancel_delayed_work_sync(&dev->cal_work);
+
+       set_bit(MT76_RESET, &dev->mt76.state);
+
+       mt76_set_channel(&dev->mt76);
+
+       tasklet_disable(&dev->pre_tbtt_tasklet);
+       tasklet_disable(&dev->dfs_pd.dfs_tasklet);
+
+       mt76x2_mac_stop(dev, true);
+       ret = mt76x2_phy_set_channel(dev, chandef);
+
+       /* channel cycle counters read-and-clear */
+       mt76_rr(dev, MT_CH_IDLE);
+       mt76_rr(dev, MT_CH_BUSY);
+
+       mt76x2_dfs_init_params(dev);
+
+       mt76x2_mac_resume(dev);
+       tasklet_enable(&dev->dfs_pd.dfs_tasklet);
+       tasklet_enable(&dev->pre_tbtt_tasklet);
+
+       clear_bit(MT76_RESET, &dev->mt76.state);
+
+       mt76_txq_schedule_all(&dev->mt76);
+
+       return ret;
+}
+
+static int
+mt76x2_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct mt76x2_dev *dev = hw->priv;
+       int ret = 0;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+               if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
+                       dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
+               else
+                       dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
+
+               mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               dev->mt76.txpower_conf = hw->conf.power_level * 2;
+
+               /* convert to per-chain power for 2x2 devices */
+               dev->mt76.txpower_conf -= 6;
+
+               if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) {
+                       mt76x2_phy_set_txpower(dev);
+                       mt76x2_tx_set_txpwr_auto(dev, dev->mt76.txpower_conf);
+               }
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               ieee80211_stop_queues(hw);
+               ret = mt76x2_set_channel(dev, &hw->conf.chandef);
+               ieee80211_wake_queues(hw);
+       }
+
+       mutex_unlock(&dev->mt76.mutex);
+
+       return ret;
+}
+
+static void
+mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                       struct ieee80211_bss_conf *info, u32 changed)
+{
+       struct mt76x2_dev *dev = hw->priv;
+       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       if (changed & BSS_CHANGED_BSSID)
+               mt76x2_mac_set_bssid(dev, mvif->idx, info->bssid);
+
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+                              MT_BEACON_TIME_CFG_INTVAL,
+                              info->beacon_int << 4);
+               dev->beacon_int = info->beacon_int;
+               dev->tbtt_count = 0;
+       }
+
+       if (changed & BSS_CHANGED_BEACON_ENABLED) {
+               tasklet_disable(&dev->pre_tbtt_tasklet);
+               mt76x2_mac_set_beacon_enable(dev, mvif->idx,
+                                            info->enable_beacon);
+               tasklet_enable(&dev->pre_tbtt_tasklet);
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               int slottime = info->use_short_slot ? 9 : 20;
+
+               dev->slottime = slottime;
+               mt76x2_set_tx_ackto(dev);
+       }
+
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+void
+mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
+{
+       struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+       int idx = msta->wcid.idx;
+
+       mt76_stop_tx_queues(&dev->mt76, sta, true);
+       mt76x02_mac_wcid_set_drop(&dev->mt76, idx, ps);
+}
+
+static void
+mt76x2_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+              const u8 *mac)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       tasklet_disable(&dev->pre_tbtt_tasklet);
+       set_bit(MT76_SCANNING, &dev->mt76.state);
+}
+
+static void
+mt76x2_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       clear_bit(MT76_SCANNING, &dev->mt76.state);
+       tasklet_enable(&dev->pre_tbtt_tasklet);
+}
+
+static void
+mt76x2_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+            u32 queues, bool drop)
+{
+}
+
+static int
+mt76x2_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       *dbm = dev->mt76.txpower_cur / 2;
+
+       /* convert from per-chain power to combined output on 2x2 devices */
+       *dbm += 3;
+
+       return 0;
+}
+
+static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
+                                     s16 coverage_class)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       mutex_lock(&dev->mt76.mutex);
+       dev->coverage_class = coverage_class;
+       mt76x2_set_tx_ackto(dev);
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+static int
+mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+{
+       return 0;
+}
+
+static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
+                             u32 rx_ant)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       if (!tx_ant || tx_ant > 3 || tx_ant != rx_ant)
+               return -EINVAL;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       dev->mt76.chainmask = (tx_ant == 3) ? 0x202 : 0x101;
+       dev->mt76.antenna_mask = tx_ant;
+
+       mt76_set_stream_caps(&dev->mt76, true);
+       mt76x2_phy_set_antenna(dev);
+
+       mutex_unlock(&dev->mt76.mutex);
+
+       return 0;
+}
+
+static int mt76x2_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
+                             u32 *rx_ant)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       mutex_lock(&dev->mt76.mutex);
+       *tx_ant = dev->mt76.antenna_mask;
+       *rx_ant = dev->mt76.antenna_mask;
+       mutex_unlock(&dev->mt76.mutex);
+
+       return 0;
+}
+
+static int
+mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       if (val != ~0 && val > 0xffff)
+               return -EINVAL;
+
+       mutex_lock(&dev->mutex);
+       mt76x2_mac_set_tx_protection(dev, val);
+       mutex_unlock(&dev->mutex);
+
+       return 0;
+}
+
+const struct ieee80211_ops mt76x2_ops = {
+       .tx = mt76x2_tx,
+       .start = mt76x2_start,
+       .stop = mt76x2_stop,
+       .add_interface = mt76x02_add_interface,
+       .remove_interface = mt76x02_remove_interface,
+       .config = mt76x2_config,
+       .configure_filter = mt76x02_configure_filter,
+       .bss_info_changed = mt76x2_bss_info_changed,
+       .sta_add = mt76x02_sta_add,
+       .sta_remove = mt76x02_sta_remove,
+       .set_key = mt76x02_set_key,
+       .conf_tx = mt76x02_conf_tx,
+       .sw_scan_start = mt76x2_sw_scan,
+       .sw_scan_complete = mt76x2_sw_scan_complete,
+       .flush = mt76x2_flush,
+       .ampdu_action = mt76x02_ampdu_action,
+       .get_txpower = mt76x2_get_txpower,
+       .wake_tx_queue = mt76_wake_tx_queue,
+       .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
+       .release_buffered_frames = mt76_release_buffered_frames,
+       .set_coverage_class = mt76x2_set_coverage_class,
+       .get_survey = mt76_get_survey,
+       .set_tim = mt76x2_set_tim,
+       .set_antenna = mt76x2_set_antenna,
+       .get_antenna = mt76x2_get_antenna,
+       .set_rts_threshold = mt76x2_set_rts_threshold,
+};
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_mcu.c
new file mode 100644 (file)
index 0000000..38fa84b
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+
+#include "mt76x2.h"
+#include "mcu.h"
+#include "eeprom.h"
+#include "../mt76x02_dma.h"
+
+static int
+mt76pci_load_rom_patch(struct mt76x2_dev *dev)
+{
+       const struct firmware *fw = NULL;
+       struct mt76x02_patch_header *hdr;
+       bool rom_protect = !is_mt7612(dev);
+       int len, ret = 0;
+       __le32 *cur;
+       u32 patch_mask, patch_reg;
+
+       if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
+               dev_err(dev->mt76.dev,
+                       "Could not get hardware semaphore for ROM PATCH\n");
+               return -ETIMEDOUT;
+       }
+
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
+               patch_mask = BIT(0);
+               patch_reg = MT_MCU_CLOCK_CTL;
+       } else {
+               patch_mask = BIT(1);
+               patch_reg = MT_MCU_COM_REG0;
+       }
+
+       if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
+               dev_info(dev->mt76.dev, "ROM patch already applied\n");
+               goto out;
+       }
+
+       ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev);
+       if (ret)
+               goto out;
+
+       if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
+               ret = -EIO;
+               dev_err(dev->mt76.dev, "Failed to load firmware\n");
+               goto out;
+       }
+
+       hdr = (struct mt76x02_patch_header *)fw->data;
+       dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
+
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET);
+
+       cur = (__le32 *) (fw->data + sizeof(*hdr));
+       len = fw->size - sizeof(*hdr);
+       mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len);
+
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
+
+       /* Trigger ROM */
+       mt76_wr(dev, MT_MCU_INT_LEVEL, 4);
+
+       if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) {
+               dev_err(dev->mt76.dev, "Failed to load ROM patch\n");
+               ret = -ETIMEDOUT;
+       }
+
+out:
+       /* release semaphore */
+       if (rom_protect)
+               mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
+       release_firmware(fw);
+       return ret;
+}
+
+static int
+mt76pci_load_firmware(struct mt76x2_dev *dev)
+{
+       const struct firmware *fw;
+       const struct mt76x02_fw_header *hdr;
+       int len, ret;
+       __le32 *cur;
+       u32 offset, val;
+
+       ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev);
+       if (ret)
+               return ret;
+
+       if (!fw || !fw->data || fw->size < sizeof(*hdr))
+               goto error;
+
+       hdr = (const struct mt76x02_fw_header *)fw->data;
+
+       len = sizeof(*hdr);
+       len += le32_to_cpu(hdr->ilm_len);
+       len += le32_to_cpu(hdr->dlm_len);
+
+       if (fw->size != len)
+               goto error;
+
+       val = le16_to_cpu(hdr->fw_ver);
+       dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
+                (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
+
+       val = le16_to_cpu(hdr->build_ver);
+       dev_info(dev->mt76.dev, "Build: %x\n", val);
+       dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
+
+       cur = (__le32 *) (fw->data + sizeof(*hdr));
+       len = le32_to_cpu(hdr->ilm_len);
+
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET);
+       mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len);
+
+       cur += len / sizeof(*cur);
+       len = le32_to_cpu(hdr->dlm_len);
+
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
+               offset = MT_MCU_DLM_ADDR_E3;
+       else
+               offset = MT_MCU_DLM_ADDR;
+
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET);
+       mt76_wr_copy(dev, offset, cur, len);
+
+       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
+
+       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
+       if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1)
+               mt76_set(dev, MT_MCU_COM_REG0, BIT(30));
+
+       /* trigger firmware */
+       mt76_wr(dev, MT_MCU_INT_LEVEL, 2);
+       if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) {
+               dev_err(dev->mt76.dev, "Firmware failed to start\n");
+               release_firmware(fw);
+               return -ETIMEDOUT;
+       }
+
+       dev_info(dev->mt76.dev, "Firmware running!\n");
+       mt76x02_set_ethtool_fwver(&dev->mt76, hdr);
+
+       release_firmware(fw);
+
+       return ret;
+
+error:
+       dev_err(dev->mt76.dev, "Invalid firmware\n");
+       release_firmware(fw);
+       return -ENOENT;
+}
+
+int mt76x2_mcu_init(struct mt76x2_dev *dev)
+{
+       static const struct mt76_mcu_ops mt76x2_mcu_ops = {
+               .mcu_msg_alloc = mt76x02_mcu_msg_alloc,
+               .mcu_send_msg = mt76x02_mcu_msg_send,
+       };
+       int ret;
+
+       dev->mt76.mcu_ops = &mt76x2_mcu_ops;
+
+       ret = mt76pci_load_rom_patch(dev);
+       if (ret)
+               return ret;
+
+       ret = mt76pci_load_firmware(dev);
+       if (ret)
+               return ret;
+
+       mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, true);
+       return 0;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
new file mode 100644 (file)
index 0000000..3926013
--- /dev/null
@@ -0,0 +1,458 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+#include "mt76x2.h"
+#include "mcu.h"
+#include "eeprom.h"
+
+static bool
+mt76x2_phy_tssi_init_cal(struct mt76x2_dev *dev)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       u32 flag = 0;
+
+       if (!mt76x02_tssi_enabled(&dev->mt76))
+               return false;
+
+       if (mt76x2_channel_silent(dev))
+               return false;
+
+       if (chan->band == NL80211_BAND_5GHZ)
+               flag |= BIT(0);
+
+       if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
+               flag |= BIT(8);
+
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, flag, true);
+       dev->cal.tssi_cal_done = true;
+       return true;
+}
+
+static void
+mt76x2_phy_channel_calibrate(struct mt76x2_dev *dev, bool mac_stopped)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
+
+       if (dev->cal.channel_cal_done)
+               return;
+
+       if (mt76x2_channel_silent(dev))
+               return;
+
+       if (!dev->cal.tssi_cal_done)
+               mt76x2_phy_tssi_init_cal(dev);
+
+       if (!mac_stopped)
+               mt76x2_mac_stop(dev, false);
+
+       if (is_5ghz)
+               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, true);
+
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, true);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, true);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, true);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, true);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_SHAPING, 0, true);
+
+       if (!mac_stopped)
+               mt76x2_mac_resume(dev);
+
+       mt76x2_apply_gain_adj(dev);
+
+       dev->cal.channel_cal_done = true;
+}
+
+void mt76x2_phy_set_antenna(struct mt76x2_dev *dev)
+{
+       u32 val;
+
+       val = mt76_rr(dev, MT_BBP(AGC, 0));
+       val &= ~(BIT(4) | BIT(1));
+       switch (dev->mt76.antenna_mask) {
+       case 1:
+               /* disable mac DAC control */
+               mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
+               mt76_clear(dev, MT_BBP(TXBE, 5), 3);
+               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3);
+               mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2);
+               /* disable DAC 1 */
+               mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4);
+
+               val &= ~(BIT(3) | BIT(0));
+               break;
+       case 2:
+               /* disable mac DAC control */
+               mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
+               mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1);
+               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc);
+               mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1);
+               /* disable DAC 0 */
+               mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1);
+
+               val &= ~BIT(3);
+               val |= BIT(0);
+               break;
+       case 3:
+       default:
+               /* enable mac DAC control */
+               mt76_set(dev, MT_BBP(IBI, 9), BIT(11));
+               mt76_set(dev, MT_BBP(TXBE, 5), 3);
+               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf);
+               mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20));
+               mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9));
+
+               val &= ~BIT(0);
+               val |= BIT(3);
+               break;
+       }
+       mt76_wr(dev, MT_BBP(AGC, 0), val);
+}
+
+static void
+mt76x2_get_agc_gain(struct mt76x2_dev *dev, u8 *dest)
+{
+       dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN);
+       dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN);
+}
+
+static int
+mt76x2_get_rssi_gain_thresh(struct mt76x2_dev *dev)
+{
+       switch (dev->mt76.chandef.width) {
+       case NL80211_CHAN_WIDTH_80:
+               return -62;
+       case NL80211_CHAN_WIDTH_40:
+               return -65;
+       default:
+               return -68;
+       }
+}
+
+static int
+mt76x2_get_low_rssi_gain_thresh(struct mt76x2_dev *dev)
+{
+       switch (dev->mt76.chandef.width) {
+       case NL80211_CHAN_WIDTH_80:
+               return -76;
+       case NL80211_CHAN_WIDTH_40:
+               return -79;
+       default:
+               return -82;
+       }
+}
+
+static void
+mt76x2_phy_set_gain_val(struct mt76x2_dev *dev)
+{
+       u32 val;
+       u8 gain_val[2];
+
+       gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
+       gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust;
+
+       if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40)
+               val = 0x1e42 << 16;
+       else
+               val = 0x1836 << 16;
+
+       val |= 0xf8;
+
+       mt76_wr(dev, MT_BBP(AGC, 8),
+               val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0]));
+       mt76_wr(dev, MT_BBP(AGC, 9),
+               val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1]));
+
+       if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR)
+               mt76x2_dfs_adjust_agc(dev);
+}
+
+static void
+mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
+{
+       u32 false_cca;
+       u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
+
+       false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1));
+       dev->cal.false_cca = false_cca;
+       if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
+               dev->cal.agc_gain_adjust += 2;
+       else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
+                (dev->cal.agc_gain_adjust >= limit && false_cca < 500))
+               dev->cal.agc_gain_adjust -= 2;
+       else
+               return;
+
+       mt76x2_phy_set_gain_val(dev);
+}
+
+static void
+mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
+{
+       u8 *gain = dev->cal.agc_gain_init;
+       u8 low_gain_delta, gain_delta;
+       bool gain_change;
+       int low_gain;
+       u32 val;
+
+       dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
+
+       low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
+                  (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));
+
+       gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
+       dev->cal.low_gain = low_gain;
+
+       if (!gain_change) {
+               mt76x2_phy_adjust_vga_gain(dev);
+               return;
+       }
+
+       if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) {
+               mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211);
+               val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf;
+               if (low_gain == 2)
+                       val |= 0x3;
+               else
+                       val |= 0x5;
+               mt76_wr(dev, MT_BBP(AGC, 26), val);
+       } else {
+               mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
+       }
+
+       if (mt76x2_has_ext_lna(dev))
+               low_gain_delta = 10;
+       else
+               low_gain_delta = 14;
+
+       if (low_gain == 2) {
+               mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
+               mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
+               mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
+               gain_delta = low_gain_delta;
+               dev->cal.agc_gain_adjust = 0;
+       } else {
+               mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
+               if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
+                       mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014);
+               else
+                       mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116);
+               mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C);
+               gain_delta = 0;
+               dev->cal.agc_gain_adjust = low_gain_delta;
+       }
+
+       dev->cal.agc_gain_cur[0] = gain[0] - gain_delta;
+       dev->cal.agc_gain_cur[1] = gain[1] - gain_delta;
+       mt76x2_phy_set_gain_val(dev);
+
+       /* clear false CCA counters */
+       mt76_rr(dev, MT_RX_STAT_1);
+}
+
+int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
+                          struct cfg80211_chan_def *chandef)
+{
+       struct ieee80211_channel *chan = chandef->chan;
+       bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
+       enum nl80211_band band = chan->band;
+       u8 channel;
+
+       u32 ext_cca_chan[4] = {
+               [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
+               [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
+               [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
+               [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
+       };
+       int ch_group_index;
+       u8 bw, bw_index;
+       int freq, freq1;
+       int ret;
+
+       dev->cal.channel_cal_done = false;
+       freq = chandef->chan->center_freq;
+       freq1 = chandef->center_freq1;
+       channel = chan->hw_value;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_40:
+               bw = 1;
+               if (freq1 > freq) {
+                       bw_index = 1;
+                       ch_group_index = 0;
+               } else {
+                       bw_index = 3;
+                       ch_group_index = 1;
+               }
+               channel += 2 - ch_group_index * 4;
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               ch_group_index = (freq - freq1 + 30) / 20;
+               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
+                       ch_group_index = 0;
+               bw = 2;
+               bw_index = ch_group_index;
+               channel += 6 - ch_group_index * 4;
+               break;
+       default:
+               bw = 0;
+               bw_index = 0;
+               ch_group_index = 0;
+               break;
+       }
+
+       mt76x2_read_rx_gain(dev);
+       mt76x2_phy_set_txpower_regs(dev, band);
+       mt76x2_configure_tx_delay(dev, band, bw);
+       mt76x2_phy_set_txpower(dev);
+
+       mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
+       mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
+
+       mt76_rmw(dev, MT_EXT_CCA_CFG,
+                (MT_EXT_CCA_CFG_CCA0 |
+                 MT_EXT_CCA_CFG_CCA1 |
+                 MT_EXT_CCA_CFG_CCA2 |
+                 MT_EXT_CCA_CFG_CCA3 |
+                 MT_EXT_CCA_CFG_CCA_MASK),
+                ext_cca_chan[ch_group_index]);
+
+       ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
+       if (ret)
+               return ret;
+
+       mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
+
+       mt76x2_phy_set_antenna(dev);
+
+       /* Enable LDPC Rx */
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
+               mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
+
+       if (!dev->cal.init_cal_done) {
+               u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
+
+               if (val != 0xff)
+                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, true);
+       }
+
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, true);
+
+       /* Rx LPF calibration */
+       if (!dev->cal.init_cal_done)
+               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, true);
+
+       dev->cal.init_cal_done = true;
+
+       mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2);
+       mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
+       mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
+       mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
+       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F);
+
+       if (scan)
+               return 0;
+
+       dev->cal.low_gain = -1;
+       mt76x2_phy_channel_calibrate(dev, true);
+       mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init);
+       memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init,
+              sizeof(dev->cal.agc_gain_cur));
+
+       /* init default values for temp compensation */
+       if (mt76x02_tssi_enabled(&dev->mt76)) {
+               mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
+                              0x38);
+               mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
+                              0x38);
+       }
+
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
+                                    MT_CALIBRATE_INTERVAL);
+
+       return 0;
+}
+
+static void
+mt76x2_phy_temp_compensate(struct mt76x2_dev *dev)
+{
+       struct mt76x2_temp_comp t;
+       int temp, db_diff;
+
+       if (mt76x2_get_temp_comp(dev, &t))
+               return;
+
+       temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL);
+       temp -= t.temp_25_ref;
+       temp = (temp * 1789) / 1000 + 25;
+       dev->cal.temp = temp;
+
+       if (temp > 25)
+               db_diff = (temp - 25) / t.high_slope;
+       else
+               db_diff = (25 - temp) / t.low_slope;
+
+       db_diff = min(db_diff, t.upper_bound);
+       db_diff = max(db_diff, t.lower_bound);
+
+       mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
+                      db_diff * 2);
+       mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
+                      db_diff * 2);
+}
+
+void mt76x2_phy_calibrate(struct work_struct *work)
+{
+       struct mt76x2_dev *dev;
+
+       dev = container_of(work, struct mt76x2_dev, cal_work.work);
+       mt76x2_phy_channel_calibrate(dev, false);
+       mt76x2_phy_tssi_compensate(dev, true);
+       mt76x2_phy_temp_compensate(dev);
+       mt76x2_phy_update_channel_gain(dev);
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
+                                    MT_CALIBRATE_INTERVAL);
+}
+
+int mt76x2_phy_start(struct mt76x2_dev *dev)
+{
+       int ret;
+
+       ret = mt76x02_mcu_set_radio_state(&dev->mt76, true, true);
+       if (ret)
+               return ret;
+
+       mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0);
+
+       return ret;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_trace.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_trace.c
new file mode 100644 (file)
index 0000000..ea4ab87
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+
+#ifndef __CHECKER__
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
+#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_tx.c
new file mode 100644 (file)
index 0000000..69dc1f3
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../mt76x02_util.h"
+#include "../mt76x02_dma.h"
+
+struct beacon_bc_data {
+       struct mt76x2_dev *dev;
+       struct sk_buff_head q;
+       struct sk_buff *tail[8];
+};
+
+int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
+                         struct sk_buff *skb, struct mt76_queue *q,
+                         struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+                         u32 *tx_info)
+{
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       int qsel = MT_QSEL_EDCA;
+       int ret;
+
+       if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128)
+               mt76x02_mac_wcid_set_drop(&dev->mt76, wcid->idx, false);
+
+       mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len);
+
+       ret = mt76x02_insert_hdr_pad(skb);
+       if (ret < 0)
+               return ret;
+
+       if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
+               qsel = MT_QSEL_MGMT;
+
+       *tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
+                  MT_TXD_INFO_80211;
+
+       if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
+               *tx_info |= MT_TXD_INFO_WIV;
+
+       return 0;
+}
+
+static void
+mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct mt76x2_dev *dev = (struct mt76x2_dev *) priv;
+       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
+       struct sk_buff *skb = NULL;
+
+       if (!(dev->beacon_mask & BIT(mvif->idx)))
+               return;
+
+       skb = ieee80211_beacon_get(mt76_hw(dev), vif);
+       if (!skb)
+               return;
+
+       mt76x2_mac_set_beacon(dev, mvif->idx, skb);
+}
+
+static void
+mt76x2_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct beacon_bc_data *data = priv;
+       struct mt76x2_dev *dev = data->dev;
+       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
+       struct ieee80211_tx_info *info;
+       struct sk_buff *skb;
+
+       if (!(dev->beacon_mask & BIT(mvif->idx)))
+               return;
+
+       skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
+       if (!skb)
+               return;
+
+       info = IEEE80211_SKB_CB(skb);
+       info->control.vif = vif;
+       info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+       mt76_skb_set_moredata(skb, true);
+       __skb_queue_tail(&data->q, skb);
+       data->tail[mvif->idx] = skb;
+}
+
+static void
+mt76x2_resync_beacon_timer(struct mt76x2_dev *dev)
+{
+       u32 timer_val = dev->beacon_int << 4;
+
+       dev->tbtt_count++;
+
+       /*
+        * Beacon timer drifts by 1us every tick, the timer is configured
+        * in 1/16 TU (64us) units.
+        */
+       if (dev->tbtt_count < 62)
+               return;
+
+       if (dev->tbtt_count >= 64) {
+               dev->tbtt_count = 0;
+               return;
+       }
+
+       /*
+        * The updated beacon interval takes effect after two TBTT, because
+        * at this point the original interval has already been loaded into
+        * the next TBTT_TIMER value
+        */
+       if (dev->tbtt_count == 62)
+               timer_val -= 1;
+
+       mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+                      MT_BEACON_TIME_CFG_INTVAL, timer_val);
+}
+
+void mt76x2_pre_tbtt_tasklet(unsigned long arg)
+{
+       struct mt76x2_dev *dev = (struct mt76x2_dev *) arg;
+       struct mt76_queue *q = &dev->mt76.q_tx[MT_TXQ_PSD];
+       struct beacon_bc_data data = {};
+       struct sk_buff *skb;
+       int i, nframes;
+
+       mt76x2_resync_beacon_timer(dev);
+
+       data.dev = dev;
+       __skb_queue_head_init(&data.q);
+
+       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+               IEEE80211_IFACE_ITER_RESUME_ALL,
+               mt76x2_update_beacon_iter, dev);
+
+       do {
+               nframes = skb_queue_len(&data.q);
+               ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+                       IEEE80211_IFACE_ITER_RESUME_ALL,
+                       mt76x2_add_buffered_bc, &data);
+       } while (nframes != skb_queue_len(&data.q));
+
+       if (!nframes)
+               return;
+
+       for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
+               if (!data.tail[i])
+                       continue;
+
+               mt76_skb_set_moredata(data.tail[i], false);
+       }
+
+       spin_lock_bh(&q->lock);
+       while ((skb = __skb_dequeue(&data.q)) != NULL) {
+               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+               struct ieee80211_vif *vif = info->control.vif;
+               struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
+
+               mt76_dma_tx_queue_skb(&dev->mt76, q, skb, &mvif->group_wcid,
+                                     NULL);
+       }
+       spin_unlock_bh(&q->lock);
+}
+
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c
new file mode 100644 (file)
index 0000000..b3ecb80
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "eeprom.h"
+#include "mcu.h"
+#include "../mt76x02_phy.h"
+
+static void
+mt76x2_adjust_high_lna_gain(struct mt76x2_dev *dev, int reg, s8 offset)
+{
+       s8 gain;
+
+       gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, mt76_rr(dev, MT_BBP(AGC, reg)));
+       gain -= offset / 2;
+       mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain);
+}
+
+static void
+mt76x2_adjust_agc_gain(struct mt76x2_dev *dev, int reg, s8 offset)
+{
+       s8 gain;
+
+       gain = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, reg)));
+       gain += offset;
+       mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_GAIN, gain);
+}
+
+void mt76x2_apply_gain_adj(struct mt76x2_dev *dev)
+{
+       s8 *gain_adj = dev->cal.rx.high_gain;
+
+       mt76x2_adjust_high_lna_gain(dev, 4, gain_adj[0]);
+       mt76x2_adjust_high_lna_gain(dev, 5, gain_adj[1]);
+
+       mt76x2_adjust_agc_gain(dev, 8, gain_adj[0]);
+       mt76x2_adjust_agc_gain(dev, 9, gain_adj[1]);
+}
+EXPORT_SYMBOL_GPL(mt76x2_apply_gain_adj);
+
+void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev,
+                                enum nl80211_band band)
+{
+       u32 pa_mode[2];
+       u32 pa_mode_adj;
+
+       if (band == NL80211_BAND_2GHZ) {
+               pa_mode[0] = 0x010055ff;
+               pa_mode[1] = 0x00550055;
+
+               mt76_wr(dev, MT_TX_ALC_CFG_2, 0x35160a00);
+               mt76_wr(dev, MT_TX_ALC_CFG_3, 0x35160a06);
+
+               if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
+                       mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0x0000ec00);
+                       mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0x0000ec00);
+               } else {
+                       mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0xf4000200);
+                       mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0xfa000200);
+               }
+       } else {
+               pa_mode[0] = 0x0000ffff;
+               pa_mode[1] = 0x00ff00ff;
+
+               if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
+                       mt76_wr(dev, MT_TX_ALC_CFG_2, 0x2f0f0400);
+                       mt76_wr(dev, MT_TX_ALC_CFG_3, 0x2f0f0476);
+               } else {
+                       mt76_wr(dev, MT_TX_ALC_CFG_2, 0x1b0f0400);
+                       mt76_wr(dev, MT_TX_ALC_CFG_3, 0x1b0f0476);
+               }
+
+               if (mt76x02_ext_pa_enabled(&dev->mt76, band))
+                       pa_mode_adj = 0x04000000;
+               else
+                       pa_mode_adj = 0;
+
+               mt76_wr(dev, MT_RF_PA_MODE_ADJ0, pa_mode_adj);
+               mt76_wr(dev, MT_RF_PA_MODE_ADJ1, pa_mode_adj);
+       }
+
+       mt76_wr(dev, MT_BB_PA_MODE_CFG0, pa_mode[0]);
+       mt76_wr(dev, MT_BB_PA_MODE_CFG1, pa_mode[1]);
+       mt76_wr(dev, MT_RF_PA_MODE_CFG0, pa_mode[0]);
+       mt76_wr(dev, MT_RF_PA_MODE_CFG1, pa_mode[1]);
+
+       if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
+               u32 val;
+
+               if (band == NL80211_BAND_2GHZ)
+                       val = 0x3c3c023c;
+               else
+                       val = 0x363c023c;
+
+               mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val);
+               mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val);
+               mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00001818);
+       } else {
+               if (band == NL80211_BAND_2GHZ) {
+                       u32 val = 0x0f3c3c3c;
+
+                       mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val);
+                       mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val);
+                       mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00000606);
+               } else {
+                       mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x383c023c);
+                       mt76_wr(dev, MT_TX1_RF_GAIN_CORR, 0x24282e28);
+                       mt76_wr(dev, MT_TX_ALC_CFG_4, 0);
+               }
+       }
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower_regs);
+
+static int
+mt76x2_get_min_rate_power(struct mt76_rate_power *r)
+{
+       int i;
+       s8 ret = 0;
+
+       for (i = 0; i < sizeof(r->all); i++) {
+               if (!r->all[i])
+                       continue;
+
+               if (ret)
+                       ret = min(ret, r->all[i]);
+               else
+                       ret = r->all[i];
+       }
+
+       return ret;
+}
+
+void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
+{
+       enum nl80211_chan_width width = dev->mt76.chandef.width;
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       struct mt76x2_tx_power_info txp;
+       int txp_0, txp_1, delta = 0;
+       struct mt76_rate_power t = {};
+       int base_power, gain;
+
+       mt76x2_get_power_info(dev, &txp, chan);
+
+       if (width == NL80211_CHAN_WIDTH_40)
+               delta = txp.delta_bw40;
+       else if (width == NL80211_CHAN_WIDTH_80)
+               delta = txp.delta_bw80;
+
+       mt76x2_get_rate_power(dev, &t, chan);
+       mt76x02_add_rate_power_offset(&t, txp.chain[0].target_power);
+       mt76x02_limit_rate_power(&t, dev->mt76.txpower_conf);
+       dev->mt76.txpower_cur = mt76x02_get_max_rate_power(&t);
+
+       base_power = mt76x2_get_min_rate_power(&t);
+       delta += base_power - txp.chain[0].target_power;
+       txp_0 = txp.chain[0].target_power + txp.chain[0].delta + delta;
+       txp_1 = txp.chain[1].target_power + txp.chain[1].delta + delta;
+
+       gain = min(txp_0, txp_1);
+       if (gain < 0) {
+               base_power -= gain;
+               txp_0 -= gain;
+               txp_1 -= gain;
+       } else if (gain > 0x2f) {
+               base_power -= gain - 0x2f;
+               txp_0 = 0x2f;
+               txp_1 = 0x2f;
+       }
+
+       mt76x02_add_rate_power_offset(&t, -base_power);
+       dev->target_power = txp.chain[0].target_power;
+       dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power;
+       dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power;
+       dev->mt76.rate_power = t;
+
+       mt76x02_phy_set_txpower(&dev->mt76, txp_0, txp_1);
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower);
+
+void mt76x2_configure_tx_delay(struct mt76x2_dev *dev,
+                              enum nl80211_band band, u8 bw)
+{
+       u32 cfg0, cfg1;
+
+       if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
+               cfg0 = bw ? 0x000b0c01 : 0x00101101;
+               cfg1 = 0x00011414;
+       } else {
+               cfg0 = bw ? 0x000b0b01 : 0x00101001;
+               cfg1 = 0x00021414;
+       }
+       mt76_wr(dev, MT_TX_SW_CFG0, cfg0);
+       mt76_wr(dev, MT_TX_SW_CFG1, cfg1);
+
+       mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, 15);
+}
+EXPORT_SYMBOL_GPL(mt76x2_configure_tx_delay);
+
+void mt76x2_phy_set_bw(struct mt76x2_dev *dev, int width, u8 ctrl)
+{
+       int core_val, agc_val;
+
+       switch (width) {
+       case NL80211_CHAN_WIDTH_80:
+               core_val = 3;
+               agc_val = 7;
+               break;
+       case NL80211_CHAN_WIDTH_40:
+               core_val = 2;
+               agc_val = 3;
+               break;
+       default:
+               core_val = 0;
+               agc_val = 1;
+               break;
+       }
+
+       mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val);
+       mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val);
+       mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl);
+       mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl);
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_set_bw);
+
+void mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper)
+{
+       switch (band) {
+       case NL80211_BAND_2GHZ:
+               mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
+               mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
+               break;
+       case NL80211_BAND_5GHZ:
+               mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
+               mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
+               break;
+       }
+
+       mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M,
+                      primary_upper);
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_set_band);
+
+int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev)
+{
+       struct mt76x02_sta *sta;
+       struct mt76_wcid *wcid;
+       int i, j, min_rssi = 0;
+       s8 cur_rssi;
+
+       local_bh_disable();
+       rcu_read_lock();
+
+       for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) {
+               unsigned long mask = dev->mt76.wcid_mask[i];
+
+               if (!mask)
+                       continue;
+
+               for (j = i * BITS_PER_LONG; mask; j++, mask >>= 1) {
+                       if (!(mask & 1))
+                               continue;
+
+                       wcid = rcu_dereference(dev->mt76.wcid[j]);
+                       if (!wcid)
+                               continue;
+
+                       sta = container_of(wcid, struct mt76x02_sta, wcid);
+                       spin_lock(&dev->mt76.rx_lock);
+                       if (sta->inactive_count++ < 5)
+                               cur_rssi = ewma_signal_read(&sta->rssi);
+                       else
+                               cur_rssi = 0;
+                       spin_unlock(&dev->mt76.rx_lock);
+
+                       if (cur_rssi < min_rssi)
+                               min_rssi = cur_rssi;
+               }
+       }
+
+       rcu_read_unlock();
+       local_bh_enable();
+
+       if (!min_rssi)
+               return -75;
+
+       return min_rssi;
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_get_min_avg_rssi);
+
+void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       struct mt76x2_tx_power_info txp;
+       struct mt76x2_tssi_comp t = {};
+
+       if (!dev->cal.tssi_cal_done)
+               return;
+
+       if (!dev->cal.tssi_comp_pending) {
+               /* TSSI trigger */
+               t.cal_mode = BIT(0);
+               mt76x2_mcu_tssi_comp(dev, &t);
+               dev->cal.tssi_comp_pending = true;
+       } else {
+               if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4))
+                       return;
+
+               dev->cal.tssi_comp_pending = false;
+               mt76x2_get_power_info(dev, &txp, chan);
+
+               if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
+                       t.pa_mode = 1;
+
+               t.cal_mode = BIT(1);
+               t.slope0 = txp.chain[0].tssi_slope;
+               t.offset0 = txp.chain[0].tssi_offset;
+               t.slope1 = txp.chain[1].tssi_slope;
+               t.offset1 = txp.chain[1].tssi_offset;
+               mt76x2_mcu_tssi_comp(dev, &t);
+
+               if (t.pa_mode || dev->cal.dpd_cal_done)
+                       return;
+
+               usleep_range(10000, 20000);
+               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD,
+                                     chan->hw_value, wait);
+               dev->cal.dpd_cal_done = true;
+       }
+}
+EXPORT_SYMBOL_GPL(mt76x2_phy_tssi_compensate);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/trace.h b/drivers/net/wireless/mediatek/mt76/mt76x2/trace.h
new file mode 100644 (file)
index 0000000..9dceaba
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if !defined(__MT76x2_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define __MT76x2_TRACE_H
+
+#include <linux/tracepoint.h>
+#include "mt76x2.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mt76x2
+
+#define MAXNAME                32
+#define DEV_ENTRY      __array(char, wiphy_name, 32)
+#define DEV_ASSIGN     strlcpy(__entry->wiphy_name, wiphy_name(mt76_hw(dev)->wiphy), MAXNAME)
+#define DEV_PR_FMT     "%s"
+#define DEV_PR_ARG     __entry->wiphy_name
+
+#define TXID_ENTRY     __field(u8, wcid) __field(u8, pktid)
+#define TXID_ASSIGN    __entry->wcid = wcid; __entry->pktid = pktid
+#define TXID_PR_FMT    " [%d:%d]"
+#define TXID_PR_ARG    __entry->wcid, __entry->pktid
+
+DECLARE_EVENT_CLASS(dev_evt,
+       TP_PROTO(struct mt76x2_dev *dev),
+       TP_ARGS(dev),
+       TP_STRUCT__entry(
+               DEV_ENTRY
+       ),
+       TP_fast_assign(
+               DEV_ASSIGN;
+       ),
+       TP_printk(DEV_PR_FMT, DEV_PR_ARG)
+);
+
+DECLARE_EVENT_CLASS(dev_txid_evt,
+       TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid),
+       TP_ARGS(dev, wcid, pktid),
+       TP_STRUCT__entry(
+               DEV_ENTRY
+               TXID_ENTRY
+       ),
+       TP_fast_assign(
+               DEV_ASSIGN;
+               TXID_ASSIGN;
+       ),
+       TP_printk(
+               DEV_PR_FMT TXID_PR_FMT,
+               DEV_PR_ARG, TXID_PR_ARG
+       )
+);
+
+DEFINE_EVENT(dev_evt, mac_txstat_poll,
+       TP_PROTO(struct mt76x2_dev *dev),
+       TP_ARGS(dev)
+);
+
+DEFINE_EVENT(dev_txid_evt, mac_txdone_add,
+       TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid),
+       TP_ARGS(dev, wcid, pktid)
+);
+
+TRACE_EVENT(mac_txstat_fetch,
+       TP_PROTO(struct mt76x2_dev *dev,
+                struct mt76x02_tx_status *stat),
+
+       TP_ARGS(dev, stat),
+
+       TP_STRUCT__entry(
+               DEV_ENTRY
+               TXID_ENTRY
+               __field(bool, success)
+               __field(bool, aggr)
+               __field(bool, ack_req)
+               __field(u16, rate)
+               __field(u8, retry)
+       ),
+
+       TP_fast_assign(
+               DEV_ASSIGN;
+               __entry->success = stat->success;
+               __entry->aggr = stat->aggr;
+               __entry->ack_req = stat->ack_req;
+               __entry->wcid = stat->wcid;
+               __entry->pktid = stat->pktid;
+               __entry->rate = stat->rate;
+               __entry->retry = stat->retry;
+       ),
+
+       TP_printk(
+               DEV_PR_FMT TXID_PR_FMT
+               " success:%d aggr:%d ack_req:%d"
+               " rate:%04x retry:%d",
+               DEV_PR_ARG, TXID_PR_ARG,
+               __entry->success, __entry->aggr, __entry->ack_req,
+               __entry->rate, __entry->retry
+       )
+);
+
+
+TRACE_EVENT(dev_irq,
+       TP_PROTO(struct mt76x2_dev *dev, u32 val, u32 mask),
+
+       TP_ARGS(dev, val, mask),
+
+       TP_STRUCT__entry(
+               DEV_ENTRY
+               __field(u32, val)
+               __field(u32, mask)
+       ),
+
+       TP_fast_assign(
+               DEV_ASSIGN;
+               __entry->val = val;
+               __entry->mask = mask;
+       ),
+
+       TP_printk(
+               DEV_PR_FMT " %08x & %08x",
+               DEV_PR_ARG, __entry->val, __entry->mask
+       )
+);
+
+#endif
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2/tx.c
new file mode 100644 (file)
index 0000000..aea1426
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2.h"
+#include "../dma.h"
+
+void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
+              struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct mt76x2_dev *dev = hw->priv;
+       struct ieee80211_vif *vif = info->control.vif;
+       struct mt76_wcid *wcid = &dev->mt76.global_wcid;
+
+       if (control->sta) {
+               struct mt76x02_sta *msta;
+
+               msta = (struct mt76x02_sta *)control->sta->drv_priv;
+               wcid = &msta->wcid;
+               /* sw encrypted frames */
+               if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
+                       control->sta = NULL;
+       }
+
+       if (vif && !control->sta) {
+               struct mt76x02_vif *mvif;
+
+               mvif = (struct mt76x02_vif *)vif->drv_priv;
+               wcid = &mvif->group_wcid;
+       }
+
+       mt76_tx(&dev->mt76, control->sta, wcid, skb);
+}
+EXPORT_SYMBOL_GPL(mt76x2_tx);
+
+s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *mdev,
+                              const struct ieee80211_tx_rate *rate)
+{
+       struct mt76x2_dev *dev = (struct mt76x2_dev *) mdev;
+       s8 max_txpwr;
+
+       if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
+               u8 mcs = ieee80211_rate_get_vht_mcs(rate);
+
+               if (mcs == 8 || mcs == 9) {
+                       max_txpwr = mdev->rate_power.vht[8];
+               } else {
+                       u8 nss, idx;
+
+                       nss = ieee80211_rate_get_vht_nss(rate);
+                       idx = ((nss - 1) << 3) + mcs;
+                       max_txpwr = mdev->rate_power.ht[idx & 0xf];
+               }
+       } else if (rate->flags & IEEE80211_TX_RC_MCS) {
+               max_txpwr = mdev->rate_power.ht[rate->idx & 0xf];
+       } else {
+               enum nl80211_band band = dev->mt76.chandef.chan->band;
+
+               if (band == NL80211_BAND_2GHZ) {
+                       const struct ieee80211_rate *r;
+                       struct wiphy *wiphy = mt76_hw(dev)->wiphy;
+                       struct mt76_rate_power *rp = &mdev->rate_power;
+
+                       r = &wiphy->bands[band]->bitrates[rate->idx];
+                       if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
+                               max_txpwr = rp->cck[r->hw_value & 0x3];
+                       else
+                               max_txpwr = rp->ofdm[r->hw_value & 0x7];
+               } else {
+                       max_txpwr = mdev->rate_power.ofdm[rate->idx & 0x7];
+               }
+       }
+
+       return max_txpwr;
+}
+EXPORT_SYMBOL_GPL(mt76x2_tx_get_max_txpwr_adj);
+
+s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj)
+{
+       txpwr = min_t(s8, txpwr, dev->mt76.txpower_conf);
+       txpwr -= (dev->target_power + dev->target_power_delta[0]);
+       txpwr = min_t(s8, txpwr, max_txpwr_adj);
+
+       if (!dev->enable_tpc)
+               return 0;
+       else if (txpwr >= 0)
+               return min_t(s8, txpwr, 7);
+       else
+               return (txpwr < -16) ? 8 : (txpwr + 32) / 2;
+}
+EXPORT_SYMBOL_GPL(mt76x2_tx_get_txpwr_adj);
+
+void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr)
+{
+       s8 txpwr_adj;
+
+       txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, txpwr,
+                                           dev->mt76.rate_power.ofdm[4]);
+       mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
+                      MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj);
+       mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
+                      MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj);
+}
+EXPORT_SYMBOL_GPL(mt76x2_tx_set_txpwr_auto);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
new file mode 100644 (file)
index 0000000..b0c1721
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "../mt76x02_usb.h"
+#include "mt76x2u.h"
+
+static const struct usb_device_id mt76x2u_device_table[] = {
+       { USB_DEVICE(0x0e8d, 0x7612) }, /* Alfa AWUS036ACM */
+       { USB_DEVICE(0x0b05, 0x1833) }, /* Asus USB-AC54 */
+       { USB_DEVICE(0x0b05, 0x17eb) }, /* Asus USB-AC55 */
+       { USB_DEVICE(0x0b05, 0x180b) }, /* Asus USB-N53 B1 */
+       { USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USB-AC1200 */
+       { USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */
+       { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */
+       { USB_DEVICE(0x0846, 0x9053) }, /* Netgear A6210 */
+       { USB_DEVICE(0x045e, 0x02e6) }, /* XBox One Wireless Adapter */
+       { },
+};
+
+static int mt76x2u_probe(struct usb_interface *intf,
+                        const struct usb_device_id *id)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct mt76x2_dev *dev;
+       int err;
+
+       dev = mt76x2u_alloc_device(&intf->dev);
+       if (!dev)
+               return -ENOMEM;
+
+       udev = usb_get_dev(udev);
+       usb_reset_device(udev);
+
+       mt76x02u_init_mcu(&dev->mt76);
+       err = mt76u_init(&dev->mt76, intf);
+       if (err < 0)
+               goto err;
+
+       dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION);
+       dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev);
+
+       err = mt76x2u_register_device(dev);
+       if (err < 0)
+               goto err;
+
+       return 0;
+
+err:
+       ieee80211_free_hw(mt76_hw(dev));
+       usb_set_intfdata(intf, NULL);
+       usb_put_dev(udev);
+
+       return err;
+}
+
+static void mt76x2u_disconnect(struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct mt76x2_dev *dev = usb_get_intfdata(intf);
+       struct ieee80211_hw *hw = mt76_hw(dev);
+
+       set_bit(MT76_REMOVED, &dev->mt76.state);
+       ieee80211_unregister_hw(hw);
+       mt76x2u_cleanup(dev);
+
+       ieee80211_free_hw(hw);
+       usb_set_intfdata(intf, NULL);
+       usb_put_dev(udev);
+}
+
+static int __maybe_unused mt76x2u_suspend(struct usb_interface *intf,
+                                         pm_message_t state)
+{
+       struct mt76x2_dev *dev = usb_get_intfdata(intf);
+       struct mt76_usb *usb = &dev->mt76.usb;
+
+       mt76u_stop_queues(&dev->mt76);
+       mt76x2u_stop_hw(dev);
+       usb_kill_urb(usb->mcu.res.urb);
+
+       return 0;
+}
+
+static int __maybe_unused mt76x2u_resume(struct usb_interface *intf)
+{
+       struct mt76x2_dev *dev = usb_get_intfdata(intf);
+       struct mt76_usb *usb = &dev->mt76.usb;
+       int err;
+
+       reinit_completion(&usb->mcu.cmpl);
+       err = mt76u_submit_buf(&dev->mt76, USB_DIR_IN,
+                              MT_EP_IN_CMD_RESP,
+                              &usb->mcu.res, GFP_KERNEL,
+                              mt76u_mcu_complete_urb,
+                              &usb->mcu.cmpl);
+       if (err < 0)
+               goto err;
+
+       err = mt76u_submit_rx_buffers(&dev->mt76);
+       if (err < 0)
+               goto err;
+
+       tasklet_enable(&usb->rx_tasklet);
+       tasklet_enable(&usb->tx_tasklet);
+
+       err = mt76x2u_init_hardware(dev);
+       if (err < 0)
+               goto err;
+
+       return 0;
+
+err:
+       mt76x2u_cleanup(dev);
+       return err;
+}
+
+MODULE_DEVICE_TABLE(usb, mt76x2u_device_table);
+MODULE_FIRMWARE(MT7662U_FIRMWARE);
+MODULE_FIRMWARE(MT7662U_ROM_PATCH);
+
+static struct usb_driver mt76x2u_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = mt76x2u_device_table,
+       .probe          = mt76x2u_probe,
+       .disconnect     = mt76x2u_disconnect,
+#ifdef CONFIG_PM
+       .suspend        = mt76x2u_suspend,
+       .resume         = mt76x2u_resume,
+       .reset_resume   = mt76x2u_resume,
+#endif /* CONFIG_PM */
+       .soft_unbind    = 1,
+       .disable_hub_initiated_lpm = 1,
+};
+module_usb_driver(mt76x2u_driver);
+
+MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_core.c
new file mode 100644 (file)
index 0000000..6eb7b28
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2u.h"
+#include "../dma.h"
+#include "../mt76x02_util.h"
+#include "../mt76x02_usb.h"
+
+static int
+mt76x2u_check_skb_rooms(struct sk_buff *skb)
+{
+       int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+       u32 need_head;
+
+       need_head = sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN;
+       if (hdr_len % 4)
+               need_head += 2;
+       return skb_cow(skb, need_head);
+}
+
+int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
+                          struct sk_buff *skb, struct mt76_queue *q,
+                          struct mt76_wcid *wcid, struct ieee80211_sta *sta,
+                          u32 *tx_info)
+{
+       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
+       struct mt76x02_txwi *txwi;
+       int err, len = skb->len;
+
+       err = mt76x2u_check_skb_rooms(skb);
+       if (err < 0)
+               return -ENOMEM;
+
+       mt76x02_insert_hdr_pad(skb);
+
+       txwi = skb_push(skb, sizeof(struct mt76x02_txwi));
+       mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
+
+       return mt76x02u_set_txinfo(skb, wcid, q2ep(q->hw_idx));
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
new file mode 100644 (file)
index 0000000..55e0dea
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+
+#include "mt76x2u.h"
+#include "../mt76x02_util.h"
+#include "../mt76x02_phy.h"
+#include "eeprom.h"
+
+static void mt76x2u_init_dma(struct mt76x2_dev *dev)
+{
+       u32 val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
+
+       val |= MT_USB_DMA_CFG_RX_DROP_OR_PAD |
+              MT_USB_DMA_CFG_RX_BULK_EN |
+              MT_USB_DMA_CFG_TX_BULK_EN;
+
+       /* disable AGGR_BULK_RX in order to receive one
+        * frame in each rx urb and avoid copies
+        */
+       val &= ~MT_USB_DMA_CFG_RX_BULK_AGG_EN;
+       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
+}
+
+static void mt76x2u_power_on_rf_patch(struct mt76x2_dev *dev)
+{
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) | BIT(16));
+       udelay(1);
+
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x1c), 0xff);
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x1c), 0x30);
+
+       mt76_wr(dev, MT_VEND_ADDR(CFG, 0x14), 0x484f);
+       udelay(1);
+
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(17));
+       usleep_range(150, 200);
+
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(16));
+       usleep_range(50, 100);
+
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x14c), BIT(19) | BIT(20));
+}
+
+static void mt76x2u_power_on_rf(struct mt76x2_dev *dev, int unit)
+{
+       int shift = unit ? 8 : 0;
+       u32 val = (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift;
+
+       /* Enable RF BG */
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) << shift);
+       usleep_range(10, 20);
+
+       /* Enable RFDIG LDO/AFE/ABB/ADDA */
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), val);
+       usleep_range(10, 20);
+
+       /* Switch RFDIG power to internal LDO */
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(2) << shift);
+       usleep_range(10, 20);
+
+       mt76x2u_power_on_rf_patch(dev);
+
+       mt76_set(dev, 0x530, 0xf);
+}
+
+static void mt76x2u_power_on(struct mt76x2_dev *dev)
+{
+       u32 val;
+
+       /* Turn on WL MTCMOS */
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x148),
+                MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP);
+
+       val = MT_WLAN_MTC_CTRL_STATE_UP |
+             MT_WLAN_MTC_CTRL_PWR_ACK |
+             MT_WLAN_MTC_CTRL_PWR_ACK_S;
+
+       mt76_poll(dev, MT_VEND_ADDR(CFG, 0x148), val, val, 1000);
+
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0x7f << 16);
+       usleep_range(10, 20);
+
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);
+       usleep_range(10, 20);
+
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0xfff);
+
+       /* Turn on AD/DA power down */
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x1204), BIT(3));
+
+       /* WLAN function enable */
+       mt76_set(dev, MT_VEND_ADDR(CFG, 0x80), BIT(0));
+
+       /* Release BBP software reset */
+       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x64), BIT(18));
+
+       mt76x2u_power_on_rf(dev, 0);
+       mt76x2u_power_on_rf(dev, 1);
+}
+
+static int mt76x2u_init_eeprom(struct mt76x2_dev *dev)
+{
+       u32 val, i;
+
+       dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev,
+                                            MT7612U_EEPROM_SIZE,
+                                            GFP_KERNEL);
+       dev->mt76.eeprom.size = MT7612U_EEPROM_SIZE;
+       if (!dev->mt76.eeprom.data)
+               return -ENOMEM;
+
+       for (i = 0; i + 4 <= MT7612U_EEPROM_SIZE; i += 4) {
+               val = mt76_rr(dev, MT_VEND_ADDR(EEPROM, i));
+               put_unaligned_le32(val, dev->mt76.eeprom.data + i);
+       }
+
+       mt76x02_eeprom_parse_hw_cap(&dev->mt76);
+       return 0;
+}
+
+struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev)
+{
+       static const struct mt76_driver_ops drv_ops = {
+               .tx_prepare_skb = mt76x2u_tx_prepare_skb,
+               .tx_complete_skb = mt76x02_tx_complete_skb,
+               .tx_status_data = mt76x02_tx_status_data,
+               .rx_skb = mt76x2_queue_rx_skb,
+       };
+       struct mt76x2_dev *dev;
+       struct mt76_dev *mdev;
+
+       mdev = mt76_alloc_device(sizeof(*dev), &mt76x2u_ops);
+       if (!mdev)
+               return NULL;
+
+       dev = container_of(mdev, struct mt76x2_dev, mt76);
+       mdev->dev = pdev;
+       mdev->drv = &drv_ops;
+
+       return dev;
+}
+
+static void mt76x2u_init_beacon_offsets(struct mt76x2_dev *dev)
+{
+       mt76_wr(dev, MT_BCN_OFFSET(0), 0x18100800);
+       mt76_wr(dev, MT_BCN_OFFSET(1), 0x38302820);
+       mt76_wr(dev, MT_BCN_OFFSET(2), 0x58504840);
+       mt76_wr(dev, MT_BCN_OFFSET(3), 0x78706860);
+}
+
+int mt76x2u_init_hardware(struct mt76x2_dev *dev)
+{
+       const struct mt76_wcid_addr addr = {
+               .macaddr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               .ba_mask = 0,
+       };
+       int i, err;
+
+       mt76x2_reset_wlan(dev, true);
+       mt76x2u_power_on(dev);
+
+       if (!mt76x02_wait_for_mac(&dev->mt76))
+               return -ETIMEDOUT;
+
+       err = mt76x2u_mcu_fw_init(dev);
+       if (err < 0)
+               return err;
+
+       if (!mt76_poll_msec(dev, MT_WPDMA_GLO_CFG,
+                           MT_WPDMA_GLO_CFG_TX_DMA_BUSY |
+                           MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100))
+               return -EIO;
+
+       /* wait for asic ready after fw load. */
+       if (!mt76x02_wait_for_mac(&dev->mt76))
+               return -ETIMEDOUT;
+
+       mt76_wr(dev, MT_HEADER_TRANS_CTRL_REG, 0);
+       mt76_wr(dev, MT_TSO_CTRL, 0);
+
+       mt76x2u_init_dma(dev);
+
+       err = mt76x2u_mcu_init(dev);
+       if (err < 0)
+               return err;
+
+       err = mt76x2u_mac_reset(dev);
+       if (err < 0)
+               return err;
+
+       mt76x02_mac_setaddr(&dev->mt76,
+                           dev->mt76.eeprom.data + MT_EE_MAC_ADDR);
+       dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
+
+       mt76x2u_init_beacon_offsets(dev);
+
+       if (!mt76x02_wait_for_txrx_idle(&dev->mt76))
+               return -ETIMEDOUT;
+
+       /* reset wcid table */
+       for (i = 0; i < 254; i++)
+               mt76_wr_copy(dev, MT_WCID_ADDR(i), &addr,
+                            sizeof(struct mt76_wcid_addr));
+
+       /* reset shared key table and pairwise key table */
+       for (i = 0; i < 4; i++)
+               mt76_wr(dev, MT_SKEY_MODE_BASE_0 + 4 * i, 0);
+       for (i = 0; i < 256; i++)
+               mt76_wr(dev, MT_WCID_ATTR(i), 1);
+
+       mt76_clear(dev, MT_BEACON_TIME_CFG,
+                  MT_BEACON_TIME_CFG_TIMER_EN |
+                  MT_BEACON_TIME_CFG_SYNC_MODE |
+                  MT_BEACON_TIME_CFG_TBTT_EN |
+                  MT_BEACON_TIME_CFG_BEACON_TX);
+
+       mt76_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e);
+       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x583f);
+
+       err = mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0);
+       if (err < 0)
+               return err;
+
+       mt76x02_phy_set_rxpath(&dev->mt76);
+       mt76x02_phy_set_txdac(&dev->mt76);
+
+       return mt76x2u_mac_stop(dev);
+}
+
+int mt76x2u_register_device(struct mt76x2_dev *dev)
+{
+       struct ieee80211_hw *hw = mt76_hw(dev);
+       struct wiphy *wiphy = hw->wiphy;
+       int err;
+
+       INIT_DELAYED_WORK(&dev->cal_work, mt76x2u_phy_calibrate);
+       mt76x2_init_device(dev);
+
+       err = mt76x2u_init_eeprom(dev);
+       if (err < 0)
+               return err;
+
+       err = mt76u_alloc_queues(&dev->mt76);
+       if (err < 0)
+               goto fail;
+
+       err = mt76u_mcu_init_rx(&dev->mt76);
+       if (err < 0)
+               return err;
+
+       err = mt76x2u_init_hardware(dev);
+       if (err < 0)
+               goto fail;
+
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+
+       err = mt76_register_device(&dev->mt76, true, mt76x02_rates,
+                                  ARRAY_SIZE(mt76x02_rates));
+       if (err)
+               goto fail;
+
+       /* check hw sg support in order to enable AMSDU */
+       if (mt76u_check_sg(&dev->mt76))
+               hw->max_tx_fragments = MT_SG_MAX_SIZE;
+       else
+               hw->max_tx_fragments = 1;
+
+       set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
+
+       mt76x2_init_debugfs(dev);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
+       mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
+
+       return 0;
+
+fail:
+       mt76x2u_cleanup(dev);
+       return err;
+}
+
+void mt76x2u_stop_hw(struct mt76x2_dev *dev)
+{
+       mt76u_stop_stat_wk(&dev->mt76);
+       cancel_delayed_work_sync(&dev->cal_work);
+       mt76x2u_mac_stop(dev);
+}
+
+void mt76x2u_cleanup(struct mt76x2_dev *dev)
+{
+       mt76x02_mcu_set_radio_state(&dev->mt76, false, false);
+       mt76x2u_stop_hw(dev);
+       mt76u_queues_deinit(&dev->mt76);
+       mt76u_mcu_deinit(&dev->mt76);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
new file mode 100644 (file)
index 0000000..ae89461
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2u.h"
+#include "eeprom.h"
+
+static void mt76x2u_mac_reset_counters(struct mt76x2_dev *dev)
+{
+       mt76_rr(dev, MT_RX_STAT_0);
+       mt76_rr(dev, MT_RX_STAT_1);
+       mt76_rr(dev, MT_RX_STAT_2);
+       mt76_rr(dev, MT_TX_STA_0);
+       mt76_rr(dev, MT_TX_STA_1);
+       mt76_rr(dev, MT_TX_STA_2);
+}
+
+static void mt76x2u_mac_fixup_xtal(struct mt76x2_dev *dev)
+{
+       s8 offset = 0;
+       u16 eep_val;
+
+       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2);
+
+       offset = eep_val & 0x7f;
+       if ((eep_val & 0xff) == 0xff)
+               offset = 0;
+       else if (eep_val & 0x80)
+               offset = 0 - offset;
+
+       eep_val >>= 8;
+       if (eep_val == 0x00 || eep_val == 0xff) {
+               eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1);
+               eep_val &= 0xff;
+
+               if (eep_val == 0x00 || eep_val == 0xff)
+                       eep_val = 0x14;
+       }
+
+       eep_val &= 0x7f;
+       mt76_rmw_field(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL5),
+                      MT_XO_CTRL5_C2_VAL, eep_val + offset);
+       mt76_set(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL6), MT_XO_CTRL6_C2_CTRL);
+
+       mt76_wr(dev, 0x504, 0x06000000);
+       mt76_wr(dev, 0x50c, 0x08800000);
+       mdelay(5);
+       mt76_wr(dev, 0x504, 0x0);
+
+       /* decrease SIFS from 16us to 13us */
+       mt76_rmw_field(dev, MT_XIFS_TIME_CFG,
+                      MT_XIFS_TIME_CFG_OFDM_SIFS, 0xd);
+       mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, MT_BKOFF_SLOT_CFG_CC_DELAY, 1);
+
+       /* init fce */
+       mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
+
+       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
+       switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) {
+       case 0:
+               mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80);
+               break;
+       case 1:
+               mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0);
+               break;
+       default:
+               break;
+       }
+}
+
+int mt76x2u_mac_reset(struct mt76x2_dev *dev)
+{
+       mt76_wr(dev, MT_WPDMA_GLO_CFG, BIT(4) | BIT(5));
+
+       /* init pbf regs */
+       mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f);
+       mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf);
+
+       mt76_write_mac_initvals(dev);
+
+       mt76_wr(dev, MT_TX_LINK_CFG, 0x1020);
+       mt76_wr(dev, MT_AUTO_RSP_CFG, 0x13);
+       mt76_wr(dev, MT_MAX_LEN_CFG, 0x2f00);
+       mt76_wr(dev, MT_TX_RTS_CFG, 0x92b20);
+
+       mt76_wr(dev, MT_WMM_AIFSN, 0x2273);
+       mt76_wr(dev, MT_WMM_CWMIN, 0x2344);
+       mt76_wr(dev, MT_WMM_CWMAX, 0x34aa);
+
+       mt76_clear(dev, MT_MAC_SYS_CTRL,
+                  MT_MAC_SYS_CTRL_RESET_CSR |
+                  MT_MAC_SYS_CTRL_RESET_BBP);
+
+       if (is_mt7612(dev))
+               mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN);
+
+       mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
+       mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31));
+
+       mt76x2u_mac_fixup_xtal(dev);
+
+       return 0;
+}
+
+int mt76x2u_mac_start(struct mt76x2_dev *dev)
+{
+       mt76x2u_mac_reset_counters(dev);
+
+       mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX);
+       mt76x02_wait_for_wpdma(&dev->mt76, 1000);
+       usleep_range(50, 100);
+
+       mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
+
+       mt76_wr(dev, MT_MAC_SYS_CTRL,
+               MT_MAC_SYS_CTRL_ENABLE_TX |
+               MT_MAC_SYS_CTRL_ENABLE_RX);
+
+       return 0;
+}
+
+int mt76x2u_mac_stop(struct mt76x2_dev *dev)
+{
+       int i, count = 0, val;
+       bool stopped = false;
+       u32 rts_cfg;
+
+       if (test_bit(MT76_REMOVED, &dev->mt76.state))
+               return -EIO;
+
+       rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
+       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
+
+       mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
+       mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
+
+       /* wait tx dma to stop */
+       for (i = 0; i < 2000; i++) {
+               val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
+               if (!(val & MT_USB_DMA_CFG_TX_BUSY) && i > 10)
+                       break;
+               usleep_range(50, 100);
+       }
+
+       /* page count on TxQ */
+       for (i = 0; i < 200; i++) {
+               if (!(mt76_rr(dev, 0x0438) & 0xffffffff) &&
+                   !(mt76_rr(dev, 0x0a30) & 0x000000ff) &&
+                   !(mt76_rr(dev, 0x0a34) & 0xff00ff00))
+                       break;
+               usleep_range(10, 20);
+       }
+
+       /* disable tx-rx */
+       mt76_clear(dev, MT_MAC_SYS_CTRL,
+                  MT_MAC_SYS_CTRL_ENABLE_RX |
+                  MT_MAC_SYS_CTRL_ENABLE_TX);
+
+       /* Wait for MAC to become idle */
+       for (i = 0; i < 1000; i++) {
+               if (!(mt76_rr(dev, MT_MAC_STATUS) & MT_MAC_STATUS_TX) &&
+                   !mt76_rr(dev, MT_BBP(IBI, 12))) {
+                       stopped = true;
+                       break;
+               }
+               usleep_range(10, 20);
+       }
+
+       if (!stopped) {
+               mt76_set(dev, MT_BBP(CORE, 4), BIT(1));
+               mt76_clear(dev, MT_BBP(CORE, 4), BIT(1));
+
+               mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
+               mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
+       }
+
+       /* page count on RxQ */
+       for (i = 0; i < 200; i++) {
+               if (!(mt76_rr(dev, 0x0430) & 0x00ff0000) &&
+                   !(mt76_rr(dev, 0x0a30) & 0xffffffff) &&
+                   !(mt76_rr(dev, 0x0a34) & 0xffffffff) &&
+                   ++count > 10)
+                       break;
+               msleep(50);
+       }
+
+       if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_RX, 0, 2000))
+               dev_warn(dev->mt76.dev, "MAC RX failed to stop\n");
+
+       /* wait rx dma to stop */
+       for (i = 0; i < 2000; i++) {
+               val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
+               if (!(val & MT_USB_DMA_CFG_RX_BUSY) && i > 10)
+                       break;
+               usleep_range(50, 100);
+       }
+
+       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
+
+       return 0;
+}
+
+void mt76x2u_mac_resume(struct mt76x2_dev *dev)
+{
+       mt76_wr(dev, MT_MAC_SYS_CTRL,
+               MT_MAC_SYS_CTRL_ENABLE_TX |
+               MT_MAC_SYS_CTRL_ENABLE_RX);
+       mt76_set(dev, MT_TXOP_CTRL_CFG, BIT(20));
+       mt76_set(dev, MT_TXOP_HLDR_ET, BIT(1));
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
new file mode 100644 (file)
index 0000000..26f1c04
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2u.h"
+#include "../mt76x02_util.h"
+
+static int mt76x2u_start(struct ieee80211_hw *hw)
+{
+       struct mt76x2_dev *dev = hw->priv;
+       int ret;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       ret = mt76x2u_mac_start(dev);
+       if (ret)
+               goto out;
+
+       set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
+
+out:
+       mutex_unlock(&dev->mt76.mutex);
+       return ret;
+}
+
+static void mt76x2u_stop(struct ieee80211_hw *hw)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       mutex_lock(&dev->mt76.mutex);
+       clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
+       mt76x2u_stop_hw(dev);
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+static int mt76x2u_add_interface(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       if (!ether_addr_equal(dev->mt76.macaddr, vif->addr))
+               mt76x02_mac_setaddr(&dev->mt76, vif->addr);
+
+       mt76x02_vif_init(&dev->mt76, vif, 0);
+       return 0;
+}
+
+static int
+mt76x2u_set_channel(struct mt76x2_dev *dev,
+                   struct cfg80211_chan_def *chandef)
+{
+       int err;
+
+       cancel_delayed_work_sync(&dev->cal_work);
+       set_bit(MT76_RESET, &dev->mt76.state);
+
+       mt76_set_channel(&dev->mt76);
+
+       mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
+       mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
+       mt76x2_mac_stop(dev, false);
+
+       err = mt76x2u_phy_set_channel(dev, chandef);
+
+       mt76x2u_mac_resume(dev);
+
+       clear_bit(MT76_RESET, &dev->mt76.state);
+       mt76_txq_schedule_all(&dev->mt76);
+
+       return err;
+}
+
+static void
+mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                        struct ieee80211_bss_conf *info, u32 changed)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               mt76x2u_phy_channel_calibrate(dev);
+               mt76x2_apply_gain_adj(dev);
+       }
+
+       if (changed & BSS_CHANGED_BSSID) {
+               mt76_wr(dev, MT_MAC_BSSID_DW0,
+                       get_unaligned_le32(info->bssid));
+               mt76_wr(dev, MT_MAC_BSSID_DW1,
+                       get_unaligned_le16(info->bssid + 4));
+       }
+
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+static int
+mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct mt76x2_dev *dev = hw->priv;
+       int err = 0;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
+               if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
+                       dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
+               else
+                       dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
+               mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               ieee80211_stop_queues(hw);
+               err = mt76x2u_set_channel(dev, &hw->conf.chandef);
+               ieee80211_wake_queues(hw);
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               dev->mt76.txpower_conf = hw->conf.power_level * 2;
+
+               /* convert to per-chain power for 2x2 devices */
+               dev->mt76.txpower_conf -= 6;
+
+               if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
+                       mt76x2_phy_set_txpower(dev);
+       }
+
+       mutex_unlock(&dev->mt76.mutex);
+
+       return err;
+}
+
+static void
+mt76x2u_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+               const u8 *mac)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       set_bit(MT76_SCANNING, &dev->mt76.state);
+}
+
+static void
+mt76x2u_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+       struct mt76x2_dev *dev = hw->priv;
+
+       clear_bit(MT76_SCANNING, &dev->mt76.state);
+}
+
+const struct ieee80211_ops mt76x2u_ops = {
+       .tx = mt76x2_tx,
+       .start = mt76x2u_start,
+       .stop = mt76x2u_stop,
+       .add_interface = mt76x2u_add_interface,
+       .remove_interface = mt76x02_remove_interface,
+       .sta_add = mt76x02_sta_add,
+       .sta_remove = mt76x02_sta_remove,
+       .set_key = mt76x02_set_key,
+       .ampdu_action = mt76x02_ampdu_action,
+       .config = mt76x2u_config,
+       .wake_tx_queue = mt76_wake_tx_queue,
+       .bss_info_changed = mt76x2u_bss_info_changed,
+       .configure_filter = mt76x02_configure_filter,
+       .conf_tx = mt76x02_conf_tx,
+       .sw_scan_start = mt76x2u_sw_scan,
+       .sw_scan_complete = mt76x2u_sw_scan_complete,
+       .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
+};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_mcu.c
new file mode 100644 (file)
index 0000000..35e157b
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/firmware.h>
+
+#include "mt76x2u.h"
+#include "eeprom.h"
+#include "../mt76x02_usb.h"
+
+#define MT_CMD_HDR_LEN                 4
+
+#define MCU_FW_URB_MAX_PAYLOAD         0x3900
+#define MCU_ROM_PATCH_MAX_PAYLOAD      2048
+
+#define MT76U_MCU_ILM_OFFSET           0x80000
+#define MT76U_MCU_DLM_OFFSET           0x110000
+#define MT76U_MCU_ROM_PATCH_OFFSET     0x90000
+
+int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap,
+                               bool ext, int rssi, u32 false_cca)
+{
+       struct {
+               __le32 channel;
+               __le32 rssi_val;
+               __le32 false_cca_val;
+       } __packed __aligned(4) msg = {
+               .rssi_val = cpu_to_le32(rssi),
+               .false_cca_val = cpu_to_le32(false_cca),
+       };
+       struct sk_buff *skb;
+       u32 val = channel;
+
+       if (ap)
+               val |= BIT(31);
+       if (ext)
+               val |= BIT(30);
+       msg.channel = cpu_to_le32(val);
+
+       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
+       return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true);
+}
+
+static void mt76x2u_mcu_load_ivb(struct mt76x2_dev *dev)
+{
+       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
+                            USB_DIR_OUT | USB_TYPE_VENDOR,
+                            0x12, 0, NULL, 0);
+}
+
+static void mt76x2u_mcu_enable_patch(struct mt76x2_dev *dev)
+{
+       struct mt76_usb *usb = &dev->mt76.usb;
+       const u8 data[] = {
+               0x6f, 0xfc, 0x08, 0x01,
+               0x20, 0x04, 0x00, 0x00,
+               0x00, 0x09, 0x00,
+       };
+
+       memcpy(usb->data, data, sizeof(data));
+       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
+                            USB_DIR_OUT | USB_TYPE_CLASS,
+                            0x12, 0, usb->data, sizeof(data));
+}
+
+static void mt76x2u_mcu_reset_wmt(struct mt76x2_dev *dev)
+{
+       struct mt76_usb *usb = &dev->mt76.usb;
+       u8 data[] = {
+               0x6f, 0xfc, 0x05, 0x01,
+               0x07, 0x01, 0x00, 0x04
+       };
+
+       memcpy(usb->data, data, sizeof(data));
+       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
+                            USB_DIR_OUT | USB_TYPE_CLASS,
+                            0x12, 0, usb->data, sizeof(data));
+}
+
+static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev)
+{
+       bool rom_protect = !is_mt7612(dev);
+       struct mt76x02_patch_header *hdr;
+       u32 val, patch_mask, patch_reg;
+       const struct firmware *fw;
+       int err;
+
+       if (rom_protect &&
+           !mt76_poll_msec(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
+               dev_err(dev->mt76.dev,
+                       "could not get hardware semaphore for ROM PATCH\n");
+               return -ETIMEDOUT;
+       }
+
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
+               patch_mask = BIT(0);
+               patch_reg = MT_MCU_CLOCK_CTL;
+       } else {
+               patch_mask = BIT(1);
+               patch_reg = MT_MCU_COM_REG0;
+       }
+
+       if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
+               dev_info(dev->mt76.dev, "ROM patch already applied\n");
+               return 0;
+       }
+
+       err = request_firmware(&fw, MT7662U_ROM_PATCH, dev->mt76.dev);
+       if (err < 0)
+               return err;
+
+       if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
+               dev_err(dev->mt76.dev, "failed to load firmware\n");
+               err = -EIO;
+               goto out;
+       }
+
+       hdr = (struct mt76x02_patch_header *)fw->data;
+       dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
+
+       /* enable USB_DMA_CFG */
+       val = MT_USB_DMA_CFG_RX_BULK_EN |
+             MT_USB_DMA_CFG_TX_BULK_EN |
+             FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
+       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
+
+       /* vendor reset */
+       mt76x02u_mcu_fw_reset(&dev->mt76);
+       usleep_range(5000, 10000);
+
+       /* enable FCE to send in-band cmd */
+       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
+       /* FCE tx_fs_base_ptr */
+       mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
+       /* FCE tx_fs_max_cnt */
+       mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
+       /* FCE pdma enable */
+       mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
+       /* FCE skip_fs_en */
+       mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
+
+       err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
+                                       fw->size - sizeof(*hdr),
+                                       MCU_ROM_PATCH_MAX_PAYLOAD,
+                                       MT76U_MCU_ROM_PATCH_OFFSET);
+       if (err < 0) {
+               err = -EIO;
+               goto out;
+       }
+
+       mt76x2u_mcu_enable_patch(dev);
+       mt76x2u_mcu_reset_wmt(dev);
+       mdelay(20);
+
+       if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 100)) {
+               dev_err(dev->mt76.dev, "failed to load ROM patch\n");
+               err = -ETIMEDOUT;
+       }
+
+out:
+       if (rom_protect)
+               mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
+       release_firmware(fw);
+       return err;
+}
+
+static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev)
+{
+       u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET;
+       const struct mt76x02_fw_header *hdr;
+       int err, len, ilm_len, dlm_len;
+       const struct firmware *fw;
+
+       err = request_firmware(&fw, MT7662U_FIRMWARE, dev->mt76.dev);
+       if (err < 0)
+               return err;
+
+       if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       hdr = (const struct mt76x02_fw_header *)fw->data;
+       ilm_len = le32_to_cpu(hdr->ilm_len);
+       dlm_len = le32_to_cpu(hdr->dlm_len);
+       len = sizeof(*hdr) + ilm_len + dlm_len;
+       if (fw->size != len) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       val = le16_to_cpu(hdr->fw_ver);
+       dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
+                (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
+
+       val = le16_to_cpu(hdr->build_ver);
+       dev_info(dev->mt76.dev, "Build: %x\n", val);
+       dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
+
+       /* vendor reset */
+       mt76x02u_mcu_fw_reset(&dev->mt76);
+       usleep_range(5000, 10000);
+
+       /* enable USB_DMA_CFG */
+       val = MT_USB_DMA_CFG_RX_BULK_EN |
+             MT_USB_DMA_CFG_TX_BULK_EN |
+             FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
+       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
+       /* enable FCE to send in-band cmd */
+       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
+       /* FCE tx_fs_base_ptr */
+       mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
+       /* FCE tx_fs_max_cnt */
+       mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
+       /* FCE pdma enable */
+       mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
+       /* FCE skip_fs_en */
+       mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
+
+       /* load ILM */
+       err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
+                                       ilm_len, MCU_FW_URB_MAX_PAYLOAD,
+                                       MT76U_MCU_ILM_OFFSET);
+       if (err < 0) {
+               err = -EIO;
+               goto out;
+       }
+
+       /* load DLM */
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
+               dlm_offset += 0x800;
+       err = mt76x02u_mcu_fw_send_data(&dev->mt76,
+                                       fw->data + sizeof(*hdr) + ilm_len,
+                                       dlm_len, MCU_FW_URB_MAX_PAYLOAD,
+                                       dlm_offset);
+       if (err < 0) {
+               err = -EIO;
+               goto out;
+       }
+
+       mt76x2u_mcu_load_ivb(dev);
+       if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 100)) {
+               dev_err(dev->mt76.dev, "firmware failed to start\n");
+               err = -ETIMEDOUT;
+               goto out;
+       }
+
+       mt76_set(dev, MT_MCU_COM_REG0, BIT(1));
+       /* enable FCE to send in-band cmd */
+       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
+       dev_dbg(dev->mt76.dev, "firmware running\n");
+       mt76x02_set_ethtool_fwver(&dev->mt76, hdr);
+
+out:
+       release_firmware(fw);
+       return err;
+}
+
+int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev)
+{
+       int err;
+
+       err = mt76x2u_mcu_load_rom_patch(dev);
+       if (err < 0)
+               return err;
+
+       return mt76x2u_mcu_load_firmware(dev);
+}
+
+int mt76x2u_mcu_init(struct mt76x2_dev *dev)
+{
+       int err;
+
+       err = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT,
+                                          1, false);
+       if (err < 0)
+               return err;
+
+       return mt76x02_mcu_set_radio_state(&dev->mt76, true, false);
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c
new file mode 100644 (file)
index 0000000..9dd1943
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "mt76x2u.h"
+#include "eeprom.h"
+
+void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev)
+{
+       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
+       bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
+
+       if (mt76x2_channel_silent(dev))
+               return;
+
+       mt76x2u_mac_stop(dev);
+
+       if (is_5ghz)
+               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, false);
+
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, false);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, false);
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, false);
+
+       mt76x2u_mac_resume(dev);
+}
+
+static void
+mt76x2u_phy_update_channel_gain(struct mt76x2_dev *dev)
+{
+       u8 channel = dev->mt76.chandef.chan->hw_value;
+       int freq, freq1;
+       u32 false_cca;
+
+       freq = dev->mt76.chandef.chan->center_freq;
+       freq1 = dev->mt76.chandef.center_freq1;
+
+       switch (dev->mt76.chandef.width) {
+       case NL80211_CHAN_WIDTH_80: {
+               int ch_group_index;
+
+               ch_group_index = (freq - freq1 + 30) / 20;
+               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
+                       ch_group_index = 0;
+               channel += 6 - ch_group_index * 4;
+               break;
+       }
+       case NL80211_CHAN_WIDTH_40:
+               if (freq1 > freq)
+                       channel += 2;
+               else
+                       channel -= 2;
+               break;
+       default:
+               break;
+       }
+
+       dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
+       false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
+                             mt76_rr(dev, MT_RX_STAT_1));
+
+       mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
+                                   dev->cal.avg_rssi_all, false_cca);
+}
+
+void mt76x2u_phy_calibrate(struct work_struct *work)
+{
+       struct mt76x2_dev *dev;
+
+       dev = container_of(work, struct mt76x2_dev, cal_work.work);
+       mt76x2_phy_tssi_compensate(dev, false);
+       mt76x2u_phy_update_channel_gain(dev);
+
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
+                                    MT_CALIBRATE_INTERVAL);
+}
+
+int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
+                           struct cfg80211_chan_def *chandef)
+{
+       u32 ext_cca_chan[4] = {
+               [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
+               [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
+               [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
+               [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
+                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
+       };
+       bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
+       struct ieee80211_channel *chan = chandef->chan;
+       u8 channel = chan->hw_value, bw, bw_index;
+       int ch_group_index, freq, freq1, ret;
+
+       dev->cal.channel_cal_done = false;
+       freq = chandef->chan->center_freq;
+       freq1 = chandef->center_freq1;
+
+       switch (chandef->width) {
+       case NL80211_CHAN_WIDTH_40:
+               bw = 1;
+               if (freq1 > freq) {
+                       bw_index = 1;
+                       ch_group_index = 0;
+               } else {
+                       bw_index = 3;
+                       ch_group_index = 1;
+               }
+               channel += 2 - ch_group_index * 4;
+               break;
+       case NL80211_CHAN_WIDTH_80:
+               ch_group_index = (freq - freq1 + 30) / 20;
+               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
+                       ch_group_index = 0;
+               bw = 2;
+               bw_index = ch_group_index;
+               channel += 6 - ch_group_index * 4;
+               break;
+       default:
+               bw = 0;
+               bw_index = 0;
+               ch_group_index = 0;
+               break;
+       }
+
+       mt76x2_read_rx_gain(dev);
+       mt76x2_phy_set_txpower_regs(dev, chan->band);
+       mt76x2_configure_tx_delay(dev, chan->band, bw);
+       mt76x2_phy_set_txpower(dev);
+
+       mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
+       mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
+
+       mt76_rmw(dev, MT_EXT_CCA_CFG,
+                (MT_EXT_CCA_CFG_CCA0 |
+                 MT_EXT_CCA_CFG_CCA1 |
+                 MT_EXT_CCA_CFG_CCA2 |
+                 MT_EXT_CCA_CFG_CCA3 |
+                 MT_EXT_CCA_CFG_CCA_MASK),
+                ext_cca_chan[ch_group_index]);
+
+       ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
+       if (ret)
+               return ret;
+
+       mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
+
+       /* Enable LDPC Rx */
+       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
+               mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
+
+       if (!dev->cal.init_cal_done) {
+               u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
+
+               if (val != 0xff)
+                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R,
+                                             0, false);
+       }
+
+       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, false);
+
+       /* Rx LPF calibration */
+       if (!dev->cal.init_cal_done)
+               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, false);
+       dev->cal.init_cal_done = true;
+
+       mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2);
+       mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
+       mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
+       mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
+       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0X04101b3f);
+
+       mt76_set(dev, MT_BBP(TXO, 4), BIT(25));
+       mt76_set(dev, MT_BBP(RXO, 13), BIT(8));
+
+       if (scan)
+               return 0;
+
+       if (mt76x02_tssi_enabled(&dev->mt76)) {
+               /* init default values for temp compensation */
+               mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
+                              0x38);
+               mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
+                              0x38);
+
+               /* init tssi calibration */
+               if (!mt76x2_channel_silent(dev)) {
+                       struct ieee80211_channel *chan;
+                       u32 flag = 0;
+
+                       chan = dev->mt76.chandef.chan;
+                       if (chan->band == NL80211_BAND_5GHZ)
+                               flag |= BIT(0);
+                       if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
+                               flag |= BIT(8);
+                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI,
+                                             flag, false);
+                       dev->cal.tssi_cal_done = true;
+               }
+       }
+
+       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
+                                    MT_CALIBRATE_INTERVAL);
+       return 0;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_common.c
deleted file mode 100644 (file)
index 3e667d8..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_mac.h"
-
-void mt76x2_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
-                        struct sk_buff *skb)
-{
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-       void *rxwi = skb->data;
-
-       if (q == MT_RXQ_MCU) {
-               /* this is used just by mmio code */
-               skb_queue_tail(&mdev->mmio.mcu.res_q, skb);
-               wake_up(&mdev->mmio.mcu.wait);
-               return;
-       }
-
-       skb_pull(skb, sizeof(struct mt76x02_rxwi));
-       if (mt76x2_mac_process_rx(dev, skb, rxwi)) {
-               dev_kfree_skb(skb);
-               return;
-       }
-
-       mt76_rx(&dev->mt76, q, skb);
-}
-EXPORT_SYMBOL_GPL(mt76x2_queue_rx_skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2_core.c
deleted file mode 100644 (file)
index 06e47f9..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/delay.h>
-#include "mt76x2.h"
-#include "mt76x2_trace.h"
-#include "mt76x02_util.h"
-
-void mt76x2_rx_poll_complete(struct mt76_dev *mdev, enum mt76_rxq_id q)
-{
-       mt76x02_irq_enable(mdev, MT_INT_RX_DONE(q));
-}
-
-irqreturn_t mt76x2_irq_handler(int irq, void *dev_instance)
-{
-       struct mt76x2_dev *dev = dev_instance;
-       u32 intr;
-
-       intr = mt76_rr(dev, MT_INT_SOURCE_CSR);
-       mt76_wr(dev, MT_INT_SOURCE_CSR, intr);
-
-       if (!test_bit(MT76_STATE_INITIALIZED, &dev->mt76.state))
-               return IRQ_NONE;
-
-       trace_dev_irq(dev, intr, dev->mt76.mmio.irqmask);
-
-       intr &= dev->mt76.mmio.irqmask;
-
-       if (intr & MT_INT_TX_DONE_ALL) {
-               mt76x02_irq_disable(&dev->mt76, MT_INT_TX_DONE_ALL);
-               tasklet_schedule(&dev->tx_tasklet);
-       }
-
-       if (intr & MT_INT_RX_DONE(0)) {
-               mt76x02_irq_disable(&dev->mt76, MT_INT_RX_DONE(0));
-               napi_schedule(&dev->mt76.napi[0]);
-       }
-
-       if (intr & MT_INT_RX_DONE(1)) {
-               mt76x02_irq_disable(&dev->mt76, MT_INT_RX_DONE(1));
-               napi_schedule(&dev->mt76.napi[1]);
-       }
-
-       if (intr & MT_INT_PRE_TBTT)
-               tasklet_schedule(&dev->pre_tbtt_tasklet);
-
-       /* send buffered multicast frames now */
-       if (intr & MT_INT_TBTT)
-               mt76_queue_kick(dev, &dev->mt76.q_tx[MT_TXQ_PSD]);
-
-       if (intr & MT_INT_TX_STAT) {
-               mt76x2_mac_poll_tx_status(dev, true);
-               tasklet_schedule(&dev->tx_tasklet);
-       }
-
-       if (intr & MT_INT_GPTIMER) {
-               mt76x02_irq_disable(&dev->mt76, MT_INT_GPTIMER);
-               tasklet_schedule(&dev->dfs_pd.dfs_tasklet);
-       }
-
-       return IRQ_HANDLED;
-}
-
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_debugfs.c
deleted file mode 100644 (file)
index ea373ba..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/debugfs.h>
-#include "mt76x2.h"
-
-static int
-mt76x2_ampdu_stat_read(struct seq_file *file, void *data)
-{
-       struct mt76x2_dev *dev = file->private;
-       int i, j;
-
-       for (i = 0; i < 4; i++) {
-               seq_puts(file, "Length: ");
-               for (j = 0; j < 8; j++)
-                       seq_printf(file, "%8d | ", i * 8 + j + 1);
-               seq_puts(file, "\n");
-               seq_puts(file, "Count:  ");
-               for (j = 0; j < 8; j++)
-                       seq_printf(file, "%8d | ", dev->aggr_stats[i * 8 + j]);
-               seq_puts(file, "\n");
-               seq_puts(file, "--------");
-               for (j = 0; j < 8; j++)
-                       seq_puts(file, "-----------");
-               seq_puts(file, "\n");
-       }
-
-       return 0;
-}
-
-static int
-mt76x2_ampdu_stat_open(struct inode *inode, struct file *f)
-{
-       return single_open(f, mt76x2_ampdu_stat_read, inode->i_private);
-}
-
-static int read_txpower(struct seq_file *file, void *data)
-{
-       struct mt76x2_dev *dev = dev_get_drvdata(file->private);
-
-       seq_printf(file, "Target power: %d\n", dev->target_power);
-
-       mt76_seq_puts_array(file, "Delta", dev->target_power_delta,
-                           ARRAY_SIZE(dev->target_power_delta));
-       return 0;
-}
-
-static const struct file_operations fops_ampdu_stat = {
-       .open = mt76x2_ampdu_stat_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static int
-mt76x2_dfs_stat_read(struct seq_file *file, void *data)
-{
-       int i;
-       struct mt76x2_dev *dev = file->private;
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       seq_printf(file, "allocated sequences:\t%d\n",
-                  dfs_pd->seq_stats.seq_pool_len);
-       seq_printf(file, "used sequences:\t\t%d\n",
-                  dfs_pd->seq_stats.seq_len);
-       seq_puts(file, "\n");
-
-       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
-               seq_printf(file, "engine: %d\n", i);
-               seq_printf(file, "  hw pattern detected:\t%d\n",
-                          dfs_pd->stats[i].hw_pattern);
-               seq_printf(file, "  hw pulse discarded:\t%d\n",
-                          dfs_pd->stats[i].hw_pulse_discarded);
-               seq_printf(file, "  sw pattern detected:\t%d\n",
-                          dfs_pd->stats[i].sw_pattern);
-       }
-
-       return 0;
-}
-
-static int
-mt76x2_dfs_stat_open(struct inode *inode, struct file *f)
-{
-       return single_open(f, mt76x2_dfs_stat_read, inode->i_private);
-}
-
-static const struct file_operations fops_dfs_stat = {
-       .open = mt76x2_dfs_stat_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-};
-
-static int read_agc(struct seq_file *file, void *data)
-{
-       struct mt76x2_dev *dev = dev_get_drvdata(file->private);
-
-       seq_printf(file, "avg_rssi: %d\n", dev->cal.avg_rssi_all);
-       seq_printf(file, "low_gain: %d\n", dev->cal.low_gain);
-       seq_printf(file, "false_cca: %d\n", dev->cal.false_cca);
-       seq_printf(file, "agc_gain_adjust: %d\n", dev->cal.agc_gain_adjust);
-
-       return 0;
-}
-
-void mt76x2_init_debugfs(struct mt76x2_dev *dev)
-{
-       struct dentry *dir;
-
-       dir = mt76_register_debugfs(&dev->mt76);
-       if (!dir)
-               return;
-
-       debugfs_create_u8("temperature", 0400, dir, &dev->cal.temp);
-       debugfs_create_bool("tpc", 0600, dir, &dev->enable_tpc);
-
-       debugfs_create_file("ampdu_stat", 0400, dir, dev, &fops_ampdu_stat);
-       debugfs_create_file("dfs_stats", 0400, dir, dev, &fops_dfs_stat);
-       debugfs_create_devm_seqfile(dev->mt76.dev, "txpower", dir,
-                                   read_txpower);
-
-       debugfs_create_devm_seqfile(dev->mt76.dev, "agc", dir, read_agc);
-}
-EXPORT_SYMBOL_GPL(mt76x2_init_debugfs);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.c
deleted file mode 100644 (file)
index 8cfa3a0..0000000
+++ /dev/null
@@ -1,878 +0,0 @@
-/*
- * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_util.h"
-
-#define RADAR_SPEC(m, len, el, eh, wl, wh,             \
-                  w_tolerance, tl, th, t_tolerance,    \
-                  bl, bh, event_exp, power_jmp)        \
-{                                                      \
-       .mode = m,                                      \
-       .avg_len = len,                                 \
-       .e_low = el,                                    \
-       .e_high = eh,                                   \
-       .w_low = wl,                                    \
-       .w_high = wh,                                   \
-       .w_margin = w_tolerance,                        \
-       .t_low = tl,                                    \
-       .t_high = th,                                   \
-       .t_margin = t_tolerance,                        \
-       .b_low = bl,                                    \
-       .b_high = bh,                                   \
-       .event_expiration = event_exp,                  \
-       .pwr_jmp = power_jmp                            \
-}
-
-static const struct mt76x2_radar_specs etsi_radar_specs[] = {
-       /* 20MHz */
-       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
-                  0x7fffffff, 0x155cc0, 0x19dd),
-       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
-                  0x7fffffff, 0x2191c0, 0x15cc),
-       /* 40MHz */
-       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
-                  0x7fffffff, 0x155cc0, 0x19dd),
-       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
-                  0x7fffffff, 0x2191c0, 0x15cc),
-       /* 80MHz */
-       RADAR_SPEC(0, 8, 2, 15, 106, 150, 10, 4900, 100096, 10, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(0, 40, 4, 59, 96, 380, 150, 4900, 100096, 40, 0,
-                  0x7fffffff, 0x155cc0, 0x19cc),
-       RADAR_SPEC(3, 60, 20, 46, 300, 640, 80, 4900, 10100, 80, 0,
-                  0x7fffffff, 0x155cc0, 0x19dd),
-       RADAR_SPEC(8, 8, 2, 9, 106, 150, 32, 4900, 296704, 32, 0,
-                  0x7fffffff, 0x2191c0, 0x15cc)
-};
-
-static const struct mt76x2_radar_specs fcc_radar_specs[] = {
-       /* 20MHz */
-       RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0,
-                  0x7fffffff, 0xfe808, 0x13dc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0xfe808, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0xfe808, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0x57bcf00, 0x1289),
-       /* 40MHz */
-       RADAR_SPEC(0, 8, 2, 12, 106, 150, 5, 2900, 80100, 5, 0,
-                  0x7fffffff, 0xfe808, 0x13dc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0xfe808, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0xfe808, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0x57bcf00, 0x1289),
-       /* 80MHz */
-       RADAR_SPEC(0, 8, 2, 14, 106, 150, 15, 2900, 80100, 15, 0,
-                  0x7fffffff, 0xfe808, 0x16cc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0xfe808, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 54, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0xfe808, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 63, 640, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0x57bcf00, 0x1289)
-};
-
-static const struct mt76x2_radar_specs jp_w56_radar_specs[] = {
-       /* 20MHz */
-       RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0,
-                  0x7fffffff, 0x14c080, 0x13dc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0x14c080, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0x14c080, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0X57bcf00, 0x1289),
-       /* 40MHz */
-       RADAR_SPEC(0, 8, 2, 7, 106, 150, 5, 2900, 80100, 5, 0,
-                  0x7fffffff, 0x14c080, 0x13dc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0x14c080, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0x14c080, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0X57bcf00, 0x1289),
-       /* 80MHz */
-       RADAR_SPEC(0, 8, 2, 9, 106, 150, 15, 2900, 80100, 15, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       RADAR_SPEC(0, 8, 2, 7, 106, 140, 5, 27600, 27900, 5, 0,
-                  0x7fffffff, 0x14c080, 0x19dd),
-       RADAR_SPEC(0, 40, 4, 44, 96, 480, 150, 2900, 80100, 40, 0,
-                  0x7fffffff, 0x14c080, 0x12cc),
-       RADAR_SPEC(2, 60, 15, 48, 940, 2080, 32, 19600, 40200, 32, 0,
-                  0x3938700, 0X57bcf00, 0x1289)
-};
-
-static const struct mt76x2_radar_specs jp_w53_radar_specs[] = {
-       /* 20MHz */
-       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 },
-       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 },
-       /* 40MHz */
-       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 },
-       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 },
-       /* 80MHz */
-       RADAR_SPEC(0, 8, 2, 9, 106, 150, 20, 28400, 77000, 20, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 },
-       RADAR_SPEC(0, 40, 4, 44, 96, 200, 150, 28400, 77000, 60, 0,
-                  0x7fffffff, 0x14c080, 0x16cc),
-       { 0 }
-};
-
-static void mt76x2_dfs_set_capture_mode_ctrl(struct mt76x2_dev *dev,
-                                            u8 enable)
-{
-       u32 data;
-
-       data = (1 << 1) | enable;
-       mt76_wr(dev, MT_BBP(DFS, 36), data);
-}
-
-static void mt76x2_dfs_seq_pool_put(struct mt76x2_dev *dev,
-                                   struct mt76x2_dfs_sequence *seq)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       list_add(&seq->head, &dfs_pd->seq_pool);
-
-       dfs_pd->seq_stats.seq_pool_len++;
-       dfs_pd->seq_stats.seq_len--;
-}
-
-static
-struct mt76x2_dfs_sequence *mt76x2_dfs_seq_pool_get(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_sequence *seq;
-
-       if (list_empty(&dfs_pd->seq_pool)) {
-               seq = devm_kzalloc(dev->mt76.dev, sizeof(*seq), GFP_ATOMIC);
-       } else {
-               seq = list_first_entry(&dfs_pd->seq_pool,
-                                      struct mt76x2_dfs_sequence,
-                                      head);
-               list_del(&seq->head);
-               dfs_pd->seq_stats.seq_pool_len--;
-       }
-       if (seq)
-               dfs_pd->seq_stats.seq_len++;
-
-       return seq;
-}
-
-static int mt76x2_dfs_get_multiple(int val, int frac, int margin)
-{
-       int remainder, factor;
-
-       if (!frac)
-               return 0;
-
-       if (abs(val - frac) <= margin)
-               return 1;
-
-       factor = val / frac;
-       remainder = val % frac;
-
-       if (remainder > margin) {
-               if ((frac - remainder) <= margin)
-                       factor++;
-               else
-                       factor = 0;
-       }
-       return factor;
-}
-
-static void mt76x2_dfs_detector_reset(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_sequence *seq, *tmp_seq;
-       int i;
-
-       /* reset hw detector */
-       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
-
-       /* reset sw detector */
-       for (i = 0; i < ARRAY_SIZE(dfs_pd->event_rb); i++) {
-               dfs_pd->event_rb[i].h_rb = 0;
-               dfs_pd->event_rb[i].t_rb = 0;
-       }
-
-       list_for_each_entry_safe(seq, tmp_seq, &dfs_pd->sequences, head) {
-               list_del_init(&seq->head);
-               mt76x2_dfs_seq_pool_put(dev, seq);
-       }
-}
-
-static bool mt76x2_dfs_check_chirp(struct mt76x2_dev *dev)
-{
-       bool ret = false;
-       u32 current_ts, delta_ts;
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       current_ts = mt76_rr(dev, MT_PBF_LIFE_TIMER);
-       delta_ts = current_ts - dfs_pd->chirp_pulse_ts;
-       dfs_pd->chirp_pulse_ts = current_ts;
-
-       /* 12 sec */
-       if (delta_ts <= (12 * (1 << 20))) {
-               if (++dfs_pd->chirp_pulse_cnt > 8)
-                       ret = true;
-       } else {
-               dfs_pd->chirp_pulse_cnt = 1;
-       }
-
-       return ret;
-}
-
-static void mt76x2_dfs_get_hw_pulse(struct mt76x2_dev *dev,
-                                   struct mt76x2_dfs_hw_pulse *pulse)
-{
-       u32 data;
-
-       /* select channel */
-       data = (MT_DFS_CH_EN << 16) | pulse->engine;
-       mt76_wr(dev, MT_BBP(DFS, 0), data);
-
-       /* reported period */
-       pulse->period = mt76_rr(dev, MT_BBP(DFS, 19));
-
-       /* reported width */
-       pulse->w1 = mt76_rr(dev, MT_BBP(DFS, 20));
-       pulse->w2 = mt76_rr(dev, MT_BBP(DFS, 23));
-
-       /* reported burst number */
-       pulse->burst = mt76_rr(dev, MT_BBP(DFS, 22));
-}
-
-static bool mt76x2_dfs_check_hw_pulse(struct mt76x2_dev *dev,
-                                     struct mt76x2_dfs_hw_pulse *pulse)
-{
-       bool ret = false;
-
-       if (!pulse->period || !pulse->w1)
-               return false;
-
-       switch (dev->dfs_pd.region) {
-       case NL80211_DFS_FCC:
-               if (pulse->engine > 3)
-                       break;
-
-               if (pulse->engine == 3) {
-                       ret = mt76x2_dfs_check_chirp(dev);
-                       break;
-               }
-
-               /* check short pulse*/
-               if (pulse->w1 < 120)
-                       ret = (pulse->period >= 2900 &&
-                              (pulse->period <= 4700 ||
-                               pulse->period >= 6400) &&
-                              (pulse->period <= 6800 ||
-                               pulse->period >= 10200) &&
-                              pulse->period <= 61600);
-               else if (pulse->w1 < 130) /* 120 - 130 */
-                       ret = (pulse->period >= 2900 &&
-                              pulse->period <= 61600);
-               else
-                       ret = (pulse->period >= 3500 &&
-                              pulse->period <= 10100);
-               break;
-       case NL80211_DFS_ETSI:
-               if (pulse->engine >= 3)
-                       break;
-
-               ret = (pulse->period >= 4900 &&
-                      (pulse->period <= 10200 ||
-                       pulse->period >= 12400) &&
-                      pulse->period <= 100100);
-               break;
-       case NL80211_DFS_JP:
-               if (dev->mt76.chandef.chan->center_freq >= 5250 &&
-                   dev->mt76.chandef.chan->center_freq <= 5350) {
-                       /* JPW53 */
-                       if (pulse->w1 <= 130)
-                               ret = (pulse->period >= 28360 &&
-                                      (pulse->period <= 28700 ||
-                                       pulse->period >= 76900) &&
-                                      pulse->period <= 76940);
-                       break;
-               }
-
-               if (pulse->engine > 3)
-                       break;
-
-               if (pulse->engine == 3) {
-                       ret = mt76x2_dfs_check_chirp(dev);
-                       break;
-               }
-
-               /* check short pulse*/
-               if (pulse->w1 < 120)
-                       ret = (pulse->period >= 2900 &&
-                              (pulse->period <= 4700 ||
-                               pulse->period >= 6400) &&
-                              (pulse->period <= 6800 ||
-                               pulse->period >= 27560) &&
-                              (pulse->period <= 27960 ||
-                               pulse->period >= 28360) &&
-                              (pulse->period <= 28700 ||
-                               pulse->period >= 79900) &&
-                              pulse->period <= 80100);
-               else if (pulse->w1 < 130) /* 120 - 130 */
-                       ret = (pulse->period >= 2900 &&
-                              (pulse->period <= 10100 ||
-                               pulse->period >= 27560) &&
-                              (pulse->period <= 27960 ||
-                               pulse->period >= 28360) &&
-                              (pulse->period <= 28700 ||
-                               pulse->period >= 79900) &&
-                              pulse->period <= 80100);
-               else
-                       ret = (pulse->period >= 3900 &&
-                              pulse->period <= 10100);
-               break;
-       case NL80211_DFS_UNSET:
-       default:
-               return false;
-       }
-
-       return ret;
-}
-
-static bool mt76x2_dfs_fetch_event(struct mt76x2_dev *dev,
-                                  struct mt76x2_dfs_event *event)
-{
-       u32 data;
-
-       /* 1st: DFS_R37[31]: 0 (engine 0) - 1 (engine 2)
-        * 2nd: DFS_R37[21:0]: pulse time
-        * 3rd: DFS_R37[11:0]: pulse width
-        * 3rd: DFS_R37[25:16]: phase
-        * 4th: DFS_R37[12:0]: current pwr
-        * 4th: DFS_R37[21:16]: pwr stable counter
-        *
-        * 1st: DFS_R37[31:0] set to 0xffffffff means no event detected
-        */
-       data = mt76_rr(dev, MT_BBP(DFS, 37));
-       if (!MT_DFS_CHECK_EVENT(data))
-               return false;
-
-       event->engine = MT_DFS_EVENT_ENGINE(data);
-       data = mt76_rr(dev, MT_BBP(DFS, 37));
-       event->ts = MT_DFS_EVENT_TIMESTAMP(data);
-       data = mt76_rr(dev, MT_BBP(DFS, 37));
-       event->width = MT_DFS_EVENT_WIDTH(data);
-
-       return true;
-}
-
-static bool mt76x2_dfs_check_event(struct mt76x2_dev *dev,
-                                  struct mt76x2_dfs_event *event)
-{
-       if (event->engine == 2) {
-               struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-               struct mt76x2_dfs_event_rb *event_buff = &dfs_pd->event_rb[1];
-               u16 last_event_idx;
-               u32 delta_ts;
-
-               last_event_idx = mt76_decr(event_buff->t_rb,
-                                          MT_DFS_EVENT_BUFLEN);
-               delta_ts = event->ts - event_buff->data[last_event_idx].ts;
-               if (delta_ts < MT_DFS_EVENT_TIME_MARGIN &&
-                   event_buff->data[last_event_idx].width >= 200)
-                       return false;
-       }
-       return true;
-}
-
-static void mt76x2_dfs_queue_event(struct mt76x2_dev *dev,
-                                  struct mt76x2_dfs_event *event)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_event_rb *event_buff;
-
-       /* add radar event to ring buffer */
-       event_buff = event->engine == 2 ? &dfs_pd->event_rb[1]
-                                       : &dfs_pd->event_rb[0];
-       event_buff->data[event_buff->t_rb] = *event;
-       event_buff->data[event_buff->t_rb].fetch_ts = jiffies;
-
-       event_buff->t_rb = mt76_incr(event_buff->t_rb, MT_DFS_EVENT_BUFLEN);
-       if (event_buff->t_rb == event_buff->h_rb)
-               event_buff->h_rb = mt76_incr(event_buff->h_rb,
-                                            MT_DFS_EVENT_BUFLEN);
-}
-
-static int mt76x2_dfs_create_sequence(struct mt76x2_dev *dev,
-                                     struct mt76x2_dfs_event *event,
-                                     u16 cur_len)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_sw_detector_params *sw_params;
-       u32 width_delta, with_sum, factor, cur_pri;
-       struct mt76x2_dfs_sequence seq, *seq_p;
-       struct mt76x2_dfs_event_rb *event_rb;
-       struct mt76x2_dfs_event *cur_event;
-       int i, j, end, pri;
-
-       event_rb = event->engine == 2 ? &dfs_pd->event_rb[1]
-                                     : &dfs_pd->event_rb[0];
-
-       i = mt76_decr(event_rb->t_rb, MT_DFS_EVENT_BUFLEN);
-       end = mt76_decr(event_rb->h_rb, MT_DFS_EVENT_BUFLEN);
-
-       while (i != end) {
-               cur_event = &event_rb->data[i];
-               with_sum = event->width + cur_event->width;
-
-               sw_params = &dfs_pd->sw_dpd_params;
-               switch (dev->dfs_pd.region) {
-               case NL80211_DFS_FCC:
-               case NL80211_DFS_JP:
-                       if (with_sum < 600)
-                               width_delta = 8;
-                       else
-                               width_delta = with_sum >> 3;
-                       break;
-               case NL80211_DFS_ETSI:
-                       if (event->engine == 2)
-                               width_delta = with_sum >> 6;
-                       else if (with_sum < 620)
-                               width_delta = 24;
-                       else
-                               width_delta = 8;
-                       break;
-               case NL80211_DFS_UNSET:
-               default:
-                       return -EINVAL;
-               }
-
-               pri = event->ts - cur_event->ts;
-               if (abs(event->width - cur_event->width) > width_delta ||
-                   pri < sw_params->min_pri)
-                       goto next;
-
-               if (pri > sw_params->max_pri)
-                       break;
-
-               seq.pri = event->ts - cur_event->ts;
-               seq.first_ts = cur_event->ts;
-               seq.last_ts = event->ts;
-               seq.engine = event->engine;
-               seq.count = 2;
-
-               j = mt76_decr(i, MT_DFS_EVENT_BUFLEN);
-               while (j != end) {
-                       cur_event = &event_rb->data[j];
-                       cur_pri = event->ts - cur_event->ts;
-                       factor = mt76x2_dfs_get_multiple(cur_pri, seq.pri,
-                                               sw_params->pri_margin);
-                       if (factor > 0) {
-                               seq.first_ts = cur_event->ts;
-                               seq.count++;
-                       }
-
-                       j = mt76_decr(j, MT_DFS_EVENT_BUFLEN);
-               }
-               if (seq.count <= cur_len)
-                       goto next;
-
-               seq_p = mt76x2_dfs_seq_pool_get(dev);
-               if (!seq_p)
-                       return -ENOMEM;
-
-               *seq_p = seq;
-               INIT_LIST_HEAD(&seq_p->head);
-               list_add(&seq_p->head, &dfs_pd->sequences);
-next:
-               i = mt76_decr(i, MT_DFS_EVENT_BUFLEN);
-       }
-       return 0;
-}
-
-static u16 mt76x2_dfs_add_event_to_sequence(struct mt76x2_dev *dev,
-                                           struct mt76x2_dfs_event *event)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_sw_detector_params *sw_params;
-       struct mt76x2_dfs_sequence *seq, *tmp_seq;
-       u16 max_seq_len = 0;
-       u32 factor, pri;
-
-       sw_params = &dfs_pd->sw_dpd_params;
-       list_for_each_entry_safe(seq, tmp_seq, &dfs_pd->sequences, head) {
-               if (event->ts > seq->first_ts + MT_DFS_SEQUENCE_WINDOW) {
-                       list_del_init(&seq->head);
-                       mt76x2_dfs_seq_pool_put(dev, seq);
-                       continue;
-               }
-
-               if (event->engine != seq->engine)
-                       continue;
-
-               pri = event->ts - seq->last_ts;
-               factor = mt76x2_dfs_get_multiple(pri, seq->pri,
-                                                sw_params->pri_margin);
-               if (factor > 0) {
-                       seq->last_ts = event->ts;
-                       seq->count++;
-                       max_seq_len = max_t(u16, max_seq_len, seq->count);
-               }
-       }
-       return max_seq_len;
-}
-
-static bool mt76x2_dfs_check_detection(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_sequence *seq;
-
-       if (list_empty(&dfs_pd->sequences))
-               return false;
-
-       list_for_each_entry(seq, &dfs_pd->sequences, head) {
-               if (seq->count > MT_DFS_SEQUENCE_TH) {
-                       dfs_pd->stats[seq->engine].sw_pattern++;
-                       return true;
-               }
-       }
-       return false;
-}
-
-static void mt76x2_dfs_add_events(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_event event;
-       int i, seq_len;
-
-       /* disable debug mode */
-       mt76x2_dfs_set_capture_mode_ctrl(dev, false);
-       for (i = 0; i < MT_DFS_EVENT_LOOP; i++) {
-               if (!mt76x2_dfs_fetch_event(dev, &event))
-                       break;
-
-               if (dfs_pd->last_event_ts > event.ts)
-                       mt76x2_dfs_detector_reset(dev);
-               dfs_pd->last_event_ts = event.ts;
-
-               if (!mt76x2_dfs_check_event(dev, &event))
-                       continue;
-
-               seq_len = mt76x2_dfs_add_event_to_sequence(dev, &event);
-               mt76x2_dfs_create_sequence(dev, &event, seq_len);
-
-               mt76x2_dfs_queue_event(dev, &event);
-       }
-       mt76x2_dfs_set_capture_mode_ctrl(dev, true);
-}
-
-static void mt76x2_dfs_check_event_window(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       struct mt76x2_dfs_event_rb *event_buff;
-       struct mt76x2_dfs_event *event;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(dfs_pd->event_rb); i++) {
-               event_buff = &dfs_pd->event_rb[i];
-
-               while (event_buff->h_rb != event_buff->t_rb) {
-                       event = &event_buff->data[event_buff->h_rb];
-
-                       /* sorted list */
-                       if (time_is_after_jiffies(event->fetch_ts +
-                                                 MT_DFS_EVENT_WINDOW))
-                               break;
-                       event_buff->h_rb = mt76_incr(event_buff->h_rb,
-                                                    MT_DFS_EVENT_BUFLEN);
-               }
-       }
-}
-
-static void mt76x2_dfs_tasklet(unsigned long arg)
-{
-       struct mt76x2_dev *dev = (struct mt76x2_dev *)arg;
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-       u32 engine_mask;
-       int i;
-
-       if (test_bit(MT76_SCANNING, &dev->mt76.state))
-               goto out;
-
-       if (time_is_before_jiffies(dfs_pd->last_sw_check +
-                                  MT_DFS_SW_TIMEOUT)) {
-               bool radar_detected;
-
-               dfs_pd->last_sw_check = jiffies;
-
-               mt76x2_dfs_add_events(dev);
-               radar_detected = mt76x2_dfs_check_detection(dev);
-               if (radar_detected) {
-                       /* sw detector rx radar pattern */
-                       ieee80211_radar_detected(dev->mt76.hw);
-                       mt76x2_dfs_detector_reset(dev);
-
-                       return;
-               }
-               mt76x2_dfs_check_event_window(dev);
-       }
-
-       engine_mask = mt76_rr(dev, MT_BBP(DFS, 1));
-       if (!(engine_mask & 0xf))
-               goto out;
-
-       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
-               struct mt76x2_dfs_hw_pulse pulse;
-
-               if (!(engine_mask & (1 << i)))
-                       continue;
-
-               pulse.engine = i;
-               mt76x2_dfs_get_hw_pulse(dev, &pulse);
-
-               if (!mt76x2_dfs_check_hw_pulse(dev, &pulse)) {
-                       dfs_pd->stats[i].hw_pulse_discarded++;
-                       continue;
-               }
-
-               /* hw detector rx radar pattern */
-               dfs_pd->stats[i].hw_pattern++;
-               ieee80211_radar_detected(dev->mt76.hw);
-               mt76x2_dfs_detector_reset(dev);
-
-               return;
-       }
-
-       /* reset hw detector */
-       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
-
-out:
-       mt76x02_irq_enable(&dev->mt76, MT_INT_GPTIMER);
-}
-
-static void mt76x2_dfs_init_sw_detector(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       switch (dev->dfs_pd.region) {
-       case NL80211_DFS_FCC:
-               dfs_pd->sw_dpd_params.max_pri = MT_DFS_FCC_MAX_PRI;
-               dfs_pd->sw_dpd_params.min_pri = MT_DFS_FCC_MIN_PRI;
-               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN;
-               break;
-       case NL80211_DFS_ETSI:
-               dfs_pd->sw_dpd_params.max_pri = MT_DFS_ETSI_MAX_PRI;
-               dfs_pd->sw_dpd_params.min_pri = MT_DFS_ETSI_MIN_PRI;
-               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN << 2;
-               break;
-       case NL80211_DFS_JP:
-               dfs_pd->sw_dpd_params.max_pri = MT_DFS_JP_MAX_PRI;
-               dfs_pd->sw_dpd_params.min_pri = MT_DFS_JP_MIN_PRI;
-               dfs_pd->sw_dpd_params.pri_margin = MT_DFS_PRI_MARGIN;
-               break;
-       case NL80211_DFS_UNSET:
-       default:
-               break;
-       }
-}
-
-static void mt76x2_dfs_set_bbp_params(struct mt76x2_dev *dev)
-{
-       u32 data;
-       u8 i, shift;
-       const struct mt76x2_radar_specs *radar_specs;
-
-       switch (dev->mt76.chandef.width) {
-       case NL80211_CHAN_WIDTH_40:
-               shift = MT_DFS_NUM_ENGINES;
-               break;
-       case NL80211_CHAN_WIDTH_80:
-               shift = 2 * MT_DFS_NUM_ENGINES;
-               break;
-       default:
-               shift = 0;
-               break;
-       }
-
-       switch (dev->dfs_pd.region) {
-       case NL80211_DFS_FCC:
-               radar_specs = &fcc_radar_specs[shift];
-               break;
-       case NL80211_DFS_ETSI:
-               radar_specs = &etsi_radar_specs[shift];
-               break;
-       case NL80211_DFS_JP:
-               if (dev->mt76.chandef.chan->center_freq >= 5250 &&
-                   dev->mt76.chandef.chan->center_freq <= 5350)
-                       radar_specs = &jp_w53_radar_specs[shift];
-               else
-                       radar_specs = &jp_w56_radar_specs[shift];
-               break;
-       case NL80211_DFS_UNSET:
-       default:
-               return;
-       }
-
-       data = (MT_DFS_VGA_MASK << 16) |
-              (MT_DFS_PWR_GAIN_OFFSET << 12) |
-              (MT_DFS_PWR_DOWN_TIME << 8) |
-              (MT_DFS_SYM_ROUND << 4) |
-              (MT_DFS_DELTA_DELAY & 0xf);
-       mt76_wr(dev, MT_BBP(DFS, 2), data);
-
-       data = (MT_DFS_RX_PE_MASK << 16) | MT_DFS_PKT_END_MASK;
-       mt76_wr(dev, MT_BBP(DFS, 3), data);
-
-       for (i = 0; i < MT_DFS_NUM_ENGINES; i++) {
-               /* configure engine */
-               mt76_wr(dev, MT_BBP(DFS, 0), i);
-
-               /* detection mode + avg_len */
-               data = ((radar_specs[i].avg_len & 0x1ff) << 16) |
-                      (radar_specs[i].mode & 0xf);
-               mt76_wr(dev, MT_BBP(DFS, 4), data);
-
-               /* dfs energy */
-               data = ((radar_specs[i].e_high & 0x0fff) << 16) |
-                      (radar_specs[i].e_low & 0x0fff);
-               mt76_wr(dev, MT_BBP(DFS, 5), data);
-
-               /* dfs period */
-               mt76_wr(dev, MT_BBP(DFS, 7), radar_specs[i].t_low);
-               mt76_wr(dev, MT_BBP(DFS, 9), radar_specs[i].t_high);
-
-               /* dfs burst */
-               mt76_wr(dev, MT_BBP(DFS, 11), radar_specs[i].b_low);
-               mt76_wr(dev, MT_BBP(DFS, 13), radar_specs[i].b_high);
-
-               /* dfs width */
-               data = ((radar_specs[i].w_high & 0x0fff) << 16) |
-                      (radar_specs[i].w_low & 0x0fff);
-               mt76_wr(dev, MT_BBP(DFS, 14), data);
-
-               /* dfs margins */
-               data = (radar_specs[i].w_margin << 16) |
-                      radar_specs[i].t_margin;
-               mt76_wr(dev, MT_BBP(DFS, 15), data);
-
-               /* dfs event expiration */
-               mt76_wr(dev, MT_BBP(DFS, 17), radar_specs[i].event_expiration);
-
-               /* dfs pwr adj */
-               mt76_wr(dev, MT_BBP(DFS, 30), radar_specs[i].pwr_jmp);
-       }
-
-       /* reset status */
-       mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
-       mt76_wr(dev, MT_BBP(DFS, 36), 0x3);
-
-       /* enable detection*/
-       mt76_wr(dev, MT_BBP(DFS, 0), MT_DFS_CH_EN << 16);
-       mt76_wr(dev, 0x212c, 0x0c350001);
-}
-
-void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev)
-{
-       u32 agc_r8, agc_r4, val_r8, val_r4, dfs_r31;
-
-       agc_r8 = mt76_rr(dev, MT_BBP(AGC, 8));
-       agc_r4 = mt76_rr(dev, MT_BBP(AGC, 4));
-
-       val_r8 = (agc_r8 & 0x00007e00) >> 9;
-       val_r4 = agc_r4 & ~0x1f000000;
-       val_r4 += (((val_r8 + 1) >> 1) << 24);
-       mt76_wr(dev, MT_BBP(AGC, 4), val_r4);
-
-       dfs_r31 = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, val_r4);
-       dfs_r31 += val_r8;
-       dfs_r31 -= (agc_r8 & 0x00000038) >> 3;
-       dfs_r31 = (dfs_r31 << 16) | 0x00000307;
-       mt76_wr(dev, MT_BBP(DFS, 31), dfs_r31);
-
-       mt76_wr(dev, MT_BBP(DFS, 32), 0x00040071);
-}
-
-void mt76x2_dfs_init_params(struct mt76x2_dev *dev)
-{
-       struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
-
-       if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
-           dev->dfs_pd.region != NL80211_DFS_UNSET) {
-               mt76x2_dfs_init_sw_detector(dev);
-               mt76x2_dfs_set_bbp_params(dev);
-               /* enable debug mode */
-               mt76x2_dfs_set_capture_mode_ctrl(dev, true);
-
-               mt76x02_irq_enable(&dev->mt76, MT_INT_GPTIMER);
-               mt76_rmw_field(dev, MT_INT_TIMER_EN,
-                              MT_INT_TIMER_EN_GP_TIMER_EN, 1);
-       } else {
-               /* disable hw detector */
-               mt76_wr(dev, MT_BBP(DFS, 0), 0);
-               /* clear detector status */
-               mt76_wr(dev, MT_BBP(DFS, 1), 0xf);
-               mt76_wr(dev, 0x212c, 0);
-
-               mt76x02_irq_disable(&dev->mt76, MT_INT_GPTIMER);
-               mt76_rmw_field(dev, MT_INT_TIMER_EN,
-                              MT_INT_TIMER_EN_GP_TIMER_EN, 0);
-       }
-}
-
-void mt76x2_dfs_init_detector(struct mt76x2_dev *dev)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       INIT_LIST_HEAD(&dfs_pd->sequences);
-       INIT_LIST_HEAD(&dfs_pd->seq_pool);
-       dfs_pd->region = NL80211_DFS_UNSET;
-       dfs_pd->last_sw_check = jiffies;
-       tasklet_init(&dfs_pd->dfs_tasklet, mt76x2_dfs_tasklet,
-                    (unsigned long)dev);
-}
-
-void mt76x2_dfs_set_domain(struct mt76x2_dev *dev,
-                          enum nl80211_dfs_regions region)
-{
-       struct mt76x2_dfs_pattern_detector *dfs_pd = &dev->dfs_pd;
-
-       if (dfs_pd->region != region) {
-               tasklet_disable(&dfs_pd->dfs_tasklet);
-               dfs_pd->region = region;
-               mt76x2_dfs_init_params(dev);
-               tasklet_enable(&dfs_pd->dfs_tasklet);
-       }
-}
-
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h b/drivers/net/wireless/mediatek/mt76/mt76x2_dfs.h
deleted file mode 100644 (file)
index 693f421..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2016 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2_DFS_H
-#define __MT76x2_DFS_H
-
-#include <linux/types.h>
-#include <linux/nl80211.h>
-
-#define MT_DFS_GP_INTERVAL             (10 << 4) /* 64 us unit */
-#define MT_DFS_NUM_ENGINES             4
-
-/* bbp params */
-#define MT_DFS_SYM_ROUND               0
-#define MT_DFS_DELTA_DELAY             2
-#define MT_DFS_VGA_MASK                        0
-#define MT_DFS_PWR_GAIN_OFFSET         3
-#define MT_DFS_PWR_DOWN_TIME           0xf
-#define MT_DFS_RX_PE_MASK              0xff
-#define MT_DFS_PKT_END_MASK            0
-#define MT_DFS_CH_EN                   0xf
-
-/* sw detector params */
-#define MT_DFS_EVENT_LOOP              64
-#define MT_DFS_SW_TIMEOUT              (HZ / 20)
-#define MT_DFS_EVENT_WINDOW            (HZ / 5)
-#define MT_DFS_SEQUENCE_WINDOW         (200 * (1 << 20))
-#define MT_DFS_EVENT_TIME_MARGIN       2000
-#define MT_DFS_PRI_MARGIN              4
-#define MT_DFS_SEQUENCE_TH             6
-
-#define MT_DFS_FCC_MAX_PRI             ((28570 << 1) + 1000)
-#define MT_DFS_FCC_MIN_PRI             (3000 - 2)
-#define MT_DFS_JP_MAX_PRI              ((80000 << 1) + 1000)
-#define MT_DFS_JP_MIN_PRI              (28500 - 2)
-#define MT_DFS_ETSI_MAX_PRI            (133333 + 125000 + 117647 + 1000)
-#define MT_DFS_ETSI_MIN_PRI            (4500 - 20)
-
-struct mt76x2_radar_specs {
-       u8 mode;
-       u16 avg_len;
-       u16 e_low;
-       u16 e_high;
-       u16 w_low;
-       u16 w_high;
-       u16 w_margin;
-       u32 t_low;
-       u32 t_high;
-       u16 t_margin;
-       u32 b_low;
-       u32 b_high;
-       u32 event_expiration;
-       u16 pwr_jmp;
-};
-
-#define MT_DFS_CHECK_EVENT(x)          ((x) != GENMASK(31, 0))
-#define MT_DFS_EVENT_ENGINE(x)         (((x) & BIT(31)) ? 2 : 0)
-#define MT_DFS_EVENT_TIMESTAMP(x)      ((x) & GENMASK(21, 0))
-#define MT_DFS_EVENT_WIDTH(x)          ((x) & GENMASK(11, 0))
-struct mt76x2_dfs_event {
-       unsigned long fetch_ts;
-       u32 ts;
-       u16 width;
-       u8 engine;
-};
-
-#define MT_DFS_EVENT_BUFLEN            256
-struct mt76x2_dfs_event_rb {
-       struct mt76x2_dfs_event data[MT_DFS_EVENT_BUFLEN];
-       int h_rb, t_rb;
-};
-
-struct mt76x2_dfs_sequence {
-       struct list_head head;
-       u32 first_ts;
-       u32 last_ts;
-       u32 pri;
-       u16 count;
-       u8 engine;
-};
-
-struct mt76x2_dfs_hw_pulse {
-       u8 engine;
-       u32 period;
-       u32 w1;
-       u32 w2;
-       u32 burst;
-};
-
-struct mt76x2_dfs_sw_detector_params {
-       u32 min_pri;
-       u32 max_pri;
-       u32 pri_margin;
-};
-
-struct mt76x2_dfs_engine_stats {
-       u32 hw_pattern;
-       u32 hw_pulse_discarded;
-       u32 sw_pattern;
-};
-
-struct mt76x2_dfs_seq_stats {
-       u32 seq_pool_len;
-       u32 seq_len;
-};
-
-struct mt76x2_dfs_pattern_detector {
-       enum nl80211_dfs_regions region;
-
-       u8 chirp_pulse_cnt;
-       u32 chirp_pulse_ts;
-
-       struct mt76x2_dfs_sw_detector_params sw_dpd_params;
-       struct mt76x2_dfs_event_rb event_rb[2];
-
-       struct list_head sequences;
-       struct list_head seq_pool;
-       struct mt76x2_dfs_seq_stats seq_stats;
-
-       unsigned long last_sw_check;
-       u32 last_event_ts;
-
-       struct mt76x2_dfs_engine_stats stats[MT_DFS_NUM_ENGINES];
-       struct tasklet_struct dfs_tasklet;
-};
-
-void mt76x2_dfs_init_params(struct mt76x2_dev *dev);
-void mt76x2_dfs_init_detector(struct mt76x2_dev *dev);
-void mt76x2_dfs_adjust_agc(struct mt76x2_dev *dev);
-void mt76x2_dfs_set_domain(struct mt76x2_dev *dev,
-                          enum nl80211_dfs_regions region);
-
-#endif /* __MT76x2_DFS_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c b/drivers/net/wireless/mediatek/mt76/mt76x2_dma.c
deleted file mode 100644 (file)
index 7e5eccd..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_dma.h"
-#include "mt76x02_util.h"
-
-void mt76x2_tx_tasklet(unsigned long data)
-{
-       struct mt76x2_dev *dev = (struct mt76x2_dev *) data;
-       int i;
-
-       mt76x2_mac_process_tx_status_fifo(dev);
-
-       for (i = MT_TXQ_MCU; i >= 0; i--)
-               mt76_queue_tx_cleanup(dev, i, false);
-
-       mt76x2_mac_poll_tx_status(dev, false);
-       mt76x02_irq_enable(&dev->mt76, MT_INT_TX_DONE_ALL);
-}
-
-void mt76x2_dma_cleanup(struct mt76x2_dev *dev)
-{
-       tasklet_kill(&dev->tx_tasklet);
-       mt76_dma_cleanup(&dev->mt76);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.c
deleted file mode 100644 (file)
index 136faa4..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <asm/unaligned.h>
-#include "mt76x2.h"
-#include "mt76x2_eeprom.h"
-
-#define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1
-
-static int
-mt76x2_eeprom_copy(struct mt76x2_dev *dev, enum mt76x02_eeprom_field field,
-                  void *dest, int len)
-{
-       if (field + len > dev->mt76.eeprom.size)
-               return -1;
-
-       memcpy(dest, dev->mt76.eeprom.data + field, len);
-       return 0;
-}
-
-static int
-mt76x2_eeprom_get_macaddr(struct mt76x2_dev *dev)
-{
-       void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR;
-
-       memcpy(dev->mt76.macaddr, src, ETH_ALEN);
-       return 0;
-}
-
-static bool
-mt76x2_has_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
-{
-       u16 *efuse_w = (u16 *) efuse;
-
-       if (efuse_w[MT_EE_NIC_CONF_0] != 0)
-               return false;
-
-       if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff)
-               return false;
-
-       if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0)
-               return false;
-
-       if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff)
-               return false;
-
-       if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0)
-               return false;
-
-       if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff)
-               return false;
-
-       return true;
-}
-
-static void
-mt76x2_apply_cal_free_data(struct mt76x2_dev *dev, u8 *efuse)
-{
-#define GROUP_5G(_id)                                                     \
-       MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
-       MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \
-       MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id),     \
-       MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1
-
-       static const u8 cal_free_bytes[] = {
-               MT_EE_XTAL_TRIM_1,
-               MT_EE_TX_POWER_EXT_PA_5G + 1,
-               MT_EE_TX_POWER_0_START_2G,
-               MT_EE_TX_POWER_0_START_2G + 1,
-               MT_EE_TX_POWER_1_START_2G,
-               MT_EE_TX_POWER_1_START_2G + 1,
-               GROUP_5G(0),
-               GROUP_5G(1),
-               GROUP_5G(2),
-               GROUP_5G(3),
-               GROUP_5G(4),
-               GROUP_5G(5),
-               MT_EE_RF_2G_TSSI_OFF_TXPOWER,
-               MT_EE_RF_2G_RX_HIGH_GAIN + 1,
-               MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN,
-               MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1,
-               MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN,
-               MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1,
-               MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN,
-               MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1,
-       };
-       u8 *eeprom = dev->mt76.eeprom.data;
-       u8 prev_grp0[4] = {
-               eeprom[MT_EE_TX_POWER_0_START_5G],
-               eeprom[MT_EE_TX_POWER_0_START_5G + 1],
-               eeprom[MT_EE_TX_POWER_1_START_5G],
-               eeprom[MT_EE_TX_POWER_1_START_5G + 1]
-       };
-       u16 val;
-       int i;
-
-       if (!mt76x2_has_cal_free_data(dev, efuse))
-               return;
-
-       for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) {
-               int offset = cal_free_bytes[i];
-
-               eeprom[offset] = efuse[offset];
-       }
-
-       if (!(efuse[MT_EE_TX_POWER_0_START_5G] |
-             efuse[MT_EE_TX_POWER_0_START_5G + 1]))
-               memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2);
-       if (!(efuse[MT_EE_TX_POWER_1_START_5G] |
-             efuse[MT_EE_TX_POWER_1_START_5G + 1]))
-               memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2);
-
-       val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT);
-       if (val != 0xffff)
-               eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff;
-
-       val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION);
-       if (val != 0xffff)
-               eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8;
-
-       val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG);
-       if (val != 0xffff)
-               eeprom[MT_EE_BT_PMUCFG] = val & 0xff;
-}
-
-static int mt76x2_check_eeprom(struct mt76x2_dev *dev)
-{
-       u16 val = get_unaligned_le16(dev->mt76.eeprom.data);
-
-       if (!val)
-               val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID);
-
-       switch (val) {
-       case 0x7662:
-       case 0x7612:
-               return 0;
-       default:
-               dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val);
-               return -EINVAL;
-       }
-}
-
-static int
-mt76x2_eeprom_load(struct mt76x2_dev *dev)
-{
-       void *efuse;
-       bool found;
-       int ret;
-
-       ret = mt76_eeprom_init(&dev->mt76, MT7662_EEPROM_SIZE);
-       if (ret < 0)
-               return ret;
-
-       found = ret;
-       if (found)
-               found = !mt76x2_check_eeprom(dev);
-
-       dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, MT7662_EEPROM_SIZE,
-                                         GFP_KERNEL);
-       dev->mt76.otp.size = MT7662_EEPROM_SIZE;
-       if (!dev->mt76.otp.data)
-               return -ENOMEM;
-
-       efuse = dev->mt76.otp.data;
-
-       if (mt76x02_get_efuse_data(&dev->mt76, 0, efuse,
-                                  MT7662_EEPROM_SIZE, MT_EE_READ))
-               goto out;
-
-       if (found) {
-               mt76x2_apply_cal_free_data(dev, efuse);
-       } else {
-               /* FIXME: check if efuse data is complete */
-               found = true;
-               memcpy(dev->mt76.eeprom.data, efuse, MT7662_EEPROM_SIZE);
-       }
-
-out:
-       if (!found)
-               return -ENOENT;
-
-       return 0;
-}
-
-static void
-mt76x2_set_rx_gain_group(struct mt76x2_dev *dev, u8 val)
-{
-       s8 *dest = dev->cal.rx.high_gain;
-
-       if (!mt76x02_field_valid(val)) {
-               dest[0] = 0;
-               dest[1] = 0;
-               return;
-       }
-
-       dest[0] = mt76x02_sign_extend(val, 4);
-       dest[1] = mt76x02_sign_extend(val >> 4, 4);
-}
-
-static void
-mt76x2_set_rssi_offset(struct mt76x2_dev *dev, int chain, u8 val)
-{
-       s8 *dest = dev->cal.rx.rssi_offset;
-
-       if (!mt76x02_field_valid(val)) {
-               dest[chain] = 0;
-               return;
-       }
-
-       dest[chain] = mt76x02_sign_extend_optional(val, 7);
-}
-
-static enum mt76x2_cal_channel_group
-mt76x2_get_cal_channel_group(int channel)
-{
-       if (channel >= 184 && channel <= 196)
-               return MT_CH_5G_JAPAN;
-       if (channel <= 48)
-               return MT_CH_5G_UNII_1;
-       if (channel <= 64)
-               return MT_CH_5G_UNII_2;
-       if (channel <= 114)
-               return MT_CH_5G_UNII_2E_1;
-       if (channel <= 144)
-               return MT_CH_5G_UNII_2E_2;
-       return MT_CH_5G_UNII_3;
-}
-
-static u8
-mt76x2_get_5g_rx_gain(struct mt76x2_dev *dev, u8 channel)
-{
-       enum mt76x2_cal_channel_group group;
-
-       group = mt76x2_get_cal_channel_group(channel);
-       switch (group) {
-       case MT_CH_5G_JAPAN:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN);
-       case MT_CH_5G_UNII_1:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8;
-       case MT_CH_5G_UNII_2:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN);
-       case MT_CH_5G_UNII_2E_1:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8;
-       case MT_CH_5G_UNII_2E_2:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN);
-       default:
-               return mt76x02_eeprom_get(&dev->mt76,
-                                         MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8;
-       }
-}
-
-void mt76x2_read_rx_gain(struct mt76x2_dev *dev)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       int channel = chan->hw_value;
-       s8 lna_5g[3], lna_2g;
-       u8 lna;
-       u16 val;
-
-       if (chan->band == NL80211_BAND_2GHZ)
-               val = mt76x02_eeprom_get(&dev->mt76,
-                                        MT_EE_RF_2G_RX_HIGH_GAIN) >> 8;
-       else
-               val = mt76x2_get_5g_rx_gain(dev, channel);
-
-       mt76x2_set_rx_gain_group(dev, val);
-
-       mt76x02_get_rx_gain(&dev->mt76, chan->band, &val, &lna_2g, lna_5g);
-       mt76x2_set_rssi_offset(dev, 0, val);
-       mt76x2_set_rssi_offset(dev, 1, val >> 8);
-
-       dev->cal.rx.mcu_gain =  (lna_2g & 0xff);
-       dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8;
-       dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16;
-       dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24;
-
-       lna = mt76x02_get_lna_gain(&dev->mt76, &lna_2g, lna_5g, chan);
-       dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8);
-}
-EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain);
-
-void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
-                          struct ieee80211_channel *chan)
-{
-       bool is_5ghz;
-       u16 val;
-
-       is_5ghz = chan->band == NL80211_BAND_5GHZ;
-
-       memset(t, 0, sizeof(*t));
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_CCK);
-       t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val);
-       t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8);
-
-       if (is_5ghz)
-               val = mt76x02_eeprom_get(&dev->mt76,
-                                        MT_EE_TX_POWER_OFDM_5G_6M);
-       else
-               val = mt76x02_eeprom_get(&dev->mt76,
-                                        MT_EE_TX_POWER_OFDM_2G_6M);
-       t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val);
-       t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8);
-
-       if (is_5ghz)
-               val = mt76x02_eeprom_get(&dev->mt76,
-                                        MT_EE_TX_POWER_OFDM_5G_24M);
-       else
-               val = mt76x02_eeprom_get(&dev->mt76,
-                                        MT_EE_TX_POWER_OFDM_2G_24M);
-       t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val);
-       t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS0);
-       t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val);
-       t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS4);
-       t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val);
-       t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS8);
-       t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val);
-       t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_HT_MCS12);
-       t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val);
-       t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS0);
-       t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val);
-       t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS4);
-       t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val);
-       t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_VHT_MCS8);
-       if (!is_5ghz)
-               val >>= 8;
-       t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8);
-
-       memcpy(t->stbc, t->ht, sizeof(t->stbc[0]) * 8);
-       t->stbc[8] = t->vht[8];
-       t->stbc[9] = t->vht[9];
-}
-EXPORT_SYMBOL_GPL(mt76x2_get_rate_power);
-
-static void
-mt76x2_get_power_info_2g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
-                        struct ieee80211_channel *chan, int chain, int offset)
-{
-       int channel = chan->hw_value;
-       int delta_idx;
-       u8 data[6];
-       u16 val;
-
-       if (channel < 6)
-               delta_idx = 3;
-       else if (channel < 11)
-               delta_idx = 4;
-       else
-               delta_idx = 5;
-
-       mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
-
-       t->chain[chain].tssi_slope = data[0];
-       t->chain[chain].tssi_offset = data[1];
-       t->chain[chain].target_power = data[2];
-       t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_TSSI_OFF_TXPOWER);
-       t->target_power = val >> 8;
-}
-
-static void
-mt76x2_get_power_info_5g(struct mt76x2_dev *dev, struct mt76x2_tx_power_info *t,
-                        struct ieee80211_channel *chan, int chain, int offset)
-{
-       int channel = chan->hw_value;
-       enum mt76x2_cal_channel_group group;
-       int delta_idx;
-       u16 val;
-       u8 data[5];
-
-       group = mt76x2_get_cal_channel_group(channel);
-       offset += group * MT_TX_POWER_GROUP_SIZE_5G;
-
-       if (channel >= 192)
-               delta_idx = 4;
-       else if (channel >= 184)
-               delta_idx = 3;
-       else if (channel < 44)
-               delta_idx = 3;
-       else if (channel < 52)
-               delta_idx = 4;
-       else if (channel < 58)
-               delta_idx = 3;
-       else if (channel < 98)
-               delta_idx = 4;
-       else if (channel < 106)
-               delta_idx = 3;
-       else if (channel < 116)
-               delta_idx = 4;
-       else if (channel < 130)
-               delta_idx = 3;
-       else if (channel < 149)
-               delta_idx = 4;
-       else if (channel < 157)
-               delta_idx = 3;
-       else
-               delta_idx = 4;
-
-       mt76x2_eeprom_copy(dev, offset, data, sizeof(data));
-
-       t->chain[chain].tssi_slope = data[0];
-       t->chain[chain].tssi_offset = data[1];
-       t->chain[chain].target_power = data[2];
-       t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_RF_2G_RX_HIGH_GAIN);
-       t->target_power = val & 0xff;
-}
-
-void mt76x2_get_power_info(struct mt76x2_dev *dev,
-                          struct mt76x2_tx_power_info *t,
-                          struct ieee80211_channel *chan)
-{
-       u16 bw40, bw80;
-
-       memset(t, 0, sizeof(*t));
-
-       bw40 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW40);
-       bw80 = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_DELTA_BW80);
-
-       if (chan->band == NL80211_BAND_5GHZ) {
-               bw40 >>= 8;
-               mt76x2_get_power_info_5g(dev, t, chan, 0,
-                                        MT_EE_TX_POWER_0_START_5G);
-               mt76x2_get_power_info_5g(dev, t, chan, 1,
-                                        MT_EE_TX_POWER_1_START_5G);
-       } else {
-               mt76x2_get_power_info_2g(dev, t, chan, 0,
-                                        MT_EE_TX_POWER_0_START_2G);
-               mt76x2_get_power_info_2g(dev, t, chan, 1,
-                                        MT_EE_TX_POWER_1_START_2G);
-       }
-
-       if (mt76x02_tssi_enabled(&dev->mt76) ||
-           !mt76x02_field_valid(t->target_power))
-               t->target_power = t->chain[0].target_power;
-
-       t->delta_bw40 = mt76x02_rate_power_val(bw40);
-       t->delta_bw80 = mt76x02_rate_power_val(bw80);
-}
-EXPORT_SYMBOL_GPL(mt76x2_get_power_info);
-
-int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t)
-{
-       enum nl80211_band band = dev->mt76.chandef.chan->band;
-       u16 val, slope;
-       u8 bounds;
-
-       memset(t, 0, sizeof(*t));
-
-       if (!mt76x02_temp_tx_alc_enabled(&dev->mt76))
-               return -EINVAL;
-
-       if (!mt76x02_ext_pa_enabled(&dev->mt76, band))
-               return -EINVAL;
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_TX_POWER_EXT_PA_5G) >> 8;
-       t->temp_25_ref = val & 0x7f;
-       if (band == NL80211_BAND_5GHZ) {
-               slope = mt76x02_eeprom_get(&dev->mt76,
-                                          MT_EE_RF_TEMP_COMP_SLOPE_5G);
-               bounds = mt76x02_eeprom_get(&dev->mt76,
-                                           MT_EE_TX_POWER_EXT_PA_5G);
-       } else {
-               slope = mt76x02_eeprom_get(&dev->mt76,
-                                          MT_EE_RF_TEMP_COMP_SLOPE_2G);
-               bounds = mt76x02_eeprom_get(&dev->mt76,
-                                           MT_EE_TX_POWER_DELTA_BW80) >> 8;
-       }
-
-       t->high_slope = slope & 0xff;
-       t->low_slope = slope >> 8;
-       t->lower_bound = 0 - (bounds & 0xf);
-       t->upper_bound = (bounds >> 4) & 0xf;
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp);
-
-int mt76x2_eeprom_init(struct mt76x2_dev *dev)
-{
-       int ret;
-
-       ret = mt76x2_eeprom_load(dev);
-       if (ret)
-               return ret;
-
-       mt76x02_eeprom_parse_hw_cap(&dev->mt76);
-       mt76x2_eeprom_get_macaddr(dev);
-       mt76_eeprom_override(&dev->mt76);
-       dev->mt76.macaddr[0] &= ~BIT(1);
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mt76x2_eeprom_init);
-
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h b/drivers/net/wireless/mediatek/mt76/mt76x2_eeprom.h
deleted file mode 100644 (file)
index c2e99bb..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2_EEPROM_H
-#define __MT76x2_EEPROM_H
-
-#include "mt76x02_eeprom.h"
-
-enum mt76x2_cal_channel_group {
-       MT_CH_5G_JAPAN,
-       MT_CH_5G_UNII_1,
-       MT_CH_5G_UNII_2,
-       MT_CH_5G_UNII_2E_1,
-       MT_CH_5G_UNII_2E_2,
-       MT_CH_5G_UNII_3,
-       __MT_CH_MAX
-};
-
-struct mt76x2_tx_power_info {
-       u8 target_power;
-
-       s8 delta_bw40;
-       s8 delta_bw80;
-
-       struct {
-               s8 tssi_slope;
-               s8 tssi_offset;
-               s8 target_power;
-               s8 delta;
-       } chain[MT_MAX_CHAINS];
-};
-
-struct mt76x2_temp_comp {
-       u8 temp_25_ref;
-       int lower_bound; /* J */
-       int upper_bound; /* J */
-       unsigned int high_slope; /* J / dB */
-       unsigned int low_slope; /* J / dB */
-};
-
-void mt76x2_get_rate_power(struct mt76x2_dev *dev, struct mt76_rate_power *t,
-                          struct ieee80211_channel *chan);
-void mt76x2_get_power_info(struct mt76x2_dev *dev,
-                          struct mt76x2_tx_power_info *t,
-                          struct ieee80211_channel *chan);
-int mt76x2_get_temp_comp(struct mt76x2_dev *dev, struct mt76x2_temp_comp *t);
-void mt76x2_read_rx_gain(struct mt76x2_dev *dev);
-
-static inline bool
-mt76x2_has_ext_lna(struct mt76x2_dev *dev)
-{
-       u32 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_1);
-
-       if (dev->mt76.chandef.chan->band == NL80211_BAND_2GHZ)
-               return val & MT_EE_NIC_CONF_1_LNA_EXT_2G;
-       else
-               return val & MT_EE_NIC_CONF_1_LNA_EXT_5G;
-}
-
-#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init.c
deleted file mode 100644 (file)
index 3f77c13..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/delay.h>
-#include "mt76x2.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x2_mcu.h"
-#include "mt76x02_util.h"
-#include "mt76x02_dma.h"
-
-static void
-mt76x2_mac_pbf_init(struct mt76x2_dev *dev)
-{
-       u32 val;
-
-       val = MT_PBF_SYS_CTRL_MCU_RESET |
-             MT_PBF_SYS_CTRL_DMA_RESET |
-             MT_PBF_SYS_CTRL_MAC_RESET |
-             MT_PBF_SYS_CTRL_PBF_RESET |
-             MT_PBF_SYS_CTRL_ASY_RESET;
-
-       mt76_set(dev, MT_PBF_SYS_CTRL, val);
-       mt76_clear(dev, MT_PBF_SYS_CTRL, val);
-
-       mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f);
-       mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf);
-}
-
-static void
-mt76x2_fixup_xtal(struct mt76x2_dev *dev)
-{
-       u16 eep_val;
-       s8 offset = 0;
-
-       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2);
-
-       offset = eep_val & 0x7f;
-       if ((eep_val & 0xff) == 0xff)
-               offset = 0;
-       else if (eep_val & 0x80)
-               offset = 0 - offset;
-
-       eep_val >>= 8;
-       if (eep_val == 0x00 || eep_val == 0xff) {
-               eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1);
-               eep_val &= 0xff;
-
-               if (eep_val == 0x00 || eep_val == 0xff)
-                       eep_val = 0x14;
-       }
-
-       eep_val &= 0x7f;
-       mt76_rmw_field(dev, MT_XO_CTRL5, MT_XO_CTRL5_C2_VAL, eep_val + offset);
-       mt76_set(dev, MT_XO_CTRL6, MT_XO_CTRL6_C2_CTRL);
-
-       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
-       switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) {
-       case 0:
-               mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80);
-               break;
-       case 1:
-               mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0);
-               break;
-       default:
-               break;
-       }
-}
-
-static int mt76x2_mac_reset(struct mt76x2_dev *dev, bool hard)
-{
-       static const u8 null_addr[ETH_ALEN] = {};
-       const u8 *macaddr = dev->mt76.macaddr;
-       u32 val;
-       int i, k;
-
-       if (!mt76x02_wait_for_mac(&dev->mt76))
-               return -ETIMEDOUT;
-
-       val = mt76_rr(dev, MT_WPDMA_GLO_CFG);
-
-       val &= ~(MT_WPDMA_GLO_CFG_TX_DMA_EN |
-                MT_WPDMA_GLO_CFG_TX_DMA_BUSY |
-                MT_WPDMA_GLO_CFG_RX_DMA_EN |
-                MT_WPDMA_GLO_CFG_RX_DMA_BUSY |
-                MT_WPDMA_GLO_CFG_DMA_BURST_SIZE);
-       val |= FIELD_PREP(MT_WPDMA_GLO_CFG_DMA_BURST_SIZE, 3);
-
-       mt76_wr(dev, MT_WPDMA_GLO_CFG, val);
-
-       mt76x2_mac_pbf_init(dev);
-       mt76_write_mac_initvals(dev);
-       mt76x2_fixup_xtal(dev);
-
-       mt76_clear(dev, MT_MAC_SYS_CTRL,
-                  MT_MAC_SYS_CTRL_RESET_CSR |
-                  MT_MAC_SYS_CTRL_RESET_BBP);
-
-       if (is_mt7612(dev))
-               mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN);
-
-       mt76_set(dev, MT_EXT_CCA_CFG, 0x0000f000);
-       mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31));
-
-       mt76_wr(dev, MT_RF_BYPASS_0, 0x06000000);
-       mt76_wr(dev, MT_RF_SETTING_0, 0x08800000);
-       usleep_range(5000, 10000);
-       mt76_wr(dev, MT_RF_BYPASS_0, 0x00000000);
-
-       mt76_wr(dev, MT_MCU_CLOCK_CTL, 0x1401);
-       mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
-
-       mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(macaddr));
-       mt76_wr(dev, MT_MAC_ADDR_DW1, get_unaligned_le16(macaddr + 4));
-
-       mt76_wr(dev, MT_MAC_BSSID_DW0, get_unaligned_le32(macaddr));
-       mt76_wr(dev, MT_MAC_BSSID_DW1, get_unaligned_le16(macaddr + 4) |
-               FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 beacons */
-               MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
-
-       /* Fire a pre-TBTT interrupt 8 ms before TBTT */
-       mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_PRE_TBTT,
-                      8 << 4);
-       mt76_rmw_field(dev, MT_INT_TIMER_CFG, MT_INT_TIMER_CFG_GP_TIMER,
-                      MT_DFS_GP_INTERVAL);
-       mt76_wr(dev, MT_INT_TIMER_EN, 0);
-
-       mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
-       if (!hard)
-               return 0;
-
-       for (i = 0; i < 256 / 32; i++)
-               mt76_wr(dev, MT_WCID_DROP_BASE + i * 4, 0);
-
-       for (i = 0; i < 256; i++)
-               mt76x02_mac_wcid_setup(&dev->mt76, i, 0, NULL);
-
-       for (i = 0; i < MT_MAX_VIFS; i++)
-               mt76x02_mac_wcid_setup(&dev->mt76, MT_VIF_WCID(i), i, NULL);
-
-       for (i = 0; i < 16; i++)
-               for (k = 0; k < 4; k++)
-                       mt76x02_mac_shared_key_setup(&dev->mt76, i, k, NULL);
-
-       for (i = 0; i < 8; i++) {
-               mt76x2_mac_set_bssid(dev, i, null_addr);
-               mt76x2_mac_set_beacon(dev, i, NULL);
-       }
-
-       for (i = 0; i < 16; i++)
-               mt76_rr(dev, MT_TX_STAT_FIFO);
-
-       mt76_wr(dev, MT_CH_TIME_CFG,
-               MT_CH_TIME_CFG_TIMER_EN |
-               MT_CH_TIME_CFG_TX_AS_BUSY |
-               MT_CH_TIME_CFG_RX_AS_BUSY |
-               MT_CH_TIME_CFG_NAV_AS_BUSY |
-               MT_CH_TIME_CFG_EIFS_AS_BUSY |
-               FIELD_PREP(MT_CH_TIME_CFG_CH_TIMER_CLR, 1));
-
-       mt76x02_set_beacon_offsets(&dev->mt76);
-
-       mt76x2_set_tx_ackto(dev);
-
-       return 0;
-}
-
-int mt76x2_mac_start(struct mt76x2_dev *dev)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               mt76_rr(dev, MT_TX_AGG_CNT(i));
-
-       for (i = 0; i < 16; i++)
-               mt76_rr(dev, MT_TX_STAT_FIFO);
-
-       memset(dev->aggr_stats, 0, sizeof(dev->aggr_stats));
-       mt76x02_mac_start(&dev->mt76);
-
-       return 0;
-}
-
-void mt76x2_mac_resume(struct mt76x2_dev *dev)
-{
-       mt76_wr(dev, MT_MAC_SYS_CTRL,
-               MT_MAC_SYS_CTRL_ENABLE_TX |
-               MT_MAC_SYS_CTRL_ENABLE_RX);
-}
-
-static void
-mt76x2_power_on_rf_patch(struct mt76x2_dev *dev)
-{
-       mt76_set(dev, 0x10130, BIT(0) | BIT(16));
-       udelay(1);
-
-       mt76_clear(dev, 0x1001c, 0xff);
-       mt76_set(dev, 0x1001c, 0x30);
-
-       mt76_wr(dev, 0x10014, 0x484f);
-       udelay(1);
-
-       mt76_set(dev, 0x10130, BIT(17));
-       udelay(125);
-
-       mt76_clear(dev, 0x10130, BIT(16));
-       udelay(50);
-
-       mt76_set(dev, 0x1014c, BIT(19) | BIT(20));
-}
-
-static void
-mt76x2_power_on_rf(struct mt76x2_dev *dev, int unit)
-{
-       int shift = unit ? 8 : 0;
-
-       /* Enable RF BG */
-       mt76_set(dev, 0x10130, BIT(0) << shift);
-       udelay(10);
-
-       /* Enable RFDIG LDO/AFE/ABB/ADDA */
-       mt76_set(dev, 0x10130, (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift);
-       udelay(10);
-
-       /* Switch RFDIG power to internal LDO */
-       mt76_clear(dev, 0x10130, BIT(2) << shift);
-       udelay(10);
-
-       mt76x2_power_on_rf_patch(dev);
-
-       mt76_set(dev, 0x530, 0xf);
-}
-
-static void
-mt76x2_power_on(struct mt76x2_dev *dev)
-{
-       u32 val;
-
-       /* Turn on WL MTCMOS */
-       mt76_set(dev, MT_WLAN_MTC_CTRL, MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP);
-
-       val = MT_WLAN_MTC_CTRL_STATE_UP |
-             MT_WLAN_MTC_CTRL_PWR_ACK |
-             MT_WLAN_MTC_CTRL_PWR_ACK_S;
-
-       mt76_poll(dev, MT_WLAN_MTC_CTRL, val, val, 1000);
-
-       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0x7f << 16);
-       udelay(10);
-
-       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xf << 24);
-       udelay(10);
-
-       mt76_set(dev, MT_WLAN_MTC_CTRL, 0xf << 24);
-       mt76_clear(dev, MT_WLAN_MTC_CTRL, 0xfff);
-
-       /* Turn on AD/DA power down */
-       mt76_clear(dev, 0x11204, BIT(3));
-
-       /* WLAN function enable */
-       mt76_set(dev, 0x10080, BIT(0));
-
-       /* Release BBP software reset */
-       mt76_clear(dev, 0x10064, BIT(18));
-
-       mt76x2_power_on_rf(dev, 0);
-       mt76x2_power_on_rf(dev, 1);
-}
-
-void mt76x2_set_tx_ackto(struct mt76x2_dev *dev)
-{
-       u8 ackto, sifs, slottime = dev->slottime;
-
-       /* As defined by IEEE 802.11-2007 17.3.8.6 */
-       slottime += 3 * dev->coverage_class;
-       mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
-                      MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
-
-       sifs = mt76_get_field(dev, MT_XIFS_TIME_CFG,
-                             MT_XIFS_TIME_CFG_OFDM_SIFS);
-
-       ackto = slottime + sifs;
-       mt76_rmw_field(dev, MT_TX_TIMEOUT_CFG,
-                      MT_TX_TIMEOUT_CFG_ACKTO, ackto);
-}
-
-int mt76x2_init_hardware(struct mt76x2_dev *dev)
-{
-       int ret;
-
-       tasklet_init(&dev->pre_tbtt_tasklet, mt76x2_pre_tbtt_tasklet,
-                    (unsigned long) dev);
-
-       mt76x02_dma_disable(&dev->mt76);
-       mt76x2_reset_wlan(dev, true);
-       mt76x2_power_on(dev);
-
-       ret = mt76x2_eeprom_init(dev);
-       if (ret)
-               return ret;
-
-       ret = mt76x2_mac_reset(dev, true);
-       if (ret)
-               return ret;
-
-       dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
-
-       ret = mt76x02_dma_init(&dev->mt76);
-       if (ret)
-               return ret;
-
-       set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
-       ret = mt76x2_mac_start(dev);
-       if (ret)
-               return ret;
-
-       ret = mt76x2_mcu_init(dev);
-       if (ret)
-               return ret;
-
-       mt76x2_mac_stop(dev, false);
-
-       return 0;
-}
-
-void mt76x2_stop_hardware(struct mt76x2_dev *dev)
-{
-       cancel_delayed_work_sync(&dev->cal_work);
-       cancel_delayed_work_sync(&dev->mac_work);
-       mt76x02_mcu_set_radio_state(&dev->mt76, false, true);
-       mt76x2_mac_stop(dev, false);
-}
-
-void mt76x2_cleanup(struct mt76x2_dev *dev)
-{
-       tasklet_disable(&dev->dfs_pd.dfs_tasklet);
-       tasklet_disable(&dev->pre_tbtt_tasklet);
-       mt76x2_stop_hardware(dev);
-       mt76x2_dma_cleanup(dev);
-       mt76x02_mcu_cleanup(&dev->mt76);
-}
-
-struct mt76x2_dev *mt76x2_alloc_device(struct device *pdev)
-{
-       static const struct mt76_driver_ops drv_ops = {
-               .txwi_size = sizeof(struct mt76x02_txwi),
-               .update_survey = mt76x2_update_channel,
-               .tx_prepare_skb = mt76x2_tx_prepare_skb,
-               .tx_complete_skb = mt76x2_tx_complete_skb,
-               .rx_skb = mt76x2_queue_rx_skb,
-               .rx_poll_complete = mt76x2_rx_poll_complete,
-               .sta_ps = mt76x2_sta_ps,
-               .get_max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj,
-       };
-       struct mt76x2_dev *dev;
-       struct mt76_dev *mdev;
-
-       mdev = mt76_alloc_device(sizeof(*dev), &mt76x2_ops);
-       if (!mdev)
-               return NULL;
-
-       dev = container_of(mdev, struct mt76x2_dev, mt76);
-       mdev->dev = pdev;
-       mdev->drv = &drv_ops;
-
-       return dev;
-}
-
-static void mt76x2_regd_notifier(struct wiphy *wiphy,
-                                struct regulatory_request *request)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct mt76x2_dev *dev = hw->priv;
-
-       mt76x2_dfs_set_domain(dev, request->dfs_region);
-}
-
-static const struct ieee80211_iface_limit if_limits[] = {
-       {
-               .max = 1,
-               .types = BIT(NL80211_IFTYPE_ADHOC)
-       }, {
-               .max = 8,
-               .types = BIT(NL80211_IFTYPE_STATION) |
-#ifdef CONFIG_MAC80211_MESH
-                        BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
-                        BIT(NL80211_IFTYPE_AP)
-        },
-};
-
-static const struct ieee80211_iface_combination if_comb[] = {
-       {
-               .limits = if_limits,
-               .n_limits = ARRAY_SIZE(if_limits),
-               .max_interfaces = 8,
-               .num_different_channels = 1,
-               .beacon_int_infra_match = true,
-               .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
-                                      BIT(NL80211_CHAN_WIDTH_20) |
-                                      BIT(NL80211_CHAN_WIDTH_40) |
-                                      BIT(NL80211_CHAN_WIDTH_80),
-       }
-};
-
-static void mt76x2_led_set_config(struct mt76_dev *mt76, u8 delay_on,
-                                 u8 delay_off)
-{
-       struct mt76x2_dev *dev = container_of(mt76, struct mt76x2_dev,
-                                             mt76);
-       u32 val;
-
-       val = MT_LED_STATUS_DURATION(0xff) |
-             MT_LED_STATUS_OFF(delay_off) |
-             MT_LED_STATUS_ON(delay_on);
-
-       mt76_wr(dev, MT_LED_S0(mt76->led_pin), val);
-       mt76_wr(dev, MT_LED_S1(mt76->led_pin), val);
-
-       val = MT_LED_CTRL_REPLAY(mt76->led_pin) |
-             MT_LED_CTRL_KICK(mt76->led_pin);
-       if (mt76->led_al)
-               val |= MT_LED_CTRL_POLARITY(mt76->led_pin);
-       mt76_wr(dev, MT_LED_CTRL, val);
-}
-
-static int mt76x2_led_set_blink(struct led_classdev *led_cdev,
-                               unsigned long *delay_on,
-                               unsigned long *delay_off)
-{
-       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
-       u8 delta_on, delta_off;
-
-       delta_off = max_t(u8, *delay_off / 10, 1);
-       delta_on = max_t(u8, *delay_on / 10, 1);
-
-       mt76x2_led_set_config(mt76, delta_on, delta_off);
-       return 0;
-}
-
-static void mt76x2_led_set_brightness(struct led_classdev *led_cdev,
-                                     enum led_brightness brightness)
-{
-       struct mt76_dev *mt76 = container_of(led_cdev, struct mt76_dev,
-                                            led_cdev);
-
-       if (!brightness)
-               mt76x2_led_set_config(mt76, 0, 0xff);
-       else
-               mt76x2_led_set_config(mt76, 0xff, 0);
-}
-
-int mt76x2_register_device(struct mt76x2_dev *dev)
-{
-       struct ieee80211_hw *hw = mt76_hw(dev);
-       struct wiphy *wiphy = hw->wiphy;
-       void *status_fifo;
-       int fifo_size;
-       int i, ret;
-
-       fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76x02_tx_status));
-       status_fifo = devm_kzalloc(dev->mt76.dev, fifo_size, GFP_KERNEL);
-       if (!status_fifo)
-               return -ENOMEM;
-
-       tasklet_init(&dev->tx_tasklet, mt76x2_tx_tasklet, (unsigned long)dev);
-       kfifo_init(&dev->txstatus_fifo, status_fifo, fifo_size);
-       INIT_DELAYED_WORK(&dev->cal_work, mt76x2_phy_calibrate);
-       INIT_DELAYED_WORK(&dev->mac_work, mt76x2_mac_work);
-
-       mt76x2_init_device(dev);
-
-       ret = mt76x2_init_hardware(dev);
-       if (ret)
-               return ret;
-
-       for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
-               u8 *addr = dev->macaddr_list[i].addr;
-
-               memcpy(addr, dev->mt76.macaddr, ETH_ALEN);
-
-               if (!i)
-                       continue;
-
-               addr[0] |= BIT(1);
-               addr[0] ^= ((i - 1) << 2);
-       }
-       wiphy->addresses = dev->macaddr_list;
-       wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);
-
-       wiphy->iface_combinations = if_comb;
-       wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
-
-       wiphy->reg_notifier = mt76x2_regd_notifier;
-
-       wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_AP) |
-#ifdef CONFIG_MAC80211_MESH
-               BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
-               BIT(NL80211_IFTYPE_ADHOC);
-
-       wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
-
-       mt76x2_dfs_init_detector(dev);
-
-       /* init led callbacks */
-       dev->mt76.led_cdev.brightness_set = mt76x2_led_set_brightness;
-       dev->mt76.led_cdev.blink_set = mt76x2_led_set_blink;
-
-       ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,
-                                  ARRAY_SIZE(mt76x02_rates));
-       if (ret)
-               goto fail;
-
-       mt76x2_init_debugfs(dev);
-       mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
-       mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
-
-       return 0;
-
-fail:
-       mt76x2_stop_hardware(dev);
-       return ret;
-}
-
-
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_init_common.c
deleted file mode 100644 (file)
index f4c4cde..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x02_phy.h"
-
-static void
-mt76x2_set_wlan_state(struct mt76x2_dev *dev, bool enable)
-{
-       u32 val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
-
-       if (enable)
-               val |= (MT_WLAN_FUN_CTRL_WLAN_EN |
-                       MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
-       else
-               val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN |
-                        MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
-
-       mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
-       udelay(20);
-}
-
-void mt76x2_reset_wlan(struct mt76x2_dev *dev, bool enable)
-{
-       u32 val;
-
-       if (!enable)
-               goto out;
-
-       val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
-
-       val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL;
-
-       if (val & MT_WLAN_FUN_CTRL_WLAN_EN) {
-               val |= MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
-               mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
-               udelay(20);
-
-               val &= ~MT_WLAN_FUN_CTRL_WLAN_RESET_RF;
-       }
-
-       mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
-       udelay(20);
-
-out:
-       mt76x2_set_wlan_state(dev, enable);
-}
-EXPORT_SYMBOL_GPL(mt76x2_reset_wlan);
-
-void mt76_write_mac_initvals(struct mt76x2_dev *dev)
-{
-#define DEFAULT_PROT_CFG_CCK                           \
-       (FIELD_PREP(MT_PROT_CFG_RATE, 0x3) |            \
-        FIELD_PREP(MT_PROT_CFG_NAV, 1) |               \
-        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |     \
-        MT_PROT_CFG_RTS_THRESH)
-
-#define DEFAULT_PROT_CFG_OFDM                          \
-       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |         \
-        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
-        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f) |     \
-        MT_PROT_CFG_RTS_THRESH)
-
-#define DEFAULT_PROT_CFG_20                            \
-       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2004) |         \
-        FIELD_PREP(MT_PROT_CFG_CTRL, 1) |              \
-        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
-        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x17))
-
-#define DEFAULT_PROT_CFG_40                            \
-       (FIELD_PREP(MT_PROT_CFG_RATE, 0x2084) |         \
-        FIELD_PREP(MT_PROT_CFG_CTRL, 1) |              \
-        FIELD_PREP(MT_PROT_CFG_NAV, 1) |                       \
-        FIELD_PREP(MT_PROT_CFG_TXOP_ALLOW, 0x3f))
-
-       static const struct mt76_reg_pair vals[] = {
-               /* Copied from MediaTek reference source */
-               { MT_PBF_SYS_CTRL,              0x00080c00 },
-               { MT_PBF_CFG,                   0x1efebcff },
-               { MT_FCE_PSE_CTRL,              0x00000001 },
-               { MT_MAC_SYS_CTRL,              0x0000000c },
-               { MT_MAX_LEN_CFG,               0x003e3f00 },
-               { MT_AMPDU_MAX_LEN_20M1S,       0xaaa99887 },
-               { MT_AMPDU_MAX_LEN_20M2S,       0x000000aa },
-               { MT_XIFS_TIME_CFG,             0x33a40d0a },
-               { MT_BKOFF_SLOT_CFG,            0x00000209 },
-               { MT_TBTT_SYNC_CFG,             0x00422010 },
-               { MT_PWR_PIN_CFG,               0x00000000 },
-               { 0x1238,                       0x001700c8 },
-               { MT_TX_SW_CFG0,                0x00101001 },
-               { MT_TX_SW_CFG1,                0x00010000 },
-               { MT_TX_SW_CFG2,                0x00000000 },
-               { MT_TXOP_CTRL_CFG,             0x0400583f },
-               { MT_TX_RTS_CFG,                0x00100020 },
-               { MT_TX_TIMEOUT_CFG,            0x000a2290 },
-               { MT_TX_RETRY_CFG,              0x47f01f0f },
-               { MT_EXP_ACK_TIME,              0x002c00dc },
-               { MT_TX_PROT_CFG6,              0xe3f42004 },
-               { MT_TX_PROT_CFG7,              0xe3f42084 },
-               { MT_TX_PROT_CFG8,              0xe3f42104 },
-               { MT_PIFS_TX_CFG,               0x00060fff },
-               { MT_RX_FILTR_CFG,              0x00015f97 },
-               { MT_LEGACY_BASIC_RATE,         0x0000017f },
-               { MT_HT_BASIC_RATE,             0x00004003 },
-               { MT_PN_PAD_MODE,               0x00000003 },
-               { MT_TXOP_HLDR_ET,              0x00000002 },
-               { 0xa44,                        0x00000000 },
-               { MT_HEADER_TRANS_CTRL_REG,     0x00000000 },
-               { MT_TSO_CTRL,                  0x00000000 },
-               { MT_AUX_CLK_CFG,               0x00000000 },
-               { MT_DACCLK_EN_DLY_CFG,         0x00000000 },
-               { MT_TX_ALC_CFG_4,              0x00000000 },
-               { MT_TX_ALC_VGA3,               0x00000000 },
-               { MT_TX_PWR_CFG_0,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_1,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_2,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_3,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_4,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_7,              0x3a3a3a3a },
-               { MT_TX_PWR_CFG_8,              0x0000003a },
-               { MT_TX_PWR_CFG_9,              0x0000003a },
-               { MT_EFUSE_CTRL,                0x0000d000 },
-               { MT_PAUSE_ENABLE_CONTROL1,     0x0000000a },
-               { MT_FCE_WLAN_FLOW_CONTROL1,    0x60401c18 },
-               { MT_WPDMA_DELAY_INT_CFG,       0x94ff0000 },
-               { MT_TX_SW_CFG3,                0x00000004 },
-               { MT_HT_FBK_TO_LEGACY,          0x00001818 },
-               { MT_VHT_HT_FBK_CFG1,           0xedcba980 },
-               { MT_PROT_AUTO_TX_CFG,          0x00830083 },
-               { MT_HT_CTRL_CFG,               0x000001ff },
-       };
-       struct mt76_reg_pair prot_vals[] = {
-               { MT_CCK_PROT_CFG,              DEFAULT_PROT_CFG_CCK },
-               { MT_OFDM_PROT_CFG,             DEFAULT_PROT_CFG_OFDM },
-               { MT_MM20_PROT_CFG,             DEFAULT_PROT_CFG_20 },
-               { MT_MM40_PROT_CFG,             DEFAULT_PROT_CFG_40 },
-               { MT_GF20_PROT_CFG,             DEFAULT_PROT_CFG_20 },
-               { MT_GF40_PROT_CFG,             DEFAULT_PROT_CFG_40 },
-       };
-
-       mt76_wr_rp(dev, 0, vals, ARRAY_SIZE(vals));
-       mt76_wr_rp(dev, 0, prot_vals, ARRAY_SIZE(prot_vals));
-}
-EXPORT_SYMBOL_GPL(mt76_write_mac_initvals);
-
-void mt76x2_init_device(struct mt76x2_dev *dev)
-{
-       struct ieee80211_hw *hw = mt76_hw(dev);
-
-       hw->queues = 4;
-       hw->max_rates = 1;
-       hw->max_report_rates = 7;
-       hw->max_rate_tries = 1;
-       hw->extra_tx_headroom = 2;
-
-       hw->sta_data_size = sizeof(struct mt76x02_sta);
-       hw->vif_data_size = sizeof(struct mt76x02_vif);
-
-       ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
-       ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
-
-       dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
-       dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING;
-
-       dev->mt76.chainmask = 0x202;
-       dev->mt76.global_wcid.idx = 255;
-       dev->mt76.global_wcid.hw_key_idx = -1;
-       dev->slottime = 9;
-
-       /* init antenna configuration */
-       dev->mt76.antenna_mask = 3;
-}
-EXPORT_SYMBOL_GPL(mt76x2_init_device);
-
-void mt76x2_init_txpower(struct mt76x2_dev *dev,
-                        struct ieee80211_supported_band *sband)
-{
-       struct ieee80211_channel *chan;
-       struct mt76x2_tx_power_info txp;
-       struct mt76_rate_power t = {};
-       int target_power;
-       int i;
-
-       for (i = 0; i < sband->n_channels; i++) {
-               chan = &sband->channels[i];
-
-               mt76x2_get_power_info(dev, &txp, chan);
-
-               target_power = max_t(int, (txp.chain[0].target_power +
-                                          txp.chain[0].delta),
-                                         (txp.chain[1].target_power +
-                                          txp.chain[1].delta));
-
-               mt76x2_get_rate_power(dev, &t, chan);
-
-               chan->max_power = mt76x02_get_max_rate_power(&t) +
-                                 target_power;
-               chan->max_power /= 2;
-
-               /* convert to combined output power on 2x2 devices */
-               chan->max_power += 3;
-       }
-}
-EXPORT_SYMBOL_GPL(mt76x2_init_txpower);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.c
deleted file mode 100644 (file)
index bb9c0a0..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/delay.h>
-#include "mt76x2.h"
-#include "mt76x2_mcu.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x2_trace.h"
-#include "mt76x02_util.h"
-
-void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr)
-{
-       idx &= 7;
-       mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
-       mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
-                      get_unaligned_le16(addr + 4));
-}
-
-void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq)
-{
-       struct mt76x02_tx_status stat = {};
-       unsigned long flags;
-       u8 update = 1;
-       bool ret;
-
-       if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
-               return;
-
-       trace_mac_txstat_poll(dev);
-
-       while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) {
-               spin_lock_irqsave(&dev->mt76.mmio.irq_lock, flags);
-               ret = mt76x02_mac_load_tx_status(&dev->mt76, &stat);
-               spin_unlock_irqrestore(&dev->mt76.mmio.irq_lock, flags);
-
-               if (!ret)
-                       break;
-
-               trace_mac_txstat_fetch(dev, &stat);
-
-               if (!irq) {
-                       mt76x02_send_tx_status(&dev->mt76, &stat, &update);
-                       continue;
-               }
-
-               kfifo_put(&dev->txstatus_fifo, stat);
-       }
-}
-
-static void
-mt76x2_mac_queue_txdone(struct mt76x2_dev *dev, struct sk_buff *skb,
-                       void *txwi_ptr)
-{
-       struct mt76x2_tx_info *txi = mt76x2_skb_tx_info(skb);
-       struct mt76x02_txwi *txwi = txwi_ptr;
-
-       mt76x2_mac_poll_tx_status(dev, false);
-
-       txi->tries = 0;
-       txi->jiffies = jiffies;
-       txi->wcid = txwi->wcid;
-       txi->pktid = txwi->pktid;
-       trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);
-       mt76x02_tx_complete(&dev->mt76, skb);
-}
-
-void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev)
-{
-       struct mt76x02_tx_status stat;
-       u8 update = 1;
-
-       while (kfifo_get(&dev->txstatus_fifo, &stat))
-               mt76x02_send_tx_status(&dev->mt76, &stat, &update);
-}
-
-void mt76x2_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
-                           struct mt76_queue_entry *e, bool flush)
-{
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-
-       if (e->txwi)
-               mt76x2_mac_queue_txdone(dev, e->skb, &e->txwi->txwi);
-       else
-               dev_kfree_skb_any(e->skb);
-}
-
-static int
-mt76_write_beacon(struct mt76x2_dev *dev, int offset, struct sk_buff *skb)
-{
-       int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
-       struct mt76x02_txwi txwi;
-
-       if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
-               return -ENOSPC;
-
-       mt76x2_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
-
-       mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
-       offset += sizeof(txwi);
-
-       mt76_wr_copy(dev, offset, skb->data, skb->len);
-       return 0;
-}
-
-static int
-__mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 bcn_idx, struct sk_buff *skb)
-{
-       int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
-       int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
-       int ret = 0;
-       int i;
-
-       /* Prevent corrupt transmissions during update */
-       mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
-
-       if (skb) {
-               ret = mt76_write_beacon(dev, beacon_addr, skb);
-               if (!ret)
-                       dev->beacon_data_mask |= BIT(bcn_idx);
-       } else {
-               dev->beacon_data_mask &= ~BIT(bcn_idx);
-               for (i = 0; i < beacon_len; i += 4)
-                       mt76_wr(dev, beacon_addr + i, 0);
-       }
-
-       mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
-
-       return ret;
-}
-
-int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx,
-                         struct sk_buff *skb)
-{
-       bool force_update = false;
-       int bcn_idx = 0;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
-               if (vif_idx == i) {
-                       force_update = !!dev->beacons[i] ^ !!skb;
-
-                       if (dev->beacons[i])
-                               dev_kfree_skb(dev->beacons[i]);
-
-                       dev->beacons[i] = skb;
-                       __mt76x2_mac_set_beacon(dev, bcn_idx, skb);
-               } else if (force_update && dev->beacons[i]) {
-                       __mt76x2_mac_set_beacon(dev, bcn_idx, dev->beacons[i]);
-               }
-
-               bcn_idx += !!dev->beacons[i];
-       }
-
-       for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
-               if (!(dev->beacon_data_mask & BIT(i)))
-                       break;
-
-               __mt76x2_mac_set_beacon(dev, i, NULL);
-       }
-
-       mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
-                      bcn_idx - 1);
-       return 0;
-}
-
-void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val)
-{
-       u8 old_mask = dev->beacon_mask;
-       bool en;
-       u32 reg;
-
-       if (val) {
-               dev->beacon_mask |= BIT(vif_idx);
-       } else {
-               dev->beacon_mask &= ~BIT(vif_idx);
-               mt76x2_mac_set_beacon(dev, vif_idx, NULL);
-       }
-
-       if (!!old_mask == !!dev->beacon_mask)
-               return;
-
-       en = dev->beacon_mask;
-
-       mt76_rmw_field(dev, MT_INT_TIMER_EN, MT_INT_TIMER_EN_PRE_TBTT_EN, en);
-       reg = MT_BEACON_TIME_CFG_BEACON_TX |
-             MT_BEACON_TIME_CFG_TBTT_EN |
-             MT_BEACON_TIME_CFG_TIMER_EN;
-       mt76_rmw(dev, MT_BEACON_TIME_CFG, reg, reg * en);
-
-       if (en)
-               mt76x02_irq_enable(&dev->mt76, MT_INT_PRE_TBTT | MT_INT_TBTT);
-       else
-               mt76x02_irq_disable(&dev->mt76, MT_INT_PRE_TBTT | MT_INT_TBTT);
-}
-
-void mt76x2_update_channel(struct mt76_dev *mdev)
-{
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-       struct mt76_channel_state *state;
-       u32 active, busy;
-
-       state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan);
-
-       busy = mt76_rr(dev, MT_CH_BUSY);
-       active = busy + mt76_rr(dev, MT_CH_IDLE);
-
-       spin_lock_bh(&dev->mt76.cc_lock);
-       state->cc_busy += busy;
-       state->cc_active += active;
-       spin_unlock_bh(&dev->mt76.cc_lock);
-}
-
-void mt76x2_mac_work(struct work_struct *work)
-{
-       struct mt76x2_dev *dev = container_of(work, struct mt76x2_dev,
-                                           mac_work.work);
-       int i, idx;
-
-       mt76x2_update_channel(&dev->mt76);
-       for (i = 0, idx = 0; i < 16; i++) {
-               u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
-
-               dev->aggr_stats[idx++] += val & 0xffff;
-               dev->aggr_stats[idx++] += val >> 16;
-       }
-
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
-                                    MT_CALIBRATE_INTERVAL);
-}
-
-void mt76x2_mac_set_tx_protection(struct mt76x2_dev *dev, u32 val)
-{
-       u32 data = 0;
-
-       if (val != ~0)
-               data = FIELD_PREP(MT_PROT_CFG_CTRL, 1) |
-                      MT_PROT_CFG_RTS_THRESH;
-
-       mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, val);
-
-       mt76_rmw(dev, MT_CCK_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_OFDM_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_MM20_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_MM40_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_GF20_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_GF40_PROT_CFG,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_TX_PROT_CFG6,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_TX_PROT_CFG7,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-       mt76_rmw(dev, MT_TX_PROT_CFG8,
-                MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mac.h
deleted file mode 100644 (file)
index 66a5729..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2_MAC_H
-#define __MT76x2_MAC_H
-
-#include "mt76.h"
-#include "mt76x02_mac.h"
-
-struct mt76x2_dev;
-struct mt76x2_sta;
-struct mt76x02_vif;
-
-struct mt76x2_tx_info {
-       unsigned long jiffies;
-       u8 tries;
-
-       u8 wcid;
-       u8 pktid;
-       u8 retry;
-};
-
-static inline struct mt76x2_tx_info *
-mt76x2_skb_tx_info(struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-
-       return (void *) info->status.status_driver_data;
-}
-
-int mt76x2_mac_start(struct mt76x2_dev *dev);
-void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force);
-void mt76x2_mac_resume(struct mt76x2_dev *dev);
-void mt76x2_mac_set_bssid(struct mt76x2_dev *dev, u8 idx, const u8 *addr);
-
-int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
-                         void *rxi);
-void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi,
-                          struct sk_buff *skb, struct mt76_wcid *wcid,
-                          struct ieee80211_sta *sta, int len);
-
-int mt76x2_mac_set_beacon(struct mt76x2_dev *dev, u8 vif_idx,
-                         struct sk_buff *skb);
-void mt76x2_mac_set_beacon_enable(struct mt76x2_dev *dev, u8 vif_idx, bool val);
-
-void mt76x2_mac_poll_tx_status(struct mt76x2_dev *dev, bool irq);
-void mt76x2_mac_process_tx_status_fifo(struct mt76x2_dev *dev);
-
-void mt76x2_mac_work(struct work_struct *work);
-
-#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mac_common.c
deleted file mode 100644 (file)
index ed4f56a..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_util.h"
-
-void mt76x2_mac_stop(struct mt76x2_dev *dev, bool force)
-{
-       bool stopped = false;
-       u32 rts_cfg;
-       int i;
-
-       mt76_wr(dev, MT_MAC_SYS_CTRL, 0);
-
-       rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
-       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
-
-       /* Wait for MAC to become idle */
-       for (i = 0; i < 300; i++) {
-               if ((mt76_rr(dev, MT_MAC_STATUS) &
-                    (MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) ||
-                   mt76_rr(dev, MT_BBP(IBI, 12))) {
-                       udelay(1);
-                       continue;
-               }
-
-               stopped = true;
-               break;
-       }
-
-       if (force && !stopped) {
-               mt76_set(dev, MT_BBP(CORE, 4), BIT(1));
-               mt76_clear(dev, MT_BBP(CORE, 4), BIT(1));
-
-               mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
-               mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
-       }
-
-       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mac_stop);
-
-void mt76x2_mac_write_txwi(struct mt76x2_dev *dev, struct mt76x02_txwi *txwi,
-                          struct sk_buff *skb, struct mt76_wcid *wcid,
-                          struct ieee80211_sta *sta, int len)
-{
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rate = &info->control.rates[0];
-       struct ieee80211_key_conf *key = info->control.hw_key;
-       u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
-       u8 nss;
-       s8 txpwr_adj, max_txpwr_adj;
-       u8 ccmp_pn[8];
-
-       memset(txwi, 0, sizeof(*txwi));
-
-       if (wcid)
-               txwi->wcid = wcid->idx;
-       else
-               txwi->wcid = 0xff;
-
-       txwi->pktid = 1;
-
-       if (wcid && wcid->sw_iv && key) {
-               u64 pn = atomic64_inc_return(&key->tx_pn);
-               ccmp_pn[0] = pn;
-               ccmp_pn[1] = pn >> 8;
-               ccmp_pn[2] = 0;
-               ccmp_pn[3] = 0x20 | (key->keyidx << 6);
-               ccmp_pn[4] = pn >> 16;
-               ccmp_pn[5] = pn >> 24;
-               ccmp_pn[6] = pn >> 32;
-               ccmp_pn[7] = pn >> 40;
-               txwi->iv = *((__le32 *)&ccmp_pn[0]);
-               txwi->eiv = *((__le32 *)&ccmp_pn[1]);
-       }
-
-       spin_lock_bh(&dev->mt76.lock);
-       if (wcid && (rate->idx < 0 || !rate->count)) {
-               txwi->rate = wcid->tx_rate;
-               max_txpwr_adj = wcid->max_txpwr_adj;
-               nss = wcid->tx_rate_nss;
-       } else {
-               txwi->rate = mt76x02_mac_tx_rate_val(&dev->mt76, rate, &nss);
-               max_txpwr_adj = mt76x2_tx_get_max_txpwr_adj(&dev->mt76, rate);
-       }
-       spin_unlock_bh(&dev->mt76.lock);
-
-       txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf,
-                                           max_txpwr_adj);
-       txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj);
-
-       if (mt76xx_rev(dev) >= MT76XX_REV_E4)
-               txwi->txstream = 0x13;
-       else if (mt76xx_rev(dev) >= MT76XX_REV_E3 &&
-                !(txwi->rate & cpu_to_le16(rate_ht_mask)))
-               txwi->txstream = 0x93;
-
-       mt76x02_mac_fill_txwi(txwi, skb, sta, len, nss);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mac_write_txwi);
-
-int mt76x2_mac_get_rssi(struct mt76x2_dev *dev, s8 rssi, int chain)
-{
-       struct mt76x2_rx_freq_cal *cal = &dev->cal.rx;
-
-       rssi += cal->rssi_offset[chain];
-       rssi -= cal->lna_gain;
-
-       return rssi;
-}
-
-static struct mt76x02_sta *
-mt76x2_rx_get_sta(struct mt76x2_dev *dev, u8 idx)
-{
-       struct mt76_wcid *wcid;
-
-       if (idx >= ARRAY_SIZE(dev->mt76.wcid))
-               return NULL;
-
-       wcid = rcu_dereference(dev->mt76.wcid[idx]);
-       if (!wcid)
-               return NULL;
-
-       return container_of(wcid, struct mt76x02_sta, wcid);
-}
-
-static struct mt76_wcid *
-mt76x2_rx_get_sta_wcid(struct mt76x2_dev *dev, struct mt76x02_sta *sta,
-                      bool unicast)
-{
-       if (!sta)
-               return NULL;
-
-       if (unicast)
-               return &sta->wcid;
-       else
-               return &sta->vif->group_wcid;
-}
-
-int mt76x2_mac_process_rx(struct mt76x2_dev *dev, struct sk_buff *skb,
-                         void *rxi)
-{
-       struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
-       struct mt76x02_rxwi *rxwi = rxi;
-       struct mt76x02_sta *sta;
-       u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
-       u32 ctl = le32_to_cpu(rxwi->ctl);
-       u16 rate = le16_to_cpu(rxwi->rate);
-       u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
-       bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
-       int pad_len = 0;
-       u8 pn_len;
-       u8 wcid;
-       int len;
-
-       if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
-               return -EINVAL;
-
-       if (rxinfo & MT_RXINFO_L2PAD)
-               pad_len += 2;
-
-       if (rxinfo & MT_RXINFO_DECRYPT) {
-               status->flag |= RX_FLAG_DECRYPTED;
-               status->flag |= RX_FLAG_MMIC_STRIPPED;
-               status->flag |= RX_FLAG_MIC_STRIPPED;
-               status->flag |= RX_FLAG_IV_STRIPPED;
-       }
-
-       wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
-       sta = mt76x2_rx_get_sta(dev, wcid);
-       status->wcid = mt76x2_rx_get_sta_wcid(dev, sta, unicast);
-
-       len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
-       pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
-       if (pn_len) {
-               int offset = ieee80211_get_hdrlen_from_skb(skb) + pad_len;
-               u8 *data = skb->data + offset;
-
-               status->iv[0] = data[7];
-               status->iv[1] = data[6];
-               status->iv[2] = data[5];
-               status->iv[3] = data[4];
-               status->iv[4] = data[1];
-               status->iv[5] = data[0];
-
-               /*
-                * Driver CCMP validation can't deal with fragments.
-                * Let mac80211 take care of it.
-                */
-               if (rxinfo & MT_RXINFO_FRAG) {
-                       status->flag &= ~RX_FLAG_IV_STRIPPED;
-               } else {
-                       pad_len += pn_len << 2;
-                       len -= pn_len << 2;
-               }
-       }
-
-       mt76x02_remove_hdr_pad(skb, pad_len);
-
-       if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
-               status->aggr = true;
-
-       if (WARN_ON_ONCE(len > skb->len))
-               return -EINVAL;
-
-       pskb_trim(skb, len);
-       status->chains = BIT(0) | BIT(1);
-       status->chain_signal[0] = mt76x2_mac_get_rssi(dev, rxwi->rssi[0], 0);
-       status->chain_signal[1] = mt76x2_mac_get_rssi(dev, rxwi->rssi[1], 1);
-       status->signal = max(status->chain_signal[0], status->chain_signal[1]);
-       status->freq = dev->mt76.chandef.chan->center_freq;
-       status->band = dev->mt76.chandef.chan->band;
-
-       status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
-       status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
-
-       if (sta) {
-               ewma_signal_add(&sta->rssi, status->signal);
-               sta->inactive_count = 0;
-       }
-
-       return mt76x02_mac_process_rate(status, rate);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mac_process_rx);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2_main.c
deleted file mode 100644 (file)
index 63691b6..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_util.h"
-
-static int
-mt76x2_start(struct ieee80211_hw *hw)
-{
-       struct mt76x2_dev *dev = hw->priv;
-       int ret;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       ret = mt76x2_mac_start(dev);
-       if (ret)
-               goto out;
-
-       ret = mt76x2_phy_start(dev);
-       if (ret)
-               goto out;
-
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
-                                    MT_CALIBRATE_INTERVAL);
-
-       set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-
-out:
-       mutex_unlock(&dev->mt76.mutex);
-       return ret;
-}
-
-static void
-mt76x2_stop(struct ieee80211_hw *hw)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       mutex_lock(&dev->mt76.mutex);
-       clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-       mt76x2_stop_hardware(dev);
-       mutex_unlock(&dev->mt76.mutex);
-}
-
-static int
-mt76x2_set_channel(struct mt76x2_dev *dev, struct cfg80211_chan_def *chandef)
-{
-       int ret;
-
-       cancel_delayed_work_sync(&dev->cal_work);
-
-       set_bit(MT76_RESET, &dev->mt76.state);
-
-       mt76_set_channel(&dev->mt76);
-
-       tasklet_disable(&dev->pre_tbtt_tasklet);
-       tasklet_disable(&dev->dfs_pd.dfs_tasklet);
-
-       mt76x2_mac_stop(dev, true);
-       ret = mt76x2_phy_set_channel(dev, chandef);
-
-       /* channel cycle counters read-and-clear */
-       mt76_rr(dev, MT_CH_IDLE);
-       mt76_rr(dev, MT_CH_BUSY);
-
-       mt76x2_dfs_init_params(dev);
-
-       mt76x2_mac_resume(dev);
-       tasklet_enable(&dev->dfs_pd.dfs_tasklet);
-       tasklet_enable(&dev->pre_tbtt_tasklet);
-
-       clear_bit(MT76_RESET, &dev->mt76.state);
-
-       mt76_txq_schedule_all(&dev->mt76);
-
-       return ret;
-}
-
-static int
-mt76x2_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct mt76x2_dev *dev = hw->priv;
-       int ret = 0;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-               if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
-                       dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
-               else
-                       dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
-
-               mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               dev->mt76.txpower_conf = hw->conf.power_level * 2;
-
-               /* convert to per-chain power for 2x2 devices */
-               dev->mt76.txpower_conf -= 6;
-
-               if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state)) {
-                       mt76x2_phy_set_txpower(dev);
-                       mt76x2_tx_set_txpwr_auto(dev, dev->mt76.txpower_conf);
-               }
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               ret = mt76x2_set_channel(dev, &hw->conf.chandef);
-               ieee80211_wake_queues(hw);
-       }
-
-       mutex_unlock(&dev->mt76.mutex);
-
-       return ret;
-}
-
-static void
-mt76x2_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                       struct ieee80211_bss_conf *info, u32 changed)
-{
-       struct mt76x2_dev *dev = hw->priv;
-       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       if (changed & BSS_CHANGED_BSSID)
-               mt76x2_mac_set_bssid(dev, mvif->idx, info->bssid);
-
-       if (changed & BSS_CHANGED_BEACON_INT) {
-               mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
-                              MT_BEACON_TIME_CFG_INTVAL,
-                              info->beacon_int << 4);
-               dev->beacon_int = info->beacon_int;
-               dev->tbtt_count = 0;
-       }
-
-       if (changed & BSS_CHANGED_BEACON_ENABLED) {
-               tasklet_disable(&dev->pre_tbtt_tasklet);
-               mt76x2_mac_set_beacon_enable(dev, mvif->idx,
-                                            info->enable_beacon);
-               tasklet_enable(&dev->pre_tbtt_tasklet);
-       }
-
-       if (changed & BSS_CHANGED_ERP_SLOT) {
-               int slottime = info->use_short_slot ? 9 : 20;
-
-               dev->slottime = slottime;
-               mt76x2_set_tx_ackto(dev);
-       }
-
-       mutex_unlock(&dev->mt76.mutex);
-}
-
-void
-mt76x2_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
-{
-       struct mt76x02_sta *msta = (struct mt76x02_sta *) sta->drv_priv;
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-       int idx = msta->wcid.idx;
-
-       mt76_stop_tx_queues(&dev->mt76, sta, true);
-       mt76x02_mac_wcid_set_drop(&dev->mt76, idx, ps);
-}
-
-static void
-mt76x2_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-              const u8 *mac)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       tasklet_disable(&dev->pre_tbtt_tasklet);
-       set_bit(MT76_SCANNING, &dev->mt76.state);
-}
-
-static void
-mt76x2_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       clear_bit(MT76_SCANNING, &dev->mt76.state);
-       tasklet_enable(&dev->pre_tbtt_tasklet);
-}
-
-static void
-mt76x2_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-            u32 queues, bool drop)
-{
-}
-
-static int
-mt76x2_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       *dbm = dev->mt76.txpower_cur / 2;
-
-       /* convert from per-chain power to combined output on 2x2 devices */
-       *dbm += 3;
-
-       return 0;
-}
-
-static void mt76x2_set_coverage_class(struct ieee80211_hw *hw,
-                                     s16 coverage_class)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       mutex_lock(&dev->mt76.mutex);
-       dev->coverage_class = coverage_class;
-       mt76x2_set_tx_ackto(dev);
-       mutex_unlock(&dev->mt76.mutex);
-}
-
-static int
-mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
-{
-       return 0;
-}
-
-static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
-                             u32 rx_ant)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       if (!tx_ant || tx_ant > 3 || tx_ant != rx_ant)
-               return -EINVAL;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       dev->mt76.chainmask = (tx_ant == 3) ? 0x202 : 0x101;
-       dev->mt76.antenna_mask = tx_ant;
-
-       mt76_set_stream_caps(&dev->mt76, true);
-       mt76x2_phy_set_antenna(dev);
-
-       mutex_unlock(&dev->mt76.mutex);
-
-       return 0;
-}
-
-static int mt76x2_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
-                             u32 *rx_ant)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       mutex_lock(&dev->mt76.mutex);
-       *tx_ant = dev->mt76.antenna_mask;
-       *rx_ant = dev->mt76.antenna_mask;
-       mutex_unlock(&dev->mt76.mutex);
-
-       return 0;
-}
-
-static int
-mt76x2_set_rts_threshold(struct ieee80211_hw *hw, u32 val)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       if (val != ~0 && val > 0xffff)
-               return -EINVAL;
-
-       mutex_lock(&dev->mutex);
-       mt76x2_mac_set_tx_protection(dev, val);
-       mutex_unlock(&dev->mutex);
-
-       return 0;
-}
-
-const struct ieee80211_ops mt76x2_ops = {
-       .tx = mt76x2_tx,
-       .start = mt76x2_start,
-       .stop = mt76x2_stop,
-       .add_interface = mt76x02_add_interface,
-       .remove_interface = mt76x02_remove_interface,
-       .config = mt76x2_config,
-       .configure_filter = mt76x02_configure_filter,
-       .bss_info_changed = mt76x2_bss_info_changed,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
-       .set_key = mt76x02_set_key,
-       .conf_tx = mt76x02_conf_tx,
-       .sw_scan_start = mt76x2_sw_scan,
-       .sw_scan_complete = mt76x2_sw_scan_complete,
-       .flush = mt76x2_flush,
-       .ampdu_action = mt76x02_ampdu_action,
-       .get_txpower = mt76x2_get_txpower,
-       .wake_tx_queue = mt76_wake_tx_queue,
-       .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
-       .release_buffered_frames = mt76_release_buffered_frames,
-       .set_coverage_class = mt76x2_set_coverage_class,
-       .get_survey = mt76_get_survey,
-       .set_tim = mt76x2_set_tim,
-       .set_antenna = mt76x2_set_antenna,
-       .get_antenna = mt76x2_get_antenna,
-       .set_rts_threshold = mt76x2_set_rts_threshold,
-};
-
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.c
deleted file mode 100644 (file)
index 55716fd..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/kernel.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-
-#include "mt76x2.h"
-#include "mt76x2_mcu.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x02_dma.h"
-
-static int
-mt76pci_load_rom_patch(struct mt76x2_dev *dev)
-{
-       const struct firmware *fw = NULL;
-       struct mt76x02_patch_header *hdr;
-       bool rom_protect = !is_mt7612(dev);
-       int len, ret = 0;
-       __le32 *cur;
-       u32 patch_mask, patch_reg;
-
-       if (rom_protect && !mt76_poll(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
-               dev_err(dev->mt76.dev,
-                       "Could not get hardware semaphore for ROM PATCH\n");
-               return -ETIMEDOUT;
-       }
-
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
-               patch_mask = BIT(0);
-               patch_reg = MT_MCU_CLOCK_CTL;
-       } else {
-               patch_mask = BIT(1);
-               patch_reg = MT_MCU_COM_REG0;
-       }
-
-       if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
-               dev_info(dev->mt76.dev, "ROM patch already applied\n");
-               goto out;
-       }
-
-       ret = request_firmware(&fw, MT7662_ROM_PATCH, dev->mt76.dev);
-       if (ret)
-               goto out;
-
-       if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
-               ret = -EIO;
-               dev_err(dev->mt76.dev, "Failed to load firmware\n");
-               goto out;
-       }
-
-       hdr = (struct mt76x02_patch_header *)fw->data;
-       dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
-
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ROM_PATCH_OFFSET);
-
-       cur = (__le32 *) (fw->data + sizeof(*hdr));
-       len = fw->size - sizeof(*hdr);
-       mt76_wr_copy(dev, MT_MCU_ROM_PATCH_ADDR, cur, len);
-
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
-
-       /* Trigger ROM */
-       mt76_wr(dev, MT_MCU_INT_LEVEL, 4);
-
-       if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 2000)) {
-               dev_err(dev->mt76.dev, "Failed to load ROM patch\n");
-               ret = -ETIMEDOUT;
-       }
-
-out:
-       /* release semaphore */
-       if (rom_protect)
-               mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
-       release_firmware(fw);
-       return ret;
-}
-
-static int
-mt76pci_load_firmware(struct mt76x2_dev *dev)
-{
-       const struct firmware *fw;
-       const struct mt76x02_fw_header *hdr;
-       int len, ret;
-       __le32 *cur;
-       u32 offset, val;
-
-       ret = request_firmware(&fw, MT7662_FIRMWARE, dev->mt76.dev);
-       if (ret)
-               return ret;
-
-       if (!fw || !fw->data || fw->size < sizeof(*hdr))
-               goto error;
-
-       hdr = (const struct mt76x02_fw_header *)fw->data;
-
-       len = sizeof(*hdr);
-       len += le32_to_cpu(hdr->ilm_len);
-       len += le32_to_cpu(hdr->dlm_len);
-
-       if (fw->size != len)
-               goto error;
-
-       val = le16_to_cpu(hdr->fw_ver);
-       dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
-                (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
-
-       val = le16_to_cpu(hdr->build_ver);
-       dev_info(dev->mt76.dev, "Build: %x\n", val);
-       dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
-
-       cur = (__le32 *) (fw->data + sizeof(*hdr));
-       len = le32_to_cpu(hdr->ilm_len);
-
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_ILM_OFFSET);
-       mt76_wr_copy(dev, MT_MCU_ILM_ADDR, cur, len);
-
-       cur += len / sizeof(*cur);
-       len = le32_to_cpu(hdr->dlm_len);
-
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
-               offset = MT_MCU_DLM_ADDR_E3;
-       else
-               offset = MT_MCU_DLM_ADDR;
-
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, MT_MCU_DLM_OFFSET);
-       mt76_wr_copy(dev, offset, cur, len);
-
-       mt76_wr(dev, MT_MCU_PCIE_REMAP_BASE4, 0);
-
-       val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
-       if (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, val) == 1)
-               mt76_set(dev, MT_MCU_COM_REG0, BIT(30));
-
-       /* trigger firmware */
-       mt76_wr(dev, MT_MCU_INT_LEVEL, 2);
-       if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 200)) {
-               dev_err(dev->mt76.dev, "Firmware failed to start\n");
-               release_firmware(fw);
-               return -ETIMEDOUT;
-       }
-
-       dev_info(dev->mt76.dev, "Firmware running!\n");
-       mt76x02_set_ethtool_fwver(&dev->mt76, hdr);
-
-       release_firmware(fw);
-
-       return ret;
-
-error:
-       dev_err(dev->mt76.dev, "Invalid firmware\n");
-       release_firmware(fw);
-       return -ENOENT;
-}
-
-int mt76x2_mcu_init(struct mt76x2_dev *dev)
-{
-       static const struct mt76_mcu_ops mt76x2_mcu_ops = {
-               .mcu_msg_alloc = mt76x02_mcu_msg_alloc,
-               .mcu_send_msg = mt76x02_mcu_msg_send,
-       };
-       int ret;
-
-       dev->mt76.mcu_ops = &mt76x2_mcu_ops;
-
-       ret = mt76pci_load_rom_patch(dev);
-       if (ret)
-               return ret;
-
-       ret = mt76pci_load_firmware(dev);
-       if (ret)
-               return ret;
-
-       mt76x02_mcu_function_select(&dev->mt76, Q_SELECT, 1, true);
-       return 0;
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu.h
deleted file mode 100644 (file)
index fa72d5a..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2_MCU_H
-#define __MT76x2_MCU_H
-
-#include "mt76x02_mcu.h"
-
-/* Register definitions */
-#define MT_MCU_CPU_CTL                 0x0704
-#define MT_MCU_CLOCK_CTL               0x0708
-#define MT_MCU_PCIE_REMAP_BASE1                0x0740
-#define MT_MCU_PCIE_REMAP_BASE2                0x0744
-#define MT_MCU_PCIE_REMAP_BASE3                0x0748
-
-#define MT_LED_CTRL                    0x0770
-#define MT_LED_CTRL_REPLAY(_n)         BIT(0 + (8 * (_n)))
-#define MT_LED_CTRL_POLARITY(_n)       BIT(1 + (8 * (_n)))
-#define MT_LED_CTRL_TX_BLINK_MODE(_n)  BIT(2 + (8 * (_n)))
-#define MT_LED_CTRL_KICK(_n)           BIT(7 + (8 * (_n)))
-
-#define MT_LED_TX_BLINK_0              0x0774
-#define MT_LED_TX_BLINK_1              0x0778
-
-#define MT_LED_S0_BASE                 0x077C
-#define MT_LED_S0(_n)                  (MT_LED_S0_BASE + 8 * (_n))
-#define MT_LED_S1_BASE                 0x0780
-#define MT_LED_S1(_n)                  (MT_LED_S1_BASE + 8 * (_n))
-#define MT_LED_STATUS_OFF_MASK         GENMASK(31, 24)
-#define MT_LED_STATUS_OFF(_v)          (((_v) << __ffs(MT_LED_STATUS_OFF_MASK)) & \
-                                        MT_LED_STATUS_OFF_MASK)
-#define MT_LED_STATUS_ON_MASK          GENMASK(23, 16)
-#define MT_LED_STATUS_ON(_v)           (((_v) << __ffs(MT_LED_STATUS_ON_MASK)) & \
-                                        MT_LED_STATUS_ON_MASK)
-#define MT_LED_STATUS_DURATION_MASK    GENMASK(15, 8)
-#define MT_LED_STATUS_DURATION(_v)     (((_v) << __ffs(MT_LED_STATUS_DURATION_MASK)) & \
-                                        MT_LED_STATUS_DURATION_MASK)
-
-#define MT_MCU_ROM_PATCH_OFFSET                0x80000
-#define MT_MCU_ROM_PATCH_ADDR          0x90000
-
-#define MT_MCU_ILM_OFFSET              0x80000
-
-#define MT_MCU_DLM_OFFSET              0x100000
-#define MT_MCU_DLM_ADDR                        0x90000
-#define MT_MCU_DLM_ADDR_E3             0x90800
-
-enum mcu_calibration {
-       MCU_CAL_R = 1,
-       MCU_CAL_TEMP_SENSOR,
-       MCU_CAL_RXDCOC,
-       MCU_CAL_RC,
-       MCU_CAL_SX_LOGEN,
-       MCU_CAL_LC,
-       MCU_CAL_TX_LOFT,
-       MCU_CAL_TXIQ,
-       MCU_CAL_TSSI,
-       MCU_CAL_TSSI_COMP,
-       MCU_CAL_DPD,
-       MCU_CAL_RXIQC_FI,
-       MCU_CAL_RXIQC_FD,
-       MCU_CAL_PWRON,
-       MCU_CAL_TX_SHAPING,
-};
-
-enum mt76x2_mcu_cr_mode {
-       MT_RF_CR,
-       MT_BBP_CR,
-       MT_RF_BBP_CR,
-       MT_HL_TEMP_CR_UPDATE,
-};
-
-struct mt76x2_tssi_comp {
-       u8 pa_mode;
-       u8 cal_mode;
-       u16 pad;
-
-       u8 slope0;
-       u8 slope1;
-       u8 offset0;
-       u8 offset1;
-} __packed __aligned(4);
-
-int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev, struct mt76x2_tssi_comp *tssi_data);
-int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain,
-                        bool force);
-
-#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_mcu_common.c
deleted file mode 100644 (file)
index eff4833..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/kernel.h>
-#include <linux/firmware.h>
-#include <linux/delay.h>
-
-#include "mt76x2.h"
-#include "mt76x2_mcu.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x02_dma.h"
-
-int mt76x2_mcu_set_channel(struct mt76x2_dev *dev, u8 channel, u8 bw,
-                          u8 bw_index, bool scan)
-{
-       struct sk_buff *skb;
-       struct {
-               u8 idx;
-               u8 scan;
-               u8 bw;
-               u8 _pad0;
-
-               __le16 chainmask;
-               u8 ext_chan;
-               u8 _pad1;
-
-       } __packed __aligned(4) msg = {
-               .idx = channel,
-               .scan = scan,
-               .bw = bw,
-               .chainmask = cpu_to_le16(dev->mt76.chainmask),
-       };
-
-       /* first set the channel without the extension channel info */
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true);
-
-       usleep_range(5000, 10000);
-
-       msg.ext_chan = 0xe0 + bw_index;
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       return mt76_mcu_send_msg(dev, skb, CMD_SWITCH_CHANNEL_OP, true);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mcu_set_channel);
-
-int mt76x2_mcu_load_cr(struct mt76x2_dev *dev, u8 type, u8 temp_level,
-                      u8 channel)
-{
-       struct mt76_dev *mdev = &dev->mt76;
-       struct sk_buff *skb;
-       struct {
-               u8 cr_mode;
-               u8 temp;
-               u8 ch;
-               u8 _pad0;
-
-               __le32 cfg;
-       } __packed __aligned(4) msg = {
-               .cr_mode = type,
-               .temp = temp_level,
-               .ch = channel,
-       };
-       u32 val;
-
-       val = BIT(31);
-       val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_0) >> 8) & 0x00ff;
-       val |= (mt76x02_eeprom_get(mdev, MT_EE_NIC_CONF_1) << 8) & 0xff00;
-       msg.cfg = cpu_to_le32(val);
-
-       /* first set the channel without the extension channel info */
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       return mt76_mcu_send_msg(dev, skb, CMD_LOAD_CR, true);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mcu_load_cr);
-
-int mt76x2_mcu_init_gain(struct mt76x2_dev *dev, u8 channel, u32 gain,
-                        bool force)
-{
-       struct sk_buff *skb;
-       struct {
-               __le32 channel;
-               __le32 gain_val;
-       } __packed __aligned(4) msg = {
-               .channel = cpu_to_le32(channel),
-               .gain_val = cpu_to_le32(gain),
-       };
-
-       if (force)
-               msg.channel |= cpu_to_le32(BIT(31));
-
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       return mt76_mcu_send_msg(dev, skb, CMD_INIT_GAIN_OP, true);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mcu_init_gain);
-
-int mt76x2_mcu_tssi_comp(struct mt76x2_dev *dev,
-                        struct mt76x2_tssi_comp *tssi_data)
-{
-       struct sk_buff *skb;
-       struct {
-               __le32 id;
-               struct mt76x2_tssi_comp data;
-       } __packed __aligned(4) msg = {
-               .id = cpu_to_le32(MCU_CAL_TSSI_COMP),
-               .data = *tssi_data,
-       };
-
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       return mt76_mcu_send_msg(dev, skb, CMD_CALIBRATION_OP, true);
-}
-EXPORT_SYMBOL_GPL(mt76x2_mcu_tssi_comp);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2_pci.c
deleted file mode 100644 (file)
index 26cfda2..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-
-#include "mt76x2.h"
-#include "mt76x2_trace.h"
-
-static const struct pci_device_id mt76pci_device_table[] = {
-       { PCI_DEVICE(0x14c3, 0x7662) },
-       { PCI_DEVICE(0x14c3, 0x7612) },
-       { PCI_DEVICE(0x14c3, 0x7602) },
-       { },
-};
-
-static int
-mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       struct mt76x2_dev *dev;
-       int ret;
-
-       ret = pcim_enable_device(pdev);
-       if (ret)
-               return ret;
-
-       ret = pcim_iomap_regions(pdev, BIT(0), pci_name(pdev));
-       if (ret)
-               return ret;
-
-       pci_set_master(pdev);
-
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret)
-               return ret;
-
-       dev = mt76x2_alloc_device(&pdev->dev);
-       if (!dev)
-               return -ENOMEM;
-
-       mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]);
-       mt76x2_reset_wlan(dev, false);
-
-       dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION);
-       dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev);
-
-       ret = devm_request_irq(dev->mt76.dev, pdev->irq, mt76x2_irq_handler,
-                              IRQF_SHARED, KBUILD_MODNAME, dev);
-       if (ret)
-               goto error;
-
-       ret = mt76x2_register_device(dev);
-       if (ret)
-               goto error;
-
-       /* Fix up ASPM configuration */
-
-       /* RG_SSUSB_G1_CDR_BIR_LTR = 0x9 */
-       mt76_rmw_field(dev, 0x15a10, 0x1f << 16, 0x9);
-
-       /* RG_SSUSB_G1_CDR_BIC_LTR = 0xf */
-       mt76_rmw_field(dev, 0x15a0c, 0xf << 28, 0xf);
-
-       /* RG_SSUSB_CDR_BR_PE1D = 0x3 */
-       mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3);
-
-       return 0;
-
-error:
-       ieee80211_free_hw(mt76_hw(dev));
-       return ret;
-}
-
-static void
-mt76pci_remove(struct pci_dev *pdev)
-{
-       struct mt76_dev *mdev = pci_get_drvdata(pdev);
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-
-       mt76_unregister_device(mdev);
-       mt76x2_cleanup(dev);
-       ieee80211_free_hw(mdev->hw);
-}
-
-MODULE_DEVICE_TABLE(pci, mt76pci_device_table);
-MODULE_FIRMWARE(MT7662_FIRMWARE);
-MODULE_FIRMWARE(MT7662_ROM_PATCH);
-MODULE_LICENSE("Dual BSD/GPL");
-
-static struct pci_driver mt76pci_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = mt76pci_device_table,
-       .probe          = mt76pci_probe,
-       .remove         = mt76pci_remove,
-};
-
-module_pci_driver(mt76pci_driver);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy.c
deleted file mode 100644 (file)
index 22e6600..0000000
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/delay.h>
-#include "mt76x2.h"
-#include "mt76x2_mcu.h"
-#include "mt76x2_eeprom.h"
-
-static bool
-mt76x2_phy_tssi_init_cal(struct mt76x2_dev *dev)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       u32 flag = 0;
-
-       if (!mt76x02_tssi_enabled(&dev->mt76))
-               return false;
-
-       if (mt76x2_channel_silent(dev))
-               return false;
-
-       if (chan->band == NL80211_BAND_5GHZ)
-               flag |= BIT(0);
-
-       if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
-               flag |= BIT(8);
-
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI, flag, true);
-       dev->cal.tssi_cal_done = true;
-       return true;
-}
-
-static void
-mt76x2_phy_channel_calibrate(struct mt76x2_dev *dev, bool mac_stopped)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
-
-       if (dev->cal.channel_cal_done)
-               return;
-
-       if (mt76x2_channel_silent(dev))
-               return;
-
-       if (!dev->cal.tssi_cal_done)
-               mt76x2_phy_tssi_init_cal(dev);
-
-       if (!mac_stopped)
-               mt76x2_mac_stop(dev, false);
-
-       if (is_5ghz)
-               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, true);
-
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, true);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, true);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, true);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, true);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_SHAPING, 0, true);
-
-       if (!mac_stopped)
-               mt76x2_mac_resume(dev);
-
-       mt76x2_apply_gain_adj(dev);
-
-       dev->cal.channel_cal_done = true;
-}
-
-void mt76x2_phy_set_antenna(struct mt76x2_dev *dev)
-{
-       u32 val;
-
-       val = mt76_rr(dev, MT_BBP(AGC, 0));
-       val &= ~(BIT(4) | BIT(1));
-       switch (dev->mt76.antenna_mask) {
-       case 1:
-               /* disable mac DAC control */
-               mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
-               mt76_clear(dev, MT_BBP(TXBE, 5), 3);
-               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3);
-               mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2);
-               /* disable DAC 1 */
-               mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4);
-
-               val &= ~(BIT(3) | BIT(0));
-               break;
-       case 2:
-               /* disable mac DAC control */
-               mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
-               mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1);
-               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc);
-               mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1);
-               /* disable DAC 0 */
-               mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1);
-
-               val &= ~BIT(3);
-               val |= BIT(0);
-               break;
-       case 3:
-       default:
-               /* enable mac DAC control */
-               mt76_set(dev, MT_BBP(IBI, 9), BIT(11));
-               mt76_set(dev, MT_BBP(TXBE, 5), 3);
-               mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf);
-               mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20));
-               mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9));
-
-               val &= ~BIT(0);
-               val |= BIT(3);
-               break;
-       }
-       mt76_wr(dev, MT_BBP(AGC, 0), val);
-}
-
-static void
-mt76x2_get_agc_gain(struct mt76x2_dev *dev, u8 *dest)
-{
-       dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN);
-       dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN);
-}
-
-static int
-mt76x2_get_rssi_gain_thresh(struct mt76x2_dev *dev)
-{
-       switch (dev->mt76.chandef.width) {
-       case NL80211_CHAN_WIDTH_80:
-               return -62;
-       case NL80211_CHAN_WIDTH_40:
-               return -65;
-       default:
-               return -68;
-       }
-}
-
-static int
-mt76x2_get_low_rssi_gain_thresh(struct mt76x2_dev *dev)
-{
-       switch (dev->mt76.chandef.width) {
-       case NL80211_CHAN_WIDTH_80:
-               return -76;
-       case NL80211_CHAN_WIDTH_40:
-               return -79;
-       default:
-               return -82;
-       }
-}
-
-static void
-mt76x2_phy_set_gain_val(struct mt76x2_dev *dev)
-{
-       u32 val;
-       u8 gain_val[2];
-
-       gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
-       gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust;
-
-       if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40)
-               val = 0x1e42 << 16;
-       else
-               val = 0x1836 << 16;
-
-       val |= 0xf8;
-
-       mt76_wr(dev, MT_BBP(AGC, 8),
-               val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0]));
-       mt76_wr(dev, MT_BBP(AGC, 9),
-               val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1]));
-
-       if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR)
-               mt76x2_dfs_adjust_agc(dev);
-}
-
-static void
-mt76x2_phy_adjust_vga_gain(struct mt76x2_dev *dev)
-{
-       u32 false_cca;
-       u8 limit = dev->cal.low_gain > 0 ? 16 : 4;
-
-       false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1));
-       dev->cal.false_cca = false_cca;
-       if (false_cca > 800 && dev->cal.agc_gain_adjust < limit)
-               dev->cal.agc_gain_adjust += 2;
-       else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) ||
-                (dev->cal.agc_gain_adjust >= limit && false_cca < 500))
-               dev->cal.agc_gain_adjust -= 2;
-       else
-               return;
-
-       mt76x2_phy_set_gain_val(dev);
-}
-
-static void
-mt76x2_phy_update_channel_gain(struct mt76x2_dev *dev)
-{
-       u8 *gain = dev->cal.agc_gain_init;
-       u8 low_gain_delta, gain_delta;
-       bool gain_change;
-       int low_gain;
-       u32 val;
-
-       dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
-
-       low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) +
-                  (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev));
-
-       gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2);
-       dev->cal.low_gain = low_gain;
-
-       if (!gain_change) {
-               mt76x2_phy_adjust_vga_gain(dev);
-               return;
-       }
-
-       if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) {
-               mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211);
-               val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf;
-               if (low_gain == 2)
-                       val |= 0x3;
-               else
-                       val |= 0x5;
-               mt76_wr(dev, MT_BBP(AGC, 26), val);
-       } else {
-               mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423);
-       }
-
-       if (mt76x2_has_ext_lna(dev))
-               low_gain_delta = 10;
-       else
-               low_gain_delta = 14;
-
-       if (low_gain == 2) {
-               mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990);
-               mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808);
-               mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808);
-               gain_delta = low_gain_delta;
-               dev->cal.agc_gain_adjust = 0;
-       } else {
-               mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991);
-               if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80)
-                       mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014);
-               else
-                       mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116);
-               mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C);
-               gain_delta = 0;
-               dev->cal.agc_gain_adjust = low_gain_delta;
-       }
-
-       dev->cal.agc_gain_cur[0] = gain[0] - gain_delta;
-       dev->cal.agc_gain_cur[1] = gain[1] - gain_delta;
-       mt76x2_phy_set_gain_val(dev);
-
-       /* clear false CCA counters */
-       mt76_rr(dev, MT_RX_STAT_1);
-}
-
-int mt76x2_phy_set_channel(struct mt76x2_dev *dev,
-                          struct cfg80211_chan_def *chandef)
-{
-       struct ieee80211_channel *chan = chandef->chan;
-       bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
-       enum nl80211_band band = chan->band;
-       u8 channel;
-
-       u32 ext_cca_chan[4] = {
-               [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
-               [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
-               [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
-               [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
-       };
-       int ch_group_index;
-       u8 bw, bw_index;
-       int freq, freq1;
-       int ret;
-
-       dev->cal.channel_cal_done = false;
-       freq = chandef->chan->center_freq;
-       freq1 = chandef->center_freq1;
-       channel = chan->hw_value;
-
-       switch (chandef->width) {
-       case NL80211_CHAN_WIDTH_40:
-               bw = 1;
-               if (freq1 > freq) {
-                       bw_index = 1;
-                       ch_group_index = 0;
-               } else {
-                       bw_index = 3;
-                       ch_group_index = 1;
-               }
-               channel += 2 - ch_group_index * 4;
-               break;
-       case NL80211_CHAN_WIDTH_80:
-               ch_group_index = (freq - freq1 + 30) / 20;
-               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
-                       ch_group_index = 0;
-               bw = 2;
-               bw_index = ch_group_index;
-               channel += 6 - ch_group_index * 4;
-               break;
-       default:
-               bw = 0;
-               bw_index = 0;
-               ch_group_index = 0;
-               break;
-       }
-
-       mt76x2_read_rx_gain(dev);
-       mt76x2_phy_set_txpower_regs(dev, band);
-       mt76x2_configure_tx_delay(dev, band, bw);
-       mt76x2_phy_set_txpower(dev);
-
-       mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
-       mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
-
-       mt76_rmw(dev, MT_EXT_CCA_CFG,
-                (MT_EXT_CCA_CFG_CCA0 |
-                 MT_EXT_CCA_CFG_CCA1 |
-                 MT_EXT_CCA_CFG_CCA2 |
-                 MT_EXT_CCA_CFG_CCA3 |
-                 MT_EXT_CCA_CFG_CCA_MASK),
-                ext_cca_chan[ch_group_index]);
-
-       ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
-       if (ret)
-               return ret;
-
-       mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
-
-       mt76x2_phy_set_antenna(dev);
-
-       /* Enable LDPC Rx */
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
-               mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
-
-       if (!dev->cal.init_cal_done) {
-               u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
-
-               if (val != 0xff)
-                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, true);
-       }
-
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, true);
-
-       /* Rx LPF calibration */
-       if (!dev->cal.init_cal_done)
-               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, true);
-
-       dev->cal.init_cal_done = true;
-
-       mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2);
-       mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
-       mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
-       mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
-       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F);
-
-       if (scan)
-               return 0;
-
-       dev->cal.low_gain = -1;
-       mt76x2_phy_channel_calibrate(dev, true);
-       mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init);
-       memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init,
-              sizeof(dev->cal.agc_gain_cur));
-
-       /* init default values for temp compensation */
-       if (mt76x02_tssi_enabled(&dev->mt76)) {
-               mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
-                              0x38);
-               mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
-                              0x38);
-       }
-
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
-                                    MT_CALIBRATE_INTERVAL);
-
-       return 0;
-}
-
-static void
-mt76x2_phy_temp_compensate(struct mt76x2_dev *dev)
-{
-       struct mt76x2_temp_comp t;
-       int temp, db_diff;
-
-       if (mt76x2_get_temp_comp(dev, &t))
-               return;
-
-       temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL);
-       temp -= t.temp_25_ref;
-       temp = (temp * 1789) / 1000 + 25;
-       dev->cal.temp = temp;
-
-       if (temp > 25)
-               db_diff = (temp - 25) / t.high_slope;
-       else
-               db_diff = (25 - temp) / t.low_slope;
-
-       db_diff = min(db_diff, t.upper_bound);
-       db_diff = max(db_diff, t.lower_bound);
-
-       mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
-                      db_diff * 2);
-       mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
-                      db_diff * 2);
-}
-
-void mt76x2_phy_calibrate(struct work_struct *work)
-{
-       struct mt76x2_dev *dev;
-
-       dev = container_of(work, struct mt76x2_dev, cal_work.work);
-       mt76x2_phy_channel_calibrate(dev, false);
-       mt76x2_phy_tssi_compensate(dev, true);
-       mt76x2_phy_temp_compensate(dev);
-       mt76x2_phy_update_channel_gain(dev);
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
-                                    MT_CALIBRATE_INTERVAL);
-}
-
-int mt76x2_phy_start(struct mt76x2_dev *dev)
-{
-       int ret;
-
-       ret = mt76x02_mcu_set_radio_state(&dev->mt76, true, true);
-       if (ret)
-               return ret;
-
-       mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0);
-
-       return ret;
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_phy_common.c
deleted file mode 100644 (file)
index dd32e75..0000000
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x2_mcu.h"
-#include "mt76x02_phy.h"
-
-static void
-mt76x2_adjust_high_lna_gain(struct mt76x2_dev *dev, int reg, s8 offset)
-{
-       s8 gain;
-
-       gain = FIELD_GET(MT_BBP_AGC_LNA_HIGH_GAIN, mt76_rr(dev, MT_BBP(AGC, reg)));
-       gain -= offset / 2;
-       mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_LNA_HIGH_GAIN, gain);
-}
-
-static void
-mt76x2_adjust_agc_gain(struct mt76x2_dev *dev, int reg, s8 offset)
-{
-       s8 gain;
-
-       gain = FIELD_GET(MT_BBP_AGC_GAIN, mt76_rr(dev, MT_BBP(AGC, reg)));
-       gain += offset;
-       mt76_rmw_field(dev, MT_BBP(AGC, reg), MT_BBP_AGC_GAIN, gain);
-}
-
-void mt76x2_apply_gain_adj(struct mt76x2_dev *dev)
-{
-       s8 *gain_adj = dev->cal.rx.high_gain;
-
-       mt76x2_adjust_high_lna_gain(dev, 4, gain_adj[0]);
-       mt76x2_adjust_high_lna_gain(dev, 5, gain_adj[1]);
-
-       mt76x2_adjust_agc_gain(dev, 8, gain_adj[0]);
-       mt76x2_adjust_agc_gain(dev, 9, gain_adj[1]);
-}
-EXPORT_SYMBOL_GPL(mt76x2_apply_gain_adj);
-
-void mt76x2_phy_set_txpower_regs(struct mt76x2_dev *dev,
-                                enum nl80211_band band)
-{
-       u32 pa_mode[2];
-       u32 pa_mode_adj;
-
-       if (band == NL80211_BAND_2GHZ) {
-               pa_mode[0] = 0x010055ff;
-               pa_mode[1] = 0x00550055;
-
-               mt76_wr(dev, MT_TX_ALC_CFG_2, 0x35160a00);
-               mt76_wr(dev, MT_TX_ALC_CFG_3, 0x35160a06);
-
-               if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
-                       mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0x0000ec00);
-                       mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0x0000ec00);
-               } else {
-                       mt76_wr(dev, MT_RF_PA_MODE_ADJ0, 0xf4000200);
-                       mt76_wr(dev, MT_RF_PA_MODE_ADJ1, 0xfa000200);
-               }
-       } else {
-               pa_mode[0] = 0x0000ffff;
-               pa_mode[1] = 0x00ff00ff;
-
-               if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
-                       mt76_wr(dev, MT_TX_ALC_CFG_2, 0x2f0f0400);
-                       mt76_wr(dev, MT_TX_ALC_CFG_3, 0x2f0f0476);
-               } else {
-                       mt76_wr(dev, MT_TX_ALC_CFG_2, 0x1b0f0400);
-                       mt76_wr(dev, MT_TX_ALC_CFG_3, 0x1b0f0476);
-               }
-
-               if (mt76x02_ext_pa_enabled(&dev->mt76, band))
-                       pa_mode_adj = 0x04000000;
-               else
-                       pa_mode_adj = 0;
-
-               mt76_wr(dev, MT_RF_PA_MODE_ADJ0, pa_mode_adj);
-               mt76_wr(dev, MT_RF_PA_MODE_ADJ1, pa_mode_adj);
-       }
-
-       mt76_wr(dev, MT_BB_PA_MODE_CFG0, pa_mode[0]);
-       mt76_wr(dev, MT_BB_PA_MODE_CFG1, pa_mode[1]);
-       mt76_wr(dev, MT_RF_PA_MODE_CFG0, pa_mode[0]);
-       mt76_wr(dev, MT_RF_PA_MODE_CFG1, pa_mode[1]);
-
-       if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
-               u32 val;
-
-               if (band == NL80211_BAND_2GHZ)
-                       val = 0x3c3c023c;
-               else
-                       val = 0x363c023c;
-
-               mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val);
-               mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val);
-               mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00001818);
-       } else {
-               if (band == NL80211_BAND_2GHZ) {
-                       u32 val = 0x0f3c3c3c;
-
-                       mt76_wr(dev, MT_TX0_RF_GAIN_CORR, val);
-                       mt76_wr(dev, MT_TX1_RF_GAIN_CORR, val);
-                       mt76_wr(dev, MT_TX_ALC_CFG_4, 0x00000606);
-               } else {
-                       mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x383c023c);
-                       mt76_wr(dev, MT_TX1_RF_GAIN_CORR, 0x24282e28);
-                       mt76_wr(dev, MT_TX_ALC_CFG_4, 0);
-               }
-       }
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower_regs);
-
-static int
-mt76x2_get_min_rate_power(struct mt76_rate_power *r)
-{
-       int i;
-       s8 ret = 0;
-
-       for (i = 0; i < sizeof(r->all); i++) {
-               if (!r->all[i])
-                       continue;
-
-               if (ret)
-                       ret = min(ret, r->all[i]);
-               else
-                       ret = r->all[i];
-       }
-
-       return ret;
-}
-
-void mt76x2_phy_set_txpower(struct mt76x2_dev *dev)
-{
-       enum nl80211_chan_width width = dev->mt76.chandef.width;
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       struct mt76x2_tx_power_info txp;
-       int txp_0, txp_1, delta = 0;
-       struct mt76_rate_power t = {};
-       int base_power, gain;
-
-       mt76x2_get_power_info(dev, &txp, chan);
-
-       if (width == NL80211_CHAN_WIDTH_40)
-               delta = txp.delta_bw40;
-       else if (width == NL80211_CHAN_WIDTH_80)
-               delta = txp.delta_bw80;
-
-       mt76x2_get_rate_power(dev, &t, chan);
-       mt76x02_add_rate_power_offset(&t, txp.chain[0].target_power);
-       mt76x02_limit_rate_power(&t, dev->mt76.txpower_conf);
-       dev->mt76.txpower_cur = mt76x02_get_max_rate_power(&t);
-
-       base_power = mt76x2_get_min_rate_power(&t);
-       delta += base_power - txp.chain[0].target_power;
-       txp_0 = txp.chain[0].target_power + txp.chain[0].delta + delta;
-       txp_1 = txp.chain[1].target_power + txp.chain[1].delta + delta;
-
-       gain = min(txp_0, txp_1);
-       if (gain < 0) {
-               base_power -= gain;
-               txp_0 -= gain;
-               txp_1 -= gain;
-       } else if (gain > 0x2f) {
-               base_power -= gain - 0x2f;
-               txp_0 = 0x2f;
-               txp_1 = 0x2f;
-       }
-
-       mt76x02_add_rate_power_offset(&t, -base_power);
-       dev->target_power = txp.chain[0].target_power;
-       dev->target_power_delta[0] = txp_0 - txp.chain[0].target_power;
-       dev->target_power_delta[1] = txp_1 - txp.chain[0].target_power;
-       dev->mt76.rate_power = t;
-
-       mt76x02_phy_set_txpower(&dev->mt76, txp_0, txp_1);
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_set_txpower);
-
-void mt76x2_configure_tx_delay(struct mt76x2_dev *dev,
-                              enum nl80211_band band, u8 bw)
-{
-       u32 cfg0, cfg1;
-
-       if (mt76x02_ext_pa_enabled(&dev->mt76, band)) {
-               cfg0 = bw ? 0x000b0c01 : 0x00101101;
-               cfg1 = 0x00011414;
-       } else {
-               cfg0 = bw ? 0x000b0b01 : 0x00101001;
-               cfg1 = 0x00021414;
-       }
-       mt76_wr(dev, MT_TX_SW_CFG0, cfg0);
-       mt76_wr(dev, MT_TX_SW_CFG1, cfg1);
-
-       mt76_rmw_field(dev, MT_XIFS_TIME_CFG, MT_XIFS_TIME_CFG_OFDM_SIFS, 15);
-}
-EXPORT_SYMBOL_GPL(mt76x2_configure_tx_delay);
-
-void mt76x2_phy_set_bw(struct mt76x2_dev *dev, int width, u8 ctrl)
-{
-       int core_val, agc_val;
-
-       switch (width) {
-       case NL80211_CHAN_WIDTH_80:
-               core_val = 3;
-               agc_val = 7;
-               break;
-       case NL80211_CHAN_WIDTH_40:
-               core_val = 2;
-               agc_val = 3;
-               break;
-       default:
-               core_val = 0;
-               agc_val = 1;
-               break;
-       }
-
-       mt76_rmw_field(dev, MT_BBP(CORE, 1), MT_BBP_CORE_R1_BW, core_val);
-       mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_BW, agc_val);
-       mt76_rmw_field(dev, MT_BBP(AGC, 0), MT_BBP_AGC_R0_CTRL_CHAN, ctrl);
-       mt76_rmw_field(dev, MT_BBP(TXBE, 0), MT_BBP_TXBE_R0_CTRL_CHAN, ctrl);
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_set_bw);
-
-void mt76x2_phy_set_band(struct mt76x2_dev *dev, int band, bool primary_upper)
-{
-       switch (band) {
-       case NL80211_BAND_2GHZ:
-               mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
-               mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
-               break;
-       case NL80211_BAND_5GHZ:
-               mt76_clear(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_2G);
-               mt76_set(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_5G);
-               break;
-       }
-
-       mt76_rmw_field(dev, MT_TX_BAND_CFG, MT_TX_BAND_CFG_UPPER_40M,
-                      primary_upper);
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_set_band);
-
-int mt76x2_phy_get_min_avg_rssi(struct mt76x2_dev *dev)
-{
-       struct mt76x02_sta *sta;
-       struct mt76_wcid *wcid;
-       int i, j, min_rssi = 0;
-       s8 cur_rssi;
-
-       local_bh_disable();
-       rcu_read_lock();
-
-       for (i = 0; i < ARRAY_SIZE(dev->mt76.wcid_mask); i++) {
-               unsigned long mask = dev->mt76.wcid_mask[i];
-
-               if (!mask)
-                       continue;
-
-               for (j = i * BITS_PER_LONG; mask; j++, mask >>= 1) {
-                       if (!(mask & 1))
-                               continue;
-
-                       wcid = rcu_dereference(dev->mt76.wcid[j]);
-                       if (!wcid)
-                               continue;
-
-                       sta = container_of(wcid, struct mt76x02_sta, wcid);
-                       spin_lock(&dev->mt76.rx_lock);
-                       if (sta->inactive_count++ < 5)
-                               cur_rssi = ewma_signal_read(&sta->rssi);
-                       else
-                               cur_rssi = 0;
-                       spin_unlock(&dev->mt76.rx_lock);
-
-                       if (cur_rssi < min_rssi)
-                               min_rssi = cur_rssi;
-               }
-       }
-
-       rcu_read_unlock();
-       local_bh_enable();
-
-       if (!min_rssi)
-               return -75;
-
-       return min_rssi;
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_get_min_avg_rssi);
-
-void mt76x2_phy_tssi_compensate(struct mt76x2_dev *dev, bool wait)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       struct mt76x2_tx_power_info txp;
-       struct mt76x2_tssi_comp t = {};
-
-       if (!dev->cal.tssi_cal_done)
-               return;
-
-       if (!dev->cal.tssi_comp_pending) {
-               /* TSSI trigger */
-               t.cal_mode = BIT(0);
-               mt76x2_mcu_tssi_comp(dev, &t);
-               dev->cal.tssi_comp_pending = true;
-       } else {
-               if (mt76_rr(dev, MT_BBP(CORE, 34)) & BIT(4))
-                       return;
-
-               dev->cal.tssi_comp_pending = false;
-               mt76x2_get_power_info(dev, &txp, chan);
-
-               if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
-                       t.pa_mode = 1;
-
-               t.cal_mode = BIT(1);
-               t.slope0 = txp.chain[0].tssi_slope;
-               t.offset0 = txp.chain[0].tssi_offset;
-               t.slope1 = txp.chain[1].tssi_slope;
-               t.offset1 = txp.chain[1].tssi_offset;
-               mt76x2_mcu_tssi_comp(dev, &t);
-
-               if (t.pa_mode || dev->cal.dpd_cal_done)
-                       return;
-
-               usleep_range(10000, 20000);
-               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_DPD,
-                                     chan->hw_value, wait);
-               dev->cal.dpd_cal_done = true;
-       }
-}
-EXPORT_SYMBOL_GPL(mt76x2_phy_tssi_compensate);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.c b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.c
deleted file mode 100644 (file)
index a09f117..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-
-#ifndef __CHECKER__
-#define CREATE_TRACE_POINTS
-#include "mt76x2_trace.h"
-
-#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h b/drivers/net/wireless/mediatek/mt76/mt76x2_trace.h
deleted file mode 100644 (file)
index eb5afea..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#if !defined(__MT76x2_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define __MT76x2_TRACE_H
-
-#include <linux/tracepoint.h>
-#include "mt76x2.h"
-
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM mt76x2
-
-#define MAXNAME                32
-#define DEV_ENTRY      __array(char, wiphy_name, 32)
-#define DEV_ASSIGN     strlcpy(__entry->wiphy_name, wiphy_name(mt76_hw(dev)->wiphy), MAXNAME)
-#define DEV_PR_FMT     "%s"
-#define DEV_PR_ARG     __entry->wiphy_name
-
-#define TXID_ENTRY     __field(u8, wcid) __field(u8, pktid)
-#define TXID_ASSIGN    __entry->wcid = wcid; __entry->pktid = pktid
-#define TXID_PR_FMT    " [%d:%d]"
-#define TXID_PR_ARG    __entry->wcid, __entry->pktid
-
-DECLARE_EVENT_CLASS(dev_evt,
-       TP_PROTO(struct mt76x2_dev *dev),
-       TP_ARGS(dev),
-       TP_STRUCT__entry(
-               DEV_ENTRY
-       ),
-       TP_fast_assign(
-               DEV_ASSIGN;
-       ),
-       TP_printk(DEV_PR_FMT, DEV_PR_ARG)
-);
-
-DECLARE_EVENT_CLASS(dev_txid_evt,
-       TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid),
-       TP_ARGS(dev, wcid, pktid),
-       TP_STRUCT__entry(
-               DEV_ENTRY
-               TXID_ENTRY
-       ),
-       TP_fast_assign(
-               DEV_ASSIGN;
-               TXID_ASSIGN;
-       ),
-       TP_printk(
-               DEV_PR_FMT TXID_PR_FMT,
-               DEV_PR_ARG, TXID_PR_ARG
-       )
-);
-
-DEFINE_EVENT(dev_evt, mac_txstat_poll,
-       TP_PROTO(struct mt76x2_dev *dev),
-       TP_ARGS(dev)
-);
-
-DEFINE_EVENT(dev_txid_evt, mac_txdone_add,
-       TP_PROTO(struct mt76x2_dev *dev, u8 wcid, u8 pktid),
-       TP_ARGS(dev, wcid, pktid)
-);
-
-TRACE_EVENT(mac_txstat_fetch,
-       TP_PROTO(struct mt76x2_dev *dev,
-                struct mt76x02_tx_status *stat),
-
-       TP_ARGS(dev, stat),
-
-       TP_STRUCT__entry(
-               DEV_ENTRY
-               TXID_ENTRY
-               __field(bool, success)
-               __field(bool, aggr)
-               __field(bool, ack_req)
-               __field(u16, rate)
-               __field(u8, retry)
-       ),
-
-       TP_fast_assign(
-               DEV_ASSIGN;
-               __entry->success = stat->success;
-               __entry->aggr = stat->aggr;
-               __entry->ack_req = stat->ack_req;
-               __entry->wcid = stat->wcid;
-               __entry->pktid = stat->pktid;
-               __entry->rate = stat->rate;
-               __entry->retry = stat->retry;
-       ),
-
-       TP_printk(
-               DEV_PR_FMT TXID_PR_FMT
-               " success:%d aggr:%d ack_req:%d"
-               " rate:%04x retry:%d",
-               DEV_PR_ARG, TXID_PR_ARG,
-               __entry->success, __entry->aggr, __entry->ack_req,
-               __entry->rate, __entry->retry
-       )
-);
-
-
-TRACE_EVENT(dev_irq,
-       TP_PROTO(struct mt76x2_dev *dev, u32 val, u32 mask),
-
-       TP_ARGS(dev, val, mask),
-
-       TP_STRUCT__entry(
-               DEV_ENTRY
-               __field(u32, val)
-               __field(u32, mask)
-       ),
-
-       TP_fast_assign(
-               DEV_ASSIGN;
-               __entry->val = val;
-               __entry->mask = mask;
-       ),
-
-       TP_printk(
-               DEV_PR_FMT " %08x & %08x",
-               DEV_PR_ARG, __entry->val, __entry->mask
-       )
-);
-
-#endif
-
-#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
-#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_FILE mt76x2_trace
-
-#include <trace/define_trace.h>
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx.c
deleted file mode 100644 (file)
index fcdf187..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "mt76x02_util.h"
-#include "mt76x02_dma.h"
-
-struct beacon_bc_data {
-       struct mt76x2_dev *dev;
-       struct sk_buff_head q;
-       struct sk_buff *tail[8];
-};
-
-int mt76x2_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
-                         struct sk_buff *skb, struct mt76_queue *q,
-                         struct mt76_wcid *wcid, struct ieee80211_sta *sta,
-                         u32 *tx_info)
-{
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       int qsel = MT_QSEL_EDCA;
-       int ret;
-
-       if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128)
-               mt76x02_mac_wcid_set_drop(&dev->mt76, wcid->idx, false);
-
-       mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len);
-
-       ret = mt76x02_insert_hdr_pad(skb);
-       if (ret < 0)
-               return ret;
-
-       if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
-               qsel = MT_QSEL_MGMT;
-
-       *tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
-                  MT_TXD_INFO_80211;
-
-       if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
-               *tx_info |= MT_TXD_INFO_WIV;
-
-       return 0;
-}
-
-static void
-mt76x2_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct mt76x2_dev *dev = (struct mt76x2_dev *) priv;
-       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
-       struct sk_buff *skb = NULL;
-
-       if (!(dev->beacon_mask & BIT(mvif->idx)))
-               return;
-
-       skb = ieee80211_beacon_get(mt76_hw(dev), vif);
-       if (!skb)
-               return;
-
-       mt76x2_mac_set_beacon(dev, mvif->idx, skb);
-}
-
-static void
-mt76x2_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct beacon_bc_data *data = priv;
-       struct mt76x2_dev *dev = data->dev;
-       struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
-       struct ieee80211_tx_info *info;
-       struct sk_buff *skb;
-
-       if (!(dev->beacon_mask & BIT(mvif->idx)))
-               return;
-
-       skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
-       if (!skb)
-               return;
-
-       info = IEEE80211_SKB_CB(skb);
-       info->control.vif = vif;
-       info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
-       mt76_skb_set_moredata(skb, true);
-       __skb_queue_tail(&data->q, skb);
-       data->tail[mvif->idx] = skb;
-}
-
-static void
-mt76x2_resync_beacon_timer(struct mt76x2_dev *dev)
-{
-       u32 timer_val = dev->beacon_int << 4;
-
-       dev->tbtt_count++;
-
-       /*
-        * Beacon timer drifts by 1us every tick, the timer is configured
-        * in 1/16 TU (64us) units.
-        */
-       if (dev->tbtt_count < 62)
-               return;
-
-       if (dev->tbtt_count >= 64) {
-               dev->tbtt_count = 0;
-               return;
-       }
-
-       /*
-        * The updated beacon interval takes effect after two TBTT, because
-        * at this point the original interval has already been loaded into
-        * the next TBTT_TIMER value
-        */
-       if (dev->tbtt_count == 62)
-               timer_val -= 1;
-
-       mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
-                      MT_BEACON_TIME_CFG_INTVAL, timer_val);
-}
-
-void mt76x2_pre_tbtt_tasklet(unsigned long arg)
-{
-       struct mt76x2_dev *dev = (struct mt76x2_dev *) arg;
-       struct mt76_queue *q = &dev->mt76.q_tx[MT_TXQ_PSD];
-       struct beacon_bc_data data = {};
-       struct sk_buff *skb;
-       int i, nframes;
-
-       mt76x2_resync_beacon_timer(dev);
-
-       data.dev = dev;
-       __skb_queue_head_init(&data.q);
-
-       ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
-               IEEE80211_IFACE_ITER_RESUME_ALL,
-               mt76x2_update_beacon_iter, dev);
-
-       do {
-               nframes = skb_queue_len(&data.q);
-               ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
-                       IEEE80211_IFACE_ITER_RESUME_ALL,
-                       mt76x2_add_buffered_bc, &data);
-       } while (nframes != skb_queue_len(&data.q));
-
-       if (!nframes)
-               return;
-
-       for (i = 0; i < ARRAY_SIZE(data.tail); i++) {
-               if (!data.tail[i])
-                       continue;
-
-               mt76_skb_set_moredata(data.tail[i], false);
-       }
-
-       spin_lock_bh(&q->lock);
-       while ((skb = __skb_dequeue(&data.q)) != NULL) {
-               struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-               struct ieee80211_vif *vif = info->control.vif;
-               struct mt76x02_vif *mvif = (struct mt76x02_vif *) vif->drv_priv;
-
-               mt76_dma_tx_queue_skb(&dev->mt76, q, skb, &mvif->group_wcid,
-                                     NULL);
-       }
-       spin_unlock_bh(&q->lock);
-}
-
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c b/drivers/net/wireless/mediatek/mt76/mt76x2_tx_common.c
deleted file mode 100644 (file)
index 1ec3c29..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2.h"
-#include "dma.h"
-
-void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
-              struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct mt76x2_dev *dev = hw->priv;
-       struct ieee80211_vif *vif = info->control.vif;
-       struct mt76_wcid *wcid = &dev->mt76.global_wcid;
-
-       if (control->sta) {
-               struct mt76x02_sta *msta;
-
-               msta = (struct mt76x02_sta *)control->sta->drv_priv;
-               wcid = &msta->wcid;
-               /* sw encrypted frames */
-               if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
-                       control->sta = NULL;
-       }
-
-       if (vif && !control->sta) {
-               struct mt76x02_vif *mvif;
-
-               mvif = (struct mt76x02_vif *)vif->drv_priv;
-               wcid = &mvif->group_wcid;
-       }
-
-       mt76_tx(&dev->mt76, control->sta, wcid, skb);
-}
-EXPORT_SYMBOL_GPL(mt76x2_tx);
-
-s8 mt76x2_tx_get_max_txpwr_adj(struct mt76_dev *mdev,
-                              const struct ieee80211_tx_rate *rate)
-{
-       struct mt76x2_dev *dev = (struct mt76x2_dev *) mdev;
-       s8 max_txpwr;
-
-       if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
-               u8 mcs = ieee80211_rate_get_vht_mcs(rate);
-
-               if (mcs == 8 || mcs == 9) {
-                       max_txpwr = mdev->rate_power.vht[8];
-               } else {
-                       u8 nss, idx;
-
-                       nss = ieee80211_rate_get_vht_nss(rate);
-                       idx = ((nss - 1) << 3) + mcs;
-                       max_txpwr = mdev->rate_power.ht[idx & 0xf];
-               }
-       } else if (rate->flags & IEEE80211_TX_RC_MCS) {
-               max_txpwr = mdev->rate_power.ht[rate->idx & 0xf];
-       } else {
-               enum nl80211_band band = dev->mt76.chandef.chan->band;
-
-               if (band == NL80211_BAND_2GHZ) {
-                       const struct ieee80211_rate *r;
-                       struct wiphy *wiphy = mt76_hw(dev)->wiphy;
-                       struct mt76_rate_power *rp = &mdev->rate_power;
-
-                       r = &wiphy->bands[band]->bitrates[rate->idx];
-                       if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
-                               max_txpwr = rp->cck[r->hw_value & 0x3];
-                       else
-                               max_txpwr = rp->ofdm[r->hw_value & 0x7];
-               } else {
-                       max_txpwr = mdev->rate_power.ofdm[rate->idx & 0x7];
-               }
-       }
-
-       return max_txpwr;
-}
-EXPORT_SYMBOL_GPL(mt76x2_tx_get_max_txpwr_adj);
-
-s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj)
-{
-       txpwr = min_t(s8, txpwr, dev->mt76.txpower_conf);
-       txpwr -= (dev->target_power + dev->target_power_delta[0]);
-       txpwr = min_t(s8, txpwr, max_txpwr_adj);
-
-       if (!dev->enable_tpc)
-               return 0;
-       else if (txpwr >= 0)
-               return min_t(s8, txpwr, 7);
-       else
-               return (txpwr < -16) ? 8 : (txpwr + 32) / 2;
-}
-EXPORT_SYMBOL_GPL(mt76x2_tx_get_txpwr_adj);
-
-void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr)
-{
-       s8 txpwr_adj;
-
-       txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, txpwr,
-                                           dev->mt76.rate_power.ofdm[4]);
-       mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
-                      MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj);
-       mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
-                      MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj);
-}
-EXPORT_SYMBOL_GPL(mt76x2_tx_set_txpwr_auto);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2_usb.c
deleted file mode 100644 (file)
index feb5cec..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "mt76x02_usb.h"
-#include "mt76x2u.h"
-
-static const struct usb_device_id mt76x2u_device_table[] = {
-       { USB_DEVICE(0x0e8d, 0x7612) }, /* Alfa AWUS036ACM */
-       { USB_DEVICE(0x0b05, 0x1833) }, /* Asus USB-AC54 */
-       { USB_DEVICE(0x0b05, 0x17eb) }, /* Asus USB-AC55 */
-       { USB_DEVICE(0x0b05, 0x180b) }, /* Asus USB-N53 B1 */
-       { USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USB-AC1200 */
-       { USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */
-       { USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */
-       { USB_DEVICE(0x0846, 0x9053) }, /* Netgear A6210 */
-       { USB_DEVICE(0x045e, 0x02e6) }, /* XBox One Wireless Adapter */
-       { },
-};
-
-static int mt76x2u_probe(struct usb_interface *intf,
-                        const struct usb_device_id *id)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct mt76x2_dev *dev;
-       int err;
-
-       dev = mt76x2u_alloc_device(&intf->dev);
-       if (!dev)
-               return -ENOMEM;
-
-       udev = usb_get_dev(udev);
-       usb_reset_device(udev);
-
-       mt76x02u_init_mcu(&dev->mt76);
-       err = mt76u_init(&dev->mt76, intf);
-       if (err < 0)
-               goto err;
-
-       dev->mt76.rev = mt76_rr(dev, MT_ASIC_VERSION);
-       dev_info(dev->mt76.dev, "ASIC revision: %08x\n", dev->mt76.rev);
-
-       err = mt76x2u_register_device(dev);
-       if (err < 0)
-               goto err;
-
-       return 0;
-
-err:
-       ieee80211_free_hw(mt76_hw(dev));
-       usb_set_intfdata(intf, NULL);
-       usb_put_dev(udev);
-
-       return err;
-}
-
-static void mt76x2u_disconnect(struct usb_interface *intf)
-{
-       struct usb_device *udev = interface_to_usbdev(intf);
-       struct mt76x2_dev *dev = usb_get_intfdata(intf);
-       struct ieee80211_hw *hw = mt76_hw(dev);
-
-       set_bit(MT76_REMOVED, &dev->mt76.state);
-       ieee80211_unregister_hw(hw);
-       mt76x2u_cleanup(dev);
-
-       ieee80211_free_hw(hw);
-       usb_set_intfdata(intf, NULL);
-       usb_put_dev(udev);
-}
-
-static int __maybe_unused mt76x2u_suspend(struct usb_interface *intf,
-                                         pm_message_t state)
-{
-       struct mt76x2_dev *dev = usb_get_intfdata(intf);
-       struct mt76_usb *usb = &dev->mt76.usb;
-
-       mt76u_stop_queues(&dev->mt76);
-       mt76x2u_stop_hw(dev);
-       usb_kill_urb(usb->mcu.res.urb);
-
-       return 0;
-}
-
-static int __maybe_unused mt76x2u_resume(struct usb_interface *intf)
-{
-       struct mt76x2_dev *dev = usb_get_intfdata(intf);
-       struct mt76_usb *usb = &dev->mt76.usb;
-       int err;
-
-       reinit_completion(&usb->mcu.cmpl);
-       err = mt76u_submit_buf(&dev->mt76, USB_DIR_IN,
-                              MT_EP_IN_CMD_RESP,
-                              &usb->mcu.res, GFP_KERNEL,
-                              mt76u_mcu_complete_urb,
-                              &usb->mcu.cmpl);
-       if (err < 0)
-               goto err;
-
-       err = mt76u_submit_rx_buffers(&dev->mt76);
-       if (err < 0)
-               goto err;
-
-       tasklet_enable(&usb->rx_tasklet);
-       tasklet_enable(&usb->tx_tasklet);
-
-       err = mt76x2u_init_hardware(dev);
-       if (err < 0)
-               goto err;
-
-       return 0;
-
-err:
-       mt76x2u_cleanup(dev);
-       return err;
-}
-
-MODULE_DEVICE_TABLE(usb, mt76x2u_device_table);
-MODULE_FIRMWARE(MT7662U_FIRMWARE);
-MODULE_FIRMWARE(MT7662U_ROM_PATCH);
-
-static struct usb_driver mt76x2u_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = mt76x2u_device_table,
-       .probe          = mt76x2u_probe,
-       .disconnect     = mt76x2u_disconnect,
-#ifdef CONFIG_PM
-       .suspend        = mt76x2u_suspend,
-       .resume         = mt76x2u_resume,
-       .reset_resume   = mt76x2u_resume,
-#endif /* CONFIG_PM */
-       .soft_unbind    = 1,
-       .disable_hub_initiated_lpm = 1,
-};
-module_usb_driver(mt76x2u_driver);
-
-MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u.h b/drivers/net/wireless/mediatek/mt76/mt76x2u.h
deleted file mode 100644 (file)
index 5d2ebdf..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __MT76x2U_H
-#define __MT76x2U_H
-
-#include <linux/device.h>
-
-#include "mt76x2.h"
-#include "mt76x2_mcu.h"
-#include "mt76x02_dma.h"
-
-#define MT7612U_EEPROM_SIZE            512
-
-#define MT_USB_AGGR_SIZE_LIMIT         21 /* 1024B unit */
-#define MT_USB_AGGR_TIMEOUT            0x80 /* 33ns unit */
-
-extern const struct ieee80211_ops mt76x2u_ops;
-
-struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev);
-int mt76x2u_register_device(struct mt76x2_dev *dev);
-int mt76x2u_init_hardware(struct mt76x2_dev *dev);
-void mt76x2u_cleanup(struct mt76x2_dev *dev);
-void mt76x2u_stop_hw(struct mt76x2_dev *dev);
-
-int mt76x2u_mac_reset(struct mt76x2_dev *dev);
-void mt76x2u_mac_resume(struct mt76x2_dev *dev);
-int mt76x2u_mac_start(struct mt76x2_dev *dev);
-int mt76x2u_mac_stop(struct mt76x2_dev *dev);
-
-int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
-                           struct cfg80211_chan_def *chandef);
-void mt76x2u_phy_calibrate(struct work_struct *work);
-void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev);
-
-void mt76x2u_mcu_complete_urb(struct urb *urb);
-int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap,
-                               bool ext, int rssi, u32 false_cca);
-int mt76x2u_mcu_init(struct mt76x2_dev *dev);
-int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev);
-
-int mt76x2u_alloc_queues(struct mt76x2_dev *dev);
-void mt76x2u_queues_deinit(struct mt76x2_dev *dev);
-void mt76x2u_stop_queues(struct mt76x2_dev *dev);
-int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
-                          struct sk_buff *skb, struct mt76_queue *q,
-                          struct mt76_wcid *wcid, struct ieee80211_sta *sta,
-                          u32 *tx_info);
-int mt76x2u_skb_dma_info(struct sk_buff *skb, enum dma_msg_port port,
-                        u32 flags);
-
-#endif /* __MT76x2U_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_core.c
deleted file mode 100644 (file)
index c2ccdeb..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2u.h"
-#include "dma.h"
-#include "mt76x02_util.h"
-#include "mt76x02_usb.h"
-
-static int
-mt76x2u_check_skb_rooms(struct sk_buff *skb)
-{
-       int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
-       u32 need_head;
-
-       need_head = sizeof(struct mt76x02_txwi) + MT_DMA_HDR_LEN;
-       if (hdr_len % 4)
-               need_head += 2;
-       return skb_cow(skb, need_head);
-}
-
-int mt76x2u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
-                          struct sk_buff *skb, struct mt76_queue *q,
-                          struct mt76_wcid *wcid, struct ieee80211_sta *sta,
-                          u32 *tx_info)
-{
-       struct mt76x2_dev *dev = container_of(mdev, struct mt76x2_dev, mt76);
-       struct mt76x02_txwi *txwi;
-       int err, len = skb->len;
-
-       err = mt76x2u_check_skb_rooms(skb);
-       if (err < 0)
-               return -ENOMEM;
-
-       mt76x02_insert_hdr_pad(skb);
-
-       txwi = skb_push(skb, sizeof(struct mt76x02_txwi));
-       mt76x2_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
-
-       return mt76x02u_set_txinfo(skb, wcid, q2ep(q->hw_idx));
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_init.c
deleted file mode 100644 (file)
index 5759a72..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/delay.h>
-
-#include "mt76x2u.h"
-#include "mt76x02_util.h"
-#include "mt76x02_phy.h"
-#include "mt76x2_eeprom.h"
-
-static void mt76x2u_init_dma(struct mt76x2_dev *dev)
-{
-       u32 val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
-
-       val |= MT_USB_DMA_CFG_RX_DROP_OR_PAD |
-              MT_USB_DMA_CFG_RX_BULK_EN |
-              MT_USB_DMA_CFG_TX_BULK_EN;
-
-       /* disable AGGR_BULK_RX in order to receive one
-        * frame in each rx urb and avoid copies
-        */
-       val &= ~MT_USB_DMA_CFG_RX_BULK_AGG_EN;
-       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
-}
-
-static void mt76x2u_power_on_rf_patch(struct mt76x2_dev *dev)
-{
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) | BIT(16));
-       udelay(1);
-
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x1c), 0xff);
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x1c), 0x30);
-
-       mt76_wr(dev, MT_VEND_ADDR(CFG, 0x14), 0x484f);
-       udelay(1);
-
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(17));
-       usleep_range(150, 200);
-
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(16));
-       usleep_range(50, 100);
-
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x14c), BIT(19) | BIT(20));
-}
-
-static void mt76x2u_power_on_rf(struct mt76x2_dev *dev, int unit)
-{
-       int shift = unit ? 8 : 0;
-       u32 val = (BIT(1) | BIT(3) | BIT(4) | BIT(5)) << shift;
-
-       /* Enable RF BG */
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), BIT(0) << shift);
-       usleep_range(10, 20);
-
-       /* Enable RFDIG LDO/AFE/ABB/ADDA */
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x130), val);
-       usleep_range(10, 20);
-
-       /* Switch RFDIG power to internal LDO */
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x130), BIT(2) << shift);
-       usleep_range(10, 20);
-
-       mt76x2u_power_on_rf_patch(dev);
-
-       mt76_set(dev, 0x530, 0xf);
-}
-
-static void mt76x2u_power_on(struct mt76x2_dev *dev)
-{
-       u32 val;
-
-       /* Turn on WL MTCMOS */
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x148),
-                MT_WLAN_MTC_CTRL_MTCMOS_PWR_UP);
-
-       val = MT_WLAN_MTC_CTRL_STATE_UP |
-             MT_WLAN_MTC_CTRL_PWR_ACK |
-             MT_WLAN_MTC_CTRL_PWR_ACK_S;
-
-       mt76_poll(dev, MT_VEND_ADDR(CFG, 0x148), val, val, 1000);
-
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0x7f << 16);
-       usleep_range(10, 20);
-
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);
-       usleep_range(10, 20);
-
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x148), 0xf << 24);
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x148), 0xfff);
-
-       /* Turn on AD/DA power down */
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x1204), BIT(3));
-
-       /* WLAN function enable */
-       mt76_set(dev, MT_VEND_ADDR(CFG, 0x80), BIT(0));
-
-       /* Release BBP software reset */
-       mt76_clear(dev, MT_VEND_ADDR(CFG, 0x64), BIT(18));
-
-       mt76x2u_power_on_rf(dev, 0);
-       mt76x2u_power_on_rf(dev, 1);
-}
-
-static int mt76x2u_init_eeprom(struct mt76x2_dev *dev)
-{
-       u32 val, i;
-
-       dev->mt76.eeprom.data = devm_kzalloc(dev->mt76.dev,
-                                            MT7612U_EEPROM_SIZE,
-                                            GFP_KERNEL);
-       dev->mt76.eeprom.size = MT7612U_EEPROM_SIZE;
-       if (!dev->mt76.eeprom.data)
-               return -ENOMEM;
-
-       for (i = 0; i + 4 <= MT7612U_EEPROM_SIZE; i += 4) {
-               val = mt76_rr(dev, MT_VEND_ADDR(EEPROM, i));
-               put_unaligned_le32(val, dev->mt76.eeprom.data + i);
-       }
-
-       mt76x02_eeprom_parse_hw_cap(&dev->mt76);
-       return 0;
-}
-
-struct mt76x2_dev *mt76x2u_alloc_device(struct device *pdev)
-{
-       static const struct mt76_driver_ops drv_ops = {
-               .tx_prepare_skb = mt76x2u_tx_prepare_skb,
-               .tx_complete_skb = mt76x02_tx_complete_skb,
-               .tx_status_data = mt76x02_tx_status_data,
-               .rx_skb = mt76x2_queue_rx_skb,
-       };
-       struct mt76x2_dev *dev;
-       struct mt76_dev *mdev;
-
-       mdev = mt76_alloc_device(sizeof(*dev), &mt76x2u_ops);
-       if (!mdev)
-               return NULL;
-
-       dev = container_of(mdev, struct mt76x2_dev, mt76);
-       mdev->dev = pdev;
-       mdev->drv = &drv_ops;
-
-       return dev;
-}
-
-static void mt76x2u_init_beacon_offsets(struct mt76x2_dev *dev)
-{
-       mt76_wr(dev, MT_BCN_OFFSET(0), 0x18100800);
-       mt76_wr(dev, MT_BCN_OFFSET(1), 0x38302820);
-       mt76_wr(dev, MT_BCN_OFFSET(2), 0x58504840);
-       mt76_wr(dev, MT_BCN_OFFSET(3), 0x78706860);
-}
-
-int mt76x2u_init_hardware(struct mt76x2_dev *dev)
-{
-       const struct mt76_wcid_addr addr = {
-               .macaddr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
-               .ba_mask = 0,
-       };
-       int i, err;
-
-       mt76x2_reset_wlan(dev, true);
-       mt76x2u_power_on(dev);
-
-       if (!mt76x02_wait_for_mac(&dev->mt76))
-               return -ETIMEDOUT;
-
-       err = mt76x2u_mcu_fw_init(dev);
-       if (err < 0)
-               return err;
-
-       if (!mt76_poll_msec(dev, MT_WPDMA_GLO_CFG,
-                           MT_WPDMA_GLO_CFG_TX_DMA_BUSY |
-                           MT_WPDMA_GLO_CFG_RX_DMA_BUSY, 0, 100))
-               return -EIO;
-
-       /* wait for asic ready after fw load. */
-       if (!mt76x02_wait_for_mac(&dev->mt76))
-               return -ETIMEDOUT;
-
-       mt76_wr(dev, MT_HEADER_TRANS_CTRL_REG, 0);
-       mt76_wr(dev, MT_TSO_CTRL, 0);
-
-       mt76x2u_init_dma(dev);
-
-       err = mt76x2u_mcu_init(dev);
-       if (err < 0)
-               return err;
-
-       err = mt76x2u_mac_reset(dev);
-       if (err < 0)
-               return err;
-
-       mt76x02_mac_setaddr(&dev->mt76,
-                           dev->mt76.eeprom.data + MT_EE_MAC_ADDR);
-       dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
-
-       mt76x2u_init_beacon_offsets(dev);
-
-       if (!mt76x02_wait_for_txrx_idle(&dev->mt76))
-               return -ETIMEDOUT;
-
-       /* reset wcid table */
-       for (i = 0; i < 254; i++)
-               mt76_wr_copy(dev, MT_WCID_ADDR(i), &addr,
-                            sizeof(struct mt76_wcid_addr));
-
-       /* reset shared key table and pairwise key table */
-       for (i = 0; i < 4; i++)
-               mt76_wr(dev, MT_SKEY_MODE_BASE_0 + 4 * i, 0);
-       for (i = 0; i < 256; i++)
-               mt76_wr(dev, MT_WCID_ATTR(i), 1);
-
-       mt76_clear(dev, MT_BEACON_TIME_CFG,
-                  MT_BEACON_TIME_CFG_TIMER_EN |
-                  MT_BEACON_TIME_CFG_SYNC_MODE |
-                  MT_BEACON_TIME_CFG_TBTT_EN |
-                  MT_BEACON_TIME_CFG_BEACON_TX);
-
-       mt76_rmw(dev, MT_US_CYC_CFG, MT_US_CYC_CNT, 0x1e);
-       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x583f);
-
-       err = mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0);
-       if (err < 0)
-               return err;
-
-       mt76x02_phy_set_rxpath(&dev->mt76);
-       mt76x02_phy_set_txdac(&dev->mt76);
-
-       return mt76x2u_mac_stop(dev);
-}
-
-int mt76x2u_register_device(struct mt76x2_dev *dev)
-{
-       struct ieee80211_hw *hw = mt76_hw(dev);
-       struct wiphy *wiphy = hw->wiphy;
-       int err;
-
-       INIT_DELAYED_WORK(&dev->cal_work, mt76x2u_phy_calibrate);
-       mt76x2_init_device(dev);
-
-       err = mt76x2u_init_eeprom(dev);
-       if (err < 0)
-               return err;
-
-       err = mt76u_alloc_queues(&dev->mt76);
-       if (err < 0)
-               goto fail;
-
-       err = mt76u_mcu_init_rx(&dev->mt76);
-       if (err < 0)
-               return err;
-
-       err = mt76x2u_init_hardware(dev);
-       if (err < 0)
-               goto fail;
-
-       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-
-       err = mt76_register_device(&dev->mt76, true, mt76x02_rates,
-                                  ARRAY_SIZE(mt76x02_rates));
-       if (err)
-               goto fail;
-
-       /* check hw sg support in order to enable AMSDU */
-       if (mt76u_check_sg(&dev->mt76))
-               hw->max_tx_fragments = MT_SG_MAX_SIZE;
-       else
-               hw->max_tx_fragments = 1;
-
-       set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state);
-
-       mt76x2_init_debugfs(dev);
-       mt76x2_init_txpower(dev, &dev->mt76.sband_2g.sband);
-       mt76x2_init_txpower(dev, &dev->mt76.sband_5g.sband);
-
-       return 0;
-
-fail:
-       mt76x2u_cleanup(dev);
-       return err;
-}
-
-void mt76x2u_stop_hw(struct mt76x2_dev *dev)
-{
-       mt76u_stop_stat_wk(&dev->mt76);
-       cancel_delayed_work_sync(&dev->cal_work);
-       mt76x2u_mac_stop(dev);
-}
-
-void mt76x2u_cleanup(struct mt76x2_dev *dev)
-{
-       mt76x02_mcu_set_radio_state(&dev->mt76, false, false);
-       mt76x2u_stop_hw(dev);
-       mt76u_queues_deinit(&dev->mt76);
-       mt76u_mcu_deinit(&dev->mt76);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mac.c
deleted file mode 100644 (file)
index f28c6fb..0000000
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2u.h"
-#include "mt76x2_eeprom.h"
-
-static void mt76x2u_mac_reset_counters(struct mt76x2_dev *dev)
-{
-       mt76_rr(dev, MT_RX_STAT_0);
-       mt76_rr(dev, MT_RX_STAT_1);
-       mt76_rr(dev, MT_RX_STAT_2);
-       mt76_rr(dev, MT_TX_STA_0);
-       mt76_rr(dev, MT_TX_STA_1);
-       mt76_rr(dev, MT_TX_STA_2);
-}
-
-static void mt76x2u_mac_fixup_xtal(struct mt76x2_dev *dev)
-{
-       s8 offset = 0;
-       u16 eep_val;
-
-       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_2);
-
-       offset = eep_val & 0x7f;
-       if ((eep_val & 0xff) == 0xff)
-               offset = 0;
-       else if (eep_val & 0x80)
-               offset = 0 - offset;
-
-       eep_val >>= 8;
-       if (eep_val == 0x00 || eep_val == 0xff) {
-               eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_XTAL_TRIM_1);
-               eep_val &= 0xff;
-
-               if (eep_val == 0x00 || eep_val == 0xff)
-                       eep_val = 0x14;
-       }
-
-       eep_val &= 0x7f;
-       mt76_rmw_field(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL5),
-                      MT_XO_CTRL5_C2_VAL, eep_val + offset);
-       mt76_set(dev, MT_VEND_ADDR(CFG, MT_XO_CTRL6), MT_XO_CTRL6_C2_CTRL);
-
-       mt76_wr(dev, 0x504, 0x06000000);
-       mt76_wr(dev, 0x50c, 0x08800000);
-       mdelay(5);
-       mt76_wr(dev, 0x504, 0x0);
-
-       /* decrease SIFS from 16us to 13us */
-       mt76_rmw_field(dev, MT_XIFS_TIME_CFG,
-                      MT_XIFS_TIME_CFG_OFDM_SIFS, 0xd);
-       mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG, MT_BKOFF_SLOT_CFG_CC_DELAY, 1);
-
-       /* init fce */
-       mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
-
-       eep_val = mt76x02_eeprom_get(&dev->mt76, MT_EE_NIC_CONF_2);
-       switch (FIELD_GET(MT_EE_NIC_CONF_2_XTAL_OPTION, eep_val)) {
-       case 0:
-               mt76_wr(dev, MT_XO_CTRL7, 0x5c1fee80);
-               break;
-       case 1:
-               mt76_wr(dev, MT_XO_CTRL7, 0x5c1feed0);
-               break;
-       default:
-               break;
-       }
-}
-
-int mt76x2u_mac_reset(struct mt76x2_dev *dev)
-{
-       mt76_wr(dev, MT_WPDMA_GLO_CFG, BIT(4) | BIT(5));
-
-       /* init pbf regs */
-       mt76_wr(dev, MT_PBF_TX_MAX_PCNT, 0xefef3f1f);
-       mt76_wr(dev, MT_PBF_RX_MAX_PCNT, 0xfebf);
-
-       mt76_write_mac_initvals(dev);
-
-       mt76_wr(dev, MT_TX_LINK_CFG, 0x1020);
-       mt76_wr(dev, MT_AUTO_RSP_CFG, 0x13);
-       mt76_wr(dev, MT_MAX_LEN_CFG, 0x2f00);
-       mt76_wr(dev, MT_TX_RTS_CFG, 0x92b20);
-
-       mt76_wr(dev, MT_WMM_AIFSN, 0x2273);
-       mt76_wr(dev, MT_WMM_CWMIN, 0x2344);
-       mt76_wr(dev, MT_WMM_CWMAX, 0x34aa);
-
-       mt76_clear(dev, MT_MAC_SYS_CTRL,
-                  MT_MAC_SYS_CTRL_RESET_CSR |
-                  MT_MAC_SYS_CTRL_RESET_BBP);
-
-       if (is_mt7612(dev))
-               mt76_clear(dev, MT_COEXCFG0, MT_COEXCFG0_COEX_EN);
-
-       mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
-       mt76_clear(dev, MT_TX_ALC_CFG_4, BIT(31));
-
-       mt76x2u_mac_fixup_xtal(dev);
-
-       return 0;
-}
-
-int mt76x2u_mac_start(struct mt76x2_dev *dev)
-{
-       mt76x2u_mac_reset_counters(dev);
-
-       mt76_wr(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX);
-       mt76x02_wait_for_wpdma(&dev->mt76, 1000);
-       usleep_range(50, 100);
-
-       mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
-
-       mt76_wr(dev, MT_MAC_SYS_CTRL,
-               MT_MAC_SYS_CTRL_ENABLE_TX |
-               MT_MAC_SYS_CTRL_ENABLE_RX);
-
-       return 0;
-}
-
-int mt76x2u_mac_stop(struct mt76x2_dev *dev)
-{
-       int i, count = 0, val;
-       bool stopped = false;
-       u32 rts_cfg;
-
-       if (test_bit(MT76_REMOVED, &dev->mt76.state))
-               return -EIO;
-
-       rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
-       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
-
-       mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
-       mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
-
-       /* wait tx dma to stop */
-       for (i = 0; i < 2000; i++) {
-               val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
-               if (!(val & MT_USB_DMA_CFG_TX_BUSY) && i > 10)
-                       break;
-               usleep_range(50, 100);
-       }
-
-       /* page count on TxQ */
-       for (i = 0; i < 200; i++) {
-               if (!(mt76_rr(dev, 0x0438) & 0xffffffff) &&
-                   !(mt76_rr(dev, 0x0a30) & 0x000000ff) &&
-                   !(mt76_rr(dev, 0x0a34) & 0xff00ff00))
-                       break;
-               usleep_range(10, 20);
-       }
-
-       /* disable tx-rx */
-       mt76_clear(dev, MT_MAC_SYS_CTRL,
-                  MT_MAC_SYS_CTRL_ENABLE_RX |
-                  MT_MAC_SYS_CTRL_ENABLE_TX);
-
-       /* Wait for MAC to become idle */
-       for (i = 0; i < 1000; i++) {
-               if (!(mt76_rr(dev, MT_MAC_STATUS) & MT_MAC_STATUS_TX) &&
-                   !mt76_rr(dev, MT_BBP(IBI, 12))) {
-                       stopped = true;
-                       break;
-               }
-               usleep_range(10, 20);
-       }
-
-       if (!stopped) {
-               mt76_set(dev, MT_BBP(CORE, 4), BIT(1));
-               mt76_clear(dev, MT_BBP(CORE, 4), BIT(1));
-
-               mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
-               mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
-       }
-
-       /* page count on RxQ */
-       for (i = 0; i < 200; i++) {
-               if (!(mt76_rr(dev, 0x0430) & 0x00ff0000) &&
-                   !(mt76_rr(dev, 0x0a30) & 0xffffffff) &&
-                   !(mt76_rr(dev, 0x0a34) & 0xffffffff) &&
-                   ++count > 10)
-                       break;
-               msleep(50);
-       }
-
-       if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_RX, 0, 2000))
-               dev_warn(dev->mt76.dev, "MAC RX failed to stop\n");
-
-       /* wait rx dma to stop */
-       for (i = 0; i < 2000; i++) {
-               val = mt76_rr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG));
-               if (!(val & MT_USB_DMA_CFG_RX_BUSY) && i > 10)
-                       break;
-               usleep_range(50, 100);
-       }
-
-       mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg);
-
-       return 0;
-}
-
-void mt76x2u_mac_resume(struct mt76x2_dev *dev)
-{
-       mt76_wr(dev, MT_MAC_SYS_CTRL,
-               MT_MAC_SYS_CTRL_ENABLE_TX |
-               MT_MAC_SYS_CTRL_ENABLE_RX);
-       mt76_set(dev, MT_TXOP_CTRL_CFG, BIT(20));
-       mt76_set(dev, MT_TXOP_HLDR_ET, BIT(1));
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_main.c
deleted file mode 100644 (file)
index a807045..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2u.h"
-#include "mt76x02_util.h"
-
-static int mt76x2u_start(struct ieee80211_hw *hw)
-{
-       struct mt76x2_dev *dev = hw->priv;
-       int ret;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       ret = mt76x2u_mac_start(dev);
-       if (ret)
-               goto out;
-
-       set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-
-out:
-       mutex_unlock(&dev->mt76.mutex);
-       return ret;
-}
-
-static void mt76x2u_stop(struct ieee80211_hw *hw)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       mutex_lock(&dev->mt76.mutex);
-       clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
-       mt76x2u_stop_hw(dev);
-       mutex_unlock(&dev->mt76.mutex);
-}
-
-static int mt76x2u_add_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_vif *vif)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       if (!ether_addr_equal(dev->mt76.macaddr, vif->addr))
-               mt76x02_mac_setaddr(&dev->mt76, vif->addr);
-
-       mt76x02_vif_init(&dev->mt76, vif, 0);
-       return 0;
-}
-
-static int
-mt76x2u_set_channel(struct mt76x2_dev *dev,
-                   struct cfg80211_chan_def *chandef)
-{
-       int err;
-
-       cancel_delayed_work_sync(&dev->cal_work);
-       set_bit(MT76_RESET, &dev->mt76.state);
-
-       mt76_set_channel(&dev->mt76);
-
-       mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
-       mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
-       mt76x2_mac_stop(dev, false);
-
-       err = mt76x2u_phy_set_channel(dev, chandef);
-
-       mt76x2u_mac_resume(dev);
-
-       clear_bit(MT76_RESET, &dev->mt76.state);
-       mt76_txq_schedule_all(&dev->mt76);
-
-       return err;
-}
-
-static void
-mt76x2u_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                        struct ieee80211_bss_conf *info, u32 changed)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               mt76x2u_phy_channel_calibrate(dev);
-               mt76x2_apply_gain_adj(dev);
-       }
-
-       if (changed & BSS_CHANGED_BSSID) {
-               mt76_wr(dev, MT_MAC_BSSID_DW0,
-                       get_unaligned_le32(info->bssid));
-               mt76_wr(dev, MT_MAC_BSSID_DW1,
-                       get_unaligned_le16(info->bssid + 4));
-       }
-
-       mutex_unlock(&dev->mt76.mutex);
-}
-
-static int
-mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct mt76x2_dev *dev = hw->priv;
-       int err = 0;
-
-       mutex_lock(&dev->mt76.mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
-               if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
-                       dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
-               else
-                       dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
-               mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ieee80211_stop_queues(hw);
-               err = mt76x2u_set_channel(dev, &hw->conf.chandef);
-               ieee80211_wake_queues(hw);
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               dev->mt76.txpower_conf = hw->conf.power_level * 2;
-
-               /* convert to per-chain power for 2x2 devices */
-               dev->mt76.txpower_conf -= 6;
-
-               if (test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
-                       mt76x2_phy_set_txpower(dev);
-       }
-
-       mutex_unlock(&dev->mt76.mutex);
-
-       return err;
-}
-
-static void
-mt76x2u_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-               const u8 *mac)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       set_bit(MT76_SCANNING, &dev->mt76.state);
-}
-
-static void
-mt76x2u_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
-{
-       struct mt76x2_dev *dev = hw->priv;
-
-       clear_bit(MT76_SCANNING, &dev->mt76.state);
-}
-
-const struct ieee80211_ops mt76x2u_ops = {
-       .tx = mt76x2_tx,
-       .start = mt76x2u_start,
-       .stop = mt76x2u_stop,
-       .add_interface = mt76x2u_add_interface,
-       .remove_interface = mt76x02_remove_interface,
-       .sta_add = mt76x02_sta_add,
-       .sta_remove = mt76x02_sta_remove,
-       .set_key = mt76x02_set_key,
-       .ampdu_action = mt76x02_ampdu_action,
-       .config = mt76x2u_config,
-       .wake_tx_queue = mt76_wake_tx_queue,
-       .bss_info_changed = mt76x2u_bss_info_changed,
-       .configure_filter = mt76x02_configure_filter,
-       .conf_tx = mt76x02_conf_tx,
-       .sw_scan_start = mt76x2u_sw_scan,
-       .sw_scan_complete = mt76x2u_sw_scan_complete,
-       .sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
-};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_mcu.c
deleted file mode 100644 (file)
index fdd94ca..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/firmware.h>
-
-#include "mt76x2u.h"
-#include "mt76x2_eeprom.h"
-#include "mt76x02_usb.h"
-
-#define MT_CMD_HDR_LEN                 4
-
-#define MCU_FW_URB_MAX_PAYLOAD         0x3900
-#define MCU_ROM_PATCH_MAX_PAYLOAD      2048
-
-#define MT76U_MCU_ILM_OFFSET           0x80000
-#define MT76U_MCU_DLM_OFFSET           0x110000
-#define MT76U_MCU_ROM_PATCH_OFFSET     0x90000
-
-int mt76x2u_mcu_set_dynamic_vga(struct mt76x2_dev *dev, u8 channel, bool ap,
-                               bool ext, int rssi, u32 false_cca)
-{
-       struct {
-               __le32 channel;
-               __le32 rssi_val;
-               __le32 false_cca_val;
-       } __packed __aligned(4) msg = {
-               .rssi_val = cpu_to_le32(rssi),
-               .false_cca_val = cpu_to_le32(false_cca),
-       };
-       struct sk_buff *skb;
-       u32 val = channel;
-
-       if (ap)
-               val |= BIT(31);
-       if (ext)
-               val |= BIT(30);
-       msg.channel = cpu_to_le32(val);
-
-       skb = mt76_mcu_msg_alloc(dev, &msg, sizeof(msg));
-       return mt76_mcu_send_msg(dev, skb, CMD_DYNC_VGA_OP, true);
-}
-
-static void mt76x2u_mcu_load_ivb(struct mt76x2_dev *dev)
-{
-       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
-                            USB_DIR_OUT | USB_TYPE_VENDOR,
-                            0x12, 0, NULL, 0);
-}
-
-static void mt76x2u_mcu_enable_patch(struct mt76x2_dev *dev)
-{
-       struct mt76_usb *usb = &dev->mt76.usb;
-       const u8 data[] = {
-               0x6f, 0xfc, 0x08, 0x01,
-               0x20, 0x04, 0x00, 0x00,
-               0x00, 0x09, 0x00,
-       };
-
-       memcpy(usb->data, data, sizeof(data));
-       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
-                            USB_DIR_OUT | USB_TYPE_CLASS,
-                            0x12, 0, usb->data, sizeof(data));
-}
-
-static void mt76x2u_mcu_reset_wmt(struct mt76x2_dev *dev)
-{
-       struct mt76_usb *usb = &dev->mt76.usb;
-       u8 data[] = {
-               0x6f, 0xfc, 0x05, 0x01,
-               0x07, 0x01, 0x00, 0x04
-       };
-
-       memcpy(usb->data, data, sizeof(data));
-       mt76u_vendor_request(&dev->mt76, MT_VEND_DEV_MODE,
-                            USB_DIR_OUT | USB_TYPE_CLASS,
-                            0x12, 0, usb->data, sizeof(data));
-}
-
-static int mt76x2u_mcu_load_rom_patch(struct mt76x2_dev *dev)
-{
-       bool rom_protect = !is_mt7612(dev);
-       struct mt76x02_patch_header *hdr;
-       u32 val, patch_mask, patch_reg;
-       const struct firmware *fw;
-       int err;
-
-       if (rom_protect &&
-           !mt76_poll_msec(dev, MT_MCU_SEMAPHORE_03, 1, 1, 600)) {
-               dev_err(dev->mt76.dev,
-                       "could not get hardware semaphore for ROM PATCH\n");
-               return -ETIMEDOUT;
-       }
-
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3) {
-               patch_mask = BIT(0);
-               patch_reg = MT_MCU_CLOCK_CTL;
-       } else {
-               patch_mask = BIT(1);
-               patch_reg = MT_MCU_COM_REG0;
-       }
-
-       if (rom_protect && (mt76_rr(dev, patch_reg) & patch_mask)) {
-               dev_info(dev->mt76.dev, "ROM patch already applied\n");
-               return 0;
-       }
-
-       err = request_firmware(&fw, MT7662U_ROM_PATCH, dev->mt76.dev);
-       if (err < 0)
-               return err;
-
-       if (!fw || !fw->data || fw->size <= sizeof(*hdr)) {
-               dev_err(dev->mt76.dev, "failed to load firmware\n");
-               err = -EIO;
-               goto out;
-       }
-
-       hdr = (struct mt76x02_patch_header *)fw->data;
-       dev_info(dev->mt76.dev, "ROM patch build: %.15s\n", hdr->build_time);
-
-       /* enable USB_DMA_CFG */
-       val = MT_USB_DMA_CFG_RX_BULK_EN |
-             MT_USB_DMA_CFG_TX_BULK_EN |
-             FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
-       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
-
-       /* vendor reset */
-       mt76x02u_mcu_fw_reset(&dev->mt76);
-       usleep_range(5000, 10000);
-
-       /* enable FCE to send in-band cmd */
-       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
-       /* FCE tx_fs_base_ptr */
-       mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
-       /* FCE tx_fs_max_cnt */
-       mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
-       /* FCE pdma enable */
-       mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
-       /* FCE skip_fs_en */
-       mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
-
-       err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
-                                       fw->size - sizeof(*hdr),
-                                       MCU_ROM_PATCH_MAX_PAYLOAD,
-                                       MT76U_MCU_ROM_PATCH_OFFSET);
-       if (err < 0) {
-               err = -EIO;
-               goto out;
-       }
-
-       mt76x2u_mcu_enable_patch(dev);
-       mt76x2u_mcu_reset_wmt(dev);
-       mdelay(20);
-
-       if (!mt76_poll_msec(dev, patch_reg, patch_mask, patch_mask, 100)) {
-               dev_err(dev->mt76.dev, "failed to load ROM patch\n");
-               err = -ETIMEDOUT;
-       }
-
-out:
-       if (rom_protect)
-               mt76_wr(dev, MT_MCU_SEMAPHORE_03, 1);
-       release_firmware(fw);
-       return err;
-}
-
-static int mt76x2u_mcu_load_firmware(struct mt76x2_dev *dev)
-{
-       u32 val, dlm_offset = MT76U_MCU_DLM_OFFSET;
-       const struct mt76x02_fw_header *hdr;
-       int err, len, ilm_len, dlm_len;
-       const struct firmware *fw;
-
-       err = request_firmware(&fw, MT7662U_FIRMWARE, dev->mt76.dev);
-       if (err < 0)
-               return err;
-
-       if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       hdr = (const struct mt76x02_fw_header *)fw->data;
-       ilm_len = le32_to_cpu(hdr->ilm_len);
-       dlm_len = le32_to_cpu(hdr->dlm_len);
-       len = sizeof(*hdr) + ilm_len + dlm_len;
-       if (fw->size != len) {
-               err = -EINVAL;
-               goto out;
-       }
-
-       val = le16_to_cpu(hdr->fw_ver);
-       dev_info(dev->mt76.dev, "Firmware Version: %d.%d.%02d\n",
-                (val >> 12) & 0xf, (val >> 8) & 0xf, val & 0xf);
-
-       val = le16_to_cpu(hdr->build_ver);
-       dev_info(dev->mt76.dev, "Build: %x\n", val);
-       dev_info(dev->mt76.dev, "Build Time: %.16s\n", hdr->build_time);
-
-       /* vendor reset */
-       mt76x02u_mcu_fw_reset(&dev->mt76);
-       usleep_range(5000, 10000);
-
-       /* enable USB_DMA_CFG */
-       val = MT_USB_DMA_CFG_RX_BULK_EN |
-             MT_USB_DMA_CFG_TX_BULK_EN |
-             FIELD_PREP(MT_USB_DMA_CFG_RX_BULK_AGG_TOUT, 0x20);
-       mt76_wr(dev, MT_VEND_ADDR(CFG, MT_USB_U3DMA_CFG), val);
-       /* enable FCE to send in-band cmd */
-       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
-       /* FCE tx_fs_base_ptr */
-       mt76_wr(dev, MT_TX_CPU_FROM_FCE_BASE_PTR, 0x400230);
-       /* FCE tx_fs_max_cnt */
-       mt76_wr(dev, MT_TX_CPU_FROM_FCE_MAX_COUNT, 0x1);
-       /* FCE pdma enable */
-       mt76_wr(dev, MT_FCE_PDMA_GLOBAL_CONF, 0x44);
-       /* FCE skip_fs_en */
-       mt76_wr(dev, MT_FCE_SKIP_FS, 0x3);
-
-       /* load ILM */
-       err = mt76x02u_mcu_fw_send_data(&dev->mt76, fw->data + sizeof(*hdr),
-                                       ilm_len, MCU_FW_URB_MAX_PAYLOAD,
-                                       MT76U_MCU_ILM_OFFSET);
-       if (err < 0) {
-               err = -EIO;
-               goto out;
-       }
-
-       /* load DLM */
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
-               dlm_offset += 0x800;
-       err = mt76x02u_mcu_fw_send_data(&dev->mt76,
-                                       fw->data + sizeof(*hdr) + ilm_len,
-                                       dlm_len, MCU_FW_URB_MAX_PAYLOAD,
-                                       dlm_offset);
-       if (err < 0) {
-               err = -EIO;
-               goto out;
-       }
-
-       mt76x2u_mcu_load_ivb(dev);
-       if (!mt76_poll_msec(dev, MT_MCU_COM_REG0, 1, 1, 100)) {
-               dev_err(dev->mt76.dev, "firmware failed to start\n");
-               err = -ETIMEDOUT;
-               goto out;
-       }
-
-       mt76_set(dev, MT_MCU_COM_REG0, BIT(1));
-       /* enable FCE to send in-band cmd */
-       mt76_wr(dev, MT_FCE_PSE_CTRL, 0x1);
-       dev_dbg(dev->mt76.dev, "firmware running\n");
-       mt76x02_set_ethtool_fwver(&dev->mt76, hdr);
-
-out:
-       release_firmware(fw);
-       return err;
-}
-
-int mt76x2u_mcu_fw_init(struct mt76x2_dev *dev)
-{
-       int err;
-
-       err = mt76x2u_mcu_load_rom_patch(dev);
-       if (err < 0)
-               return err;
-
-       return mt76x2u_mcu_load_firmware(dev);
-}
-
-int mt76x2u_mcu_init(struct mt76x2_dev *dev)
-{
-       int err;
-
-       err = mt76x02_mcu_function_select(&dev->mt76, Q_SELECT,
-                                          1, false);
-       if (err < 0)
-               return err;
-
-       return mt76x02_mcu_set_radio_state(&dev->mt76, true, false);
-}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2u_phy.c
deleted file mode 100644 (file)
index 06362d3..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mt76x2u.h"
-#include "mt76x2_eeprom.h"
-
-void mt76x2u_phy_channel_calibrate(struct mt76x2_dev *dev)
-{
-       struct ieee80211_channel *chan = dev->mt76.chandef.chan;
-       bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
-
-       if (mt76x2_channel_silent(dev))
-               return;
-
-       mt76x2u_mac_stop(dev);
-
-       if (is_5ghz)
-               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_LC, 0, false);
-
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, false);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, false);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, false);
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, false);
-
-       mt76x2u_mac_resume(dev);
-}
-
-static void
-mt76x2u_phy_update_channel_gain(struct mt76x2_dev *dev)
-{
-       u8 channel = dev->mt76.chandef.chan->hw_value;
-       int freq, freq1;
-       u32 false_cca;
-
-       freq = dev->mt76.chandef.chan->center_freq;
-       freq1 = dev->mt76.chandef.center_freq1;
-
-       switch (dev->mt76.chandef.width) {
-       case NL80211_CHAN_WIDTH_80: {
-               int ch_group_index;
-
-               ch_group_index = (freq - freq1 + 30) / 20;
-               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
-                       ch_group_index = 0;
-               channel += 6 - ch_group_index * 4;
-               break;
-       }
-       case NL80211_CHAN_WIDTH_40:
-               if (freq1 > freq)
-                       channel += 2;
-               else
-                       channel -= 2;
-               break;
-       default:
-               break;
-       }
-
-       dev->cal.avg_rssi_all = mt76x2_phy_get_min_avg_rssi(dev);
-       false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS,
-                             mt76_rr(dev, MT_RX_STAT_1));
-
-       mt76x2u_mcu_set_dynamic_vga(dev, channel, false, false,
-                                   dev->cal.avg_rssi_all, false_cca);
-}
-
-void mt76x2u_phy_calibrate(struct work_struct *work)
-{
-       struct mt76x2_dev *dev;
-
-       dev = container_of(work, struct mt76x2_dev, cal_work.work);
-       mt76x2_phy_tssi_compensate(dev, false);
-       mt76x2u_phy_update_channel_gain(dev);
-
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
-                                    MT_CALIBRATE_INTERVAL);
-}
-
-int mt76x2u_phy_set_channel(struct mt76x2_dev *dev,
-                           struct cfg80211_chan_def *chandef)
-{
-       u32 ext_cca_chan[4] = {
-               [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
-               [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
-               [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
-               [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
-                     FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
-       };
-       bool scan = test_bit(MT76_SCANNING, &dev->mt76.state);
-       struct ieee80211_channel *chan = chandef->chan;
-       u8 channel = chan->hw_value, bw, bw_index;
-       int ch_group_index, freq, freq1, ret;
-
-       dev->cal.channel_cal_done = false;
-       freq = chandef->chan->center_freq;
-       freq1 = chandef->center_freq1;
-
-       switch (chandef->width) {
-       case NL80211_CHAN_WIDTH_40:
-               bw = 1;
-               if (freq1 > freq) {
-                       bw_index = 1;
-                       ch_group_index = 0;
-               } else {
-                       bw_index = 3;
-                       ch_group_index = 1;
-               }
-               channel += 2 - ch_group_index * 4;
-               break;
-       case NL80211_CHAN_WIDTH_80:
-               ch_group_index = (freq - freq1 + 30) / 20;
-               if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
-                       ch_group_index = 0;
-               bw = 2;
-               bw_index = ch_group_index;
-               channel += 6 - ch_group_index * 4;
-               break;
-       default:
-               bw = 0;
-               bw_index = 0;
-               ch_group_index = 0;
-               break;
-       }
-
-       mt76x2_read_rx_gain(dev);
-       mt76x2_phy_set_txpower_regs(dev, chan->band);
-       mt76x2_configure_tx_delay(dev, chan->band, bw);
-       mt76x2_phy_set_txpower(dev);
-
-       mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1);
-       mt76x2_phy_set_bw(dev, chandef->width, ch_group_index);
-
-       mt76_rmw(dev, MT_EXT_CCA_CFG,
-                (MT_EXT_CCA_CFG_CCA0 |
-                 MT_EXT_CCA_CFG_CCA1 |
-                 MT_EXT_CCA_CFG_CCA2 |
-                 MT_EXT_CCA_CFG_CCA3 |
-                 MT_EXT_CCA_CFG_CCA_MASK),
-                ext_cca_chan[ch_group_index]);
-
-       ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
-       if (ret)
-               return ret;
-
-       mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
-
-       /* Enable LDPC Rx */
-       if (mt76xx_rev(dev) >= MT76XX_REV_E3)
-               mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
-
-       if (!dev->cal.init_cal_done) {
-               u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT);
-
-               if (val != 0xff)
-                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R,
-                                             0, false);
-       }
-
-       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, false);
-
-       /* Rx LPF calibration */
-       if (!dev->cal.init_cal_done)
-               mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, false);
-       dev->cal.init_cal_done = true;
-
-       mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2);
-       mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
-       mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
-       mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
-       mt76_wr(dev, MT_TXOP_CTRL_CFG, 0X04101b3f);
-
-       mt76_set(dev, MT_BBP(TXO, 4), BIT(25));
-       mt76_set(dev, MT_BBP(RXO, 13), BIT(8));
-
-       if (scan)
-               return 0;
-
-       if (mt76x02_tssi_enabled(&dev->mt76)) {
-               /* init default values for temp compensation */
-               mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
-                              0x38);
-               mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
-                              0x38);
-
-               /* init tssi calibration */
-               if (!mt76x2_channel_silent(dev)) {
-                       struct ieee80211_channel *chan;
-                       u32 flag = 0;
-
-                       chan = dev->mt76.chandef.chan;
-                       if (chan->band == NL80211_BAND_5GHZ)
-                               flag |= BIT(0);
-                       if (mt76x02_ext_pa_enabled(&dev->mt76, chan->band))
-                               flag |= BIT(8);
-                       mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TSSI,
-                                             flag, false);
-                       dev->cal.tssi_cal_done = true;
-               }
-       }
-
-       ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
-                                    MT_CALIBRATE_INTERVAL);
-       return 0;
-}