aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bcma/Kconfig19
-rw-r--r--drivers/bcma/Makefile4
-rw-r--r--drivers/bcma/bcma_private.h47
-rw-r--r--drivers/bcma/driver_gpio.c4
-rw-r--r--drivers/bcma/driver_pci.c26
-rw-r--r--drivers/bcma/driver_pci_host.c1
-rw-r--r--drivers/bcma/driver_pcie2.c29
-rw-r--r--drivers/bcma/host_pci.c43
-rw-r--r--drivers/bcma/main.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h27
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c101
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c164
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c4
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c132
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h15
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c27
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c158
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h61
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c61
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c95
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c52
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h275
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_mci.h310
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_wow.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c42
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c32
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c28
-rw-r--r--drivers/net/wireless/ath/wil6210/ethtool.c34
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c70
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c166
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c22
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c123
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h34
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c9
-rw-r--r--drivers/net/wireless/b43/main.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c166
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c13
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c30
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c115
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h47
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c11
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c68
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h151
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c54
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h1
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h191
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h64
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c133
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c180
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h125
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c44
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c215
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c150
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c600
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c207
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c6
-rw-r--r--drivers/net/wireless/libertas/debugfs.c3
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c14
-rw-r--r--drivers/net/wireless/mwifiex/decl.h1
-rw-r--r--drivers/net/wireless/mwifiex/init.c1
-rw-r--r--drivers/net/wireless/mwifiex/main.c16
-rw-r--r--drivers/net/wireless/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c10
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h6
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c13
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h62
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c8
-rw-r--r--drivers/net/wireless/mwifiex/util.c30
-rw-r--r--drivers/net/wireless/rtlwifi/base.h6
-rw-r--r--drivers/net/wireless/rtlwifi/cam.h2
-rw-r--r--drivers/net/wireless/rtlwifi/core.h2
-rw-r--r--drivers/net/wireless/rtlwifi/efuse.h6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/phy.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/def.h39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/def.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/rf.h1
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c11
-rw-r--r--drivers/ssb/main.c2
-rw-r--r--include/linux/bcma/bcma.h12
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h11
-rw-r--r--include/linux/bcma/bcma_driver_gmac_cmn.h6
-rw-r--r--include/linux/bcma/bcma_driver_mips.h15
-rw-r--r--include/linux/bcma/bcma_driver_pci.h6
-rw-r--r--include/linux/bcma/bcma_driver_pcie2.h4
137 files changed, 3304 insertions, 2340 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 0ee48be23837..9be17d3431bb 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -1,6 +1,6 @@
1config BCMA_POSSIBLE 1config BCMA_POSSIBLE
2 bool 2 bool
3 depends on HAS_IOMEM && HAS_DMA 3 depends on HAS_IOMEM && HAS_DMA && PCI
4 default y 4 default y
5 5
6menu "Broadcom specific AMBA" 6menu "Broadcom specific AMBA"
@@ -26,6 +26,7 @@ config BCMA_HOST_PCI_POSSIBLE
26config BCMA_HOST_PCI 26config BCMA_HOST_PCI
27 bool "Support for BCMA on PCI-host bus" 27 bool "Support for BCMA on PCI-host bus"
28 depends on BCMA_HOST_PCI_POSSIBLE 28 depends on BCMA_HOST_PCI_POSSIBLE
29 select BCMA_DRIVER_PCI
29 default y 30 default y
30 31
31config BCMA_DRIVER_PCI_HOSTMODE 32config BCMA_DRIVER_PCI_HOSTMODE
@@ -44,6 +45,22 @@ config BCMA_HOST_SOC
44 45
45 If unsure, say N 46 If unsure, say N
46 47
48# TODO: make it depend on PCI when ready
49config BCMA_DRIVER_PCI
50 bool
51 default y
52 help
53 BCMA bus may have many versions of PCIe core. This driver
54 supports:
55 1) PCIe core working in clientmode
56 2) PCIe Gen 2 clientmode core
57
58 In general PCIe (Gen 2) clientmode core is required on PCIe
59 hosted buses. It's responsible for initialization and basic
60 hardware management.
61 This driver is also prerequisite for a hostmode PCIe core
62 support.
63
47config BCMA_DRIVER_MIPS 64config BCMA_DRIVER_MIPS
48 bool "BCMA Broadcom MIPS core driver" 65 bool "BCMA Broadcom MIPS core driver"
49 depends on BCMA && MIPS 66 depends on BCMA && MIPS
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 838b4b9d352f..f32af9b76bcd 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -3,8 +3,8 @@ bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
3bcma-y += driver_chipcommon_b.o 3bcma-y += driver_chipcommon_b.o
4bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o 4bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
5bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o 5bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
6bcma-y += driver_pci.o 6bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o
7bcma-y += driver_pcie2.o 7bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pcie2.o
8bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 8bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
9bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o 9bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
10bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o 10bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index ac6c5fca906d..5a1d22489afc 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -26,6 +26,7 @@ bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
26 int timeout); 26 int timeout);
27void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); 27void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core);
28void bcma_init_bus(struct bcma_bus *bus); 28void bcma_init_bus(struct bcma_bus *bus);
29void bcma_unregister_cores(struct bcma_bus *bus);
29int bcma_bus_register(struct bcma_bus *bus); 30int bcma_bus_register(struct bcma_bus *bus);
30void bcma_bus_unregister(struct bcma_bus *bus); 31void bcma_bus_unregister(struct bcma_bus *bus);
31int __init bcma_bus_early_register(struct bcma_bus *bus); 32int __init bcma_bus_early_register(struct bcma_bus *bus);
@@ -42,6 +43,9 @@ int bcma_bus_scan(struct bcma_bus *bus);
42int bcma_sprom_get(struct bcma_bus *bus); 43int bcma_sprom_get(struct bcma_bus *bus);
43 44
44/* driver_chipcommon.c */ 45/* driver_chipcommon.c */
46void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
47void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
48void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
45#ifdef CONFIG_BCMA_DRIVER_MIPS 49#ifdef CONFIG_BCMA_DRIVER_MIPS
46void bcma_chipco_serial_init(struct bcma_drv_cc *cc); 50void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
47extern struct platform_device bcma_pflash_dev; 51extern struct platform_device bcma_pflash_dev;
@@ -52,6 +56,8 @@ int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb);
52void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb); 56void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb);
53 57
54/* driver_chipcommon_pmu.c */ 58/* driver_chipcommon_pmu.c */
59void bcma_pmu_early_init(struct bcma_drv_cc *cc);
60void bcma_pmu_init(struct bcma_drv_cc *cc);
55u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); 61u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
56u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); 62u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
57 63
@@ -101,6 +107,14 @@ static inline void __exit bcma_host_soc_unregister_driver(void)
101 107
102/* driver_pci.c */ 108/* driver_pci.c */
103u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); 109u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
110void bcma_core_pci_early_init(struct bcma_drv_pci *pc);
111void bcma_core_pci_init(struct bcma_drv_pci *pc);
112void bcma_core_pci_up(struct bcma_drv_pci *pc);
113void bcma_core_pci_down(struct bcma_drv_pci *pc);
114
115/* driver_pcie2.c */
116void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2);
117void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2);
104 118
105extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc); 119extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
106 120
@@ -117,6 +131,39 @@ static inline void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
117} 131}
118#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */ 132#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
119 133
134/**************************************************
135 * driver_mips.c
136 **************************************************/
137
138#ifdef CONFIG_BCMA_DRIVER_MIPS
139unsigned int bcma_core_mips_irq(struct bcma_device *dev);
140void bcma_core_mips_early_init(struct bcma_drv_mips *mcore);
141void bcma_core_mips_init(struct bcma_drv_mips *mcore);
142#else
143static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev)
144{
145 return 0;
146}
147static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
148{
149}
150static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore)
151{
152}
153#endif
154
155/**************************************************
156 * driver_gmac_cmn.c
157 **************************************************/
158
159#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN
160void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc);
161#else
162static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc)
163{
164}
165#endif
166
120#ifdef CONFIG_BCMA_DRIVER_GPIO 167#ifdef CONFIG_BCMA_DRIVER_GPIO
121/* driver_gpio.c */ 168/* driver_gpio.c */
122int bcma_gpio_init(struct bcma_drv_cc *cc); 169int bcma_gpio_init(struct bcma_drv_cc *cc);
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index 598a6cd9028a..dce34fb52e27 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
76 bcma_chipco_gpio_pullup(cc, 1 << gpio, 0); 76 bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
77} 77}
78 78
79#if IS_BUILTIN(CONFIG_BCM47XX) 79#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
80static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio) 80static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
81{ 81{
82 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip); 82 struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
@@ -215,7 +215,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
215 chip->set = bcma_gpio_set_value; 215 chip->set = bcma_gpio_set_value;
216 chip->direction_input = bcma_gpio_direction_input; 216 chip->direction_input = bcma_gpio_direction_input;
217 chip->direction_output = bcma_gpio_direction_output; 217 chip->direction_output = bcma_gpio_direction_output;
218#if IS_BUILTIN(CONFIG_BCM47XX) 218#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
219 chip->to_irq = bcma_gpio_to_irq; 219 chip->to_irq = bcma_gpio_to_irq;
220#endif 220#endif
221#if IS_BUILTIN(CONFIG_OF) 221#if IS_BUILTIN(CONFIG_OF)
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c
index 786666488a2d..cfd35bc1c5a3 100644
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -282,21 +282,21 @@ void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
282} 282}
283EXPORT_SYMBOL_GPL(bcma_core_pci_power_save); 283EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
284 284
285int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, 285int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core,
286 bool enable) 286 bool enable)
287{ 287{
288 struct pci_dev *pdev; 288 struct pci_dev *pdev;
289 u32 coremask, tmp; 289 u32 coremask, tmp;
290 int err = 0; 290 int err = 0;
291 291
292 if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) { 292 if (bus->hosttype != BCMA_HOSTTYPE_PCI) {
293 /* This bcma device is not on a PCI host-bus. So the IRQs are 293 /* This bcma device is not on a PCI host-bus. So the IRQs are
294 * not routed through the PCI core. 294 * not routed through the PCI core.
295 * So we must not enable routing through the PCI core. */ 295 * So we must not enable routing through the PCI core. */
296 goto out; 296 goto out;
297 } 297 }
298 298
299 pdev = pc->core->bus->host_pci; 299 pdev = bus->host_pci;
300 300
301 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); 301 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
302 if (err) 302 if (err)
@@ -328,28 +328,12 @@ static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
328 bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG); 328 bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
329} 329}
330 330
331void bcma_core_pci_up(struct bcma_bus *bus) 331void bcma_core_pci_up(struct bcma_drv_pci *pc)
332{ 332{
333 struct bcma_drv_pci *pc;
334
335 if (bus->hosttype != BCMA_HOSTTYPE_PCI)
336 return;
337
338 pc = &bus->drv_pci[0];
339
340 bcma_core_pci_extend_L1timer(pc, true); 333 bcma_core_pci_extend_L1timer(pc, true);
341} 334}
342EXPORT_SYMBOL_GPL(bcma_core_pci_up);
343 335
344void bcma_core_pci_down(struct bcma_bus *bus) 336void bcma_core_pci_down(struct bcma_drv_pci *pc)
345{ 337{
346 struct bcma_drv_pci *pc;
347
348 if (bus->hosttype != BCMA_HOSTTYPE_PCI)
349 return;
350
351 pc = &bus->drv_pci[0];
352
353 bcma_core_pci_extend_L1timer(pc, false); 338 bcma_core_pci_extend_L1timer(pc, false);
354} 339}
355EXPORT_SYMBOL_GPL(bcma_core_pci_down);
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index c8a6b741967b..c42cec7c7ecc 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -11,6 +11,7 @@
11 11
12#include "bcma_private.h" 12#include "bcma_private.h"
13#include <linux/pci.h> 13#include <linux/pci.h>
14#include <linux/slab.h>
14#include <linux/export.h> 15#include <linux/export.h>
15#include <linux/bcma/bcma.h> 16#include <linux/bcma/bcma.h>
16#include <asm/paccess.h> 17#include <asm/paccess.h>
diff --git a/drivers/bcma/driver_pcie2.c b/drivers/bcma/driver_pcie2.c
index e4be537b0c66..b1a6e327cb23 100644
--- a/drivers/bcma/driver_pcie2.c
+++ b/drivers/bcma/driver_pcie2.c
@@ -10,6 +10,7 @@
10 10
11#include "bcma_private.h" 11#include "bcma_private.h"
12#include <linux/bcma/bcma.h> 12#include <linux/bcma/bcma.h>
13#include <linux/pci.h>
13 14
14/************************************************** 15/**************************************************
15 * R/W ops. 16 * R/W ops.
@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2)
156 157
157void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2) 158void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
158{ 159{
159 struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo; 160 struct bcma_bus *bus = pcie2->core->bus;
161 struct bcma_chipinfo *ci = &bus->chipinfo;
160 u32 tmp; 162 u32 tmp;
161 163
162 tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54)); 164 tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
163 if ((tmp & 0xe) >> 1 == 2) 165 if ((tmp & 0xe) >> 1 == 2)
164 bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17); 166 bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
165 167
166 /* TODO: Do we need pcie_reqsize? */ 168 switch (bus->chipinfo.id) {
169 case BCMA_CHIP_ID_BCM4360:
170 case BCMA_CHIP_ID_BCM4352:
171 pcie2->reqsize = 1024;
172 break;
173 default:
174 pcie2->reqsize = 128;
175 break;
176 }
167 177
168 if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3) 178 if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
169 bcma_core_pcie2_war_delay_perst_enab(pcie2, true); 179 bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
173 pciedev_crwlpciegen2_180(pcie2); 183 pciedev_crwlpciegen2_180(pcie2);
174 pciedev_crwlpciegen2_182(pcie2); 184 pciedev_crwlpciegen2_182(pcie2);
175} 185}
186
187/**************************************************
188 * Runtime ops.
189 **************************************************/
190
191void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2)
192{
193 struct bcma_bus *bus = pcie2->core->bus;
194 struct pci_dev *dev = bus->host_pci;
195 int err;
196
197 err = pcie_set_readrq(dev, pcie2->reqsize);
198 if (err)
199 bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err);
200}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 53c6a8a58859..a62a2f9091f5 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -213,16 +213,26 @@ static int bcma_host_pci_probe(struct pci_dev *dev,
213 /* Initialize struct, detect chip */ 213 /* Initialize struct, detect chip */
214 bcma_init_bus(bus); 214 bcma_init_bus(bus);
215 215
216 /* Scan bus to find out generation of PCIe core */
217 err = bcma_bus_scan(bus);
218 if (err)
219 goto err_pci_unmap_mmio;
220
221 if (bcma_find_core(bus, BCMA_CORE_PCIE2))
222 bus->host_is_pcie2 = true;
223
216 /* Register */ 224 /* Register */
217 err = bcma_bus_register(bus); 225 err = bcma_bus_register(bus);
218 if (err) 226 if (err)
219 goto err_pci_unmap_mmio; 227 goto err_unregister_cores;
220 228
221 pci_set_drvdata(dev, bus); 229 pci_set_drvdata(dev, bus);
222 230
223out: 231out:
224 return err; 232 return err;
225 233
234err_unregister_cores:
235 bcma_unregister_cores(bus);
226err_pci_unmap_mmio: 236err_pci_unmap_mmio:
227 pci_iounmap(dev, bus->mmio); 237 pci_iounmap(dev, bus->mmio);
228err_pci_release_regions: 238err_pci_release_regions:
@@ -283,9 +293,12 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
283 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, 293 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
284 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, 294 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
285 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, 295 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
296 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
286 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, 297 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
298 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
287 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) }, 299 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
288 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) }, 300 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
301 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) },
289 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, 302 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
290 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */ 303 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */
291 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */ 304 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */
@@ -310,3 +323,31 @@ void __exit bcma_host_pci_exit(void)
310{ 323{
311 pci_unregister_driver(&bcma_pci_bridge_driver); 324 pci_unregister_driver(&bcma_pci_bridge_driver);
312} 325}
326
327/**************************************************
328 * Runtime ops for drivers.
329 **************************************************/
330
331/* See also pcicore_up */
332void bcma_host_pci_up(struct bcma_bus *bus)
333{
334 if (bus->hosttype != BCMA_HOSTTYPE_PCI)
335 return;
336
337 if (bus->host_is_pcie2)
338 bcma_core_pcie2_up(&bus->drv_pcie2);
339 else
340 bcma_core_pci_up(&bus->drv_pci[0]);
341}
342EXPORT_SYMBOL_GPL(bcma_host_pci_up);
343
344/* See also pcicore_down */
345void bcma_host_pci_down(struct bcma_bus *bus)
346{
347 if (bus->hosttype != BCMA_HOSTTYPE_PCI)
348 return;
349
350 if (!bus->host_is_pcie2)
351 bcma_core_pci_down(&bus->drv_pci[0]);
352}
353EXPORT_SYMBOL_GPL(bcma_host_pci_down);
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 38bde6eab8a4..9635f1033ce5 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -363,7 +363,7 @@ static int bcma_register_devices(struct bcma_bus *bus)
363 return 0; 363 return 0;
364} 364}
365 365
366static void bcma_unregister_cores(struct bcma_bus *bus) 366void bcma_unregister_cores(struct bcma_bus *bus)
367{ 367{
368 struct bcma_device *core, *tmp; 368 struct bcma_device *core, *tmp;
369 369
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index c18647b87f71..0eddb204d85b 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -39,7 +39,7 @@ struct ath10k_ce_pipe;
39#define CE_DESC_FLAGS_GATHER (1 << 0) 39#define CE_DESC_FLAGS_GATHER (1 << 0)
40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) 40#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC 41#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
42#define CE_DESC_FLAGS_META_DATA_LSB 3 42#define CE_DESC_FLAGS_META_DATA_LSB 2
43 43
44struct ce_desc { 44struct ce_desc {
45 __le32 addr; 45 __le32 addr;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 310e12bc078a..c0e454bb6a8d 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -436,16 +436,16 @@ static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
436 436
437static void ath10k_core_free_firmware_files(struct ath10k *ar) 437static void ath10k_core_free_firmware_files(struct ath10k *ar)
438{ 438{
439 if (ar->board && !IS_ERR(ar->board)) 439 if (!IS_ERR(ar->board))
440 release_firmware(ar->board); 440 release_firmware(ar->board);
441 441
442 if (ar->otp && !IS_ERR(ar->otp)) 442 if (!IS_ERR(ar->otp))
443 release_firmware(ar->otp); 443 release_firmware(ar->otp);
444 444
445 if (ar->firmware && !IS_ERR(ar->firmware)) 445 if (!IS_ERR(ar->firmware))
446 release_firmware(ar->firmware); 446 release_firmware(ar->firmware);
447 447
448 if (ar->cal_file && !IS_ERR(ar->cal_file)) 448 if (!IS_ERR(ar->cal_file))
449 release_firmware(ar->cal_file); 449 release_firmware(ar->cal_file);
450 450
451 ar->board = NULL; 451 ar->board = NULL;
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index d60e46fe6d19..f65310c3ba5f 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -159,6 +159,25 @@ struct ath10k_fw_stats_peer {
159 u32 peer_rx_rate; /* 10x only */ 159 u32 peer_rx_rate; /* 10x only */
160}; 160};
161 161
162struct ath10k_fw_stats_vdev {
163 struct list_head list;
164
165 u32 vdev_id;
166 u32 beacon_snr;
167 u32 data_snr;
168 u32 num_tx_frames[4];
169 u32 num_rx_frames;
170 u32 num_tx_frames_retries[4];
171 u32 num_tx_frames_failures[4];
172 u32 num_rts_fail;
173 u32 num_rts_success;
174 u32 num_rx_err;
175 u32 num_rx_discard;
176 u32 num_tx_not_acked;
177 u32 tx_rate_history[10];
178 u32 beacon_rssi_history[10];
179};
180
162struct ath10k_fw_stats_pdev { 181struct ath10k_fw_stats_pdev {
163 struct list_head list; 182 struct list_head list;
164 183
@@ -220,6 +239,7 @@ struct ath10k_fw_stats_pdev {
220 239
221struct ath10k_fw_stats { 240struct ath10k_fw_stats {
222 struct list_head pdevs; 241 struct list_head pdevs;
242 struct list_head vdevs;
223 struct list_head peers; 243 struct list_head peers;
224}; 244};
225 245
@@ -288,6 +308,7 @@ struct ath10k_vif {
288 bool is_started; 308 bool is_started;
289 bool is_up; 309 bool is_up;
290 bool spectral_enabled; 310 bool spectral_enabled;
311 bool ps;
291 u32 aid; 312 u32 aid;
292 u8 bssid[ETH_ALEN]; 313 u8 bssid[ETH_ALEN];
293 314
@@ -413,6 +434,12 @@ enum ath10k_fw_features {
413 */ 434 */
414 ATH10K_FW_FEATURE_WMI_10_2 = 4, 435 ATH10K_FW_FEATURE_WMI_10_2 = 4,
415 436
437 /* Some firmware revisions lack proper multi-interface client powersave
438 * implementation. Enabling PS could result in connection drops,
439 * traffic stalls, etc.
440 */
441 ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5,
442
416 /* keep last */ 443 /* keep last */
417 ATH10K_FW_FEATURE_COUNT, 444 ATH10K_FW_FEATURE_COUNT,
418}; 445};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index d2281e5c2ffe..301081db1ef6 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -243,6 +243,16 @@ static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head)
243 } 243 }
244} 244}
245 245
246static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head)
247{
248 struct ath10k_fw_stats_vdev *i, *tmp;
249
250 list_for_each_entry_safe(i, tmp, head, list) {
251 list_del(&i->list);
252 kfree(i);
253 }
254}
255
246static void ath10k_debug_fw_stats_peers_free(struct list_head *head) 256static void ath10k_debug_fw_stats_peers_free(struct list_head *head)
247{ 257{
248 struct ath10k_fw_stats_peer *i, *tmp; 258 struct ath10k_fw_stats_peer *i, *tmp;
@@ -258,6 +268,7 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
258 spin_lock_bh(&ar->data_lock); 268 spin_lock_bh(&ar->data_lock);
259 ar->debug.fw_stats_done = false; 269 ar->debug.fw_stats_done = false;
260 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 270 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
271 ath10k_debug_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
261 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); 272 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers);
262 spin_unlock_bh(&ar->data_lock); 273 spin_unlock_bh(&ar->data_lock);
263} 274}
@@ -273,14 +284,27 @@ static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
273 return num; 284 return num;
274} 285}
275 286
287static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
288{
289 struct ath10k_fw_stats_vdev *i;
290 size_t num = 0;
291
292 list_for_each_entry(i, head, list)
293 ++num;
294
295 return num;
296}
297
276void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 298void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
277{ 299{
278 struct ath10k_fw_stats stats = {}; 300 struct ath10k_fw_stats stats = {};
279 bool is_start, is_started, is_end; 301 bool is_start, is_started, is_end;
280 size_t num_peers; 302 size_t num_peers;
303 size_t num_vdevs;
281 int ret; 304 int ret;
282 305
283 INIT_LIST_HEAD(&stats.pdevs); 306 INIT_LIST_HEAD(&stats.pdevs);
307 INIT_LIST_HEAD(&stats.vdevs);
284 INIT_LIST_HEAD(&stats.peers); 308 INIT_LIST_HEAD(&stats.peers);
285 309
286 spin_lock_bh(&ar->data_lock); 310 spin_lock_bh(&ar->data_lock);
@@ -308,6 +332,7 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
308 } 332 }
309 333
310 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); 334 num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers);
335 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
311 is_start = (list_empty(&ar->debug.fw_stats.pdevs) && 336 is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
312 !list_empty(&stats.pdevs)); 337 !list_empty(&stats.pdevs));
313 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && 338 is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -330,7 +355,13 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
330 goto free; 355 goto free;
331 } 356 }
332 357
358 if (num_vdevs >= BITS_PER_LONG) {
359 ath10k_warn(ar, "dropping fw vdev stats\n");
360 goto free;
361 }
362
333 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); 363 list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers);
364 list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs);
334 } 365 }
335 366
336 complete(&ar->debug.fw_stats_complete); 367 complete(&ar->debug.fw_stats_complete);
@@ -340,6 +371,7 @@ free:
340 * resources if that is not the case. 371 * resources if that is not the case.
341 */ 372 */
342 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); 373 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs);
374 ath10k_debug_fw_stats_vdevs_free(&stats.vdevs);
343 ath10k_debug_fw_stats_peers_free(&stats.peers); 375 ath10k_debug_fw_stats_peers_free(&stats.peers);
344 376
345unlock: 377unlock:
@@ -363,7 +395,10 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
363 395
364 reinit_completion(&ar->debug.fw_stats_complete); 396 reinit_completion(&ar->debug.fw_stats_complete);
365 397
366 ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); 398 ret = ath10k_wmi_request_stats(ar,
399 WMI_STAT_PDEV |
400 WMI_STAT_VDEV |
401 WMI_STAT_PEER);
367 if (ret) { 402 if (ret) {
368 ath10k_warn(ar, "could not request stats (%d)\n", ret); 403 ath10k_warn(ar, "could not request stats (%d)\n", ret);
369 return ret; 404 return ret;
@@ -395,8 +430,11 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
395 unsigned int len = 0; 430 unsigned int len = 0;
396 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; 431 unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
397 const struct ath10k_fw_stats_pdev *pdev; 432 const struct ath10k_fw_stats_pdev *pdev;
433 const struct ath10k_fw_stats_vdev *vdev;
398 const struct ath10k_fw_stats_peer *peer; 434 const struct ath10k_fw_stats_peer *peer;
399 size_t num_peers; 435 size_t num_peers;
436 size_t num_vdevs;
437 int i;
400 438
401 spin_lock_bh(&ar->data_lock); 439 spin_lock_bh(&ar->data_lock);
402 440
@@ -408,6 +446,7 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
408 } 446 }
409 447
410 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); 448 num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
449 num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);
411 450
412 len += scnprintf(buf + len, buf_len - len, "\n"); 451 len += scnprintf(buf + len, buf_len - len, "\n");
413 len += scnprintf(buf + len, buf_len - len, "%30s\n", 452 len += scnprintf(buf + len, buf_len - len, "%30s\n",
@@ -531,6 +570,65 @@ static void ath10k_fw_stats_fill(struct ath10k *ar,
531 570
532 len += scnprintf(buf + len, buf_len - len, "\n"); 571 len += scnprintf(buf + len, buf_len - len, "\n");
533 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", 572 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
573 "ath10k VDEV stats", num_vdevs);
574 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
575 "=================");
576
577 list_for_each_entry(vdev, &fw_stats->vdevs, list) {
578 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
579 "vdev id", vdev->vdev_id);
580 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
581 "beacon snr", vdev->beacon_snr);
582 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
583 "data snr", vdev->data_snr);
584 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
585 "num rx frames", vdev->num_rx_frames);
586 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
587 "num rts fail", vdev->num_rts_fail);
588 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
589 "num rts success", vdev->num_rts_success);
590 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
591 "num rx err", vdev->num_rx_err);
592 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
593 "num rx discard", vdev->num_rx_discard);
594 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
595 "num tx not acked", vdev->num_tx_not_acked);
596
597 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
598 len += scnprintf(buf + len, buf_len - len,
599 "%25s [%02d] %u\n",
600 "num tx frames", i,
601 vdev->num_tx_frames[i]);
602
603 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
604 len += scnprintf(buf + len, buf_len - len,
605 "%25s [%02d] %u\n",
606 "num tx frames retries", i,
607 vdev->num_tx_frames_retries[i]);
608
609 for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
610 len += scnprintf(buf + len, buf_len - len,
611 "%25s [%02d] %u\n",
612 "num tx frames failures", i,
613 vdev->num_tx_frames_failures[i]);
614
615 for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
616 len += scnprintf(buf + len, buf_len - len,
617 "%25s [%02d] 0x%08x\n",
618 "tx rate history", i,
619 vdev->tx_rate_history[i]);
620
621 for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
622 len += scnprintf(buf + len, buf_len - len,
623 "%25s [%02d] %u\n",
624 "beacon rssi history", i,
625 vdev->beacon_rssi_history[i]);
626
627 len += scnprintf(buf + len, buf_len - len, "\n");
628 }
629
630 len += scnprintf(buf + len, buf_len - len, "\n");
631 len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
534 "ath10k PEER stats", num_peers); 632 "ath10k PEER stats", num_peers);
535 len += scnprintf(buf + len, buf_len - len, "%30s\n\n", 633 len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
536 "================="); 634 "=================");
@@ -1900,6 +1998,7 @@ int ath10k_debug_create(struct ath10k *ar)
1900 return -ENOMEM; 1998 return -ENOMEM;
1901 1999
1902 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); 2000 INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
2001 INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
1903 INIT_LIST_HEAD(&ar->debug.fw_stats.peers); 2002 INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
1904 2003
1905 return 0; 2004 return 0;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index c1da44f65a4d..01a2b384f358 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -176,7 +176,7 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
176 * automatically balances load wrt to CPU power. 176 * automatically balances load wrt to CPU power.
177 * 177 *
178 * This probably comes at a cost of lower maximum throughput but 178 * This probably comes at a cost of lower maximum throughput but
179 * improves the avarage and stability. */ 179 * improves the average and stability. */
180 spin_lock_bh(&htt->rx_ring.lock); 180 spin_lock_bh(&htt->rx_ring.lock);
181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; 181 num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt;
182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit); 182 num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit);
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 6c364bb98924..5d2db069d46e 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -611,7 +611,7 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
611 611
612 ret = ath10k_vdev_setup_sync(ar); 612 ret = ath10k_vdev_setup_sync(ar);
613 if (ret) { 613 if (ret) {
614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n", 614 ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n",
615 vdev_id, ret); 615 vdev_id, ret);
616 return ret; 616 return ret;
617 } 617 }
@@ -658,7 +658,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
658 658
659 ret = ath10k_vdev_setup_sync(ar); 659 ret = ath10k_vdev_setup_sync(ar);
660 if (ret) 660 if (ret)
661 ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n", 661 ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n",
662 ar->monitor_vdev_id, ret); 662 ar->monitor_vdev_id, ret);
663 663
664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", 664 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
@@ -927,8 +927,9 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
927 927
928 ret = ath10k_vdev_setup_sync(ar); 928 ret = ath10k_vdev_setup_sync(ar);
929 if (ret) { 929 if (ret) {
930 ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n", 930 ath10k_warn(ar,
931 arg.vdev_id, ret); 931 "failed to synchronize setup for vdev %i restart %d: %d\n",
932 arg.vdev_id, restart, ret);
932 return ret; 933 return ret;
933 } 934 }
934 935
@@ -966,7 +967,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
966 967
967 ret = ath10k_vdev_setup_sync(ar); 968 ret = ath10k_vdev_setup_sync(ar);
968 if (ret) { 969 if (ret) {
969 ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n", 970 ath10k_warn(ar, "failed to synchronize setup for vdev %i stop: %d\n",
970 arvif->vdev_id, ret); 971 arvif->vdev_id, ret);
971 return ret; 972 return ret;
972 } 973 }
@@ -1253,6 +1254,20 @@ static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1253 return 0; 1254 return 0;
1254} 1255}
1255 1256
1257static int ath10k_mac_ps_vif_count(struct ath10k *ar)
1258{
1259 struct ath10k_vif *arvif;
1260 int num = 0;
1261
1262 lockdep_assert_held(&ar->conf_mutex);
1263
1264 list_for_each_entry(arvif, &ar->arvifs, list)
1265 if (arvif->ps)
1266 num++;
1267
1268 return num;
1269}
1270
1256static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) 1271static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1257{ 1272{
1258 struct ath10k *ar = arvif->ar; 1273 struct ath10k *ar = arvif->ar;
@@ -1262,13 +1277,24 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1262 enum wmi_sta_ps_mode psmode; 1277 enum wmi_sta_ps_mode psmode;
1263 int ret; 1278 int ret;
1264 int ps_timeout; 1279 int ps_timeout;
1280 bool enable_ps;
1265 1281
1266 lockdep_assert_held(&arvif->ar->conf_mutex); 1282 lockdep_assert_held(&arvif->ar->conf_mutex);
1267 1283
1268 if (arvif->vif->type != NL80211_IFTYPE_STATION) 1284 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1269 return 0; 1285 return 0;
1270 1286
1271 if (vif->bss_conf.ps) { 1287 enable_ps = arvif->ps;
1288
1289 if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 &&
1290 !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT,
1291 ar->fw_features)) {
1292 ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n",
1293 arvif->vdev_id);
1294 enable_ps = false;
1295 }
1296
1297 if (enable_ps) {
1272 psmode = WMI_STA_PS_MODE_ENABLED; 1298 psmode = WMI_STA_PS_MODE_ENABLED;
1273 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1299 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1274 1300
@@ -1781,6 +1807,68 @@ static int ath10k_setup_peer_smps(struct ath10k *ar, struct ath10k_vif *arvif,
1781 ath10k_smps_map[smps]); 1807 ath10k_smps_map[smps]);
1782} 1808}
1783 1809
1810static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar,
1811 struct ieee80211_vif *vif,
1812 struct ieee80211_sta_vht_cap vht_cap)
1813{
1814 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1815 int ret;
1816 u32 param;
1817 u32 value;
1818
1819 if (!(ar->vht_cap_info &
1820 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1821 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
1822 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1823 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
1824 return 0;
1825
1826 param = ar->wmi.vdev_param->txbf;
1827 value = 0;
1828
1829 if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED))
1830 return 0;
1831
1832 /* The following logic is correct. If a remote STA advertises support
1833 * for being a beamformer then we should enable us being a beamformee.
1834 */
1835
1836 if (ar->vht_cap_info &
1837 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1838 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) {
1839 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
1840 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1841
1842 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
1843 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE;
1844 }
1845
1846 if (ar->vht_cap_info &
1847 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
1848 IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) {
1849 if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
1850 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1851
1852 if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)
1853 value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER;
1854 }
1855
1856 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE)
1857 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE;
1858
1859 if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER)
1860 value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER;
1861
1862 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value);
1863 if (ret) {
1864 ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n",
1865 value, ret);
1866 return ret;
1867 }
1868
1869 return 0;
1870}
1871
1784/* can be called only in mac80211 callbacks due to `key_count` usage */ 1872/* can be called only in mac80211 callbacks due to `key_count` usage */
1785static void ath10k_bss_assoc(struct ieee80211_hw *hw, 1873static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1786 struct ieee80211_vif *vif, 1874 struct ieee80211_vif *vif,
@@ -1789,6 +1877,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1789 struct ath10k *ar = hw->priv; 1877 struct ath10k *ar = hw->priv;
1790 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1878 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1791 struct ieee80211_sta_ht_cap ht_cap; 1879 struct ieee80211_sta_ht_cap ht_cap;
1880 struct ieee80211_sta_vht_cap vht_cap;
1792 struct wmi_peer_assoc_complete_arg peer_arg; 1881 struct wmi_peer_assoc_complete_arg peer_arg;
1793 struct ieee80211_sta *ap_sta; 1882 struct ieee80211_sta *ap_sta;
1794 int ret; 1883 int ret;
@@ -1811,6 +1900,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1811 /* ap_sta must be accessed only within rcu section which must be left 1900 /* ap_sta must be accessed only within rcu section which must be left
1812 * before calling ath10k_setup_peer_smps() which might sleep. */ 1901 * before calling ath10k_setup_peer_smps() which might sleep. */
1813 ht_cap = ap_sta->ht_cap; 1902 ht_cap = ap_sta->ht_cap;
1903 vht_cap = ap_sta->vht_cap;
1814 1904
1815 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); 1905 ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg);
1816 if (ret) { 1906 if (ret) {
@@ -1836,6 +1926,13 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1836 return; 1926 return;
1837 } 1927 }
1838 1928
1929 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1930 if (ret) {
1931 ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n",
1932 arvif->vdev_id, bss_conf->bssid, ret);
1933 return;
1934 }
1935
1839 ath10k_dbg(ar, ATH10K_DBG_MAC, 1936 ath10k_dbg(ar, ATH10K_DBG_MAC,
1840 "mac vdev %d up (associated) bssid %pM aid %d\n", 1937 "mac vdev %d up (associated) bssid %pM aid %d\n",
1841 arvif->vdev_id, bss_conf->bssid, bss_conf->aid); 1938 arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
@@ -1853,6 +1950,18 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
1853 } 1950 }
1854 1951
1855 arvif->is_up = true; 1952 arvif->is_up = true;
1953
1954 /* Workaround: Some firmware revisions (tested with qca6174
1955 * WLAN.RM.2.0-00073) have buggy powersave state machine and must be
1956 * poked with peer param command.
1957 */
1958 ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid,
1959 WMI_PEER_DUMMY_VAR, 1);
1960 if (ret) {
1961 ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n",
1962 arvif->bssid, arvif->vdev_id, ret);
1963 return;
1964 }
1856} 1965}
1857 1966
1858static void ath10k_bss_disassoc(struct ieee80211_hw *hw, 1967static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
@@ -1860,6 +1969,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1860{ 1969{
1861 struct ath10k *ar = hw->priv; 1970 struct ath10k *ar = hw->priv;
1862 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 1971 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1972 struct ieee80211_sta_vht_cap vht_cap = {};
1863 int ret; 1973 int ret;
1864 1974
1865 lockdep_assert_held(&ar->conf_mutex); 1975 lockdep_assert_held(&ar->conf_mutex);
@@ -1874,6 +1984,13 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1874 1984
1875 arvif->def_wep_key_idx = -1; 1985 arvif->def_wep_key_idx = -1;
1876 1986
1987 ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap);
1988 if (ret) {
1989 ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n",
1990 arvif->vdev_id, ret);
1991 return;
1992 }
1993
1877 arvif->is_up = false; 1994 arvif->is_up = false;
1878} 1995}
1879 1996
@@ -2554,6 +2671,17 @@ static int ath10k_start_scan(struct ath10k *ar,
2554 return -ETIMEDOUT; 2671 return -ETIMEDOUT;
2555 } 2672 }
2556 2673
2674 /* If we failed to start the scan, return error code at
2675 * this point. This is probably due to some issue in the
2676 * firmware, but no need to wedge the driver due to that...
2677 */
2678 spin_lock_bh(&ar->data_lock);
2679 if (ar->scan.state == ATH10K_SCAN_IDLE) {
2680 spin_unlock_bh(&ar->data_lock);
2681 return -EINVAL;
2682 }
2683 spin_unlock_bh(&ar->data_lock);
2684
2557 /* Add a 200ms margin to account for event/command processing */ 2685 /* Add a 200ms margin to account for event/command processing */
2558 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, 2686 ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
2559 msecs_to_jiffies(arg->max_scan_time+200)); 2687 msecs_to_jiffies(arg->max_scan_time+200));
@@ -3323,9 +3451,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3323 list_del(&arvif->list); 3451 list_del(&arvif->list);
3324 3452
3325 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { 3453 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3326 ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); 3454 ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id,
3455 vif->addr);
3327 if (ret) 3456 if (ret)
3328 ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n", 3457 ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n",
3329 arvif->vdev_id, ret); 3458 arvif->vdev_id, ret);
3330 3459
3331 kfree(arvif->u.ap.noa_data); 3460 kfree(arvif->u.ap.noa_data);
@@ -3339,6 +3468,21 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3339 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", 3468 ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
3340 arvif->vdev_id, ret); 3469 arvif->vdev_id, ret);
3341 3470
3471 /* Some firmware revisions don't notify host about self-peer removal
3472 * until after associated vdev is deleted.
3473 */
3474 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
3475 ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id,
3476 vif->addr);
3477 if (ret)
3478 ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n",
3479 arvif->vdev_id, ret);
3480
3481 spin_lock_bh(&ar->data_lock);
3482 ar->num_peers--;
3483 spin_unlock_bh(&ar->data_lock);
3484 }
3485
3342 ath10k_peer_cleanup(ar, arvif->vdev_id); 3486 ath10k_peer_cleanup(ar, arvif->vdev_id);
3343 3487
3344 mutex_unlock(&ar->conf_mutex); 3488 mutex_unlock(&ar->conf_mutex);
@@ -3534,7 +3678,9 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3534 } 3678 }
3535 3679
3536 if (changed & BSS_CHANGED_PS) { 3680 if (changed & BSS_CHANGED_PS) {
3537 ret = ath10k_mac_vif_setup_ps(arvif); 3681 arvif->ps = vif->bss_conf.ps;
3682
3683 ret = ath10k_config_ps(ar);
3538 if (ret) 3684 if (ret)
3539 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n", 3685 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
3540 arvif->vdev_id, ret); 3686 arvif->vdev_id, ret);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index e6972b09333e..7681237fe298 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -104,7 +104,7 @@ static const struct ce_attr host_ce_config_wlan[] = {
104 { 104 {
105 .flags = CE_ATTR_FLAGS, 105 .flags = CE_ATTR_FLAGS,
106 .src_nentries = 0, 106 .src_nentries = 0,
107 .src_sz_max = 512, 107 .src_sz_max = 2048,
108 .dest_nentries = 512, 108 .dest_nentries = 512,
109 }, 109 },
110 110
@@ -174,7 +174,7 @@ static const struct ce_pipe_config target_ce_config_wlan[] = {
174 .pipenum = __cpu_to_le32(1), 174 .pipenum = __cpu_to_le32(1),
175 .pipedir = __cpu_to_le32(PIPEDIR_IN), 175 .pipedir = __cpu_to_le32(PIPEDIR_IN),
176 .nentries = __cpu_to_le32(32), 176 .nentries = __cpu_to_le32(32),
177 .nbytes_max = __cpu_to_le32(512), 177 .nbytes_max = __cpu_to_le32(2048),
178 .flags = __cpu_to_le32(CE_ATTR_FLAGS), 178 .flags = __cpu_to_le32(CE_ATTR_FLAGS),
179 .reserved = __cpu_to_le32(0), 179 .reserved = __cpu_to_le32(0),
180 }, 180 },
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 04dc4b9db04e..c8b64e7a6089 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -110,8 +110,7 @@ struct wmi_ops {
110 bool deliver_cab); 110 bool deliver_cab);
111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar, 111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
112 const struct wmi_wmm_params_all_arg *arg); 112 const struct wmi_wmm_params_all_arg *arg);
113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, 113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar, u32 stats_mask);
114 enum wmi_stats_id stats_id);
115 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar, 114 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
116 enum wmi_force_fw_hang_type type, 115 enum wmi_force_fw_hang_type type,
117 u32 delay_ms); 116 u32 delay_ms);
@@ -816,14 +815,14 @@ ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
816} 815}
817 816
818static inline int 817static inline int
819ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 818ath10k_wmi_request_stats(struct ath10k *ar, u32 stats_mask)
820{ 819{
821 struct sk_buff *skb; 820 struct sk_buff *skb;
822 821
823 if (!ar->wmi.ops->gen_request_stats) 822 if (!ar->wmi.ops->gen_request_stats)
824 return -EOPNOTSUPP; 823 return -EOPNOTSUPP;
825 824
826 skb = ar->wmi.ops->gen_request_stats(ar, stats_id); 825 skb = ar->wmi.ops->gen_request_stats(ar, stats_mask);
827 if (IS_ERR(skb)) 826 if (IS_ERR(skb))
828 return PTR_ERR(skb); 827 return PTR_ERR(skb);
829 828
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 71614ba1b145..ee0c5f602e29 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -869,16 +869,57 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
869 return 0; 869 return 0;
870} 870}
871 871
872static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
873 struct ath10k_fw_stats_vdev *dst)
874{
875 int i;
876
877 dst->vdev_id = __le32_to_cpu(src->vdev_id);
878 dst->beacon_snr = __le32_to_cpu(src->beacon_snr);
879 dst->data_snr = __le32_to_cpu(src->data_snr);
880 dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames);
881 dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail);
882 dst->num_rts_success = __le32_to_cpu(src->num_rts_success);
883 dst->num_rx_err = __le32_to_cpu(src->num_rx_err);
884 dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard);
885 dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked);
886
887 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++)
888 dst->num_tx_frames[i] =
889 __le32_to_cpu(src->num_tx_frames[i]);
890
891 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++)
892 dst->num_tx_frames_retries[i] =
893 __le32_to_cpu(src->num_tx_frames_retries[i]);
894
895 for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++)
896 dst->num_tx_frames_failures[i] =
897 __le32_to_cpu(src->num_tx_frames_failures[i]);
898
899 for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++)
900 dst->tx_rate_history[i] =
901 __le32_to_cpu(src->tx_rate_history[i]);
902
903 for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++)
904 dst->beacon_rssi_history[i] =
905 __le32_to_cpu(src->beacon_rssi_history[i]);
906}
907
872static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, 908static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
873 struct sk_buff *skb, 909 struct sk_buff *skb,
874 struct ath10k_fw_stats *stats) 910 struct ath10k_fw_stats *stats)
875{ 911{
876 const void **tb; 912 const void **tb;
877 const struct wmi_stats_event *ev; 913 const struct wmi_tlv_stats_ev *ev;
878 const void *data; 914 const void *data;
879 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 915 u32 num_pdev_stats;
916 u32 num_vdev_stats;
917 u32 num_peer_stats;
918 u32 num_bcnflt_stats;
919 u32 num_chan_stats;
880 size_t data_len; 920 size_t data_len;
881 int ret; 921 int ret;
922 int i;
882 923
883 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); 924 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
884 if (IS_ERR(tb)) { 925 if (IS_ERR(tb)) {
@@ -899,8 +940,73 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
899 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); 940 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
900 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); 941 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
901 num_peer_stats = __le32_to_cpu(ev->num_peer_stats); 942 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
943 num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats);
944 num_chan_stats = __le32_to_cpu(ev->num_chan_stats);
945
946 ath10k_dbg(ar, ATH10K_DBG_WMI,
947 "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n",
948 num_pdev_stats, num_vdev_stats, num_peer_stats,
949 num_bcnflt_stats, num_chan_stats);
950
951 for (i = 0; i < num_pdev_stats; i++) {
952 const struct wmi_pdev_stats *src;
953 struct ath10k_fw_stats_pdev *dst;
954
955 src = data;
956 if (data_len < sizeof(*src))
957 return -EPROTO;
958
959 data += sizeof(*src);
960 data_len -= sizeof(*src);
961
962 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
963 if (!dst)
964 continue;
965
966 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
967 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
968 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
969 list_add_tail(&dst->list, &stats->pdevs);
970 }
971
972 for (i = 0; i < num_vdev_stats; i++) {
973 const struct wmi_tlv_vdev_stats *src;
974 struct ath10k_fw_stats_vdev *dst;
975
976 src = data;
977 if (data_len < sizeof(*src))
978 return -EPROTO;
979
980 data += sizeof(*src);
981 data_len -= sizeof(*src);
982
983 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
984 if (!dst)
985 continue;
902 986
903 WARN_ON(1); /* FIXME: not implemented yet */ 987 ath10k_wmi_tlv_pull_vdev_stats(src, dst);
988 list_add_tail(&dst->list, &stats->vdevs);
989 }
990
991 for (i = 0; i < num_peer_stats; i++) {
992 const struct wmi_10x_peer_stats *src;
993 struct ath10k_fw_stats_peer *dst;
994
995 src = data;
996 if (data_len < sizeof(*src))
997 return -EPROTO;
998
999 data += sizeof(*src);
1000 data_len -= sizeof(*src);
1001
1002 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1003 if (!dst)
1004 continue;
1005
1006 ath10k_wmi_pull_peer_stats(&src->old, dst);
1007 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
1008 list_add_tail(&dst->list, &stats->peers);
1009 }
904 1010
905 kfree(tb); 1011 kfree(tb);
906 return 0; 1012 return 0;
@@ -1604,14 +1710,12 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1604 const struct wmi_wmm_params_all_arg *arg) 1710 const struct wmi_wmm_params_all_arg *arg)
1605{ 1711{
1606 struct wmi_tlv_vdev_set_wmm_cmd *cmd; 1712 struct wmi_tlv_vdev_set_wmm_cmd *cmd;
1607 struct wmi_wmm_params *wmm;
1608 struct wmi_tlv *tlv; 1713 struct wmi_tlv *tlv;
1609 struct sk_buff *skb; 1714 struct sk_buff *skb;
1610 size_t len; 1715 size_t len;
1611 void *ptr; 1716 void *ptr;
1612 1717
1613 len = (sizeof(*tlv) + sizeof(*cmd)) + 1718 len = sizeof(*tlv) + sizeof(*cmd);
1614 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1615 skb = ath10k_wmi_alloc_skb(ar, len); 1719 skb = ath10k_wmi_alloc_skb(ar, len);
1616 if (!skb) 1720 if (!skb)
1617 return ERR_PTR(-ENOMEM); 1721 return ERR_PTR(-ENOMEM);
@@ -1623,13 +1727,10 @@ ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1623 cmd = (void *)tlv->value; 1727 cmd = (void *)tlv->value;
1624 cmd->vdev_id = __cpu_to_le32(vdev_id); 1728 cmd->vdev_id = __cpu_to_le32(vdev_id);
1625 1729
1626 ptr += sizeof(*tlv); 1730 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be);
1627 ptr += sizeof(*cmd); 1731 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk);
1628 1732 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi);
1629 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); 1733 ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo);
1630 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1631 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1632 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1633 1734
1634 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); 1735 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
1635 return skb; 1736 return skb;
@@ -2080,8 +2181,7 @@ ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
2080} 2181}
2081 2182
2082static struct sk_buff * 2183static struct sk_buff *
2083ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, 2184ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
2084 enum wmi_stats_id stats_id)
2085{ 2185{
2086 struct wmi_request_stats_cmd *cmd; 2186 struct wmi_request_stats_cmd *cmd;
2087 struct wmi_tlv *tlv; 2187 struct wmi_tlv *tlv;
@@ -2095,7 +2195,7 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
2095 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); 2195 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
2096 tlv->len = __cpu_to_le16(sizeof(*cmd)); 2196 tlv->len = __cpu_to_le16(sizeof(*cmd));
2097 cmd = (void *)tlv->value; 2197 cmd = (void *)tlv->value;
2098 cmd->stats_id = __cpu_to_le32(stats_id); 2198 cmd->stats_id = __cpu_to_le32(stats_mask);
2099 2199
2100 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); 2200 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
2101 return skb; 2201 return skb;
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
index de68fe76eae6..a6c8280cc4b1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -1302,8 +1302,14 @@ struct wmi_tlv_pdev_set_wmm_cmd {
1302 __le32 dg_type; /* no idea.. */ 1302 __le32 dg_type; /* no idea.. */
1303} __packed; 1303} __packed;
1304 1304
1305struct wmi_tlv_vdev_wmm_params {
1306 __le32 dummy;
1307 struct wmi_wmm_params params;
1308} __packed;
1309
1305struct wmi_tlv_vdev_set_wmm_cmd { 1310struct wmi_tlv_vdev_set_wmm_cmd {
1306 __le32 vdev_id; 1311 __le32 vdev_id;
1312 struct wmi_tlv_vdev_wmm_params vdev_wmm_params[4];
1307} __packed; 1313} __packed;
1308 1314
1309struct wmi_tlv_phyerr_ev { 1315struct wmi_tlv_phyerr_ev {
@@ -1439,6 +1445,15 @@ struct wmi_tlv_sta_keepalive_cmd {
1439 __le32 interval; /* in seconds */ 1445 __le32 interval; /* in seconds */
1440} __packed; 1446} __packed;
1441 1447
1448struct wmi_tlv_stats_ev {
1449 __le32 stats_id; /* WMI_STAT_ */
1450 __le32 num_pdev_stats;
1451 __le32 num_vdev_stats;
1452 __le32 num_peer_stats;
1453 __le32 num_bcnflt_stats;
1454 __le32 num_chan_stats;
1455} __packed;
1456
1442void ath10k_wmi_tlv_attach(struct ath10k *ar); 1457void ath10k_wmi_tlv_attach(struct ath10k *ar);
1443 1458
1444#endif 1459#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index aeea1c793943..c7ea77edce24 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1125,6 +1125,25 @@ static void ath10k_wmi_event_scan_started(struct ath10k *ar)
1125 } 1125 }
1126} 1126}
1127 1127
1128static void ath10k_wmi_event_scan_start_failed(struct ath10k *ar)
1129{
1130 lockdep_assert_held(&ar->data_lock);
1131
1132 switch (ar->scan.state) {
1133 case ATH10K_SCAN_IDLE:
1134 case ATH10K_SCAN_RUNNING:
1135 case ATH10K_SCAN_ABORTING:
1136 ath10k_warn(ar, "received scan start failed event in an invalid scan state: %s (%d)\n",
1137 ath10k_scan_state_str(ar->scan.state),
1138 ar->scan.state);
1139 break;
1140 case ATH10K_SCAN_STARTING:
1141 complete(&ar->scan.started);
1142 __ath10k_scan_finish(ar);
1143 break;
1144 }
1145}
1146
1128static void ath10k_wmi_event_scan_completed(struct ath10k *ar) 1147static void ath10k_wmi_event_scan_completed(struct ath10k *ar)
1129{ 1148{
1130 lockdep_assert_held(&ar->data_lock); 1149 lockdep_assert_held(&ar->data_lock);
@@ -1292,6 +1311,7 @@ int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
1292 break; 1311 break;
1293 case WMI_SCAN_EVENT_START_FAILED: 1312 case WMI_SCAN_EVENT_START_FAILED:
1294 ath10k_warn(ar, "received scan start failure event\n"); 1313 ath10k_warn(ar, "received scan start failure event\n");
1314 ath10k_wmi_event_scan_start_failed(ar);
1295 break; 1315 break;
1296 case WMI_SCAN_EVENT_DEQUEUED: 1316 case WMI_SCAN_EVENT_DEQUEUED:
1297 case WMI_SCAN_EVENT_PREEMPTED: 1317 case WMI_SCAN_EVENT_PREEMPTED:
@@ -4954,7 +4974,7 @@ ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
4954} 4974}
4955 4975
4956static struct sk_buff * 4976static struct sk_buff *
4957ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 4977ath10k_wmi_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
4958{ 4978{
4959 struct wmi_request_stats_cmd *cmd; 4979 struct wmi_request_stats_cmd *cmd;
4960 struct sk_buff *skb; 4980 struct sk_buff *skb;
@@ -4964,9 +4984,10 @@ ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
4964 return ERR_PTR(-ENOMEM); 4984 return ERR_PTR(-ENOMEM);
4965 4985
4966 cmd = (struct wmi_request_stats_cmd *)skb->data; 4986 cmd = (struct wmi_request_stats_cmd *)skb->data;
4967 cmd->stats_id = __cpu_to_le32(stats_id); 4987 cmd->stats_id = __cpu_to_le32(stats_mask);
4968 4988
4969 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4989 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats 0x%08x\n",
4990 stats_mask);
4970 return skb; 4991 return skb;
4971} 4992}
4972 4993
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 20ce3603e64b..adf935bf0580 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -3057,8 +3057,12 @@ struct wmi_pdev_stats_peer {
3057} __packed; 3057} __packed;
3058 3058
3059enum wmi_stats_id { 3059enum wmi_stats_id {
3060 WMI_REQUEST_PEER_STAT = 0x01, 3060 WMI_STAT_PEER = BIT(0),
3061 WMI_REQUEST_AP_STAT = 0x02 3061 WMI_STAT_AP = BIT(1),
3062 WMI_STAT_PDEV = BIT(2),
3063 WMI_STAT_VDEV = BIT(3),
3064 WMI_STAT_BCNFLT = BIT(4),
3065 WMI_STAT_VDEV_RATE = BIT(5),
3062}; 3066};
3063 3067
3064struct wlan_inst_rssi_args { 3068struct wlan_inst_rssi_args {
@@ -3093,7 +3097,7 @@ struct wmi_pdev_suspend_cmd {
3093} __packed; 3097} __packed;
3094 3098
3095struct wmi_stats_event { 3099struct wmi_stats_event {
3096 __le32 stats_id; /* %WMI_REQUEST_ */ 3100 __le32 stats_id; /* WMI_STAT_ */
3097 /* 3101 /*
3098 * number of pdev stats event structures 3102 * number of pdev stats event structures
3099 * (wmi_pdev_stats) 0 or 1 3103 * (wmi_pdev_stats) 0 or 1
@@ -3745,6 +3749,11 @@ enum wmi_10x_vdev_param {
3745 WMI_10X_VDEV_PARAM_VHT80_RATEMASK, 3749 WMI_10X_VDEV_PARAM_VHT80_RATEMASK,
3746}; 3750};
3747 3751
3752#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0)
3753#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1)
3754#define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2)
3755#define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
3756
3748/* slot time long */ 3757/* slot time long */
3749#define WMI_VDEV_SLOT_TIME_LONG 0x1 3758#define WMI_VDEV_SLOT_TIME_LONG 0x1
3750/* slot time short */ 3759/* slot time short */
@@ -4436,7 +4445,8 @@ enum wmi_peer_param {
4436 WMI_PEER_AUTHORIZE = 0x3, 4445 WMI_PEER_AUTHORIZE = 0x3,
4437 WMI_PEER_CHAN_WIDTH = 0x4, 4446 WMI_PEER_CHAN_WIDTH = 0x4,
4438 WMI_PEER_NSS = 0x5, 4447 WMI_PEER_NSS = 0x5,
4439 WMI_PEER_USE_4ADDR = 0x6 4448 WMI_PEER_USE_4ADDR = 0x6,
4449 WMI_PEER_DUMMY_VAR = 0xff, /* dummy parameter for STA PS workaround */
4440}; 4450};
4441 4451
4442struct wmi_peer_set_param_cmd { 4452struct wmi_peer_set_param_cmd {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index 7b94a6c7db3d..bd169fae32a1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -284,12 +284,12 @@ static void ar9003_mci_prep_interface(struct ath_hw *ah)
284 AR_MCI_INTERRUPT_RX_MSG_CONT_RST); 284 AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
285 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); 285 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);
286 286
287 if (mci->is_2g) { 287 if (mci->is_2g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
288 ar9003_mci_send_lna_transfer(ah, true); 288 ar9003_mci_send_lna_transfer(ah, true);
289 udelay(5); 289 udelay(5);
290 } 290 }
291 291
292 if ((mci->is_2g && !mci->update_2g5g)) { 292 if (mci->is_2g && !mci->update_2g5g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
293 if (ar9003_mci_wait_for_interrupt(ah, 293 if (ar9003_mci_wait_for_interrupt(ah,
294 AR_MCI_INTERRUPT_RX_MSG_RAW, 294 AR_MCI_INTERRUPT_RX_MSG_RAW,
295 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, 295 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
@@ -593,7 +593,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
593 if (!time_out) 593 if (!time_out)
594 break; 594 break;
595 595
596 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); 596 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
597 597
598 if (offset == MCI_GPM_INVALID) 598 if (offset == MCI_GPM_INVALID)
599 continue; 599 continue;
@@ -657,7 +657,7 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
657 time_out = 0; 657 time_out = 0;
658 658
659 while (more_data == MCI_GPM_MORE) { 659 while (more_data == MCI_GPM_MORE) {
660 offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); 660 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
661 if (offset == MCI_GPM_INVALID) 661 if (offset == MCI_GPM_INVALID)
662 break; 662 break;
663 663
@@ -771,8 +771,14 @@ exit:
771 771
772static void ar9003_mci_mute_bt(struct ath_hw *ah) 772static void ar9003_mci_mute_bt(struct ath_hw *ah)
773{ 773{
774 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
775
774 /* disable all MCI messages */ 776 /* disable all MCI messages */
775 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); 777 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
778 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
779 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
780 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
781 REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
776 REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 782 REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
777 783
778 /* wait pending HW messages to flush out */ 784 /* wait pending HW messages to flush out */
@@ -783,9 +789,10 @@ static void ar9003_mci_mute_bt(struct ath_hw *ah)
783 * 1. reset not after resuming from full sleep 789 * 1. reset not after resuming from full sleep
784 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment 790 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
785 */ 791 */
786 ar9003_mci_send_lna_take(ah, true); 792 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
787 793 ar9003_mci_send_lna_take(ah, true);
788 udelay(5); 794 udelay(5);
795 }
789 796
790 ar9003_mci_send_sys_sleeping(ah, true); 797 ar9003_mci_send_sys_sleeping(ah, true);
791} 798}
@@ -821,6 +828,80 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
821 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); 828 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
822} 829}
823 830
831static void ar9003_mci_stat_setup(struct ath_hw *ah)
832{
833 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
834
835 if (!AR_SREV_9565(ah))
836 return;
837
838 if (mci->config & ATH_MCI_CONFIG_MCI_STAT_DBG) {
839 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
840 AR_MCI_DBG_CNT_CTRL_ENABLE, 1);
841 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
842 AR_MCI_DBG_CNT_CTRL_BT_LINKID,
843 MCI_STAT_ALL_BT_LINKID);
844 } else {
845 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
846 AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
847 }
848}
849
850static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw *ah)
851{
852 u32 regval;
853
854 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
855 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
856 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
857 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
858 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
859 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
860 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
861 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
862 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
863
864 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
865 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1);
866 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
867}
868
869static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw *ah)
870{
871 u32 regval;
872
873 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
874 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
875 SM(0, AR_BTCOEX_CTRL_PA_SHARED) |
876 SM(0, AR_BTCOEX_CTRL_LNA_SHARED) |
877 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
878 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
879 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
880 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
881 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
882
883 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
884 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0);
885 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
886}
887
888static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw *ah)
889{
890 u32 regval;
891
892 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
893 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
894 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
895 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
896 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
897 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
898 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
899 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
900 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
901
902 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
903}
904
824int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, 905int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
825 bool is_full_sleep) 906 bool is_full_sleep)
826{ 907{
@@ -831,11 +912,6 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
831 ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n", 912 ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
832 is_full_sleep, is_2g); 913 is_full_sleep, is_2g);
833 914
834 if (!mci->gpm_addr && !mci->sched_addr) {
835 ath_err(common, "MCI GPM and schedule buffers are not allocated\n");
836 return -ENOMEM;
837 }
838
839 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { 915 if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
840 ath_err(common, "BTCOEX control register is dead\n"); 916 ath_err(common, "BTCOEX control register is dead\n");
841 return -EINVAL; 917 return -EINVAL;
@@ -850,26 +926,17 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
850 * To avoid MCI state machine be affected by incoming remote MCI msgs, 926 * To avoid MCI state machine be affected by incoming remote MCI msgs,
851 * MCI mode will be enabled later, right before reset the MCI TX and RX. 927 * MCI mode will be enabled later, right before reset the MCI TX and RX.
852 */ 928 */
853
854 regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
855 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
856 SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
857 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
858 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
859 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
860 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
861 if (AR_SREV_9565(ah)) { 929 if (AR_SREV_9565(ah)) {
862 regval |= SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 930 u8 ant = MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH);
863 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK); 931
864 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 932 if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED)
865 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1); 933 ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah);
934 else
935 ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah);
866 } else { 936 } else {
867 regval |= SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 937 ar9003_mci_set_btcoex_ctrl_9462(ah);
868 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK);
869 } 938 }
870 939
871 REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
872
873 if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) 940 if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
874 ar9003_mci_osla_setup(ah, true); 941 ar9003_mci_osla_setup(ah, true);
875 else 942 else
@@ -926,23 +993,26 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
926 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); 993 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
927 REG_WRITE(ah, AR_MCI_COMMAND2, regval); 994 REG_WRITE(ah, AR_MCI_COMMAND2, regval);
928 995
929 ar9003_mci_get_next_gpm_offset(ah, true, NULL); 996 /* Init GPM offset after MCI Reset Rx */
997 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);
930 998
931 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 999 REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
932 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | 1000 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
933 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM))); 1001 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
934 1002
935 REG_CLR_BIT(ah, AR_MCI_TX_CTRL, 1003 if (MCI_ANT_ARCH_PA_LNA_SHARED(mci))
936 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1004 REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
1005 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
1006 else
1007 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
1008 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
937 1009
938 ar9003_mci_observation_set_up(ah); 1010 ar9003_mci_observation_set_up(ah);
939 1011
940 mci->ready = true; 1012 mci->ready = true;
941 ar9003_mci_prep_interface(ah); 1013 ar9003_mci_prep_interface(ah);
1014 ar9003_mci_stat_setup(ah);
942 1015
943 if (AR_SREV_9565(ah))
944 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
945 AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
946 if (en_int) 1016 if (en_int)
947 ar9003_mci_enable_interrupt(ah); 1017 ar9003_mci_enable_interrupt(ah);
948 1018
@@ -1218,6 +1288,14 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
1218 } 1288 }
1219 value &= AR_BTCOEX_CTRL_MCI_MODE_EN; 1289 value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
1220 break; 1290 break;
1291 case MCI_STATE_INIT_GPM_OFFSET:
1292 value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1293
1294 if (value < mci->gpm_len)
1295 mci->gpm_idx = value;
1296 else
1297 mci->gpm_idx = 0;
1298 break;
1221 case MCI_STATE_LAST_SCHD_MSG_OFFSET: 1299 case MCI_STATE_LAST_SCHD_MSG_OFFSET:
1222 value = MS(REG_READ(ah, AR_MCI_RX_STATUS), 1300 value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
1223 AR_MCI_RX_LAST_SCHD_MSG_INDEX); 1301 AR_MCI_RX_LAST_SCHD_MSG_INDEX);
@@ -1364,21 +1442,11 @@ void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
1364 mci->gpm_idx = 0; 1442 mci->gpm_idx = 0;
1365} 1443}
1366 1444
1367u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) 1445u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more)
1368{ 1446{
1369 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; 1447 struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
1370 u32 offset, more_gpm = 0, gpm_ptr; 1448 u32 offset, more_gpm = 0, gpm_ptr;
1371 1449
1372 if (first) {
1373 gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
1374
1375 if (gpm_ptr >= mci->gpm_len)
1376 gpm_ptr = 0;
1377
1378 mci->gpm_idx = gpm_ptr;
1379 return gpm_ptr;
1380 }
1381
1382 /* 1450 /*
1383 * This could be useful to avoid new GPM message interrupt which 1451 * This could be useful to avoid new GPM message interrupt which
1384 * may lead to spurious interrupt after power sleep, or multiple 1452 * may lead to spurious interrupt after power sleep, or multiple
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
index 66d7ab9f920d..e288611c12d5 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
@@ -92,14 +92,36 @@ enum mci_gpm_coex_bt_update_flags_op {
92#define ATH_MCI_CONFIG_CLK_DIV 0x00003000 92#define ATH_MCI_CONFIG_CLK_DIV 0x00003000
93#define ATH_MCI_CONFIG_CLK_DIV_S 12 93#define ATH_MCI_CONFIG_CLK_DIV_S 12
94#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000 94#define ATH_MCI_CONFIG_DISABLE_TUNING 0x00004000
95#define ATH_MCI_CONFIG_DISABLE_AIC 0x00008000
96#define ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN 0x007f0000
97#define ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN_S 16
98#define ATH_MCI_CONFIG_NO_QUIET_ACK 0x00800000
99#define ATH_MCI_CONFIG_NO_QUIET_ACK_S 23
100#define ATH_MCI_CONFIG_ANT_ARCH 0x07000000
101#define ATH_MCI_CONFIG_ANT_ARCH_S 24
102#define ATH_MCI_CONFIG_FORCE_QUIET_ACK 0x08000000
103#define ATH_MCI_CONFIG_FORCE_QUIET_ACK_S 27
104#define ATH_MCI_CONFIG_FORCE_2CHAIN_ACK 0x10000000
105#define ATH_MCI_CONFIG_MCI_STAT_DBG 0x20000000
95#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000 106#define ATH_MCI_CONFIG_MCI_WEIGHT_DBG 0x40000000
96#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000 107#define ATH_MCI_CONFIG_DISABLE_MCI 0x80000000
97 108
98#define ATH_MCI_CONFIG_MCI_OBS_MASK (ATH_MCI_CONFIG_MCI_OBS_MCI | \ 109#define ATH_MCI_CONFIG_MCI_OBS_MASK (ATH_MCI_CONFIG_MCI_OBS_MCI | \
99 ATH_MCI_CONFIG_MCI_OBS_TXRX | \ 110 ATH_MCI_CONFIG_MCI_OBS_TXRX | \
100 ATH_MCI_CONFIG_MCI_OBS_BT) 111 ATH_MCI_CONFIG_MCI_OBS_BT)
112
101#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F 113#define ATH_MCI_CONFIG_MCI_OBS_GPIO 0x0000002F
102 114
115#define ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_NON_SHARED 0x00
116#define ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED 0x01
117#define ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_NON_SHARED 0x02
118#define ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_SHARED 0x03
119#define ATH_MCI_ANT_ARCH_3_ANT 0x04
120
121#define MCI_ANT_ARCH_PA_LNA_SHARED(mci) \
122 ((MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH) == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED) || \
123 (MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH) == ATH_MCI_ANT_ARCH_2_ANT_PA_LNA_SHARED))
124
103enum mci_message_header { /* length of payload */ 125enum mci_message_header { /* length of payload */
104 MCI_LNA_CTRL = 0x10, /* len = 0 */ 126 MCI_LNA_CTRL = 0x10, /* len = 0 */
105 MCI_CONT_NACK = 0x20, /* len = 0 */ 127 MCI_CONT_NACK = 0x20, /* len = 0 */
@@ -188,20 +210,55 @@ enum mci_bt_state {
188 MCI_BT_CAL 210 MCI_BT_CAL
189}; 211};
190 212
213enum mci_ps_state {
214 MCI_PS_DISABLE,
215 MCI_PS_ENABLE,
216 MCI_PS_ENABLE_OFF,
217 MCI_PS_ENABLE_ON
218};
219
191/* Type of state query */ 220/* Type of state query */
192enum mci_state_type { 221enum mci_state_type {
193 MCI_STATE_ENABLE, 222 MCI_STATE_ENABLE,
223 MCI_STATE_INIT_GPM_OFFSET,
224 MCI_STATE_CHECK_GPM_OFFSET,
225 MCI_STATE_NEXT_GPM_OFFSET,
226 MCI_STATE_LAST_GPM_OFFSET,
227 MCI_STATE_BT,
228 MCI_STATE_SET_BT_SLEEP,
194 MCI_STATE_SET_BT_AWAKE, 229 MCI_STATE_SET_BT_AWAKE,
230 MCI_STATE_SET_BT_CAL_START,
231 MCI_STATE_SET_BT_CAL,
195 MCI_STATE_LAST_SCHD_MSG_OFFSET, 232 MCI_STATE_LAST_SCHD_MSG_OFFSET,
196 MCI_STATE_REMOTE_SLEEP, 233 MCI_STATE_REMOTE_SLEEP,
234 MCI_STATE_CONT_STATUS,
197 MCI_STATE_RESET_REQ_WAKE, 235 MCI_STATE_RESET_REQ_WAKE,
198 MCI_STATE_SEND_WLAN_COEX_VERSION, 236 MCI_STATE_SEND_WLAN_COEX_VERSION,
237 MCI_STATE_SET_BT_COEX_VERSION,
238 MCI_STATE_SEND_WLAN_CHANNELS,
199 MCI_STATE_SEND_VERSION_QUERY, 239 MCI_STATE_SEND_VERSION_QUERY,
200 MCI_STATE_SEND_STATUS_QUERY, 240 MCI_STATE_SEND_STATUS_QUERY,
241 MCI_STATE_NEED_FLUSH_BT_INFO,
242 MCI_STATE_SET_CONCUR_TX_PRI,
201 MCI_STATE_RECOVER_RX, 243 MCI_STATE_RECOVER_RX,
202 MCI_STATE_NEED_FTP_STOMP, 244 MCI_STATE_NEED_FTP_STOMP,
245 MCI_STATE_NEED_TUNING,
246 MCI_STATE_NEED_STAT_DEBUG,
247 MCI_STATE_SHARED_CHAIN_CONCUR_TX,
248 MCI_STATE_AIC_CAL,
249 MCI_STATE_AIC_START,
250 MCI_STATE_AIC_CAL_RESET,
251 MCI_STATE_AIC_CAL_SINGLE,
252 MCI_STATE_IS_AR9462,
253 MCI_STATE_IS_AR9565_1ANT,
254 MCI_STATE_IS_AR9565_2ANT,
255 MCI_STATE_WLAN_WEAK_SIGNAL,
256 MCI_STATE_SET_WLAN_PS_STATE,
257 MCI_STATE_GET_WLAN_PS_STATE,
203 MCI_STATE_DEBUG, 258 MCI_STATE_DEBUG,
204 MCI_STATE_NEED_FLUSH_BT_INFO, 259 MCI_STATE_STAT_DEBUG,
260 MCI_STATE_ALLOW_FCS,
261 MCI_STATE_SET_2G_CONTENTION,
205 MCI_STATE_MAX 262 MCI_STATE_MAX
206}; 263};
207 264
@@ -255,7 +312,7 @@ int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
255void ar9003_mci_cleanup(struct ath_hw *ah); 312void ar9003_mci_cleanup(struct ath_hw *ah);
256void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, 313void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
257 u32 *rx_msg_intr); 314 u32 *rx_msg_intr);
258u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); 315u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more);
259void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); 316void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor);
260void ar9003_mci_send_wlan_channels(struct ath_hw *ah); 317void ar9003_mci_send_wlan_channels(struct ath_hw *ah);
261/* 318/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 86bfc9604dca..bea41df9fbd7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -20,11 +20,25 @@
20#include "reg_wow.h" 20#include "reg_wow.h"
21#include "hw-ops.h" 21#include "hw-ops.h"
22 22
23static void ath9k_hw_set_sta_powersave(struct ath_hw *ah)
24{
25 if (!ath9k_hw_mci_is_enabled(ah))
26 goto set;
27 /*
28 * If MCI is being used, set PWR_SAV only when MCI's
29 * PS state is disabled.
30 */
31 if (ar9003_mci_state(ah, MCI_STATE_GET_WLAN_PS_STATE) != MCI_PS_DISABLE)
32 return;
33set:
34 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
35}
36
23static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
24{ 38{
25 struct ath_common *common = ath9k_hw_common(ah); 39 struct ath_common *common = ath9k_hw_common(ah);
26 40
27 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 41 ath9k_hw_set_sta_powersave(ah);
28 42
29 /* set rx disable bit */ 43 /* set rx disable bit */
30 REG_WRITE(ah, AR_CR, AR_CR_RXD); 44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
@@ -44,6 +58,9 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
44 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE); 58 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE);
45 } 59 }
46 60
61 if (ath9k_hw_mci_is_enabled(ah))
62 REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
63
47 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 64 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
48} 65}
49 66
@@ -74,8 +91,6 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
74 for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 91 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
75 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 92 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
76 93
77 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
78
79 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | 94 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
80 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); 95 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
81 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | 96 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
@@ -88,9 +103,11 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
88 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); 103 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
89 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); 104 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
90 105
91 if (AR_SREV_9462_20(ah)) { 106 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
92 /* AR9462 2.0 has an extra descriptor word (time based 107 /*
93 * discard) compared to other chips */ 108 * AR9462 2.0 and AR9565 have an extra descriptor word
109 * (time based discard) compared to other chips.
110 */
94 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); 111 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
95 wow_ka_data_word0 = AR_WOW_TXBUF(13); 112 wow_ka_data_word0 = AR_WOW_TXBUF(13);
96 } else { 113 } else {
@@ -99,7 +116,6 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
99 116
100 for (i = 0; i < KAL_NUM_DATA_WORDS; i++) 117 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
101 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); 118 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
102
103} 119}
104 120
105int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 121int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
@@ -170,18 +186,17 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
170 u32 val = 0, rval; 186 u32 val = 0, rval;
171 187
172 /* 188 /*
173 * read the WoW status register to know 189 * Read the WoW status register to know
174 * the wakeup reason 190 * the wakeup reason.
175 */ 191 */
176 rval = REG_READ(ah, AR_WOW_PATTERN); 192 rval = REG_READ(ah, AR_WOW_PATTERN);
177 val = AR_WOW_STATUS(rval); 193 val = AR_WOW_STATUS(rval);
178 194
179 /* 195 /*
180 * mask only the WoW events that we have enabled. Sometimes 196 * Mask only the WoW events that we have enabled. Sometimes
181 * we have spurious WoW events from the AR_WOW_PATTERN 197 * we have spurious WoW events from the AR_WOW_PATTERN
182 * register. This mask will clean it up. 198 * register. This mask will clean it up.
183 */ 199 */
184
185 val &= ah->wow.wow_event_mask; 200 val &= ah->wow.wow_event_mask;
186 201
187 if (val) { 202 if (val) {
@@ -195,6 +210,15 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
195 wow_status |= AH_WOW_BEACON_MISS; 210 wow_status |= AH_WOW_BEACON_MISS;
196 } 211 }
197 212
213 rval = REG_READ(ah, AR_MAC_PCU_WOW4);
214 val = AR_WOW_STATUS2(rval);
215 val &= ah->wow.wow_event_mask2;
216
217 if (val) {
218 if (AR_WOW2_PATTERN_FOUND(val))
219 wow_status |= AH_WOW_USER_PATTERN_EN;
220 }
221
198 /* 222 /*
199 * set and clear WOW_PME_CLEAR registers for the chip to 223 * set and clear WOW_PME_CLEAR registers for the chip to
200 * generate next wow signal. 224 * generate next wow signal.
@@ -206,10 +230,12 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
206 AR_PMCTRL_PWR_STATE_D1D3); 230 AR_PMCTRL_PWR_STATE_D1D3);
207 231
208 /* 232 /*
209 * clear all events 233 * Clear all events.
210 */ 234 */
211 REG_WRITE(ah, AR_WOW_PATTERN, 235 REG_WRITE(ah, AR_WOW_PATTERN,
212 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); 236 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
237 REG_WRITE(ah, AR_MAC_PCU_WOW4,
238 AR_WOW_CLEAR_EVENTS2(REG_READ(ah, AR_MAC_PCU_WOW4)));
213 239
214 /* 240 /*
215 * restore the beacon threshold to init value 241 * restore the beacon threshold to init value
@@ -226,7 +252,15 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
226 if (ah->is_pciexpress) 252 if (ah->is_pciexpress)
227 ath9k_hw_configpcipowersave(ah, false); 253 ath9k_hw_configpcipowersave(ah, false);
228 254
255 if (AR_SREV_9462(ah) || AR_SREV_9565(ah) || AR_SREV_9485(ah)) {
256 u32 dc = REG_READ(ah, AR_DIRECT_CONNECT);
257
258 if (!(dc & AR_DC_TSF2_ENABLE))
259 ath9k_hw_gen_timer_start_tsf2(ah);
260 }
261
229 ah->wow.wow_event_mask = 0; 262 ah->wow.wow_event_mask = 0;
263 ah->wow.wow_event_mask2 = 0;
230 264
231 return wow_status; 265 return wow_status;
232} 266}
@@ -408,6 +442,9 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
408 442
409 ath9k_hw_wow_set_arwr_reg(ah); 443 ath9k_hw_wow_set_arwr_reg(ah);
410 444
445 if (ath9k_hw_mci_is_enabled(ah))
446 REG_WRITE(ah, AR_RTC_KEEP_AWAKE, 0x2);
447
411 /* HW WoW */ 448 /* HW WoW */
412 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, BIT(5)); 449 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, BIT(5));
413 450
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0f8e9464e4ab..7e89236c0e13 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -645,6 +645,7 @@ void ath9k_calculate_iter_data(struct ath_softc *sc,
645 struct ath9k_vif_iter_data *iter_data); 645 struct ath9k_vif_iter_data *iter_data);
646void ath9k_calculate_summary_state(struct ath_softc *sc, 646void ath9k_calculate_summary_state(struct ath_softc *sc,
647 struct ath_chanctx *ctx); 647 struct ath_chanctx *ctx);
648void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif);
648 649
649/*******************/ 650/*******************/
650/* Beacon Handling */ 651/* Beacon Handling */
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 3dfc2c7f1f07..5a084d94ed90 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -103,7 +103,9 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
103 return; 103 return;
104 } 104 }
105 105
106 if (AR_SREV_9300_20_OR_LATER(ah)) { 106 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
107 btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
108 } else if (AR_SREV_9300_20_OR_LATER(ah)) {
107 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; 109 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
108 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; 110 btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
109 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; 111 btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
@@ -307,6 +309,18 @@ static void ath9k_hw_btcoex_enable_mci(struct ath_hw *ah)
307 btcoex->enabled = true; 309 btcoex->enabled = true;
308} 310}
309 311
312static void ath9k_hw_btcoex_disable_mci(struct ath_hw *ah)
313{
314 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
315 int i;
316
317 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
318
319 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
320 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
321 btcoex_hw->wlan_weight[i]);
322}
323
310void ath9k_hw_btcoex_enable(struct ath_hw *ah) 324void ath9k_hw_btcoex_enable(struct ath_hw *ah)
311{ 325{
312 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 326 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
@@ -318,17 +332,18 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
318 ath9k_hw_btcoex_enable_2wire(ah); 332 ath9k_hw_btcoex_enable_2wire(ah);
319 break; 333 break;
320 case ATH_BTCOEX_CFG_3WIRE: 334 case ATH_BTCOEX_CFG_3WIRE:
321 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
322 ath9k_hw_btcoex_enable_mci(ah);
323 return;
324 }
325 ath9k_hw_btcoex_enable_3wire(ah); 335 ath9k_hw_btcoex_enable_3wire(ah);
326 break; 336 break;
337 case ATH_BTCOEX_CFG_MCI:
338 ath9k_hw_btcoex_enable_mci(ah);
339 break;
327 } 340 }
328 341
329 REG_RMW(ah, AR_GPIO_PDPU, 342 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI) {
330 (0x2 << (btcoex_hw->btactive_gpio * 2)), 343 REG_RMW(ah, AR_GPIO_PDPU,
331 (0x3 << (btcoex_hw->btactive_gpio * 2))); 344 (0x2 << (btcoex_hw->btactive_gpio * 2)),
345 (0x3 << (btcoex_hw->btactive_gpio * 2)));
346 }
332 347
333 ah->btcoex_hw.enabled = true; 348 ah->btcoex_hw.enabled = true;
334} 349}
@@ -340,14 +355,14 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
340 int i; 355 int i;
341 356
342 btcoex_hw->enabled = false; 357 btcoex_hw->enabled = false;
343 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 358
344 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); 359 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) {
345 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 360 ath9k_hw_btcoex_disable_mci(ah);
346 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
347 btcoex_hw->wlan_weight[i]);
348 return; 361 return;
349 } 362 }
350 ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); 363
364 if (!AR_SREV_9300_20_OR_LATER(ah))
365 ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);
351 366
352 ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio, 367 ath9k_hw_cfg_output(ah, btcoex_hw->wlanactive_gpio,
353 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 368 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 6de26ea5d5fa..5fe62ff2223b 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -58,6 +58,7 @@ enum ath_btcoex_scheme {
58 ATH_BTCOEX_CFG_NONE, 58 ATH_BTCOEX_CFG_NONE,
59 ATH_BTCOEX_CFG_2WIRE, 59 ATH_BTCOEX_CFG_2WIRE,
60 ATH_BTCOEX_CFG_3WIRE, 60 ATH_BTCOEX_CFG_3WIRE,
61 ATH_BTCOEX_CFG_MCI,
61}; 62};
62 63
63struct ath9k_hw_mci { 64struct ath9k_hw_mci {
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 50a2e0ac3b8b..dbf8f4959642 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1156,7 +1156,10 @@ static ssize_t write_file_tpc(struct file *file, const char __user *user_buf,
1156 1156
1157 if (tpc_enabled != ah->tpc_enabled) { 1157 if (tpc_enabled != ah->tpc_enabled) {
1158 ah->tpc_enabled = tpc_enabled; 1158 ah->tpc_enabled = tpc_enabled;
1159 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false); 1159
1160 mutex_lock(&sc->mutex);
1161 ath9k_set_txpower(sc, NULL);
1162 mutex_unlock(&sc->mutex);
1160 } 1163 }
1161 1164
1162 return count; 1165 return count;
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index da344b27326c..86d46c196966 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -202,17 +202,16 @@ static void ath_btcoex_period_timer(unsigned long data)
202 } 202 }
203 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 203 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
204 204
205 ath9k_mci_update_rssi(sc);
206
207 ath9k_ps_wakeup(sc); 205 ath9k_ps_wakeup(sc);
206 spin_lock_bh(&btcoex->btcoex_lock);
208 207
209 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) 208 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) {
210 ath_detect_bt_priority(sc); 209 ath9k_mci_update_rssi(sc);
211
212 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
213 ath_mci_ftp_adjust(sc); 210 ath_mci_ftp_adjust(sc);
211 }
214 212
215 spin_lock_bh(&btcoex->btcoex_lock); 213 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
214 ath_detect_bt_priority(sc);
216 215
217 stomp_type = btcoex->bt_stomp_type; 216 stomp_type = btcoex->bt_stomp_type;
218 timer_period = btcoex->btcoex_no_stomp; 217 timer_period = btcoex->btcoex_no_stomp;
@@ -252,9 +251,6 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg)
252 struct ath_softc *sc = (struct ath_softc *)arg; 251 struct ath_softc *sc = (struct ath_softc *)arg;
253 struct ath_hw *ah = sc->sc_ah; 252 struct ath_hw *ah = sc->sc_ah;
254 struct ath_btcoex *btcoex = &sc->btcoex; 253 struct ath_btcoex *btcoex = &sc->btcoex;
255 struct ath_common *common = ath9k_hw_common(ah);
256
257 ath_dbg(common, BTCOEX, "no stomp timer running\n");
258 254
259 ath9k_ps_wakeup(sc); 255 ath9k_ps_wakeup(sc);
260 spin_lock_bh(&btcoex->btcoex_lock); 256 spin_lock_bh(&btcoex->btcoex_lock);
@@ -271,7 +267,7 @@ static void ath_btcoex_no_stomp_timer(unsigned long arg)
271 ath9k_ps_restore(sc); 267 ath9k_ps_restore(sc);
272} 268}
273 269
274static int ath_init_btcoex_timer(struct ath_softc *sc) 270static void ath_init_btcoex_timer(struct ath_softc *sc)
275{ 271{
276 struct ath_btcoex *btcoex = &sc->btcoex; 272 struct ath_btcoex *btcoex = &sc->btcoex;
277 273
@@ -280,6 +276,7 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
280 btcoex->btcoex_period / 100; 276 btcoex->btcoex_period / 100;
281 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 277 btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) *
282 btcoex->btcoex_period / 100; 278 btcoex->btcoex_period / 100;
279 btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
283 280
284 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, 281 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
285 (unsigned long) sc); 282 (unsigned long) sc);
@@ -287,8 +284,6 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
287 (unsigned long) sc); 284 (unsigned long) sc);
288 285
289 spin_lock_init(&btcoex->btcoex_lock); 286 spin_lock_init(&btcoex->btcoex_lock);
290
291 return 0;
292} 287}
293 288
294/* 289/*
@@ -299,6 +294,10 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
299 struct ath_btcoex *btcoex = &sc->btcoex; 294 struct ath_btcoex *btcoex = &sc->btcoex;
300 struct ath_hw *ah = sc->sc_ah; 295 struct ath_hw *ah = sc->sc_ah;
301 296
297 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE &&
298 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI)
299 return;
300
302 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); 301 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n");
303 302
304 /* make sure duty cycle timer is also stopped when resuming */ 303 /* make sure duty cycle timer is also stopped when resuming */
@@ -312,13 +311,19 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)
312 mod_timer(&btcoex->period_timer, jiffies); 311 mod_timer(&btcoex->period_timer, jiffies);
313} 312}
314 313
315
316/* 314/*
317 * Pause btcoex timer and bt duty cycle timer 315 * Pause btcoex timer and bt duty cycle timer
318 */ 316 */
319void ath9k_btcoex_timer_pause(struct ath_softc *sc) 317void ath9k_btcoex_timer_pause(struct ath_softc *sc)
320{ 318{
321 struct ath_btcoex *btcoex = &sc->btcoex; 319 struct ath_btcoex *btcoex = &sc->btcoex;
320 struct ath_hw *ah = sc->sc_ah;
321
322 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_3WIRE &&
323 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI)
324 return;
325
326 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Stopping btcoex timers\n");
322 327
323 del_timer_sync(&btcoex->period_timer); 328 del_timer_sync(&btcoex->period_timer);
324 del_timer_sync(&btcoex->no_stomp_timer); 329 del_timer_sync(&btcoex->no_stomp_timer);
@@ -356,33 +361,33 @@ void ath9k_start_btcoex(struct ath_softc *sc)
356{ 361{
357 struct ath_hw *ah = sc->sc_ah; 362 struct ath_hw *ah = sc->sc_ah;
358 363
359 if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && 364 if (ah->btcoex_hw.enabled ||
360 !ah->btcoex_hw.enabled) { 365 ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
361 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) 366 return;
362 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
363 AR_STOMP_LOW_WLAN_WGHT, 0);
364 else
365 ath9k_hw_btcoex_set_weight(ah, 0, 0,
366 ATH_BTCOEX_STOMP_NONE);
367 ath9k_hw_btcoex_enable(ah);
368 367
369 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 368 if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
370 ath9k_btcoex_timer_resume(sc); 369 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
371 } 370 AR_STOMP_LOW_WLAN_WGHT, 0);
371 else
372 ath9k_hw_btcoex_set_weight(ah, 0, 0,
373 ATH_BTCOEX_STOMP_NONE);
374 ath9k_hw_btcoex_enable(ah);
375 ath9k_btcoex_timer_resume(sc);
372} 376}
373 377
374void ath9k_stop_btcoex(struct ath_softc *sc) 378void ath9k_stop_btcoex(struct ath_softc *sc)
375{ 379{
376 struct ath_hw *ah = sc->sc_ah; 380 struct ath_hw *ah = sc->sc_ah;
377 381
378 if (ah->btcoex_hw.enabled && 382 if (!ah->btcoex_hw.enabled ||
379 ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { 383 ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_NONE)
380 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) 384 return;
381 ath9k_btcoex_timer_pause(sc); 385
382 ath9k_hw_btcoex_disable(ah); 386 ath9k_btcoex_timer_pause(sc);
383 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) 387 ath9k_hw_btcoex_disable(ah);
384 ath_mci_flush_profile(&sc->btcoex.mci); 388
385 } 389 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI)
390 ath_mci_flush_profile(&sc->btcoex.mci);
386} 391}
387 392
388void ath9k_deinit_btcoex(struct ath_softc *sc) 393void ath9k_deinit_btcoex(struct ath_softc *sc)
@@ -409,22 +414,20 @@ int ath9k_init_btcoex(struct ath_softc *sc)
409 break; 414 break;
410 case ATH_BTCOEX_CFG_3WIRE: 415 case ATH_BTCOEX_CFG_3WIRE:
411 ath9k_hw_btcoex_init_3wire(sc->sc_ah); 416 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
412 r = ath_init_btcoex_timer(sc); 417 ath_init_btcoex_timer(sc);
413 if (r)
414 return -1;
415 txq = sc->tx.txq_map[IEEE80211_AC_BE]; 418 txq = sc->tx.txq_map[IEEE80211_AC_BE];
416 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); 419 ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
417 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; 420 break;
418 if (ath9k_hw_mci_is_enabled(ah)) { 421 case ATH_BTCOEX_CFG_MCI:
419 sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; 422 ath_init_btcoex_timer(sc);
420 INIT_LIST_HEAD(&sc->btcoex.mci.info);
421 423
422 r = ath_mci_setup(sc); 424 sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
423 if (r) 425 INIT_LIST_HEAD(&sc->btcoex.mci.info);
424 return r; 426 ath9k_hw_btcoex_init_mci(ah);
425 427
426 ath9k_hw_btcoex_init_mci(ah); 428 r = ath_mci_setup(sc);
427 } 429 if (r)
430 return r;
428 431
429 break; 432 break;
430 default: 433 default:
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 8e7153b186ed..10c02f5cbc5e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -40,6 +40,7 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
40 { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */ 40 { USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
41 { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */ 41 { USB_DEVICE(0x0cf3, 0xb002) }, /* Ubiquiti WifiStation */
42 { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */ 42 { USB_DEVICE(0x057c, 0x8403) }, /* AVM FRITZ!WLAN 11N v2 USB */
43 { USB_DEVICE(0x0471, 0x209e) }, /* Philips (or NXP) PTA01 */
43 44
44 { USB_DEVICE(0x0cf3, 0x7015), 45 { USB_DEVICE(0x0cf3, 0x7015),
45 .driver_info = AR9287_USB }, /* Atheros */ 46 .driver_info = AR9287_USB }, /* Atheros */
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index e82e570de330..29a25d92add7 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -27,6 +27,7 @@
27#include "eeprom.h" 27#include "eeprom.h"
28#include "calib.h" 28#include "calib.h"
29#include "reg.h" 29#include "reg.h"
30#include "reg_mci.h"
30#include "phy.h" 31#include "phy.h"
31#include "btcoex.h" 32#include "btcoex.h"
32#include "dynack.h" 33#include "dynack.h"
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 93ed99a72542..b0badef71ce7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1172,6 +1172,38 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1172 ath9k_ps_restore(sc); 1172 ath9k_ps_restore(sc);
1173} 1173}
1174 1174
1175static void ath9k_tpc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1176{
1177 int *power = (int *)data;
1178
1179 if (*power < vif->bss_conf.txpower)
1180 *power = vif->bss_conf.txpower;
1181}
1182
1183/* Called with sc->mutex held. */
1184void ath9k_set_txpower(struct ath_softc *sc, struct ieee80211_vif *vif)
1185{
1186 int power;
1187 struct ath_hw *ah = sc->sc_ah;
1188 struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
1189
1190 ath9k_ps_wakeup(sc);
1191 if (ah->tpc_enabled) {
1192 power = (vif) ? vif->bss_conf.txpower : -1;
1193 ieee80211_iterate_active_interfaces_atomic(
1194 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1195 ath9k_tpc_vif_iter, &power);
1196 if (power == -1)
1197 power = sc->hw->conf.power_level;
1198 } else {
1199 power = sc->hw->conf.power_level;
1200 }
1201 sc->cur_chan->txpower = 2 * power;
1202 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
1203 sc->cur_chan->cur_txpower = reg->max_power_level;
1204 ath9k_ps_restore(sc);
1205}
1206
1175static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, 1207static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
1176 struct ieee80211_vif *vif) 1208 struct ieee80211_vif *vif)
1177{ 1209{
@@ -1225,6 +1257,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1225 1257
1226 ath9k_assign_hw_queues(hw, vif); 1258 ath9k_assign_hw_queues(hw, vif);
1227 1259
1260 ath9k_set_txpower(sc, vif);
1261
1228 an->sc = sc; 1262 an->sc = sc;
1229 an->sta = NULL; 1263 an->sta = NULL;
1230 an->vif = vif; 1264 an->vif = vif;
@@ -1265,6 +1299,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1265 ath9k_assign_hw_queues(hw, vif); 1299 ath9k_assign_hw_queues(hw, vif);
1266 ath9k_calculate_summary_state(sc, avp->chanctx); 1300 ath9k_calculate_summary_state(sc, avp->chanctx);
1267 1301
1302 ath9k_set_txpower(sc, vif);
1303
1268 mutex_unlock(&sc->mutex); 1304 mutex_unlock(&sc->mutex);
1269 return 0; 1305 return 0;
1270} 1306}
@@ -1294,6 +1330,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1294 1330
1295 ath9k_calculate_summary_state(sc, avp->chanctx); 1331 ath9k_calculate_summary_state(sc, avp->chanctx);
1296 1332
1333 ath9k_set_txpower(sc, NULL);
1334
1297 mutex_unlock(&sc->mutex); 1335 mutex_unlock(&sc->mutex);
1298} 1336}
1299 1337
@@ -1397,14 +1435,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1397 ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef); 1435 ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
1398 } 1436 }
1399 1437
1400 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1401 ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
1402 sc->cur_chan->txpower = 2 * conf->power_level;
1403 ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
1404 sc->cur_chan->txpower,
1405 &sc->cur_chan->cur_txpower);
1406 }
1407
1408 mutex_unlock(&sc->mutex); 1438 mutex_unlock(&sc->mutex);
1409 ath9k_ps_restore(sc); 1439 ath9k_ps_restore(sc);
1410 1440
@@ -1764,6 +1794,12 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1764 if (changed & CHECK_ANI) 1794 if (changed & CHECK_ANI)
1765 ath_check_ani(sc); 1795 ath_check_ani(sc);
1766 1796
1797 if (changed & BSS_CHANGED_TXPOWER) {
1798 ath_dbg(common, CONFIG, "vif %pM power %d dbm power_type %d\n",
1799 vif->addr, bss_conf->txpower, bss_conf->txpower_type);
1800 ath9k_set_txpower(sc, vif);
1801 }
1802
1767 mutex_unlock(&sc->mutex); 1803 mutex_unlock(&sc->mutex);
1768 ath9k_ps_restore(sc); 1804 ath9k_ps_restore(sc);
1769 1805
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 3f7a11edb82a..66596b95273f 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -495,7 +495,7 @@ void ath_mci_intr(struct ath_softc *sc)
495 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); 495 ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg);
496 496
497 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) { 497 if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) {
498 ar9003_mci_get_next_gpm_offset(ah, true, NULL); 498 ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);
499 return; 499 return;
500 } 500 }
501 501
@@ -559,8 +559,7 @@ void ath_mci_intr(struct ath_softc *sc)
559 return; 559 return;
560 560
561 pgpm = mci->gpm_buf.bf_addr; 561 pgpm = mci->gpm_buf.bf_addr;
562 offset = ar9003_mci_get_next_gpm_offset(ah, false, 562 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
563 &more_data);
564 563
565 if (offset == MCI_GPM_INVALID) 564 if (offset == MCI_GPM_INVALID)
566 break; 565 break;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 9587ec655680..1234399a43dd 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -2044,279 +2044,4 @@ enum {
2044#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0 2044#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
2045#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6 2045#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
2046 2046
2047/* MCI Registers */
2048
2049#define AR_MCI_COMMAND0 0x1800
2050#define AR_MCI_COMMAND0_HEADER 0xFF
2051#define AR_MCI_COMMAND0_HEADER_S 0
2052#define AR_MCI_COMMAND0_LEN 0x1f00
2053#define AR_MCI_COMMAND0_LEN_S 8
2054#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP 0x2000
2055#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP_S 13
2056
2057#define AR_MCI_COMMAND1 0x1804
2058
2059#define AR_MCI_COMMAND2 0x1808
2060#define AR_MCI_COMMAND2_RESET_TX 0x01
2061#define AR_MCI_COMMAND2_RESET_TX_S 0
2062#define AR_MCI_COMMAND2_RESET_RX 0x02
2063#define AR_MCI_COMMAND2_RESET_RX_S 1
2064#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES 0x3FC
2065#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES_S 2
2066#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP 0x400
2067#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP_S 10
2068
2069#define AR_MCI_RX_CTRL 0x180c
2070
2071#define AR_MCI_TX_CTRL 0x1810
2072/* 0 = no division, 1 = divide by 2, 2 = divide by 4, 3 = divide by 8 */
2073#define AR_MCI_TX_CTRL_CLK_DIV 0x03
2074#define AR_MCI_TX_CTRL_CLK_DIV_S 0
2075#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE 0x04
2076#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE_S 2
2077#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ 0xFFFFF8
2078#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ_S 3
2079#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM 0xF000000
2080#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM_S 24
2081
2082#define AR_MCI_MSG_ATTRIBUTES_TABLE 0x1814
2083#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM 0xFFFF
2084#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM_S 0
2085#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR 0xFFFF0000
2086#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR_S 16
2087
2088#define AR_MCI_SCHD_TABLE_0 0x1818
2089#define AR_MCI_SCHD_TABLE_1 0x181c
2090#define AR_MCI_GPM_0 0x1820
2091#define AR_MCI_GPM_1 0x1824
2092#define AR_MCI_GPM_WRITE_PTR 0xFFFF0000
2093#define AR_MCI_GPM_WRITE_PTR_S 16
2094#define AR_MCI_GPM_BUF_LEN 0x0000FFFF
2095#define AR_MCI_GPM_BUF_LEN_S 0
2096
2097#define AR_MCI_INTERRUPT_RAW 0x1828
2098#define AR_MCI_INTERRUPT_EN 0x182c
2099#define AR_MCI_INTERRUPT_SW_MSG_DONE 0x00000001
2100#define AR_MCI_INTERRUPT_SW_MSG_DONE_S 0
2101#define AR_MCI_INTERRUPT_CPU_INT_MSG 0x00000002
2102#define AR_MCI_INTERRUPT_CPU_INT_MSG_S 1
2103#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL 0x00000004
2104#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL_S 2
2105#define AR_MCI_INTERRUPT_RX_INVALID_HDR 0x00000008
2106#define AR_MCI_INTERRUPT_RX_INVALID_HDR_S 3
2107#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL 0x00000010
2108#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL_S 4
2109#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL 0x00000020
2110#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL_S 5
2111#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL 0x00000080
2112#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL_S 7
2113#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL 0x00000100
2114#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL_S 8
2115#define AR_MCI_INTERRUPT_RX_MSG 0x00000200
2116#define AR_MCI_INTERRUPT_RX_MSG_S 9
2117#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE 0x00000400
2118#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE_S 10
2119#define AR_MCI_INTERRUPT_BT_PRI 0x07fff800
2120#define AR_MCI_INTERRUPT_BT_PRI_S 11
2121#define AR_MCI_INTERRUPT_BT_PRI_THRESH 0x08000000
2122#define AR_MCI_INTERRUPT_BT_PRI_THRESH_S 27
2123#define AR_MCI_INTERRUPT_BT_FREQ 0x10000000
2124#define AR_MCI_INTERRUPT_BT_FREQ_S 28
2125#define AR_MCI_INTERRUPT_BT_STOMP 0x20000000
2126#define AR_MCI_INTERRUPT_BT_STOMP_S 29
2127#define AR_MCI_INTERRUPT_BB_AIC_IRQ 0x40000000
2128#define AR_MCI_INTERRUPT_BB_AIC_IRQ_S 30
2129#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT 0x80000000
2130#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT_S 31
2131
2132#define AR_MCI_INTERRUPT_DEFAULT (AR_MCI_INTERRUPT_SW_MSG_DONE | \
2133 AR_MCI_INTERRUPT_RX_INVALID_HDR | \
2134 AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
2135 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
2136 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
2137 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL | \
2138 AR_MCI_INTERRUPT_RX_MSG | \
2139 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE | \
2140 AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)
2141
2142#define AR_MCI_INTERRUPT_MSG_FAIL_MASK (AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
2143 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
2144 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
2145 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL)
2146
2147#define AR_MCI_REMOTE_CPU_INT 0x1830
2148#define AR_MCI_REMOTE_CPU_INT_EN 0x1834
2149#define AR_MCI_INTERRUPT_RX_MSG_RAW 0x1838
2150#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c
2151#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
2152#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0
2153#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
2154#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1
2155#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
2156#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2
2157#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
2158#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3
2159#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
2160#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4
2161#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
2162#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5
2163#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
2164#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6
2165#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
2166#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8
2167#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
2168#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9
2169#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
2170#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10
2171#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
2172#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11
2173#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
2174#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12
2175#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \
2176 AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL| \
2177 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
2178 AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
2179 AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
2180 AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
2181
2182#define AR_MCI_INTERRUPT_RX_MSG_DEFAULT (AR_MCI_INTERRUPT_RX_MSG_GPM | \
2183 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET| \
2184 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING | \
2185 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING| \
2186 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
2187
2188#define AR_MCI_CPU_INT 0x1840
2189
2190#define AR_MCI_RX_STATUS 0x1844
2191#define AR_MCI_RX_LAST_SCHD_MSG_INDEX 0x00000F00
2192#define AR_MCI_RX_LAST_SCHD_MSG_INDEX_S 8
2193#define AR_MCI_RX_REMOTE_SLEEP 0x00001000
2194#define AR_MCI_RX_REMOTE_SLEEP_S 12
2195#define AR_MCI_RX_MCI_CLK_REQ 0x00002000
2196#define AR_MCI_RX_MCI_CLK_REQ_S 13
2197
2198#define AR_MCI_CONT_STATUS 0x1848
2199#define AR_MCI_CONT_RSSI_POWER 0x000000FF
2200#define AR_MCI_CONT_RSSI_POWER_S 0
2201#define AR_MCI_CONT_PRIORITY 0x0000FF00
2202#define AR_MCI_CONT_PRIORITY_S 8
2203#define AR_MCI_CONT_TXRX 0x00010000
2204#define AR_MCI_CONT_TXRX_S 16
2205
2206#define AR_MCI_BT_PRI0 0x184c
2207#define AR_MCI_BT_PRI1 0x1850
2208#define AR_MCI_BT_PRI2 0x1854
2209#define AR_MCI_BT_PRI3 0x1858
2210#define AR_MCI_BT_PRI 0x185c
2211#define AR_MCI_WL_FREQ0 0x1860
2212#define AR_MCI_WL_FREQ1 0x1864
2213#define AR_MCI_WL_FREQ2 0x1868
2214#define AR_MCI_GAIN 0x186c
2215#define AR_MCI_WBTIMER1 0x1870
2216#define AR_MCI_WBTIMER2 0x1874
2217#define AR_MCI_WBTIMER3 0x1878
2218#define AR_MCI_WBTIMER4 0x187c
2219#define AR_MCI_MAXGAIN 0x1880
2220#define AR_MCI_HW_SCHD_TBL_CTL 0x1884
2221#define AR_MCI_HW_SCHD_TBL_D0 0x1888
2222#define AR_MCI_HW_SCHD_TBL_D1 0x188c
2223#define AR_MCI_HW_SCHD_TBL_D2 0x1890
2224#define AR_MCI_HW_SCHD_TBL_D3 0x1894
2225#define AR_MCI_TX_PAYLOAD0 0x1898
2226#define AR_MCI_TX_PAYLOAD1 0x189c
2227#define AR_MCI_TX_PAYLOAD2 0x18a0
2228#define AR_MCI_TX_PAYLOAD3 0x18a4
2229#define AR_BTCOEX_WBTIMER 0x18a8
2230
2231#define AR_BTCOEX_CTRL 0x18ac
2232#define AR_BTCOEX_CTRL_AR9462_MODE 0x00000001
2233#define AR_BTCOEX_CTRL_AR9462_MODE_S 0
2234#define AR_BTCOEX_CTRL_WBTIMER_EN 0x00000002
2235#define AR_BTCOEX_CTRL_WBTIMER_EN_S 1
2236#define AR_BTCOEX_CTRL_MCI_MODE_EN 0x00000004
2237#define AR_BTCOEX_CTRL_MCI_MODE_EN_S 2
2238#define AR_BTCOEX_CTRL_LNA_SHARED 0x00000008
2239#define AR_BTCOEX_CTRL_LNA_SHARED_S 3
2240#define AR_BTCOEX_CTRL_PA_SHARED 0x00000010
2241#define AR_BTCOEX_CTRL_PA_SHARED_S 4
2242#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN 0x00000020
2243#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN_S 5
2244#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN 0x00000040
2245#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN_S 6
2246#define AR_BTCOEX_CTRL_NUM_ANTENNAS 0x00000180
2247#define AR_BTCOEX_CTRL_NUM_ANTENNAS_S 7
2248#define AR_BTCOEX_CTRL_RX_CHAIN_MASK 0x00000E00
2249#define AR_BTCOEX_CTRL_RX_CHAIN_MASK_S 9
2250#define AR_BTCOEX_CTRL_AGGR_THRESH 0x00007000
2251#define AR_BTCOEX_CTRL_AGGR_THRESH_S 12
2252#define AR_BTCOEX_CTRL_1_CHAIN_BCN 0x00080000
2253#define AR_BTCOEX_CTRL_1_CHAIN_BCN_S 19
2254#define AR_BTCOEX_CTRL_1_CHAIN_ACK 0x00100000
2255#define AR_BTCOEX_CTRL_1_CHAIN_ACK_S 20
2256#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN 0x1FE00000
2257#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN_S 28
2258#define AR_BTCOEX_CTRL_REDUCE_TXPWR 0x20000000
2259#define AR_BTCOEX_CTRL_REDUCE_TXPWR_S 29
2260#define AR_BTCOEX_CTRL_SPDT_ENABLE_10 0x40000000
2261#define AR_BTCOEX_CTRL_SPDT_ENABLE_10_S 30
2262#define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000
2263#define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31
2264
2265#define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2))
2266#define AR_BTCOEX_WL_LNA 0x1940
2267#define AR_BTCOEX_RFGAIN_CTRL 0x1944
2268#define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF
2269#define AR_BTCOEX_WL_LNA_TIMEOUT_S 0
2270
2271#define AR_BTCOEX_CTRL2 0x1948
2272#define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800
2273#define AR_BTCOEX_CTRL2_TXPWR_THRESH_S 11
2274#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK 0x00380000
2275#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK_S 19
2276#define AR_BTCOEX_CTRL2_RX_DEWEIGHT 0x00400000
2277#define AR_BTCOEX_CTRL2_RX_DEWEIGHT_S 22
2278#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL 0x00800000
2279#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL_S 23
2280#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL 0x01000000
2281#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL_S 24
2282#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE 0x02000000
2283#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE_S 25
2284
2285#define AR_BTCOEX_CTRL_SPDT_ENABLE 0x00000001
2286#define AR_BTCOEX_CTRL_SPDT_ENABLE_S 0
2287#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL 0x00000002
2288#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL_S 1
2289#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT 0x00000004
2290#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT_S 2
2291#define AR_GLB_WLAN_UART_INTF_EN 0x00020000
2292#define AR_GLB_WLAN_UART_INTF_EN_S 17
2293#define AR_GLB_DS_JTAG_DISABLE 0x00040000
2294#define AR_GLB_DS_JTAG_DISABLE_S 18
2295
2296#define AR_BTCOEX_RC 0x194c
2297#define AR_BTCOEX_MAX_RFGAIN(_x) (0x1950 + ((_x) << 2))
2298#define AR_BTCOEX_DBG 0x1a50
2299#define AR_MCI_LAST_HW_MSG_HDR 0x1a54
2300#define AR_MCI_LAST_HW_MSG_BDY 0x1a58
2301
2302#define AR_MCI_SCHD_TABLE_2 0x1a5c
2303#define AR_MCI_SCHD_TABLE_2_MEM_BASED 0x00000001
2304#define AR_MCI_SCHD_TABLE_2_MEM_BASED_S 0
2305#define AR_MCI_SCHD_TABLE_2_HW_BASED 0x00000002
2306#define AR_MCI_SCHD_TABLE_2_HW_BASED_S 1
2307
2308#define AR_BTCOEX_CTRL3 0x1a60
2309#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff
2310#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0
2311
2312#define AR_GLB_SWREG_DISCONT_MODE 0x2002c
2313#define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3
2314
2315#define AR_MCI_MISC 0x1a74
2316#define AR_MCI_MISC_HW_FIX_EN 0x00000001
2317#define AR_MCI_MISC_HW_FIX_EN_S 0
2318#define AR_MCI_DBG_CNT_CTRL 0x1a78
2319#define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001
2320#define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0
2321
2322#endif 2047#endif
diff --git a/drivers/net/wireless/ath/ath9k/reg_mci.h b/drivers/net/wireless/ath/ath9k/reg_mci.h
new file mode 100644
index 000000000000..6251310704e3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/reg_mci.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REG_MCI_H
18#define REG_MCI_H
19
20#define AR_MCI_COMMAND0 0x1800
21#define AR_MCI_COMMAND0_HEADER 0xFF
22#define AR_MCI_COMMAND0_HEADER_S 0
23#define AR_MCI_COMMAND0_LEN 0x1f00
24#define AR_MCI_COMMAND0_LEN_S 8
25#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP 0x2000
26#define AR_MCI_COMMAND0_DISABLE_TIMESTAMP_S 13
27
28#define AR_MCI_COMMAND1 0x1804
29
30#define AR_MCI_COMMAND2 0x1808
31#define AR_MCI_COMMAND2_RESET_TX 0x01
32#define AR_MCI_COMMAND2_RESET_TX_S 0
33#define AR_MCI_COMMAND2_RESET_RX 0x02
34#define AR_MCI_COMMAND2_RESET_RX_S 1
35#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES 0x3FC
36#define AR_MCI_COMMAND2_RESET_RX_NUM_CYCLES_S 2
37#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP 0x400
38#define AR_MCI_COMMAND2_RESET_REQ_WAKEUP_S 10
39
40#define AR_MCI_RX_CTRL 0x180c
41
42#define AR_MCI_TX_CTRL 0x1810
43/*
44 * 0 = no division,
45 * 1 = divide by 2,
46 * 2 = divide by 4,
47 * 3 = divide by 8
48 */
49#define AR_MCI_TX_CTRL_CLK_DIV 0x03
50#define AR_MCI_TX_CTRL_CLK_DIV_S 0
51#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE 0x04
52#define AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE_S 2
53#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ 0xFFFFF8
54#define AR_MCI_TX_CTRL_GAIN_UPDATE_FREQ_S 3
55#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM 0xF000000
56#define AR_MCI_TX_CTRL_GAIN_UPDATE_NUM_S 24
57
58#define AR_MCI_MSG_ATTRIBUTES_TABLE 0x1814
59#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM 0xFFFF
60#define AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM_S 0
61#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR 0xFFFF0000
62#define AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR_S 16
63
64#define AR_MCI_SCHD_TABLE_0 0x1818
65#define AR_MCI_SCHD_TABLE_1 0x181c
66#define AR_MCI_GPM_0 0x1820
67#define AR_MCI_GPM_1 0x1824
68#define AR_MCI_GPM_WRITE_PTR 0xFFFF0000
69#define AR_MCI_GPM_WRITE_PTR_S 16
70#define AR_MCI_GPM_BUF_LEN 0x0000FFFF
71#define AR_MCI_GPM_BUF_LEN_S 0
72
73#define AR_MCI_INTERRUPT_RAW 0x1828
74
75#define AR_MCI_INTERRUPT_EN 0x182c
76#define AR_MCI_INTERRUPT_SW_MSG_DONE 0x00000001
77#define AR_MCI_INTERRUPT_SW_MSG_DONE_S 0
78#define AR_MCI_INTERRUPT_CPU_INT_MSG 0x00000002
79#define AR_MCI_INTERRUPT_CPU_INT_MSG_S 1
80#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL 0x00000004
81#define AR_MCI_INTERRUPT_RX_CKSUM_FAIL_S 2
82#define AR_MCI_INTERRUPT_RX_INVALID_HDR 0x00000008
83#define AR_MCI_INTERRUPT_RX_INVALID_HDR_S 3
84#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL 0x00000010
85#define AR_MCI_INTERRUPT_RX_HW_MSG_FAIL_S 4
86#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL 0x00000020
87#define AR_MCI_INTERRUPT_RX_SW_MSG_FAIL_S 5
88#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL 0x00000080
89#define AR_MCI_INTERRUPT_TX_HW_MSG_FAIL_S 7
90#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL 0x00000100
91#define AR_MCI_INTERRUPT_TX_SW_MSG_FAIL_S 8
92#define AR_MCI_INTERRUPT_RX_MSG 0x00000200
93#define AR_MCI_INTERRUPT_RX_MSG_S 9
94#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE 0x00000400
95#define AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE_S 10
96#define AR_MCI_INTERRUPT_BT_PRI 0x07fff800
97#define AR_MCI_INTERRUPT_BT_PRI_S 11
98#define AR_MCI_INTERRUPT_BT_PRI_THRESH 0x08000000
99#define AR_MCI_INTERRUPT_BT_PRI_THRESH_S 27
100#define AR_MCI_INTERRUPT_BT_FREQ 0x10000000
101#define AR_MCI_INTERRUPT_BT_FREQ_S 28
102#define AR_MCI_INTERRUPT_BT_STOMP 0x20000000
103#define AR_MCI_INTERRUPT_BT_STOMP_S 29
104#define AR_MCI_INTERRUPT_BB_AIC_IRQ 0x40000000
105#define AR_MCI_INTERRUPT_BB_AIC_IRQ_S 30
106#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT 0x80000000
107#define AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT_S 31
108
109#define AR_MCI_REMOTE_CPU_INT 0x1830
110#define AR_MCI_REMOTE_CPU_INT_EN 0x1834
111#define AR_MCI_INTERRUPT_RX_MSG_RAW 0x1838
112#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c
113#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
114#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0
115#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
116#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1
117#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
118#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2
119#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
120#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3
121#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
122#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4
123#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
124#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5
125#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
126#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6
127#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
128#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8
129#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
130#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9
131#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
132#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10
133#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
134#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11
135#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
136#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12
137
138#define AR_MCI_CPU_INT 0x1840
139
140#define AR_MCI_RX_STATUS 0x1844
141#define AR_MCI_RX_LAST_SCHD_MSG_INDEX 0x00000F00
142#define AR_MCI_RX_LAST_SCHD_MSG_INDEX_S 8
143#define AR_MCI_RX_REMOTE_SLEEP 0x00001000
144#define AR_MCI_RX_REMOTE_SLEEP_S 12
145#define AR_MCI_RX_MCI_CLK_REQ 0x00002000
146#define AR_MCI_RX_MCI_CLK_REQ_S 13
147
148#define AR_MCI_CONT_STATUS 0x1848
149#define AR_MCI_CONT_RSSI_POWER 0x000000FF
150#define AR_MCI_CONT_RSSI_POWER_S 0
151#define AR_MCI_CONT_PRIORITY 0x0000FF00
152#define AR_MCI_CONT_PRIORITY_S 8
153#define AR_MCI_CONT_TXRX 0x00010000
154#define AR_MCI_CONT_TXRX_S 16
155
156#define AR_MCI_BT_PRI0 0x184c
157#define AR_MCI_BT_PRI1 0x1850
158#define AR_MCI_BT_PRI2 0x1854
159#define AR_MCI_BT_PRI3 0x1858
160#define AR_MCI_BT_PRI 0x185c
161#define AR_MCI_WL_FREQ0 0x1860
162#define AR_MCI_WL_FREQ1 0x1864
163#define AR_MCI_WL_FREQ2 0x1868
164#define AR_MCI_GAIN 0x186c
165#define AR_MCI_WBTIMER1 0x1870
166#define AR_MCI_WBTIMER2 0x1874
167#define AR_MCI_WBTIMER3 0x1878
168#define AR_MCI_WBTIMER4 0x187c
169#define AR_MCI_MAXGAIN 0x1880
170#define AR_MCI_HW_SCHD_TBL_CTL 0x1884
171#define AR_MCI_HW_SCHD_TBL_D0 0x1888
172#define AR_MCI_HW_SCHD_TBL_D1 0x188c
173#define AR_MCI_HW_SCHD_TBL_D2 0x1890
174#define AR_MCI_HW_SCHD_TBL_D3 0x1894
175#define AR_MCI_TX_PAYLOAD0 0x1898
176#define AR_MCI_TX_PAYLOAD1 0x189c
177#define AR_MCI_TX_PAYLOAD2 0x18a0
178#define AR_MCI_TX_PAYLOAD3 0x18a4
179#define AR_BTCOEX_WBTIMER 0x18a8
180
181#define AR_BTCOEX_CTRL 0x18ac
182#define AR_BTCOEX_CTRL_AR9462_MODE 0x00000001
183#define AR_BTCOEX_CTRL_AR9462_MODE_S 0
184#define AR_BTCOEX_CTRL_WBTIMER_EN 0x00000002
185#define AR_BTCOEX_CTRL_WBTIMER_EN_S 1
186#define AR_BTCOEX_CTRL_MCI_MODE_EN 0x00000004
187#define AR_BTCOEX_CTRL_MCI_MODE_EN_S 2
188#define AR_BTCOEX_CTRL_LNA_SHARED 0x00000008
189#define AR_BTCOEX_CTRL_LNA_SHARED_S 3
190#define AR_BTCOEX_CTRL_PA_SHARED 0x00000010
191#define AR_BTCOEX_CTRL_PA_SHARED_S 4
192#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN 0x00000020
193#define AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN_S 5
194#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN 0x00000040
195#define AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN_S 6
196#define AR_BTCOEX_CTRL_NUM_ANTENNAS 0x00000180
197#define AR_BTCOEX_CTRL_NUM_ANTENNAS_S 7
198#define AR_BTCOEX_CTRL_RX_CHAIN_MASK 0x00000E00
199#define AR_BTCOEX_CTRL_RX_CHAIN_MASK_S 9
200#define AR_BTCOEX_CTRL_AGGR_THRESH 0x00007000
201#define AR_BTCOEX_CTRL_AGGR_THRESH_S 12
202#define AR_BTCOEX_CTRL_1_CHAIN_BCN 0x00080000
203#define AR_BTCOEX_CTRL_1_CHAIN_BCN_S 19
204#define AR_BTCOEX_CTRL_1_CHAIN_ACK 0x00100000
205#define AR_BTCOEX_CTRL_1_CHAIN_ACK_S 20
206#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN 0x1FE00000
207#define AR_BTCOEX_CTRL_WAIT_BA_MARGIN_S 28
208#define AR_BTCOEX_CTRL_REDUCE_TXPWR 0x20000000
209#define AR_BTCOEX_CTRL_REDUCE_TXPWR_S 29
210#define AR_BTCOEX_CTRL_SPDT_ENABLE_10 0x40000000
211#define AR_BTCOEX_CTRL_SPDT_ENABLE_10_S 30
212#define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000
213#define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31
214
215#define AR_BTCOEX_WL_WEIGHTS0 0x18b0
216#define AR_BTCOEX_WL_WEIGHTS1 0x18b4
217#define AR_BTCOEX_WL_WEIGHTS2 0x18b8
218#define AR_BTCOEX_WL_WEIGHTS3 0x18bc
219
220#define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2))
221#define AR_BTCOEX_WL_LNA 0x1940
222#define AR_BTCOEX_RFGAIN_CTRL 0x1944
223#define AR_BTCOEX_WL_LNA_TIMEOUT 0x003FFFFF
224#define AR_BTCOEX_WL_LNA_TIMEOUT_S 0
225
226#define AR_BTCOEX_CTRL2 0x1948
227#define AR_BTCOEX_CTRL2_TXPWR_THRESH 0x0007F800
228#define AR_BTCOEX_CTRL2_TXPWR_THRESH_S 11
229#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK 0x00380000
230#define AR_BTCOEX_CTRL2_TX_CHAIN_MASK_S 19
231#define AR_BTCOEX_CTRL2_RX_DEWEIGHT 0x00400000
232#define AR_BTCOEX_CTRL2_RX_DEWEIGHT_S 22
233#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL 0x00800000
234#define AR_BTCOEX_CTRL2_GPIO_OBS_SEL_S 23
235#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL 0x01000000
236#define AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL_S 24
237#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE 0x02000000
238#define AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE_S 25
239
240#define AR_BTCOEX_CTRL_SPDT_ENABLE 0x00000001
241#define AR_BTCOEX_CTRL_SPDT_ENABLE_S 0
242#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL 0x00000002
243#define AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL_S 1
244#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT 0x00000004
245#define AR_BTCOEX_CTRL_USE_LATCHED_BT_ANT_S 2
246#define AR_GLB_WLAN_UART_INTF_EN 0x00020000
247#define AR_GLB_WLAN_UART_INTF_EN_S 17
248#define AR_GLB_DS_JTAG_DISABLE 0x00040000
249#define AR_GLB_DS_JTAG_DISABLE_S 18
250
251#define AR_BTCOEX_RC 0x194c
252#define AR_BTCOEX_MAX_RFGAIN(_x) (0x1950 + ((_x) << 2))
253#define AR_BTCOEX_DBG 0x1a50
254#define AR_MCI_LAST_HW_MSG_HDR 0x1a54
255#define AR_MCI_LAST_HW_MSG_BDY 0x1a58
256
257#define AR_MCI_SCHD_TABLE_2 0x1a5c
258#define AR_MCI_SCHD_TABLE_2_MEM_BASED 0x00000001
259#define AR_MCI_SCHD_TABLE_2_MEM_BASED_S 0
260#define AR_MCI_SCHD_TABLE_2_HW_BASED 0x00000002
261#define AR_MCI_SCHD_TABLE_2_HW_BASED_S 1
262
263#define AR_BTCOEX_CTRL3 0x1a60
264#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT 0x00000fff
265#define AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT_S 0
266
267#define AR_GLB_SWREG_DISCONT_MODE 0x2002c
268#define AR_GLB_SWREG_DISCONT_EN_BT_WLAN 0x3
269
270#define AR_MCI_MISC 0x1a74
271#define AR_MCI_MISC_HW_FIX_EN 0x00000001
272#define AR_MCI_MISC_HW_FIX_EN_S 0
273
274#define AR_MCI_DBG_CNT_CTRL 0x1a78
275#define AR_MCI_DBG_CNT_CTRL_ENABLE 0x00000001
276#define AR_MCI_DBG_CNT_CTRL_ENABLE_S 0
277#define AR_MCI_DBG_CNT_CTRL_BT_LINKID 0x000007f8
278#define AR_MCI_DBG_CNT_CTRL_BT_LINKID_S 3
279
280#define MCI_STAT_ALL_BT_LINKID 0xffff
281
282#define AR_MCI_INTERRUPT_DEFAULT (AR_MCI_INTERRUPT_SW_MSG_DONE | \
283 AR_MCI_INTERRUPT_RX_INVALID_HDR | \
284 AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
285 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
286 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
287 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL | \
288 AR_MCI_INTERRUPT_RX_MSG | \
289 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE | \
290 AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)
291
292#define AR_MCI_INTERRUPT_MSG_FAIL_MASK (AR_MCI_INTERRUPT_RX_HW_MSG_FAIL | \
293 AR_MCI_INTERRUPT_RX_SW_MSG_FAIL | \
294 AR_MCI_INTERRUPT_TX_HW_MSG_FAIL | \
295 AR_MCI_INTERRUPT_TX_SW_MSG_FAIL)
296
297#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \
298 AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL | \
299 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
300 AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
301 AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
302 AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
303
304#define AR_MCI_INTERRUPT_RX_MSG_DEFAULT (AR_MCI_INTERRUPT_RX_MSG_GPM | \
305 AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET | \
306 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING | \
307 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | \
308 AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
309
310#endif /* REG_MCI_H */
diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
index 3abfca56ca58..453054078cc4 100644
--- a/drivers/net/wireless/ath/ath9k/reg_wow.h
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -72,7 +72,7 @@
72#define AR_WOW_MAC_INTR_EN 0x00040000 72#define AR_WOW_MAC_INTR_EN 0x00040000
73#define AR_WOW_MAGIC_EN 0x00010000 73#define AR_WOW_MAGIC_EN 0x00010000
74#define AR_WOW_PATTERN_EN(x) (x & 0xff) 74#define AR_WOW_PATTERN_EN(x) (x & 0xff)
75#define AR_WOW_PAT_FOUND_SHIFT 8 75#define AR_WOW_PAT_FOUND_SHIFT 8
76#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT)) 76#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
77#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT) 77#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
78#define AR_WOW_MAGIC_PAT_FOUND 0x00020000 78#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
@@ -90,6 +90,14 @@
90 AR_WOW_BEACON_FAIL | \ 90 AR_WOW_BEACON_FAIL | \
91 AR_WOW_KEEP_ALIVE_FAIL)) 91 AR_WOW_KEEP_ALIVE_FAIL))
92 92
93#define AR_WOW2_PATTERN_EN(x) ((x & 0xff) << 0)
94#define AR_WOW2_PATTERN_FOUND_SHIFT 8
95#define AR_WOW2_PATTERN_FOUND(x) (x & (0xff << AR_WOW2_PATTERN_FOUND_SHIFT))
96#define AR_WOW2_PATTERN_FOUND_MASK ((0xff) << AR_WOW2_PATTERN_FOUND_SHIFT)
97
98#define AR_WOW_STATUS2(x) (x & AR_WOW2_PATTERN_FOUND_MASK)
99#define AR_WOW_CLEAR_EVENTS2(x) (x & ~(AR_WOW2_PATTERN_EN(0xff)))
100
93#define AR_WOW_AIFS_CNT(x) (x & 0xff) 101#define AR_WOW_AIFS_CNT(x) (x & 0xff)
94#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8) 102#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
95#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16) 103#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 1b8e75c4d2c2..0acd079ba96b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1103,14 +1103,28 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1103 struct sk_buff *skb; 1103 struct sk_buff *skb;
1104 struct ath_frame_info *fi; 1104 struct ath_frame_info *fi;
1105 struct ieee80211_tx_info *info; 1105 struct ieee80211_tx_info *info;
1106 struct ieee80211_vif *vif;
1106 struct ath_hw *ah = sc->sc_ah; 1107 struct ath_hw *ah = sc->sc_ah;
1107 1108
1108 if (sc->tx99_state || !ah->tpc_enabled) 1109 if (sc->tx99_state || !ah->tpc_enabled)
1109 return MAX_RATE_POWER; 1110 return MAX_RATE_POWER;
1110 1111
1111 skb = bf->bf_mpdu; 1112 skb = bf->bf_mpdu;
1112 fi = get_frame_info(skb);
1113 info = IEEE80211_SKB_CB(skb); 1113 info = IEEE80211_SKB_CB(skb);
1114 vif = info->control.vif;
1115
1116 if (!vif) {
1117 max_power = sc->cur_chan->cur_txpower;
1118 goto out;
1119 }
1120
1121 if (vif->bss_conf.txpower_type != NL80211_TX_POWER_LIMITED) {
1122 max_power = min_t(u8, sc->cur_chan->cur_txpower,
1123 2 * vif->bss_conf.txpower);
1124 goto out;
1125 }
1126
1127 fi = get_frame_info(skb);
1114 1128
1115 if (!AR_SREV_9300_20_OR_LATER(ah)) { 1129 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1116 int txpower = fi->tx_power; 1130 int txpower = fi->tx_power;
@@ -1147,25 +1161,25 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1147 txpower -= 2; 1161 txpower -= 2;
1148 1162
1149 txpower = max(txpower, 0); 1163 txpower = max(txpower, 0);
1150 max_power = min_t(u8, ah->tx_power[rateidx], txpower); 1164 max_power = min_t(u8, ah->tx_power[rateidx],
1151 1165 2 * vif->bss_conf.txpower);
1152 /* XXX: clamp minimum TX power at 1 for AR9160 since if 1166 max_power = min_t(u8, max_power, txpower);
1153 * max_power is set to 0, frames are transmitted at max
1154 * TX power
1155 */
1156 if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
1157 max_power = 1;
1158 } else if (!bf->bf_state.bfs_paprd) { 1167 } else if (!bf->bf_state.bfs_paprd) {
1159 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) 1168 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
1160 max_power = min(ah->tx_power_stbc[rateidx], 1169 max_power = min_t(u8, ah->tx_power_stbc[rateidx],
1161 fi->tx_power); 1170 2 * vif->bss_conf.txpower);
1162 else 1171 else
1163 max_power = min(ah->tx_power[rateidx], fi->tx_power); 1172 max_power = min_t(u8, ah->tx_power[rateidx],
1173 2 * vif->bss_conf.txpower);
1174 max_power = min(max_power, fi->tx_power);
1164 } else { 1175 } else {
1165 max_power = ah->paprd_training_power; 1176 max_power = ah->paprd_training_power;
1166 } 1177 }
1167 1178out:
1168 return max_power; 1179 /* XXX: clamp minimum TX power at 1 for AR9160 since if max_power
1180 * is set to 0, frames are transmitted at max TX power
1181 */
1182 return (!max_power && !AR_SREV_9280_20_OR_LATER(ah)) ? 1 : max_power;
1169} 1183}
1170 1184
1171static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, 1185static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 2d5ea21be47e..4bd708c8716c 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -387,11 +387,25 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
387 int ch; 387 int ch;
388 int rc = 0; 388 int rc = 0;
389 389
390 wil_print_connect_params(wil, sme);
391
390 if (test_bit(wil_status_fwconnecting, wil->status) || 392 if (test_bit(wil_status_fwconnecting, wil->status) ||
391 test_bit(wil_status_fwconnected, wil->status)) 393 test_bit(wil_status_fwconnected, wil->status))
392 return -EALREADY; 394 return -EALREADY;
393 395
394 wil_print_connect_params(wil, sme); 396 if (sme->ie_len > WMI_MAX_IE_LEN) {
397 wil_err(wil, "IE too large (%td bytes)\n", sme->ie_len);
398 return -ERANGE;
399 }
400
401 rsn_eid = sme->ie ?
402 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
403 NULL;
404
405 if (sme->privacy && !rsn_eid) {
406 wil_err(wil, "Missing RSN IE for secure connection\n");
407 return -EINVAL;
408 }
395 409
396 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 410 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
397 sme->ssid, sme->ssid_len, 411 sme->ssid, sme->ssid_len,
@@ -407,17 +421,9 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
407 rc = -ENOENT; 421 rc = -ENOENT;
408 goto out; 422 goto out;
409 } 423 }
424 wil->privacy = sme->privacy;
410 425
411 rsn_eid = sme->ie ? 426 if (wil->privacy) {
412 cfg80211_find_ie(WLAN_EID_RSN, sme->ie, sme->ie_len) :
413 NULL;
414 if (rsn_eid) {
415 if (sme->ie_len > WMI_MAX_IE_LEN) {
416 rc = -ERANGE;
417 wil_err(wil, "IE too large (%td bytes)\n",
418 sme->ie_len);
419 goto out;
420 }
421 /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */ 427 /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */
422 rc = wmi_del_cipher_key(wil, 0, bss->bssid); 428 rc = wmi_del_cipher_key(wil, 0, bss->bssid);
423 if (rc) { 429 if (rc) {
@@ -450,7 +456,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
450 bss->capability); 456 bss->capability);
451 goto out; 457 goto out;
452 } 458 }
453 if (rsn_eid) { 459 if (wil->privacy) {
454 conn.dot11_auth_mode = WMI_AUTH11_SHARED; 460 conn.dot11_auth_mode = WMI_AUTH11_SHARED;
455 conn.auth_mode = WMI_AUTH_WPA2_PSK; 461 conn.auth_mode = WMI_AUTH_WPA2_PSK;
456 conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP; 462 conn.pairwise_crypto_type = WMI_CRYPT_AES_GCMP;
@@ -769,7 +775,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
769 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, 775 wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len,
770 bcon->assocresp_ies); 776 bcon->assocresp_ies);
771 777
772 wil->secure_pcp = info->privacy; 778 wil->privacy = info->privacy;
773 779
774 netif_carrier_on(ndev); 780 netif_carrier_on(ndev);
775 781
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 45c3558ec804..3830cc20d4fa 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -29,6 +29,7 @@
29static u32 mem_addr; 29static u32 mem_addr;
30static u32 dbg_txdesc_index; 30static u32 dbg_txdesc_index;
31static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */ 31static u32 dbg_vring_index; /* 24+ for Rx, 0..23 for Tx */
32u32 vring_idle_trsh = 16; /* HW fetches up to 16 descriptors at once */
32 33
33enum dbg_off_type { 34enum dbg_off_type {
34 doff_u32 = 0, 35 doff_u32 = 0,
@@ -102,23 +103,30 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
102 % vring->size; 103 % vring->size;
103 int avail = vring->size - used - 1; 104 int avail = vring->size - used - 1;
104 char name[10]; 105 char name[10];
106 char sidle[10];
105 /* performance monitoring */ 107 /* performance monitoring */
106 cycles_t now = get_cycles(); 108 cycles_t now = get_cycles();
107 uint64_t idle = txdata->idle * 100; 109 uint64_t idle = txdata->idle * 100;
108 uint64_t total = now - txdata->begin; 110 uint64_t total = now - txdata->begin;
109 111
110 do_div(idle, total); 112 if (total != 0) {
113 do_div(idle, total);
114 snprintf(sidle, sizeof(sidle), "%3d%%",
115 (int)idle);
116 } else {
117 snprintf(sidle, sizeof(sidle), "N/A");
118 }
111 txdata->begin = now; 119 txdata->begin = now;
112 txdata->idle = 0ULL; 120 txdata->idle = 0ULL;
113 121
114 snprintf(name, sizeof(name), "tx_%2d", i); 122 snprintf(name, sizeof(name), "tx_%2d", i);
115 123
116 seq_printf(s, 124 seq_printf(s,
117 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %3d%%\n", 125 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %s\n",
118 wil->sta[cid].addr, cid, tid, 126 wil->sta[cid].addr, cid, tid,
119 txdata->agg_wsize, txdata->agg_timeout, 127 txdata->agg_wsize, txdata->agg_timeout,
120 txdata->agg_amsdu ? "+" : "-", 128 txdata->agg_amsdu ? "+" : "-",
121 used, avail, (int)idle); 129 used, avail, sidle);
122 130
123 wil_print_vring(s, wil, name, vring, '_', 'H'); 131 wil_print_vring(s, wil, name, vring, '_', 'H');
124 } 132 }
@@ -549,7 +557,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
549 dev_close(ndev); 557 dev_close(ndev);
550 ndev->flags &= ~IFF_UP; 558 ndev->flags &= ~IFF_UP;
551 rtnl_unlock(); 559 rtnl_unlock();
552 wil_reset(wil); 560 wil_reset(wil, true);
553 561
554 return len; 562 return len;
555} 563}
@@ -618,7 +626,7 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf,
618 struct wil6210_priv *wil = file->private_data; 626 struct wil6210_priv *wil = file->private_data;
619 int rc; 627 int rc;
620 char *kbuf = kmalloc(len + 1, GFP_KERNEL); 628 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
621 char cmd[8]; 629 char cmd[9];
622 int p1, p2, p3; 630 int p1, p2, p3;
623 631
624 if (!kbuf) 632 if (!kbuf)
@@ -1392,7 +1400,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
1392 1400
1393/* fields in struct wil6210_priv */ 1401/* fields in struct wil6210_priv */
1394static const struct dbg_off dbg_wil_off[] = { 1402static const struct dbg_off dbg_wil_off[] = {
1395 WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), 1403 WIL_FIELD(privacy, S_IRUGO, doff_u32),
1396 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong), 1404 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong),
1397 WIL_FIELD(fw_version, S_IRUGO, doff_u32), 1405 WIL_FIELD(fw_version, S_IRUGO, doff_u32),
1398 WIL_FIELD(hw_version, S_IRUGO, doff_x32), 1406 WIL_FIELD(hw_version, S_IRUGO, doff_x32),
@@ -1412,6 +1420,8 @@ static const struct dbg_off dbg_statics[] = {
1412 {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32}, 1420 {"desc_index", S_IRUGO | S_IWUSR, (ulong)&dbg_txdesc_index, doff_u32},
1413 {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32}, 1421 {"vring_index", S_IRUGO | S_IWUSR, (ulong)&dbg_vring_index, doff_u32},
1414 {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32}, 1422 {"mem_addr", S_IRUGO | S_IWUSR, (ulong)&mem_addr, doff_u32},
1423 {"vring_idle_trsh", S_IRUGO | S_IWUSR, (ulong)&vring_idle_trsh,
1424 doff_u32},
1415 {}, 1425 {},
1416}; 1426};
1417 1427
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c
index 4c44a82c34d7..0ea695ff98ad 100644
--- a/drivers/net/wireless/ath/wil6210/ethtool.c
+++ b/drivers/net/wireless/ath/wil6210/ethtool.c
@@ -50,27 +50,19 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
50 50
51 wil_dbg_misc(wil, "%s()\n", __func__); 51 wil_dbg_misc(wil, "%s()\n", __func__);
52 52
53 if (test_bit(hw_capability_advanced_itr_moderation, 53 tx_itr_en = ioread32(wil->csr +
54 wil->hw_capabilities)) { 54 HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL));
55 tx_itr_en = ioread32(wil->csr + 55 if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
56 HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL)); 56 tx_itr_val =
57 if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN) 57 ioread32(wil->csr +
58 tx_itr_val = 58 HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH));
59 ioread32(wil->csr + 59
60 HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH)); 60 rx_itr_en = ioread32(wil->csr +
61 61 HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL));
62 rx_itr_en = ioread32(wil->csr + 62 if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
63 HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL)); 63 rx_itr_val =
64 if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN) 64 ioread32(wil->csr +
65 rx_itr_val = 65 HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
66 ioread32(wil->csr +
67 HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
68 } else {
69 rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
70 if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN)
71 rx_itr_val = ioread32(wil->csr +
72 HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
73 }
74 66
75 cp->tx_coalesce_usecs = tx_itr_val; 67 cp->tx_coalesce_usecs = tx_itr_val;
76 cp->rx_coalesce_usecs = rx_itr_val; 68 cp->rx_coalesce_usecs = rx_itr_val;
diff --git a/drivers/net/wireless/ath/wil6210/fw.c b/drivers/net/wireless/ath/wil6210/fw.c
index 93c5cc16c515..4428345e5a47 100644
--- a/drivers/net/wireless/ath/wil6210/fw.c
+++ b/drivers/net/wireless/ath/wil6210/fw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -20,6 +20,7 @@
20#include "fw.h" 20#include "fw.h"
21 21
22MODULE_FIRMWARE(WIL_FW_NAME); 22MODULE_FIRMWARE(WIL_FW_NAME);
23MODULE_FIRMWARE(WIL_FW2_NAME);
23 24
24/* target operations */ 25/* target operations */
25/* register read */ 26/* register read */
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index d4acf93a9a02..157f5ef384e0 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -451,8 +451,6 @@ static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size)
451 } 451 }
452 return -EINVAL; 452 return -EINVAL;
453 } 453 }
454 /* Mark FW as loaded from host */
455 S(RGF_USER_USAGE_6, 1);
456 454
457 return rc; 455 return rc;
458} 456}
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index a6f923086f31..28ffc18466c4 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -166,9 +166,16 @@ void wil_unmask_irq(struct wil6210_priv *wil)
166/* target write operation */ 166/* target write operation */
167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) 167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
168 168
169static 169void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
170void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
171{ 170{
171 wil_dbg_irq(wil, "%s()\n", __func__);
172
173 /* disable interrupt moderation for monitor
174 * to get better timestamp precision
175 */
176 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
177 return;
178
172 /* Disable and clear tx counter before (re)configuration */ 179 /* Disable and clear tx counter before (re)configuration */
173 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR); 180 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR);
174 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration); 181 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration);
@@ -206,42 +213,8 @@ void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
206 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL); 213 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL);
207} 214}
208 215
209static
210void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil)
211{
212 /* disable, use usec resolution */
213 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR);
214
215 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration);
216 W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration);
217 /* start it */
218 W(RGF_DMA_ITR_CNT_CRL,
219 BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK);
220}
221
222#undef W 216#undef W
223 217
224void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
225{
226 wil_dbg_irq(wil, "%s()\n", __func__);
227
228 /* disable interrupt moderation for monitor
229 * to get better timestamp precision
230 */
231 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
232 return;
233
234 if (test_bit(hw_capability_advanced_itr_moderation,
235 wil->hw_capabilities))
236 wil_configure_interrupt_moderation_new(wil);
237 else {
238 /* Advanced interrupt moderation is not available before
239 * Sparrow v2. Will use legacy interrupt moderation
240 */
241 wil_configure_interrupt_moderation_lgc(wil);
242 }
243}
244
245static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 218static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
246{ 219{
247 struct wil6210_priv *wil = cookie; 220 struct wil6210_priv *wil = cookie;
@@ -253,7 +226,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
253 trace_wil6210_irq_rx(isr); 226 trace_wil6210_irq_rx(isr);
254 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr); 227 wil_dbg_irq(wil, "ISR RX 0x%08x\n", isr);
255 228
256 if (!isr) { 229 if (unlikely(!isr)) {
257 wil_err(wil, "spurious IRQ: RX\n"); 230 wil_err(wil, "spurious IRQ: RX\n");
258 return IRQ_NONE; 231 return IRQ_NONE;
259 } 232 }
@@ -266,17 +239,18 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
266 * action is always the same - should empty the accumulated 239 * action is always the same - should empty the accumulated
267 * packets from the RX ring. 240 * packets from the RX ring.
268 */ 241 */
269 if (isr & (BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH)) { 242 if (likely(isr & (BIT_DMA_EP_RX_ICR_RX_DONE |
243 BIT_DMA_EP_RX_ICR_RX_HTRSH))) {
270 wil_dbg_irq(wil, "RX done\n"); 244 wil_dbg_irq(wil, "RX done\n");
271 245
272 if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) 246 if (unlikely(isr & BIT_DMA_EP_RX_ICR_RX_HTRSH))
273 wil_err_ratelimited(wil, 247 wil_err_ratelimited(wil,
274 "Received \"Rx buffer is in risk of overflow\" interrupt\n"); 248 "Received \"Rx buffer is in risk of overflow\" interrupt\n");
275 249
276 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | 250 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE |
277 BIT_DMA_EP_RX_ICR_RX_HTRSH); 251 BIT_DMA_EP_RX_ICR_RX_HTRSH);
278 if (test_bit(wil_status_reset_done, wil->status)) { 252 if (likely(test_bit(wil_status_reset_done, wil->status))) {
279 if (test_bit(wil_status_napi_en, wil->status)) { 253 if (likely(test_bit(wil_status_napi_en, wil->status))) {
280 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 254 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n");
281 need_unmask = false; 255 need_unmask = false;
282 napi_schedule(&wil->napi_rx); 256 napi_schedule(&wil->napi_rx);
@@ -289,7 +263,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
289 } 263 }
290 } 264 }
291 265
292 if (isr) 266 if (unlikely(isr))
293 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr); 267 wil_err(wil, "un-handled RX ISR bits 0x%08x\n", isr);
294 268
295 /* Rx IRQ will be enabled when NAPI processing finished */ 269 /* Rx IRQ will be enabled when NAPI processing finished */
@@ -313,19 +287,19 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
313 trace_wil6210_irq_tx(isr); 287 trace_wil6210_irq_tx(isr);
314 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr); 288 wil_dbg_irq(wil, "ISR TX 0x%08x\n", isr);
315 289
316 if (!isr) { 290 if (unlikely(!isr)) {
317 wil_err(wil, "spurious IRQ: TX\n"); 291 wil_err(wil, "spurious IRQ: TX\n");
318 return IRQ_NONE; 292 return IRQ_NONE;
319 } 293 }
320 294
321 wil6210_mask_irq_tx(wil); 295 wil6210_mask_irq_tx(wil);
322 296
323 if (isr & BIT_DMA_EP_TX_ICR_TX_DONE) { 297 if (likely(isr & BIT_DMA_EP_TX_ICR_TX_DONE)) {
324 wil_dbg_irq(wil, "TX done\n"); 298 wil_dbg_irq(wil, "TX done\n");
325 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 299 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
326 /* clear also all VRING interrupts */ 300 /* clear also all VRING interrupts */
327 isr &= ~(BIT(25) - 1UL); 301 isr &= ~(BIT(25) - 1UL);
328 if (test_bit(wil_status_reset_done, wil->status)) { 302 if (likely(test_bit(wil_status_reset_done, wil->status))) {
329 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 303 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n");
330 need_unmask = false; 304 need_unmask = false;
331 napi_schedule(&wil->napi_tx); 305 napi_schedule(&wil->napi_tx);
@@ -334,7 +308,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
334 } 308 }
335 } 309 }
336 310
337 if (isr) 311 if (unlikely(isr))
338 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr); 312 wil_err(wil, "un-handled TX ISR bits 0x%08x\n", isr);
339 313
340 /* Tx IRQ will be enabled when NAPI processing finished */ 314 /* Tx IRQ will be enabled when NAPI processing finished */
@@ -523,11 +497,11 @@ static irqreturn_t wil6210_hardirq(int irq, void *cookie)
523 /** 497 /**
524 * pseudo_cause is Clear-On-Read, no need to ACK 498 * pseudo_cause is Clear-On-Read, no need to ACK
525 */ 499 */
526 if ((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)) 500 if (unlikely((pseudo_cause == 0) || ((pseudo_cause & 0xff) == 0xff)))
527 return IRQ_NONE; 501 return IRQ_NONE;
528 502
529 /* FIXME: IRQ mask debug */ 503 /* FIXME: IRQ mask debug */
530 if (wil6210_debug_irq_mask(wil, pseudo_cause)) 504 if (unlikely(wil6210_debug_irq_mask(wil, pseudo_cause)))
531 return IRQ_NONE; 505 return IRQ_NONE;
532 506
533 trace_wil6210_irq_pseudo(pseudo_cause); 507 trace_wil6210_irq_pseudo(pseudo_cause);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index b04e0afdcb21..db74e811f5c4 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -29,10 +29,6 @@ bool no_fw_recovery;
29module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); 29module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
30MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery"); 30MODULE_PARM_DESC(no_fw_recovery, " disable automatic FW error recovery");
31 31
32static bool no_fw_load = true;
33module_param(no_fw_load, bool, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash.");
35
36/* if not set via modparam, will be set to default value of 1/8 of 32/* if not set via modparam, will be set to default value of 1/8 of
37 * rx ring size during init flow 33 * rx ring size during init flow
38 */ 34 */
@@ -520,8 +516,6 @@ static int wil_target_reset(struct wil6210_priv *wil)
520{ 516{
521 int delay = 0; 517 int delay = 0;
522 u32 x; 518 u32 x;
523 bool is_reset_v2 = test_bit(hw_capability_reset_v2,
524 wil->hw_capabilities);
525 519
526 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name); 520 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name);
527 521
@@ -532,82 +526,67 @@ static int wil_target_reset(struct wil6210_priv *wil)
532 526
533 wil_halt_cpu(wil); 527 wil_halt_cpu(wil);
534 528
529 /* clear all boot loader "ready" bits */
530 W(RGF_USER_BL + offsetof(struct RGF_BL, ready), 0);
535 /* Clear Fw Download notification */ 531 /* Clear Fw Download notification */
536 C(RGF_USER_USAGE_6, BIT(0)); 532 C(RGF_USER_USAGE_6, BIT(0));
537 533
538 if (is_reset_v2) { 534 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN);
539 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); 535 /* XTAL stabilization should take about 3ms */
540 /* XTAL stabilization should take about 3ms */ 536 usleep_range(5000, 7000);
541 usleep_range(5000, 7000); 537 x = R(RGF_CAF_PLL_LOCK_STATUS);
542 x = R(RGF_CAF_PLL_LOCK_STATUS); 538 if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) {
543 if (!(x & BIT_CAF_OSC_DIG_XTAL_STABLE)) { 539 wil_err(wil, "Xtal stabilization timeout\n"
544 wil_err(wil, "Xtal stabilization timeout\n" 540 "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x);
545 "RGF_CAF_PLL_LOCK_STATUS = 0x%08x\n", x); 541 return -ETIME;
546 return -ETIME;
547 }
548 /* switch 10k to XTAL*/
549 C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF);
550 /* 40 MHz */
551 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL);
552
553 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
554 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
555 } 542 }
543 /* switch 10k to XTAL*/
544 C(RGF_USER_SPARROW_M_4, BIT_SPARROW_M_4_SEL_SLEEP_OR_REF);
545 /* 40 MHz */
546 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL);
547
548 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
549 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
556 550
557 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 551 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
558 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 552 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
559 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 553 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x000000f0);
560 is_reset_v2 ? 0x000000f0 : 0x00000170);
561 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); 554 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00);
562 555
563 if (is_reset_v2) { 556 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
564 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 557 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
565 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
566 }
567 558
568 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 559 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
569 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 560 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
570 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 561 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
571 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 562 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
572 563
573 if (is_reset_v2) { 564 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
574 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 565 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); /* reset A2 PCIE AHB */
575 /* reset A2 PCIE AHB */
576 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
577 } else {
578 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
579 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
580 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
581 }
582 566
583 /* TODO: check order here!!! Erez code is different */
584 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 567 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
585 568
586 /* wait until device ready. typical time is 200..250 msec */ 569 /* wait until device ready. typical time is 20..80 msec */
587 do { 570 do {
588 msleep(RST_DELAY); 571 msleep(RST_DELAY);
589 x = R(RGF_USER_HW_MACHINE_STATE); 572 x = R(RGF_USER_BL + offsetof(struct RGF_BL, ready));
590 if (delay++ > RST_COUNT) { 573 if (delay++ > RST_COUNT) {
591 wil_err(wil, "Reset not completed, hw_state 0x%08x\n", 574 wil_err(wil, "Reset not completed, bl.ready 0x%08x\n",
592 x); 575 x);
593 return -ETIME; 576 return -ETIME;
594 } 577 }
595 } while (x != HW_MACHINE_BOOT_DONE); 578 } while (!(x & BIT_BL_READY));
596
597 if (!is_reset_v2)
598 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
599 579
600 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 580 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
601 581
582 /* enable fix for HW bug related to the SA/DA swap in AP Rx */
583 S(RGF_DMA_OFUL_NID_0, BIT_DMA_OFUL_NID_0_RX_EXT_TR_EN |
584 BIT_DMA_OFUL_NID_0_RX_EXT_A3_SRC);
585
602 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); 586 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY);
603 return 0; 587 return 0;
604} 588}
605 589
606#undef R
607#undef W
608#undef S
609#undef C
610
611void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 590void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
612{ 591{
613 le32_to_cpus(&r->base); 592 le32_to_cpus(&r->base);
@@ -617,6 +596,32 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
617 le32_to_cpus(&r->head); 596 le32_to_cpus(&r->head);
618} 597}
619 598
599static int wil_get_bl_info(struct wil6210_priv *wil)
600{
601 struct net_device *ndev = wil_to_ndev(wil);
602 struct RGF_BL bl;
603
604 wil_memcpy_fromio_32(&bl, wil->csr + HOSTADDR(RGF_USER_BL), sizeof(bl));
605 le32_to_cpus(&bl.ready);
606 le32_to_cpus(&bl.version);
607 le32_to_cpus(&bl.rf_type);
608 le32_to_cpus(&bl.baseband_type);
609
610 if (!is_valid_ether_addr(bl.mac_address)) {
611 wil_err(wil, "BL: Invalid MAC %pM\n", bl.mac_address);
612 return -EINVAL;
613 }
614
615 ether_addr_copy(ndev->perm_addr, bl.mac_address);
616 if (!is_valid_ether_addr(ndev->dev_addr))
617 ether_addr_copy(ndev->dev_addr, bl.mac_address);
618 wil_info(wil,
619 "Boot Loader: ver = %d MAC = %pM RF = 0x%08x bband = 0x%08x\n",
620 bl.version, bl.mac_address, bl.rf_type, bl.baseband_type);
621
622 return 0;
623}
624
620static int wil_wait_for_fw_ready(struct wil6210_priv *wil) 625static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
621{ 626{
622 ulong to = msecs_to_jiffies(1000); 627 ulong to = msecs_to_jiffies(1000);
@@ -637,7 +642,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
637 * After calling this routine, you're expected to reload 642 * After calling this routine, you're expected to reload
638 * the firmware. 643 * the firmware.
639 */ 644 */
640int wil_reset(struct wil6210_priv *wil) 645int wil_reset(struct wil6210_priv *wil, bool load_fw)
641{ 646{
642 int rc; 647 int rc;
643 648
@@ -675,30 +680,36 @@ int wil_reset(struct wil6210_priv *wil)
675 if (rc) 680 if (rc)
676 return rc; 681 return rc;
677 682
678 if (!no_fw_load) { 683 rc = wil_get_bl_info(wil);
679 wil_info(wil, "Use firmware <%s>\n", WIL_FW_NAME); 684 if (rc)
685 return rc;
686
687 if (load_fw) {
688 wil_info(wil, "Use firmware <%s> + board <%s>\n", WIL_FW_NAME,
689 WIL_FW2_NAME);
690
680 wil_halt_cpu(wil); 691 wil_halt_cpu(wil);
681 /* Loading f/w from the file */ 692 /* Loading f/w from the file */
682 rc = wil_request_firmware(wil, WIL_FW_NAME); 693 rc = wil_request_firmware(wil, WIL_FW_NAME);
683 if (rc) 694 if (rc)
684 return rc; 695 return rc;
696 rc = wil_request_firmware(wil, WIL_FW2_NAME);
697 if (rc)
698 return rc;
685 699
686 /* clear any interrupts which on-card-firmware may have set */ 700 /* Mark FW as loaded from host */
701 S(RGF_USER_USAGE_6, 1);
702
703 /* clear any interrupts which on-card-firmware
704 * may have set
705 */
687 wil6210_clear_irq(wil); 706 wil6210_clear_irq(wil);
688 { /* CAF_ICR - clear and mask */ 707 /* CAF_ICR - clear and mask */
689 u32 a = HOSTADDR(RGF_CAF_ICR) + 708 /* it is W1C, clear by writing back same value */
690 offsetof(struct RGF_ICR, ICR); 709 S(RGF_CAF_ICR + offsetof(struct RGF_ICR, ICR), 0);
691 u32 m = HOSTADDR(RGF_CAF_ICR) + 710 W(RGF_CAF_ICR + offsetof(struct RGF_ICR, IMV), ~0);
692 offsetof(struct RGF_ICR, IMV); 711
693 u32 icr = ioread32(wil->csr + a);
694
695 iowrite32(icr, wil->csr + a); /* W1C */
696 iowrite32(~0, wil->csr + m);
697 wmb(); /* wait for completion */
698 }
699 wil_release_cpu(wil); 712 wil_release_cpu(wil);
700 } else {
701 wil_info(wil, "Use firmware from on-card flash\n");
702 } 713 }
703 714
704 /* init after reset */ 715 /* init after reset */
@@ -706,15 +717,22 @@ int wil_reset(struct wil6210_priv *wil)
706 reinit_completion(&wil->wmi_ready); 717 reinit_completion(&wil->wmi_ready);
707 reinit_completion(&wil->wmi_call); 718 reinit_completion(&wil->wmi_call);
708 719
709 wil_configure_interrupt_moderation(wil); 720 if (load_fw) {
710 wil_unmask_irq(wil); 721 wil_configure_interrupt_moderation(wil);
722 wil_unmask_irq(wil);
711 723
712 /* we just started MAC, wait for FW ready */ 724 /* we just started MAC, wait for FW ready */
713 rc = wil_wait_for_fw_ready(wil); 725 rc = wil_wait_for_fw_ready(wil);
726 }
714 727
715 return rc; 728 return rc;
716} 729}
717 730
731#undef R
732#undef W
733#undef S
734#undef C
735
718void wil_fw_error_recovery(struct wil6210_priv *wil) 736void wil_fw_error_recovery(struct wil6210_priv *wil)
719{ 737{
720 wil_dbg_misc(wil, "starting fw error recovery\n"); 738 wil_dbg_misc(wil, "starting fw error recovery\n");
@@ -730,7 +748,7 @@ int __wil_up(struct wil6210_priv *wil)
730 748
731 WARN_ON(!mutex_is_locked(&wil->mutex)); 749 WARN_ON(!mutex_is_locked(&wil->mutex));
732 750
733 rc = wil_reset(wil); 751 rc = wil_reset(wil, true);
734 if (rc) 752 if (rc)
735 return rc; 753 return rc;
736 754
@@ -837,7 +855,7 @@ int __wil_down(struct wil6210_priv *wil)
837 if (!iter) 855 if (!iter)
838 wil_err(wil, "timeout waiting for idle FW/HW\n"); 856 wil_err(wil, "timeout waiting for idle FW/HW\n");
839 857
840 wil_rx_fini(wil); 858 wil_reset(wil, false);
841 859
842 return 0; 860 return 0;
843} 861}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 3dd26709ccb2..25343cffe229 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -39,18 +39,6 @@ void wil_set_capabilities(struct wil6210_priv *wil)
39 bitmap_zero(wil->hw_capabilities, hw_capability_last); 39 bitmap_zero(wil->hw_capabilities, hw_capability_last);
40 40
41 switch (rev_id) { 41 switch (rev_id) {
42 case JTAG_DEV_ID_MARLON_B0:
43 wil->hw_name = "Marlon B0";
44 wil->hw_version = HW_VER_MARLON_B0;
45 break;
46 case JTAG_DEV_ID_SPARROW_A0:
47 wil->hw_name = "Sparrow A0";
48 wil->hw_version = HW_VER_SPARROW_A0;
49 break;
50 case JTAG_DEV_ID_SPARROW_A1:
51 wil->hw_name = "Sparrow A1";
52 wil->hw_version = HW_VER_SPARROW_A1;
53 break;
54 case JTAG_DEV_ID_SPARROW_B0: 42 case JTAG_DEV_ID_SPARROW_B0:
55 wil->hw_name = "Sparrow B0"; 43 wil->hw_name = "Sparrow B0";
56 wil->hw_version = HW_VER_SPARROW_B0; 44 wil->hw_version = HW_VER_SPARROW_B0;
@@ -62,13 +50,6 @@ void wil_set_capabilities(struct wil6210_priv *wil)
62 } 50 }
63 51
64 wil_info(wil, "Board hardware is %s\n", wil->hw_name); 52 wil_info(wil, "Board hardware is %s\n", wil->hw_name);
65
66 if (wil->hw_version >= HW_VER_SPARROW_A0)
67 set_bit(hw_capability_reset_v2, wil->hw_capabilities);
68
69 if (wil->hw_version >= HW_VER_SPARROW_B0)
70 set_bit(hw_capability_advanced_itr_moderation,
71 wil->hw_capabilities);
72} 53}
73 54
74void wil_disable_irq(struct wil6210_priv *wil) 55void wil_disable_irq(struct wil6210_priv *wil)
@@ -150,7 +131,7 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
150 131
151 /* need reset here to obtain MAC */ 132 /* need reset here to obtain MAC */
152 mutex_lock(&wil->mutex); 133 mutex_lock(&wil->mutex);
153 rc = wil_reset(wil); 134 rc = wil_reset(wil, false);
154 mutex_unlock(&wil->mutex); 135 mutex_unlock(&wil->mutex);
155 if (debug_fw) 136 if (debug_fw)
156 rc = 0; 137 rc = 0;
@@ -305,7 +286,6 @@ static void wil_pcie_remove(struct pci_dev *pdev)
305} 286}
306 287
307static const struct pci_device_id wil6210_pcie_ids[] = { 288static const struct pci_device_id wil6210_pcie_ids[] = {
308 { PCI_DEVICE(0x1ae9, 0x0301) },
309 { PCI_DEVICE(0x1ae9, 0x0310) }, 289 { PCI_DEVICE(0x1ae9, 0x0310) },
310 { PCI_DEVICE(0x1ae9, 0x0302) }, /* same as above, firmware broken */ 290 { PCI_DEVICE(0x1ae9, 0x0302) }, /* same as above, firmware broken */
311 { /* end: all zeroes */ }, 291 { /* end: all zeroes */ },
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 8439f65db259..7f2f560b8638 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -53,34 +53,38 @@ static inline int wil_vring_is_full(struct vring *vring)
53 return wil_vring_next_tail(vring) == vring->swhead; 53 return wil_vring_next_tail(vring) == vring->swhead;
54} 54}
55 55
56/* 56/* Used space in Tx Vring */
57 * Available space in Tx Vring 57static inline int wil_vring_used_tx(struct vring *vring)
58 */
59static inline int wil_vring_avail_tx(struct vring *vring)
60{ 58{
61 u32 swhead = vring->swhead; 59 u32 swhead = vring->swhead;
62 u32 swtail = vring->swtail; 60 u32 swtail = vring->swtail;
63 int used = (vring->size + swhead - swtail) % vring->size; 61 return (vring->size + swhead - swtail) % vring->size;
62}
64 63
65 return vring->size - used - 1; 64/* Available space in Tx Vring */
65static inline int wil_vring_avail_tx(struct vring *vring)
66{
67 return vring->size - wil_vring_used_tx(vring) - 1;
66} 68}
67 69
68/** 70/* wil_vring_wmark_low - low watermark for available descriptor space */
69 * wil_vring_wmark_low - low watermark for available descriptor space
70 */
71static inline int wil_vring_wmark_low(struct vring *vring) 71static inline int wil_vring_wmark_low(struct vring *vring)
72{ 72{
73 return vring->size/8; 73 return vring->size/8;
74} 74}
75 75
76/** 76/* wil_vring_wmark_high - high watermark for available descriptor space */
77 * wil_vring_wmark_high - high watermark for available descriptor space
78 */
79static inline int wil_vring_wmark_high(struct vring *vring) 77static inline int wil_vring_wmark_high(struct vring *vring)
80{ 78{
81 return vring->size/4; 79 return vring->size/4;
82} 80}
83 81
82/* wil_val_in_range - check if value in [min,max) */
83static inline bool wil_val_in_range(int val, int min, int max)
84{
85 return val >= min && val < max;
86}
87
84static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) 88static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
85{ 89{
86 struct device *dev = wil_to_dev(wil); 90 struct device *dev = wil_to_dev(wil);
@@ -98,8 +102,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
98 vring->va = NULL; 102 vring->va = NULL;
99 return -ENOMEM; 103 return -ENOMEM;
100 } 104 }
101 /* 105 /* vring->va should be aligned on its size rounded up to power of 2
102 * vring->va should be aligned on its size rounded up to power of 2
103 * This is granted by the dma_alloc_coherent 106 * This is granted by the dma_alloc_coherent
104 */ 107 */
105 vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL); 108 vring->va = dma_alloc_coherent(dev, sz, &vring->pa, GFP_KERNEL);
@@ -346,27 +349,6 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
346 } 349 }
347} 350}
348 351
349/*
350 * Fast swap in place between 2 registers
351 */
352static void wil_swap_u16(u16 *a, u16 *b)
353{
354 *a ^= *b;
355 *b ^= *a;
356 *a ^= *b;
357}
358
359static void wil_swap_ethaddr(void *data)
360{
361 struct ethhdr *eth = data;
362 u16 *s = (u16 *)eth->h_source;
363 u16 *d = (u16 *)eth->h_dest;
364
365 wil_swap_u16(s++, d++);
366 wil_swap_u16(s++, d++);
367 wil_swap_u16(s, d);
368}
369
370/** 352/**
371 * reap 1 frame from @swhead 353 * reap 1 frame from @swhead
372 * 354 *
@@ -386,17 +368,16 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
386 unsigned int sz = mtu_max + ETH_HLEN; 368 unsigned int sz = mtu_max + ETH_HLEN;
387 u16 dmalen; 369 u16 dmalen;
388 u8 ftype; 370 u8 ftype;
389 u8 ds_bits;
390 int cid; 371 int cid;
391 struct wil_net_stats *stats; 372 struct wil_net_stats *stats;
392 373
393 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); 374 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
394 375
395 if (wil_vring_is_empty(vring)) 376 if (unlikely(wil_vring_is_empty(vring)))
396 return NULL; 377 return NULL;
397 378
398 _d = &vring->va[vring->swhead].rx; 379 _d = &vring->va[vring->swhead].rx;
399 if (!(_d->dma.status & RX_DMA_STATUS_DU)) { 380 if (unlikely(!(_d->dma.status & RX_DMA_STATUS_DU))) {
400 /* it is not error, we just reached end of Rx done area */ 381 /* it is not error, we just reached end of Rx done area */
401 return NULL; 382 return NULL;
402 } 383 }
@@ -416,7 +397,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
416 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, 397 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
417 (const void *)d, sizeof(*d), false); 398 (const void *)d, sizeof(*d), false);
418 399
419 if (dmalen > sz) { 400 if (unlikely(dmalen > sz)) {
420 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen); 401 wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
421 kfree_skb(skb); 402 kfree_skb(skb);
422 return NULL; 403 return NULL;
@@ -445,14 +426,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
445 * in Rx descriptor. If type is not data, it is 802.11 frame as is 426 * in Rx descriptor. If type is not data, it is 802.11 frame as is
446 */ 427 */
447 ftype = wil_rxdesc_ftype(d) << 2; 428 ftype = wil_rxdesc_ftype(d) << 2;
448 if (ftype != IEEE80211_FTYPE_DATA) { 429 if (unlikely(ftype != IEEE80211_FTYPE_DATA)) {
449 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype); 430 wil_dbg_txrx(wil, "Non-data frame ftype 0x%08x\n", ftype);
450 /* TODO: process it */ 431 /* TODO: process it */
451 kfree_skb(skb); 432 kfree_skb(skb);
452 return NULL; 433 return NULL;
453 } 434 }
454 435
455 if (skb->len < ETH_HLEN) { 436 if (unlikely(skb->len < ETH_HLEN)) {
456 wil_err(wil, "Short frame, len = %d\n", skb->len); 437 wil_err(wil, "Short frame, len = %d\n", skb->len);
457 /* TODO: process it (i.e. BAR) */ 438 /* TODO: process it (i.e. BAR) */
458 kfree_skb(skb); 439 kfree_skb(skb);
@@ -463,9 +444,9 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
463 * and in case of error drop the packet 444 * and in case of error drop the packet
464 * higher stack layers will handle retransmission (if required) 445 * higher stack layers will handle retransmission (if required)
465 */ 446 */
466 if (d->dma.status & RX_DMA_STATUS_L4I) { 447 if (likely(d->dma.status & RX_DMA_STATUS_L4I)) {
467 /* L4 protocol identified, csum calculated */ 448 /* L4 protocol identified, csum calculated */
468 if ((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0) 449 if (likely((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0))
469 skb->ip_summed = CHECKSUM_UNNECESSARY; 450 skb->ip_summed = CHECKSUM_UNNECESSARY;
470 /* If HW reports bad checksum, let IP stack re-check it 451 /* If HW reports bad checksum, let IP stack re-check it
471 * For example, HW don't understand Microsoft IP stack that 452 * For example, HW don't understand Microsoft IP stack that
@@ -474,15 +455,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
474 */ 455 */
475 } 456 }
476 457
477 ds_bits = wil_rxdesc_ds_bits(d);
478 if (ds_bits == 1) {
479 /*
480 * HW bug - in ToDS mode, i.e. Rx on AP side,
481 * addresses get swapped
482 */
483 wil_swap_ethaddr(skb->data);
484 }
485
486 return skb; 458 return skb;
487} 459}
488 460
@@ -503,7 +475,7 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
503 (next_tail != v->swhead) && (count-- > 0); 475 (next_tail != v->swhead) && (count-- > 0);
504 v->swtail = next_tail) { 476 v->swtail = next_tail) {
505 rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom); 477 rc = wil_vring_alloc_skb(wil, v, v->swtail, headroom);
506 if (rc) { 478 if (unlikely(rc)) {
507 wil_err(wil, "Error %d in wil_rx_refill[%d]\n", 479 wil_err(wil, "Error %d in wil_rx_refill[%d]\n",
508 rc, v->swtail); 480 rc, v->swtail);
509 break; 481 break;
@@ -565,7 +537,7 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
565 struct vring *v = &wil->vring_rx; 537 struct vring *v = &wil->vring_rx;
566 struct sk_buff *skb; 538 struct sk_buff *skb;
567 539
568 if (!v->va) { 540 if (unlikely(!v->va)) {
569 wil_err(wil, "Rx IRQ while Rx not yet initialized\n"); 541 wil_err(wil, "Rx IRQ while Rx not yet initialized\n");
570 return; 542 return;
571 } 543 }
@@ -952,13 +924,14 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
952 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; 924 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
953 uint i = swhead; 925 uint i = swhead;
954 dma_addr_t pa; 926 dma_addr_t pa;
927 int used;
955 928
956 wil_dbg_txrx(wil, "%s()\n", __func__); 929 wil_dbg_txrx(wil, "%s()\n", __func__);
957 930
958 if (unlikely(!txdata->enabled)) 931 if (unlikely(!txdata->enabled))
959 return -EINVAL; 932 return -EINVAL;
960 933
961 if (avail < 1 + nr_frags) { 934 if (unlikely(avail < 1 + nr_frags)) {
962 wil_err_ratelimited(wil, 935 wil_err_ratelimited(wil,
963 "Tx ring[%2d] full. No space for %d fragments\n", 936 "Tx ring[%2d] full. No space for %d fragments\n",
964 vring_index, 1 + nr_frags); 937 vring_index, 1 + nr_frags);
@@ -979,7 +952,7 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
979 /* 1-st segment */ 952 /* 1-st segment */
980 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 953 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
981 /* Process TCP/UDP checksum offloading */ 954 /* Process TCP/UDP checksum offloading */
982 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) { 955 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) {
983 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n", 956 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
984 vring_index); 957 vring_index);
985 goto dma_error; 958 goto dma_error;
@@ -1027,8 +1000,14 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1027 */ 1000 */
1028 vring->ctx[i].skb = skb_get(skb); 1001 vring->ctx[i].skb = skb_get(skb);
1029 1002
1030 if (wil_vring_is_empty(vring)) /* performance monitoring */ 1003 /* performance monitoring */
1004 used = wil_vring_used_tx(vring);
1005 if (wil_val_in_range(vring_idle_trsh,
1006 used, used + nr_frags + 1)) {
1031 txdata->idle += get_cycles() - txdata->last_idle; 1007 txdata->idle += get_cycles() - txdata->last_idle;
1008 wil_dbg_txrx(wil, "Ring[%2d] not idle %d -> %d\n",
1009 vring_index, used, used + nr_frags + 1);
1010 }
1032 1011
1033 /* advance swhead */ 1012 /* advance swhead */
1034 wil_vring_advance_head(vring, nr_frags + 1); 1013 wil_vring_advance_head(vring, nr_frags + 1);
@@ -1082,18 +1061,18 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1082 int rc; 1061 int rc;
1083 1062
1084 wil_dbg_txrx(wil, "%s()\n", __func__); 1063 wil_dbg_txrx(wil, "%s()\n", __func__);
1085 if (!test_bit(wil_status_fwready, wil->status)) { 1064 if (unlikely(!test_bit(wil_status_fwready, wil->status))) {
1086 if (!pr_once_fw) { 1065 if (!pr_once_fw) {
1087 wil_err(wil, "FW not ready\n"); 1066 wil_err(wil, "FW not ready\n");
1088 pr_once_fw = true; 1067 pr_once_fw = true;
1089 } 1068 }
1090 goto drop; 1069 goto drop;
1091 } 1070 }
1092 if (!test_bit(wil_status_fwconnected, wil->status)) { 1071 if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) {
1093 wil_err(wil, "FW not connected\n"); 1072 wil_err(wil, "FW not connected\n");
1094 goto drop; 1073 goto drop;
1095 } 1074 }
1096 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 1075 if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) {
1097 wil_err(wil, "Xmit in monitor mode not supported\n"); 1076 wil_err(wil, "Xmit in monitor mode not supported\n");
1098 goto drop; 1077 goto drop;
1099 } 1078 }
@@ -1109,7 +1088,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1109 else 1088 else
1110 vring = wil_tx_bcast(wil, skb); 1089 vring = wil_tx_bcast(wil, skb);
1111 } 1090 }
1112 if (!vring) { 1091 if (unlikely(!vring)) {
1113 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1092 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1114 goto drop; 1093 goto drop;
1115 } 1094 }
@@ -1117,7 +1096,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1117 rc = wil_tx_vring(wil, vring, skb); 1096 rc = wil_tx_vring(wil, vring, skb);
1118 1097
1119 /* do we still have enough room in the vring? */ 1098 /* do we still have enough room in the vring? */
1120 if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring)) { 1099 if (unlikely(wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))) {
1121 netif_tx_stop_all_queues(wil_to_ndev(wil)); 1100 netif_tx_stop_all_queues(wil_to_ndev(wil));
1122 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n"); 1101 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
1123 } 1102 }
@@ -1172,19 +1151,23 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1172 int cid = wil->vring2cid_tid[ringid][0]; 1151 int cid = wil->vring2cid_tid[ringid][0];
1173 struct wil_net_stats *stats = &wil->sta[cid].stats; 1152 struct wil_net_stats *stats = &wil->sta[cid].stats;
1174 volatile struct vring_tx_desc *_d; 1153 volatile struct vring_tx_desc *_d;
1154 int used_before_complete;
1155 int used_new;
1175 1156
1176 if (!vring->va) { 1157 if (unlikely(!vring->va)) {
1177 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid); 1158 wil_err(wil, "Tx irq[%d]: vring not initialized\n", ringid);
1178 return 0; 1159 return 0;
1179 } 1160 }
1180 1161
1181 if (!txdata->enabled) { 1162 if (unlikely(!txdata->enabled)) {
1182 wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid); 1163 wil_info(wil, "Tx irq[%d]: vring disabled\n", ringid);
1183 return 0; 1164 return 0;
1184 } 1165 }
1185 1166
1186 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid); 1167 wil_dbg_txrx(wil, "%s(%d)\n", __func__, ringid);
1187 1168
1169 used_before_complete = wil_vring_used_tx(vring);
1170
1188 while (!wil_vring_is_empty(vring)) { 1171 while (!wil_vring_is_empty(vring)) {
1189 int new_swtail; 1172 int new_swtail;
1190 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1173 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
@@ -1196,7 +1179,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1196 /* TODO: check we are not past head */ 1179 /* TODO: check we are not past head */
1197 1180
1198 _d = &vring->va[lf].tx; 1181 _d = &vring->va[lf].tx;
1199 if (!(_d->dma.status & TX_DMA_STATUS_DU)) 1182 if (unlikely(!(_d->dma.status & TX_DMA_STATUS_DU)))
1200 break; 1183 break;
1201 1184
1202 new_swtail = (lf + 1) % vring->size; 1185 new_swtail = (lf + 1) % vring->size;
@@ -1224,7 +1207,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1224 wil_txdesc_unmap(dev, d, ctx); 1207 wil_txdesc_unmap(dev, d, ctx);
1225 1208
1226 if (skb) { 1209 if (skb) {
1227 if (d->dma.error == 0) { 1210 if (likely(d->dma.error == 0)) {
1228 ndev->stats.tx_packets++; 1211 ndev->stats.tx_packets++;
1229 stats->tx_packets++; 1212 stats->tx_packets++;
1230 ndev->stats.tx_bytes += skb->len; 1213 ndev->stats.tx_bytes += skb->len;
@@ -1246,8 +1229,12 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1246 } 1229 }
1247 } 1230 }
1248 1231
1249 if (wil_vring_is_empty(vring)) { /* performance monitoring */ 1232 /* performance monitoring */
1250 wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid); 1233 used_new = wil_vring_used_tx(vring);
1234 if (wil_val_in_range(vring_idle_trsh,
1235 used_new, used_before_complete)) {
1236 wil_dbg_txrx(wil, "Ring[%2d] idle %d -> %d\n",
1237 ringid, used_before_complete, used_new);
1251 txdata->last_idle = get_cycles(); 1238 txdata->last_idle = get_cycles();
1252 } 1239 }
1253 1240
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 94611568fc9a..b6e65c37d410 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -27,9 +27,11 @@ extern bool no_fw_recovery;
27extern unsigned int mtu_max; 27extern unsigned int mtu_max;
28extern unsigned short rx_ring_overflow_thrsh; 28extern unsigned short rx_ring_overflow_thrsh;
29extern int agg_wsize; 29extern int agg_wsize;
30extern u32 vring_idle_trsh;
30 31
31#define WIL_NAME "wil6210" 32#define WIL_NAME "wil6210"
32#define WIL_FW_NAME "wil6210.fw" 33#define WIL_FW_NAME "wil6210.fw" /* code */
34#define WIL_FW2_NAME "wil6210.board" /* board & radio parameters */
33 35
34#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ 36#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
35 37
@@ -120,6 +122,16 @@ struct RGF_ICR {
120 u32 IMC; /* Mask Clear, write 1 to clear */ 122 u32 IMC; /* Mask Clear, write 1 to clear */
121} __packed; 123} __packed;
122 124
125struct RGF_BL {
126 u32 ready; /* 0x880A3C bit [0] */
127#define BIT_BL_READY BIT(0)
128 u32 version; /* 0x880A40 version of the BL struct */
129 u32 rf_type; /* 0x880A44 ID of the connected RF */
130 u32 baseband_type; /* 0x880A48 ID of the baseband */
131 u8 mac_address[ETH_ALEN]; /* 0x880A4C permanent MAC */
132 u8 pad[2];
133} __packed;
134
123/* registers - FW addresses */ 135/* registers - FW addresses */
124#define RGF_USER_USAGE_1 (0x880004) 136#define RGF_USER_USAGE_1 (0x880004)
125#define RGF_USER_USAGE_6 (0x880018) 137#define RGF_USER_USAGE_6 (0x880018)
@@ -130,6 +142,7 @@ struct RGF_ICR {
130#define RGF_USER_MAC_CPU_0 (0x8801fc) 142#define RGF_USER_MAC_CPU_0 (0x8801fc)
131 #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */ 143 #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */
132#define RGF_USER_USER_SCRATCH_PAD (0x8802bc) 144#define RGF_USER_USER_SCRATCH_PAD (0x8802bc)
145#define RGF_USER_BL (0x880A3C) /* Boot Loader */
133#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */ 146#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */
134#define RGF_USER_CLKS_CTL_0 (0x880abc) 147#define RGF_USER_CLKS_CTL_0 (0x880abc)
135 #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */ 148 #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */
@@ -169,6 +182,13 @@ struct RGF_ICR {
169 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3) 182 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3)
170 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4) 183 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4)
171 184
185/* Offload control (Sparrow B0+) */
186#define RGF_DMA_OFUL_NID_0 (0x881cd4)
187 #define BIT_DMA_OFUL_NID_0_RX_EXT_TR_EN BIT(0)
188 #define BIT_DMA_OFUL_NID_0_TX_EXT_TR_EN BIT(1)
189 #define BIT_DMA_OFUL_NID_0_RX_EXT_A3_SRC BIT(2)
190 #define BIT_DMA_OFUL_NID_0_TX_EXT_A3_SRC BIT(3)
191
172/* New (sparrow v2+) interrupt moderation control */ 192/* New (sparrow v2+) interrupt moderation control */
173#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40) 193#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40)
174#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34) 194#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34)
@@ -229,16 +249,10 @@ struct RGF_ICR {
229 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) 249 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
230 250
231#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */ 251#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
232 #define JTAG_DEV_ID_MARLON_B0 (0x0612072f)
233 #define JTAG_DEV_ID_SPARROW_A0 (0x0632072f)
234 #define JTAG_DEV_ID_SPARROW_A1 (0x1632072f)
235 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f) 252 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
236 253
237enum { 254enum {
238 HW_VER_UNKNOWN, 255 HW_VER_UNKNOWN,
239 HW_VER_MARLON_B0, /* JTAG_DEV_ID_MARLON_B0 */
240 HW_VER_SPARROW_A0, /* JTAG_DEV_ID_SPARROW_A0 */
241 HW_VER_SPARROW_A1, /* JTAG_DEV_ID_SPARROW_A1 */
242 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */ 256 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
243}; 257};
244 258
@@ -482,8 +496,6 @@ enum {
482}; 496};
483 497
484enum { 498enum {
485 hw_capability_reset_v2 = 0,
486 hw_capability_advanced_itr_moderation = 1,
487 hw_capability_last 499 hw_capability_last
488}; 500};
489 501
@@ -528,7 +540,7 @@ struct wil6210_priv {
528 wait_queue_head_t wq; /* for all wait_event() use */ 540 wait_queue_head_t wq; /* for all wait_event() use */
529 /* profile */ 541 /* profile */
530 u32 monitor_flags; 542 u32 monitor_flags;
531 u32 secure_pcp; /* create secure PCP? */ 543 u32 privacy; /* secure connection? */
532 int sinfo_gen; 544 int sinfo_gen;
533 /* interrupt moderation */ 545 /* interrupt moderation */
534 u32 tx_max_burst_duration; 546 u32 tx_max_burst_duration;
@@ -658,7 +670,7 @@ int wil_if_add(struct wil6210_priv *wil);
658void wil_if_remove(struct wil6210_priv *wil); 670void wil_if_remove(struct wil6210_priv *wil);
659int wil_priv_init(struct wil6210_priv *wil); 671int wil_priv_init(struct wil6210_priv *wil);
660void wil_priv_deinit(struct wil6210_priv *wil); 672void wil_priv_deinit(struct wil6210_priv *wil);
661int wil_reset(struct wil6210_priv *wil); 673int wil_reset(struct wil6210_priv *wil, bool no_fw);
662void wil_fw_error_recovery(struct wil6210_priv *wil); 674void wil_fw_error_recovery(struct wil6210_priv *wil);
663void wil_set_recovery_state(struct wil6210_priv *wil, int state); 675void wil_set_recovery_state(struct wil6210_priv *wil, int state);
664int wil_up(struct wil6210_priv *wil); 676int wil_up(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0f3e4334c8e3..021313524913 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -281,7 +281,6 @@ int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
281/*=== Event handlers ===*/ 281/*=== Event handlers ===*/
282static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) 282static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
283{ 283{
284 struct net_device *ndev = wil_to_ndev(wil);
285 struct wireless_dev *wdev = wil->wdev; 284 struct wireless_dev *wdev = wil->wdev;
286 struct wmi_ready_event *evt = d; 285 struct wmi_ready_event *evt = d;
287 286
@@ -290,11 +289,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
290 289
291 wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version, 290 wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
292 evt->mac, wil->n_mids); 291 evt->mac, wil->n_mids);
293 292 /* ignore MAC address, we already have it from the boot loader */
294 if (!is_valid_ether_addr(ndev->dev_addr)) {
295 memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
296 memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
297 }
298 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version), 293 snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
299 "%d", wil->fw_version); 294 "%d", wil->fw_version);
300} 295}
@@ -879,7 +874,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
879 struct wmi_pcp_started_event evt; 874 struct wmi_pcp_started_event evt;
880 } __packed reply; 875 } __packed reply;
881 876
882 if (!wil->secure_pcp) 877 if (!wil->privacy)
883 cmd.disable_sec = 1; 878 cmd.disable_sec = 1;
884 879
885 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || 880 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) ||
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 31c7e4d41a9a..ac99798570e8 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4819,7 +4819,7 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4819 switch (dev->dev->bus_type) { 4819 switch (dev->dev->bus_type) {
4820#ifdef CONFIG_B43_BCMA 4820#ifdef CONFIG_B43_BCMA
4821 case B43_BUS_BCMA: 4821 case B43_BUS_BCMA:
4822 bcma_core_pci_down(dev->dev->bdev->bus); 4822 bcma_host_pci_down(dev->dev->bdev->bus);
4823 break; 4823 break;
4824#endif 4824#endif
4825#ifdef CONFIG_B43_SSB 4825#ifdef CONFIG_B43_SSB
@@ -4866,9 +4866,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4866 switch (dev->dev->bus_type) { 4866 switch (dev->dev->bus_type) {
4867#ifdef CONFIG_B43_BCMA 4867#ifdef CONFIG_B43_BCMA
4868 case B43_BUS_BCMA: 4868 case B43_BUS_BCMA:
4869 bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0], 4869 bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
4870 dev->dev->bdev, true); 4870 dev->dev->bdev, true);
4871 bcma_core_pci_up(dev->dev->bdev->bus); 4871 bcma_host_pci_up(dev->dev->bdev->bus);
4872 break; 4872 break;
4873#endif 4873#endif
4874#ifdef CONFIG_B43_SSB 4874#ifdef CONFIG_B43_SSB
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 7944224e3fc9..c438ccdb6ed8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -58,6 +58,14 @@
58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */ 58#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */ 59#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
60 60
61struct brcmf_sdiod_freezer {
62 atomic_t freezing;
63 atomic_t thread_count;
64 u32 frozen_count;
65 wait_queue_head_t thread_freeze;
66 struct completion resumed;
67};
68
61static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; 69static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
62module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0); 70module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
63MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); 71MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
@@ -197,6 +205,30 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
197 return 0; 205 return 0;
198} 206}
199 207
208void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
209 enum brcmf_sdiod_state state)
210{
211 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM ||
212 state == sdiodev->state)
213 return;
214
215 brcmf_dbg(TRACE, "%d -> %d\n", sdiodev->state, state);
216 switch (sdiodev->state) {
217 case BRCMF_SDIOD_DATA:
218 /* any other state means bus interface is down */
219 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
220 break;
221 case BRCMF_SDIOD_DOWN:
222 /* transition from DOWN to DATA means bus interface is up */
223 if (state == BRCMF_SDIOD_DATA)
224 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_UP);
225 break;
226 default:
227 break;
228 }
229 sdiodev->state = state;
230}
231
200static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, 232static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func,
201 uint regaddr, u8 byte) 233 uint regaddr, u8 byte)
202{ 234{
@@ -269,12 +301,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
269 return ret; 301 return ret;
270} 302}
271 303
272static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev)
273{
274 sdiodev->state = BRCMF_STATE_NOMEDIUM;
275 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
276}
277
278static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 304static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
279 u8 regsz, void *data, bool write) 305 u8 regsz, void *data, bool write)
280{ 306{
@@ -282,7 +308,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
282 s32 retry = 0; 308 s32 retry = 0;
283 int ret; 309 int ret;
284 310
285 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 311 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
286 return -ENOMEDIUM; 312 return -ENOMEDIUM;
287 313
288 /* 314 /*
@@ -308,7 +334,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
308 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 334 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
309 335
310 if (ret == -ENOMEDIUM) 336 if (ret == -ENOMEDIUM)
311 brcmf_sdiod_nomedium_state(sdiodev); 337 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
312 else if (ret != 0) { 338 else if (ret != 0) {
313 /* 339 /*
314 * SleepCSR register access can fail when 340 * SleepCSR register access can fail when
@@ -331,7 +357,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
331 int err = 0, i; 357 int err = 0, i;
332 u8 addr[3]; 358 u8 addr[3];
333 359
334 if (sdiodev->state == BRCMF_STATE_NOMEDIUM) 360 if (sdiodev->state == BRCMF_SDIOD_NOMEDIUM)
335 return -ENOMEDIUM; 361 return -ENOMEDIUM;
336 362
337 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 363 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
@@ -460,7 +486,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
460 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, 486 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
461 req_sz); 487 req_sz);
462 if (err == -ENOMEDIUM) 488 if (err == -ENOMEDIUM)
463 brcmf_sdiod_nomedium_state(sdiodev); 489 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
464 return err; 490 return err;
465} 491}
466 492
@@ -595,7 +621,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
595 621
596 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 622 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
597 if (ret == -ENOMEDIUM) { 623 if (ret == -ENOMEDIUM) {
598 brcmf_sdiod_nomedium_state(sdiodev); 624 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_NOMEDIUM);
599 break; 625 break;
600 } else if (ret != 0) { 626 } else if (ret != 0) {
601 brcmf_err("CMD53 sg block %s failed %d\n", 627 brcmf_err("CMD53 sg block %s failed %d\n",
@@ -877,6 +903,87 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
877 sdiodev->txglomsz = brcmf_sdiod_txglomsz; 903 sdiodev->txglomsz = brcmf_sdiod_txglomsz;
878} 904}
879 905
906#ifdef CONFIG_PM_SLEEP
907static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
908{
909 sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL);
910 if (!sdiodev->freezer)
911 return -ENOMEM;
912 atomic_set(&sdiodev->freezer->thread_count, 0);
913 atomic_set(&sdiodev->freezer->freezing, 0);
914 init_waitqueue_head(&sdiodev->freezer->thread_freeze);
915 init_completion(&sdiodev->freezer->resumed);
916 return 0;
917}
918
919static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
920{
921 if (sdiodev->freezer) {
922 WARN_ON(atomic_read(&sdiodev->freezer->freezing));
923 kfree(sdiodev->freezer);
924 }
925}
926
927static int brcmf_sdiod_freezer_on(struct brcmf_sdio_dev *sdiodev)
928{
929 atomic_t *expect = &sdiodev->freezer->thread_count;
930 int res = 0;
931
932 sdiodev->freezer->frozen_count = 0;
933 reinit_completion(&sdiodev->freezer->resumed);
934 atomic_set(&sdiodev->freezer->freezing, 1);
935 brcmf_sdio_trigger_dpc(sdiodev->bus);
936 wait_event(sdiodev->freezer->thread_freeze,
937 atomic_read(expect) == sdiodev->freezer->frozen_count);
938 sdio_claim_host(sdiodev->func[1]);
939 res = brcmf_sdio_sleep(sdiodev->bus, true);
940 sdio_release_host(sdiodev->func[1]);
941 return res;
942}
943
944static void brcmf_sdiod_freezer_off(struct brcmf_sdio_dev *sdiodev)
945{
946 sdio_claim_host(sdiodev->func[1]);
947 brcmf_sdio_sleep(sdiodev->bus, false);
948 sdio_release_host(sdiodev->func[1]);
949 atomic_set(&sdiodev->freezer->freezing, 0);
950 complete_all(&sdiodev->freezer->resumed);
951}
952
953bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
954{
955 return atomic_read(&sdiodev->freezer->freezing);
956}
957
958void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
959{
960 if (!brcmf_sdiod_freezing(sdiodev))
961 return;
962 sdiodev->freezer->frozen_count++;
963 wake_up(&sdiodev->freezer->thread_freeze);
964 wait_for_completion(&sdiodev->freezer->resumed);
965}
966
967void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
968{
969 atomic_inc(&sdiodev->freezer->thread_count);
970}
971
972void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
973{
974 atomic_dec(&sdiodev->freezer->thread_count);
975}
976#else
977static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev)
978{
979 return 0;
980}
981
982static void brcmf_sdiod_freezer_detach(struct brcmf_sdio_dev *sdiodev)
983{
984}
985#endif /* CONFIG_PM_SLEEP */
986
880static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) 987static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
881{ 988{
882 if (sdiodev->bus) { 989 if (sdiodev->bus) {
@@ -884,6 +991,8 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
884 sdiodev->bus = NULL; 991 sdiodev->bus = NULL;
885 } 992 }
886 993
994 brcmf_sdiod_freezer_detach(sdiodev);
995
887 /* Disable Function 2 */ 996 /* Disable Function 2 */
888 sdio_claim_host(sdiodev->func[2]); 997 sdio_claim_host(sdiodev->func[2]);
889 sdio_disable_func(sdiodev->func[2]); 998 sdio_disable_func(sdiodev->func[2]);
@@ -955,6 +1064,10 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
955 */ 1064 */
956 brcmf_sdiod_sgtable_alloc(sdiodev); 1065 brcmf_sdiod_sgtable_alloc(sdiodev);
957 1066
1067 ret = brcmf_sdiod_freezer_attach(sdiodev);
1068 if (ret)
1069 goto out;
1070
958 /* try to attach to the target device */ 1071 /* try to attach to the target device */
959 sdiodev->bus = brcmf_sdio_probe(sdiodev); 1072 sdiodev->bus = brcmf_sdio_probe(sdiodev);
960 if (!sdiodev->bus) { 1073 if (!sdiodev->bus) {
@@ -1050,9 +1163,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1050 bus_if->wowl_supported = true; 1163 bus_if->wowl_supported = true;
1051#endif 1164#endif
1052 1165
1053 sdiodev->sleeping = false; 1166 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
1054 atomic_set(&sdiodev->suspend, false);
1055 init_waitqueue_head(&sdiodev->idle_wait);
1056 1167
1057 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n"); 1168 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1058 err = brcmf_sdiod_probe(sdiodev); 1169 err = brcmf_sdiod_probe(sdiodev);
@@ -1114,24 +1225,22 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1114#ifdef CONFIG_PM_SLEEP 1225#ifdef CONFIG_PM_SLEEP
1115static int brcmf_ops_sdio_suspend(struct device *dev) 1226static int brcmf_ops_sdio_suspend(struct device *dev)
1116{ 1227{
1228 struct sdio_func *func;
1117 struct brcmf_bus *bus_if; 1229 struct brcmf_bus *bus_if;
1118 struct brcmf_sdio_dev *sdiodev; 1230 struct brcmf_sdio_dev *sdiodev;
1119 mmc_pm_flag_t sdio_flags; 1231 mmc_pm_flag_t sdio_flags;
1120 1232
1121 brcmf_dbg(SDIO, "Enter\n"); 1233 func = container_of(dev, struct sdio_func, dev);
1234 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1235 if (func->num != SDIO_FUNC_1)
1236 return 0;
1237
1122 1238
1123 bus_if = dev_get_drvdata(dev); 1239 bus_if = dev_get_drvdata(dev);
1124 sdiodev = bus_if->bus_priv.sdio; 1240 sdiodev = bus_if->bus_priv.sdio;
1125 1241
1126 /* wait for watchdog to go idle */ 1242 brcmf_sdiod_freezer_on(sdiodev);
1127 if (wait_event_timeout(sdiodev->idle_wait, sdiodev->sleeping,
1128 msecs_to_jiffies(3 * BRCMF_WD_POLL_MS)) == 0) {
1129 brcmf_err("bus still active\n");
1130 return -EBUSY;
1131 }
1132 /* disable watchdog */
1133 brcmf_sdio_wd_timer(sdiodev->bus, 0); 1243 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1134 atomic_set(&sdiodev->suspend, true);
1135 1244
1136 if (sdiodev->wowl_enabled) { 1245 if (sdiodev->wowl_enabled) {
1137 sdio_flags = MMC_PM_KEEP_POWER; 1246 sdio_flags = MMC_PM_KEEP_POWER;
@@ -1149,12 +1258,13 @@ static int brcmf_ops_sdio_resume(struct device *dev)
1149{ 1258{
1150 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1259 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1151 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1260 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
1261 struct sdio_func *func = container_of(dev, struct sdio_func, dev);
1152 1262
1153 brcmf_dbg(SDIO, "Enter\n"); 1263 brcmf_dbg(SDIO, "Enter: F%d\n", func->num);
1154 if (sdiodev->pdata && sdiodev->pdata->oob_irq_supported) 1264 if (func->num != SDIO_FUNC_2)
1155 disable_irq_wake(sdiodev->pdata->oob_irq_nr); 1265 return 0;
1156 brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); 1266
1157 atomic_set(&sdiodev->suspend, false); 1267 brcmf_sdiod_freezer_off(sdiodev);
1158 return 0; 1268 return 0;
1159} 1269}
1160 1270
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 06727a61b438..9b805c9fd51e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -1050,10 +1050,6 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif) 1050 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; 1051 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1052 1052
1053 /* Arm scan timeout timer */
1054 mod_timer(&cfg->escan_timeout, jiffies +
1055 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1056
1057 escan_req = false; 1053 escan_req = false;
1058 if (request) { 1054 if (request) {
1059 /* scan bss */ 1055 /* scan bss */
@@ -1112,12 +1108,14 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1112 } 1108 }
1113 } 1109 }
1114 1110
1111 /* Arm scan timeout timer */
1112 mod_timer(&cfg->escan_timeout, jiffies +
1113 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1114
1115 return 0; 1115 return 0;
1116 1116
1117scan_out: 1117scan_out:
1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); 1118 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1119 if (timer_pending(&cfg->escan_timeout))
1120 del_timer_sync(&cfg->escan_timeout);
1121 cfg->scan_request = NULL; 1119 cfg->scan_request = NULL;
1122 return err; 1120 return err;
1123} 1121}
@@ -2252,7 +2250,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2252 2250
2253 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { 2251 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2254 /* we ignore this key index in this case */ 2252 /* we ignore this key index in this case */
2255 brcmf_err("invalid key index (%d)\n", key_idx);
2256 return -EINVAL; 2253 return -EINVAL;
2257 } 2254 }
2258 2255
@@ -4272,7 +4269,7 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4272 return -EIO; 4269 return -EIO;
4273 4270
4274 memcpy(&scbval.ea, params->mac, ETH_ALEN); 4271 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4275 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING); 4272 scbval.val = cpu_to_le32(params->reason_code);
4276 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, 4273 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4277 &scbval, sizeof(scbval)); 4274 &scbval, sizeof(scbval));
4278 if (err) 4275 if (err)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index 2d6e2cc1b12c..f8f47dcfa886 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -944,6 +944,34 @@ fail:
944 return ret; 944 return ret;
945} 945}
946 946
947static int brcmf_revinfo_read(struct seq_file *s, void *data)
948{
949 struct brcmf_bus *bus_if = dev_get_drvdata(s->private);
950 struct brcmf_rev_info *ri = &bus_if->drvr->revinfo;
951 char drev[BRCMU_DOTREV_LEN];
952 char brev[BRCMU_BOARDREV_LEN];
953
954 seq_printf(s, "vendorid: 0x%04x\n", ri->vendorid);
955 seq_printf(s, "deviceid: 0x%04x\n", ri->deviceid);
956 seq_printf(s, "radiorev: %s\n", brcmu_dotrev_str(ri->radiorev, drev));
957 seq_printf(s, "chipnum: %u (%x)\n", ri->chipnum, ri->chipnum);
958 seq_printf(s, "chiprev: %u\n", ri->chiprev);
959 seq_printf(s, "chippkg: %u\n", ri->chippkg);
960 seq_printf(s, "corerev: %u\n", ri->corerev);
961 seq_printf(s, "boardid: 0x%04x\n", ri->boardid);
962 seq_printf(s, "boardvendor: 0x%04x\n", ri->boardvendor);
963 seq_printf(s, "boardrev: %s\n", brcmu_boardrev_str(ri->boardrev, brev));
964 seq_printf(s, "driverrev: %s\n", brcmu_dotrev_str(ri->driverrev, drev));
965 seq_printf(s, "ucoderev: %u\n", ri->ucoderev);
966 seq_printf(s, "bus: %u\n", ri->bus);
967 seq_printf(s, "phytype: %u\n", ri->phytype);
968 seq_printf(s, "phyrev: %u\n", ri->phyrev);
969 seq_printf(s, "anarev: %u\n", ri->anarev);
970 seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
971
972 return 0;
973}
974
947int brcmf_bus_start(struct device *dev) 975int brcmf_bus_start(struct device *dev)
948{ 976{
949 int ret = -1; 977 int ret = -1;
@@ -974,6 +1002,8 @@ int brcmf_bus_start(struct device *dev)
974 if (ret < 0) 1002 if (ret < 0)
975 goto fail; 1003 goto fail;
976 1004
1005 brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read);
1006
977 /* assure we have chipid before feature attach */ 1007 /* assure we have chipid before feature attach */
978 if (!bus_if->chip) { 1008 if (!bus_if->chip) {
979 bus_if->chip = drvr->revinfo.chipnum; 1009 bus_if->chip = drvr->revinfo.chipnum;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index faec35c899ec..257ee70feb5b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -515,6 +515,7 @@ struct brcmf_sdio {
515 bool txoff; /* Transmit flow-controlled */ 515 bool txoff; /* Transmit flow-controlled */
516 struct brcmf_sdio_count sdcnt; 516 struct brcmf_sdio_count sdcnt;
517 bool sr_enabled; /* SaveRestore enabled */ 517 bool sr_enabled; /* SaveRestore enabled */
518 bool sleeping;
518 519
519 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 520 u8 tx_hdrlen; /* sdio bus header length for tx packet */
520 bool txglom; /* host tx glomming enable flag */ 521 bool txglom; /* host tx glomming enable flag */
@@ -1013,12 +1014,12 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1013 1014
1014 brcmf_dbg(SDIO, "Enter: request %s currently %s\n", 1015 brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
1015 (sleep ? "SLEEP" : "WAKE"), 1016 (sleep ? "SLEEP" : "WAKE"),
1016 (bus->sdiodev->sleeping ? "SLEEP" : "WAKE")); 1017 (bus->sleeping ? "SLEEP" : "WAKE"));
1017 1018
1018 /* If SR is enabled control bus state with KSO */ 1019 /* If SR is enabled control bus state with KSO */
1019 if (bus->sr_enabled) { 1020 if (bus->sr_enabled) {
1020 /* Done if we're already in the requested state */ 1021 /* Done if we're already in the requested state */
1021 if (sleep == bus->sdiodev->sleeping) 1022 if (sleep == bus->sleeping)
1022 goto end; 1023 goto end;
1023 1024
1024 /* Going to sleep */ 1025 /* Going to sleep */
@@ -1026,6 +1027,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1026 /* Don't sleep if something is pending */ 1027 /* Don't sleep if something is pending */
1027 if (atomic_read(&bus->intstatus) || 1028 if (atomic_read(&bus->intstatus) ||
1028 atomic_read(&bus->ipend) > 0 || 1029 atomic_read(&bus->ipend) > 0 ||
1030 bus->ctrl_frame_stat ||
1029 (!atomic_read(&bus->fcstate) && 1031 (!atomic_read(&bus->fcstate) &&
1030 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 1032 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
1031 data_ok(bus))) { 1033 data_ok(bus))) {
@@ -1065,9 +1067,7 @@ end:
1065 } else { 1067 } else {
1066 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1068 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
1067 } 1069 }
1068 bus->sdiodev->sleeping = sleep; 1070 bus->sleeping = sleep;
1069 if (sleep)
1070 wake_up(&bus->sdiodev->idle_wait);
1071 brcmf_dbg(SDIO, "new state %s\n", 1071 brcmf_dbg(SDIO, "new state %s\n",
1072 (sleep ? "SLEEP" : "WAKE")); 1072 (sleep ? "SLEEP" : "WAKE"));
1073done: 1073done:
@@ -1909,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1909 bus->rxpending = true; 1909 bus->rxpending = true;
1910 1910
1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA; 1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_SDIOD_DATA;
1913 rd->seq_num++, rxleft--) { 1913 rd->seq_num++, rxleft--) {
1914 1914
1915 /* Handle glomming separately */ 1915 /* Handle glomming separately */
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2415 } 2415 }
2416 2416
2417 /* Deflow-control stack if needed */ 2417 /* Deflow-control stack if needed */
2418 if ((bus->sdiodev->state == BRCMF_STATE_DATA) && 2418 if ((bus->sdiodev->state == BRCMF_SDIOD_DATA) &&
2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
2420 bus->txoff = false; 2420 bus->txoff = false;
2421 brcmf_txflowblock(bus->sdiodev->dev, false); 2421 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2503 bus->watchdog_tsk = NULL; 2503 bus->watchdog_tsk = NULL;
2504 } 2504 }
2505 2505
2506 if (sdiodev->state != BRCMF_STATE_NOMEDIUM) { 2506 if (sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
2507 sdio_claim_host(sdiodev->func[1]); 2507 sdio_claim_host(sdiodev->func[1]);
2508 2508
2509 /* Enable clock for device interrupts */ 2509 /* Enable clock for device interrupts */
@@ -2603,21 +2603,6 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2603 return ret; 2603 return ret;
2604} 2604}
2605 2605
2606static int brcmf_sdio_pm_resume_wait(struct brcmf_sdio_dev *sdiodev)
2607{
2608#ifdef CONFIG_PM_SLEEP
2609 int retry;
2610
2611 /* Wait for possible resume to complete */
2612 retry = 0;
2613 while ((atomic_read(&sdiodev->suspend)) && (retry++ != 50))
2614 msleep(20);
2615 if (atomic_read(&sdiodev->suspend))
2616 return -EIO;
2617#endif
2618 return 0;
2619}
2620
2621static void brcmf_sdio_dpc(struct brcmf_sdio *bus) 2606static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2622{ 2607{
2623 u32 newstatus = 0; 2608 u32 newstatus = 0;
@@ -2628,9 +2613,6 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2628 2613
2629 brcmf_dbg(TRACE, "Enter\n"); 2614 brcmf_dbg(TRACE, "Enter\n");
2630 2615
2631 if (brcmf_sdio_pm_resume_wait(bus->sdiodev))
2632 return;
2633
2634 sdio_claim_host(bus->sdiodev->func[1]); 2616 sdio_claim_host(bus->sdiodev->func[1]);
2635 2617
2636 /* If waiting for HTAVAIL, check status */ 2618 /* If waiting for HTAVAIL, check status */
@@ -2755,7 +2737,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2755 brcmf_sdio_sendfromq(bus, framecnt); 2737 brcmf_sdio_sendfromq(bus, framecnt);
2756 } 2738 }
2757 2739
2758 if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) { 2740 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
2759 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2741 brcmf_err("failed backplane access over SDIO, halting operation\n");
2760 atomic_set(&bus->intstatus, 0); 2742 atomic_set(&bus->intstatus, 0);
2761 } else if (atomic_read(&bus->intstatus) || 2743 } else if (atomic_read(&bus->intstatus) ||
@@ -2862,11 +2844,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2862 qcount[prec] = pktq_plen(&bus->txq, prec); 2844 qcount[prec] = pktq_plen(&bus->txq, prec);
2863#endif 2845#endif
2864 2846
2865 if (atomic_read(&bus->dpc_tskcnt) == 0) { 2847 brcmf_sdio_trigger_dpc(bus);
2866 atomic_inc(&bus->dpc_tskcnt);
2867 queue_work(bus->brcmf_wq, &bus->datawork);
2868 }
2869
2870 return ret; 2848 return ret;
2871} 2849}
2872 2850
@@ -2964,11 +2942,8 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2964 bus->ctrl_frame_buf = msg; 2942 bus->ctrl_frame_buf = msg;
2965 bus->ctrl_frame_len = msglen; 2943 bus->ctrl_frame_len = msglen;
2966 bus->ctrl_frame_stat = true; 2944 bus->ctrl_frame_stat = true;
2967 if (atomic_read(&bus->dpc_tskcnt) == 0) {
2968 atomic_inc(&bus->dpc_tskcnt);
2969 queue_work(bus->brcmf_wq, &bus->datawork);
2970 }
2971 2945
2946 brcmf_sdio_trigger_dpc(bus);
2972 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, 2947 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
2973 msecs_to_jiffies(CTL_DONE_TIMEOUT)); 2948 msecs_to_jiffies(CTL_DONE_TIMEOUT));
2974 2949
@@ -3411,7 +3386,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3411 } 3386 }
3412 3387
3413 /* Allow full data communication using DPC from now on. */ 3388 /* Allow full data communication using DPC from now on. */
3414 bus->sdiodev->state = BRCMF_STATE_DATA; 3389 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3415 bcmerror = 0; 3390 bcmerror = 0;
3416 3391
3417err: 3392err:
@@ -3548,6 +3523,14 @@ done:
3548 return err; 3523 return err;
3549} 3524}
3550 3525
3526void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
3527{
3528 if (atomic_read(&bus->dpc_tskcnt) == 0) {
3529 atomic_inc(&bus->dpc_tskcnt);
3530 queue_work(bus->brcmf_wq, &bus->datawork);
3531 }
3532}
3533
3551void brcmf_sdio_isr(struct brcmf_sdio *bus) 3534void brcmf_sdio_isr(struct brcmf_sdio *bus)
3552{ 3535{
3553 brcmf_dbg(TRACE, "Enter\n"); 3536 brcmf_dbg(TRACE, "Enter\n");
@@ -3557,7 +3540,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3557 return; 3540 return;
3558 } 3541 }
3559 3542
3560 if (bus->sdiodev->state != BRCMF_STATE_DATA) { 3543 if (bus->sdiodev->state != BRCMF_SDIOD_DATA) {
3561 brcmf_err("bus is down. we have nothing to do\n"); 3544 brcmf_err("bus is down. we have nothing to do\n");
3562 return; 3545 return;
3563 } 3546 }
@@ -3602,9 +3585,8 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3602 SDIO_CCCR_INTx, 3585 SDIO_CCCR_INTx,
3603 NULL); 3586 NULL);
3604 sdio_release_host(bus->sdiodev->func[1]); 3587 sdio_release_host(bus->sdiodev->func[1]);
3605 intstatus = 3588 intstatus = devpend & (INTR_STATUS_FUNC1 |
3606 devpend & (INTR_STATUS_FUNC1 | 3589 INTR_STATUS_FUNC2);
3607 INTR_STATUS_FUNC2);
3608 } 3590 }
3609 3591
3610 /* If there is something, make like the ISR and 3592 /* If there is something, make like the ISR and
@@ -3623,7 +3605,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3623 } 3605 }
3624#ifdef DEBUG 3606#ifdef DEBUG
3625 /* Poll for console output periodically */ 3607 /* Poll for console output periodically */
3626 if (bus->sdiodev->state == BRCMF_STATE_DATA && 3608 if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
3627 bus->console_interval != 0) { 3609 bus->console_interval != 0) {
3628 bus->console.count += BRCMF_WD_POLL_MS; 3610 bus->console.count += BRCMF_WD_POLL_MS;
3629 if (bus->console.count >= bus->console_interval) { 3611 if (bus->console.count >= bus->console_interval) {
@@ -3667,6 +3649,11 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3667 atomic_set(&bus->dpc_tskcnt, 0); 3649 atomic_set(&bus->dpc_tskcnt, 0);
3668 brcmf_sdio_dpc(bus); 3650 brcmf_sdio_dpc(bus);
3669 } 3651 }
3652 if (brcmf_sdiod_freezing(bus->sdiodev)) {
3653 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
3654 brcmf_sdiod_try_freeze(bus->sdiodev);
3655 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
3656 }
3670} 3657}
3671 3658
3672static void 3659static void
@@ -3944,13 +3931,19 @@ static int
3944brcmf_sdio_watchdog_thread(void *data) 3931brcmf_sdio_watchdog_thread(void *data)
3945{ 3932{
3946 struct brcmf_sdio *bus = (struct brcmf_sdio *)data; 3933 struct brcmf_sdio *bus = (struct brcmf_sdio *)data;
3934 int wait;
3947 3935
3948 allow_signal(SIGTERM); 3936 allow_signal(SIGTERM);
3949 /* Run until signal received */ 3937 /* Run until signal received */
3938 brcmf_sdiod_freezer_count(bus->sdiodev);
3950 while (1) { 3939 while (1) {
3951 if (kthread_should_stop()) 3940 if (kthread_should_stop())
3952 break; 3941 break;
3953 if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { 3942 brcmf_sdiod_freezer_uncount(bus->sdiodev);
3943 wait = wait_for_completion_interruptible(&bus->watchdog_wait);
3944 brcmf_sdiod_freezer_count(bus->sdiodev);
3945 brcmf_sdiod_try_freeze(bus->sdiodev);
3946 if (!wait) {
3954 brcmf_sdio_bus_watchdog(bus); 3947 brcmf_sdio_bus_watchdog(bus);
3955 /* Count the tick for reference */ 3948 /* Count the tick for reference */
3956 bus->sdcnt.tickcnt++; 3949 bus->sdcnt.tickcnt++;
@@ -3971,7 +3964,7 @@ brcmf_sdio_watchdog(unsigned long data)
3971 /* Reschedule the watchdog */ 3964 /* Reschedule the watchdog */
3972 if (bus->wd_timer_valid) 3965 if (bus->wd_timer_valid)
3973 mod_timer(&bus->timer, 3966 mod_timer(&bus->timer,
3974 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 3967 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
3975 } 3968 }
3976} 3969}
3977 3970
@@ -4089,6 +4082,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4089{ 4082{
4090 int ret; 4083 int ret;
4091 struct brcmf_sdio *bus; 4084 struct brcmf_sdio *bus;
4085 struct workqueue_struct *wq;
4092 4086
4093 brcmf_dbg(TRACE, "Enter\n"); 4087 brcmf_dbg(TRACE, "Enter\n");
4094 4088
@@ -4117,12 +4111,16 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4117 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; 4111 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
4118 } 4112 }
4119 4113
4120 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 4114 /* single-threaded workqueue */
4121 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 4115 wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
4122 if (bus->brcmf_wq == NULL) { 4116 dev_name(&sdiodev->func[1]->dev));
4117 if (!wq) {
4123 brcmf_err("insufficient memory to create txworkqueue\n"); 4118 brcmf_err("insufficient memory to create txworkqueue\n");
4124 goto fail; 4119 goto fail;
4125 } 4120 }
4121 brcmf_sdiod_freezer_count(sdiodev);
4122 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
4123 bus->brcmf_wq = wq;
4126 4124
4127 /* attempt to attach to the dongle */ 4125 /* attempt to attach to the dongle */
4128 if (!(brcmf_sdio_probe_attach(bus))) { 4126 if (!(brcmf_sdio_probe_attach(bus))) {
@@ -4143,7 +4141,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4143 /* Initialize watchdog thread */ 4141 /* Initialize watchdog thread */
4144 init_completion(&bus->watchdog_wait); 4142 init_completion(&bus->watchdog_wait);
4145 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread, 4143 bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread,
4146 bus, "brcmf_watchdog"); 4144 bus, "brcmf_wdog/%s",
4145 dev_name(&sdiodev->func[1]->dev));
4147 if (IS_ERR(bus->watchdog_tsk)) { 4146 if (IS_ERR(bus->watchdog_tsk)) {
4148 pr_warn("brcmf_watchdog thread failed to start\n"); 4147 pr_warn("brcmf_watchdog thread failed to start\n");
4149 bus->watchdog_tsk = NULL; 4148 bus->watchdog_tsk = NULL;
@@ -4242,7 +4241,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4242 destroy_workqueue(bus->brcmf_wq); 4241 destroy_workqueue(bus->brcmf_wq);
4243 4242
4244 if (bus->ci) { 4243 if (bus->ci) {
4245 if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) { 4244 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
4246 sdio_claim_host(bus->sdiodev->func[1]); 4245 sdio_claim_host(bus->sdiodev->func[1]);
4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4246 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4248 /* Leave the device in state where it is 4247 /* Leave the device in state where it is
@@ -4277,7 +4276,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4277 } 4276 }
4278 4277
4279 /* don't start the wd until fw is loaded */ 4278 /* don't start the wd until fw is loaded */
4280 if (bus->sdiodev->state != BRCMF_STATE_DATA) 4279 if (bus->sdiodev->state != BRCMF_SDIOD_DATA)
4281 return; 4280 return;
4282 4281
4283 if (wdtick) { 4282 if (wdtick) {
@@ -4290,16 +4289,28 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4290 dynamically changed or in the first instance 4289 dynamically changed or in the first instance
4291 */ 4290 */
4292 bus->timer.expires = 4291 bus->timer.expires =
4293 jiffies + BRCMF_WD_POLL_MS * HZ / 1000; 4292 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS);
4294 add_timer(&bus->timer); 4293 add_timer(&bus->timer);
4295 4294
4296 } else { 4295 } else {
4297 /* Re arm the timer, at last watchdog period */ 4296 /* Re arm the timer, at last watchdog period */
4298 mod_timer(&bus->timer, 4297 mod_timer(&bus->timer,
4299 jiffies + BRCMF_WD_POLL_MS * HZ / 1000); 4298 jiffies + msecs_to_jiffies(BRCMF_WD_POLL_MS));
4300 } 4299 }
4301 4300
4302 bus->wd_timer_valid = true; 4301 bus->wd_timer_valid = true;
4303 bus->save_ms = wdtick; 4302 bus->save_ms = wdtick;
4304 } 4303 }
4305} 4304}
4305
4306int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep)
4307{
4308 int ret;
4309
4310 sdio_claim_host(bus->sdiodev->func[1]);
4311 ret = brcmf_sdio_bus_sleep(bus, sleep, false);
4312 sdio_release_host(bus->sdiodev->func[1]);
4313
4314 return ret;
4315}
4316
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index ec2586a8425c..7328478b2d7b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -155,11 +155,17 @@
155/* watchdog polling interval in ms */ 155/* watchdog polling interval in ms */
156#define BRCMF_WD_POLL_MS 10 156#define BRCMF_WD_POLL_MS 10
157 157
158/* The state of the bus */ 158/**
159enum brcmf_sdio_state { 159 * enum brcmf_sdiod_state - the state of the bus.
160 BRCMF_STATE_DOWN, /* Device available, still initialising */ 160 *
161 BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */ 161 * @BRCMF_SDIOD_DOWN: Device can be accessed, no DPC.
162 BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */ 162 * @BRCMF_SDIOD_DATA: Ready for data transfers, DPC enabled.
163 * @BRCMF_SDIOD_NOMEDIUM: No medium access to dongle possible.
164 */
165enum brcmf_sdiod_state {
166 BRCMF_SDIOD_DOWN,
167 BRCMF_SDIOD_DATA,
168 BRCMF_SDIOD_NOMEDIUM
163}; 169};
164 170
165struct brcmf_sdreg { 171struct brcmf_sdreg {
@@ -169,15 +175,13 @@ struct brcmf_sdreg {
169}; 175};
170 176
171struct brcmf_sdio; 177struct brcmf_sdio;
178struct brcmf_sdiod_freezer;
172 179
173struct brcmf_sdio_dev { 180struct brcmf_sdio_dev {
174 struct sdio_func *func[SDIO_MAX_FUNCS]; 181 struct sdio_func *func[SDIO_MAX_FUNCS];
175 u8 num_funcs; /* Supported funcs on client */ 182 u8 num_funcs; /* Supported funcs on client */
176 u32 sbwad; /* Save backplane window address */ 183 u32 sbwad; /* Save backplane window address */
177 struct brcmf_sdio *bus; 184 struct brcmf_sdio *bus;
178 atomic_t suspend; /* suspend flag */
179 bool sleeping;
180 wait_queue_head_t idle_wait;
181 struct device *dev; 185 struct device *dev;
182 struct brcmf_bus *bus_if; 186 struct brcmf_bus *bus_if;
183 struct brcmfmac_sdio_platform_data *pdata; 187 struct brcmfmac_sdio_platform_data *pdata;
@@ -194,7 +198,8 @@ struct brcmf_sdio_dev {
194 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 198 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
195 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 199 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
196 bool wowl_enabled; 200 bool wowl_enabled;
197 enum brcmf_sdio_state state; 201 enum brcmf_sdiod_state state;
202 struct brcmf_sdiod_freezer *freezer;
198}; 203};
199 204
200/* sdio core registers */ 205/* sdio core registers */
@@ -337,6 +342,28 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
337 342
338/* Issue an abort to the specified function */ 343/* Issue an abort to the specified function */
339int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); 344int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
345void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
346 enum brcmf_sdiod_state state);
347#ifdef CONFIG_PM_SLEEP
348bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev);
349void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev);
350void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev);
351void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev);
352#else
353static inline bool brcmf_sdiod_freezing(struct brcmf_sdio_dev *sdiodev)
354{
355 return false;
356}
357static inline void brcmf_sdiod_try_freeze(struct brcmf_sdio_dev *sdiodev)
358{
359}
360static inline void brcmf_sdiod_freezer_count(struct brcmf_sdio_dev *sdiodev)
361{
362}
363static inline void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev)
364{
365}
366#endif /* CONFIG_PM_SLEEP */
340 367
341struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); 368struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
342void brcmf_sdio_remove(struct brcmf_sdio *bus); 369void brcmf_sdio_remove(struct brcmf_sdio *bus);
@@ -344,5 +371,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus);
344 371
345void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); 372void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick);
346void brcmf_sdio_wowl_config(struct device *dev, bool enabled); 373void brcmf_sdio_wowl_config(struct device *dev, bool enabled);
374int brcmf_sdio_sleep(struct brcmf_sdio *bus, bool sleep);
375void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus);
347 376
348#endif /* BRCMFMAC_SDIO_H */ 377#endif /* BRCMFMAC_SDIO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index eb8584a9c49a..c84af1dfc88f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4668,7 +4668,7 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core,
4668 brcms_c_coredisable(wlc_hw); 4668 brcms_c_coredisable(wlc_hw);
4669 4669
4670 /* Match driver "down" state */ 4670 /* Match driver "down" state */
4671 bcma_core_pci_down(wlc_hw->d11core->bus); 4671 bcma_host_pci_down(wlc_hw->d11core->bus);
4672 4672
4673 /* turn off pll and xtal to match driver "down" state */ 4673 /* turn off pll and xtal to match driver "down" state */
4674 brcms_b_xtal(wlc_hw, OFF); 4674 brcms_b_xtal(wlc_hw, OFF);
@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4959 * Configure pci/pcmcia here instead of in brcms_c_attach() 4959 * Configure pci/pcmcia here instead of in brcms_c_attach()
4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up. 4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
4961 */ 4961 */
4962 bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core, 4962 bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
4963 true); 4963 true);
4964 4964
4965 /* 4965 /*
@@ -4969,12 +4969,12 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4969 */ 4969 */
4970 if (brcms_b_radio_read_hwdisabled(wlc_hw)) { 4970 if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
4971 /* put SB PCI in down state again */ 4971 /* put SB PCI in down state again */
4972 bcma_core_pci_down(wlc_hw->d11core->bus); 4972 bcma_host_pci_down(wlc_hw->d11core->bus);
4973 brcms_b_xtal(wlc_hw, OFF); 4973 brcms_b_xtal(wlc_hw, OFF);
4974 return -ENOMEDIUM; 4974 return -ENOMEDIUM;
4975 } 4975 }
4976 4976
4977 bcma_core_pci_up(wlc_hw->d11core->bus); 4977 bcma_host_pci_up(wlc_hw->d11core->bus);
4978 4978
4979 /* reset the d11 core */ 4979 /* reset the d11 core */
4980 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); 4980 brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -5171,7 +5171,7 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw)
5171 5171
5172 /* turn off primary xtal and pll */ 5172 /* turn off primary xtal and pll */
5173 if (!wlc_hw->noreset) { 5173 if (!wlc_hw->noreset) {
5174 bcma_core_pci_down(wlc_hw->d11core->bus); 5174 bcma_host_pci_down(wlc_hw->d11core->bus);
5175 brcms_b_xtal(wlc_hw, OFF); 5175 brcms_b_xtal(wlc_hw, OFF);
5176 } 5176 }
5177 } 5177 }
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 084f18f4f950..99dac9b8a082 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -23041,10 +23041,7 @@ static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
23041 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) 23041 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL)
23042 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, 23042 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23043 NPHY_RSSI_SEL_W1); 23043 NPHY_RSSI_SEL_W1);
23044 else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) 23044 else /* RADIO_2055_WBRSSI_G2_SEL */
23045 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23046 NPHY_RSSI_SEL_W2);
23047 else
23048 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, 23045 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1,
23049 NPHY_RSSI_SEL_W2); 23046 NPHY_RSSI_SEL_W2);
23050 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) 23047 if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL)
@@ -23053,13 +23050,9 @@ static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type)
23053 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) 23050 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL)
23054 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, 23051 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23055 NPHY_RSSI_SEL_W1); 23052 NPHY_RSSI_SEL_W1);
23056 else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) 23053 else /* RADIO_2055_WBRSSI_G1_SEL */
23057 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, 23054 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23058 NPHY_RSSI_SEL_W2); 23055 NPHY_RSSI_SEL_W2);
23059 else
23060 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2,
23061 NPHY_RSSI_SEL_W2);
23062
23063 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); 23056 wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type);
23064 23057
23065 write_phy_reg(pi, 0x91, rfctrlintc_state[0]); 23058 write_phy_reg(pi, 0x91, rfctrlintc_state[0]);
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index eaaeea19d8c5..bac60b2bc3f0 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -1678,7 +1678,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search)
1678 lq_sta->total_success > lq_sta->max_success_limit || 1678 lq_sta->total_success > lq_sta->max_success_limit ||
1679 (!lq_sta->search_better_tbl && lq_sta->flush_timer && 1679 (!lq_sta->search_better_tbl && lq_sta->flush_timer &&
1680 flush_interval_passed)) { 1680 flush_interval_passed)) {
1681 D_RATE("LQ: stay is expired %d %d %d\n:", 1681 D_RATE("LQ: stay is expired %d %d %d\n",
1682 lq_sta->total_failed, lq_sta->total_success, 1682 lq_sta->total_failed, lq_sta->total_success,
1683 flush_interval_passed); 1683 flush_interval_passed);
1684 1684
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index c4d6dd7402d9..234e30f498b2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1549,7 +1549,7 @@ static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1549 table.blink1, table.blink2, table.ilink1, 1549 table.blink1, table.blink2, table.ilink1,
1550 table.ilink2, table.bcon_time, table.gp1, 1550 table.ilink2, table.bcon_time, table.gp1,
1551 table.gp2, table.gp3, table.ucode_ver, 1551 table.gp2, table.gp3, table.ucode_ver,
1552 table.hw_ver, table.brd_ver); 1552 table.hw_ver, 0, table.brd_ver);
1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id, 1553 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
1554 desc_lookup(table.error_id)); 1554 desc_lookup(table.error_id));
1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc); 1555 IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 97e38d2e2983..0597a9cfd2f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -77,8 +77,8 @@
77#define IWL3160_UCODE_API_OK 10 77#define IWL3160_UCODE_API_OK 10
78 78
79/* Lowest firmware API version supported */ 79/* Lowest firmware API version supported */
80#define IWL7260_UCODE_API_MIN 9 80#define IWL7260_UCODE_API_MIN 10
81#define IWL3160_UCODE_API_MIN 9 81#define IWL3160_UCODE_API_MIN 10
82 82
83/* NVM versions */ 83/* NVM versions */
84#define IWL7260_NVM_VERSION 0x0a1d 84#define IWL7260_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 2f7fe8167dc9..d8dfa6da6307 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -75,7 +75,7 @@
75#define IWL8000_UCODE_API_OK 10 75#define IWL8000_UCODE_API_OK 10
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL8000_UCODE_API_MIN 9 78#define IWL8000_UCODE_API_MIN 10
79 79
80/* NVM versions */ 80/* NVM versions */
81#define IWL8000_NVM_VERSION 0x0a1d 81#define IWL8000_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index 78bd41bf34b0..53555a0fce56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -431,11 +431,11 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low, 431 TP_PROTO(const struct device *dev, u32 desc, u32 tsf_low,
432 u32 data1, u32 data2, u32 line, u32 blink1, 432 u32 data1, u32 data2, u32 line, u32 blink1,
433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, 433 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
434 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, 434 u32 gp1, u32 gp2, u32 gp3, u32 major, u32 minor, u32 hw_ver,
435 u32 brd_ver), 435 u32 brd_ver),
436 TP_ARGS(dev, desc, tsf_low, data1, data2, line, 436 TP_ARGS(dev, desc, tsf_low, data1, data2, line,
437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2, 437 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
438 gp3, ucode_ver, hw_ver, brd_ver), 438 gp3, major, minor, hw_ver, brd_ver),
439 TP_STRUCT__entry( 439 TP_STRUCT__entry(
440 DEV_ENTRY 440 DEV_ENTRY
441 __field(u32, desc) 441 __field(u32, desc)
@@ -451,7 +451,8 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
451 __field(u32, gp1) 451 __field(u32, gp1)
452 __field(u32, gp2) 452 __field(u32, gp2)
453 __field(u32, gp3) 453 __field(u32, gp3)
454 __field(u32, ucode_ver) 454 __field(u32, major)
455 __field(u32, minor)
455 __field(u32, hw_ver) 456 __field(u32, hw_ver)
456 __field(u32, brd_ver) 457 __field(u32, brd_ver)
457 ), 458 ),
@@ -470,21 +471,22 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
470 __entry->gp1 = gp1; 471 __entry->gp1 = gp1;
471 __entry->gp2 = gp2; 472 __entry->gp2 = gp2;
472 __entry->gp3 = gp3; 473 __entry->gp3 = gp3;
473 __entry->ucode_ver = ucode_ver; 474 __entry->major = major;
475 __entry->minor = minor;
474 __entry->hw_ver = hw_ver; 476 __entry->hw_ver = hw_ver;
475 __entry->brd_ver = brd_ver; 477 __entry->brd_ver = brd_ver;
476 ), 478 ),
477 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, " 479 TP_printk("[%s] #%02d %010u data 0x%08X 0x%08X line %u, "
478 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X " 480 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
479 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X " 481 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X major 0x%08X "
480 "hw 0x%08X brd 0x%08X", 482 "minor 0x%08X hw 0x%08X brd 0x%08X",
481 __get_str(dev), __entry->desc, __entry->tsf_low, 483 __get_str(dev), __entry->desc, __entry->tsf_low,
482 __entry->data1, 484 __entry->data1,
483 __entry->data2, __entry->line, __entry->blink1, 485 __entry->data2, __entry->line, __entry->blink1,
484 __entry->blink2, __entry->ilink1, __entry->ilink2, 486 __entry->blink2, __entry->ilink1, __entry->ilink2,
485 __entry->bcon_time, __entry->gp1, __entry->gp2, 487 __entry->bcon_time, __entry->gp1, __entry->gp2,
486 __entry->gp3, __entry->ucode_ver, __entry->hw_ver, 488 __entry->gp3, __entry->major, __entry->minor,
487 __entry->brd_ver) 489 __entry->hw_ver, __entry->brd_ver)
488); 490);
489 491
490TRACE_EVENT(iwlwifi_dev_ucode_event, 492TRACE_EVENT(iwlwifi_dev_ucode_event,
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 996e7f16adf9..141331d41abf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -175,6 +175,8 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
175 kfree(drv->fw.dbg_dest_tlv); 175 kfree(drv->fw.dbg_dest_tlv);
176 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++) 176 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_conf_tlv); i++)
177 kfree(drv->fw.dbg_conf_tlv[i]); 177 kfree(drv->fw.dbg_conf_tlv[i]);
178 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++)
179 kfree(drv->fw.dbg_trigger_tlv[i]);
178 180
179 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) 181 for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
180 iwl_free_fw_img(drv, drv->fw.img + i); 182 iwl_free_fw_img(drv, drv->fw.img + i);
@@ -293,8 +295,10 @@ struct iwl_firmware_pieces {
293 295
294 /* FW debug data parsed for driver usage */ 296 /* FW debug data parsed for driver usage */
295 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 297 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
296 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 298 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
297 size_t dbg_conf_tlv_len[FW_DBG_MAX]; 299 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
300 struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
301 size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
298}; 302};
299 303
300/* 304/*
@@ -842,6 +846,23 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
842 capa->n_scan_channels = 846 capa->n_scan_channels =
843 le32_to_cpup((__le32 *)tlv_data); 847 le32_to_cpup((__le32 *)tlv_data);
844 break; 848 break;
849 case IWL_UCODE_TLV_FW_VERSION: {
850 __le32 *ptr = (void *)tlv_data;
851 u32 major, minor;
852 u8 local_comp;
853
854 if (tlv_len != sizeof(u32) * 3)
855 goto invalid_tlv_len;
856
857 major = le32_to_cpup(ptr++);
858 minor = le32_to_cpup(ptr++);
859 local_comp = le32_to_cpup(ptr);
860
861 snprintf(drv->fw.fw_version,
862 sizeof(drv->fw.fw_version), "%u.%u.%u",
863 major, minor, local_comp);
864 break;
865 }
845 case IWL_UCODE_TLV_FW_DBG_DEST: { 866 case IWL_UCODE_TLV_FW_DBG_DEST: {
846 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data; 867 struct iwl_fw_dbg_dest_tlv *dest = (void *)tlv_data;
847 868
@@ -897,6 +918,31 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
897 pieces->dbg_conf_tlv_len[conf->id] = tlv_len; 918 pieces->dbg_conf_tlv_len[conf->id] = tlv_len;
898 break; 919 break;
899 } 920 }
921 case IWL_UCODE_TLV_FW_DBG_TRIGGER: {
922 struct iwl_fw_dbg_trigger_tlv *trigger =
923 (void *)tlv_data;
924 u32 trigger_id = le32_to_cpu(trigger->id);
925
926 if (trigger_id >= ARRAY_SIZE(drv->fw.dbg_trigger_tlv)) {
927 IWL_ERR(drv,
928 "Skip unknown trigger: %u\n",
929 trigger->id);
930 break;
931 }
932
933 if (pieces->dbg_trigger_tlv[trigger_id]) {
934 IWL_ERR(drv,
935 "Ignore duplicate dbg trigger %u\n",
936 trigger->id);
937 break;
938 }
939
940 IWL_INFO(drv, "Found debug trigger: %u\n", trigger->id);
941
942 pieces->dbg_trigger_tlv[trigger_id] = trigger;
943 pieces->dbg_trigger_tlv_len[trigger_id] = tlv_len;
944 break;
945 }
900 case IWL_UCODE_TLV_SEC_RT_USNIFFER: 946 case IWL_UCODE_TLV_SEC_RT_USNIFFER:
901 usniffer_images = true; 947 usniffer_images = true;
902 iwl_store_ucode_sec(pieces, tlv_data, 948 iwl_store_ucode_sec(pieces, tlv_data,
@@ -1107,7 +1153,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1107 if (err) 1153 if (err)
1108 goto try_again; 1154 goto try_again;
1109 1155
1110 api_ver = IWL_UCODE_API(drv->fw.ucode_ver); 1156 if (drv->fw.ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)
1157 api_ver = drv->fw.ucode_ver;
1158 else
1159 api_ver = IWL_UCODE_API(drv->fw.ucode_ver);
1111 1160
1112 /* 1161 /*
1113 * api_ver should match the api version forming part of the 1162 * api_ver should match the api version forming part of the
@@ -1178,6 +1227,19 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1178 } 1227 }
1179 } 1228 }
1180 1229
1230 for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
1231 if (pieces->dbg_trigger_tlv[i]) {
1232 drv->fw.dbg_trigger_tlv_len[i] =
1233 pieces->dbg_trigger_tlv_len[i];
1234 drv->fw.dbg_trigger_tlv[i] =
1235 kmemdup(pieces->dbg_trigger_tlv[i],
1236 drv->fw.dbg_trigger_tlv_len[i],
1237 GFP_KERNEL);
1238 if (!drv->fw.dbg_trigger_tlv[i])
1239 goto out_free_fw;
1240 }
1241 }
1242
1181 /* Now that we can no longer fail, copy information */ 1243 /* Now that we can no longer fail, copy information */
1182 1244
1183 /* 1245 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 919a2548a92c..37b38a585dd1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -82,6 +82,8 @@
82 * sections like this in a single file. 82 * sections like this in a single file.
83 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers 83 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
84 * @IWL_FW_ERROR_DUMP_MEM: chunk of memory 84 * @IWL_FW_ERROR_DUMP_MEM: chunk of memory
85 * @IWL_FW_ERROR_DUMP_ERROR_INFO: description of what triggered this dump.
86 * Structured as &struct iwl_fw_error_dump_trigger_desc.
85 */ 87 */
86enum iwl_fw_error_dump_type { 88enum iwl_fw_error_dump_type {
87 /* 0 is deprecated */ 89 /* 0 is deprecated */
@@ -94,6 +96,7 @@ enum iwl_fw_error_dump_type {
94 IWL_FW_ERROR_DUMP_TXF = 7, 96 IWL_FW_ERROR_DUMP_TXF = 7,
95 IWL_FW_ERROR_DUMP_FH_REGS = 8, 97 IWL_FW_ERROR_DUMP_FH_REGS = 8,
96 IWL_FW_ERROR_DUMP_MEM = 9, 98 IWL_FW_ERROR_DUMP_MEM = 9,
99 IWL_FW_ERROR_DUMP_ERROR_INFO = 10,
97 100
98 IWL_FW_ERROR_DUMP_MAX, 101 IWL_FW_ERROR_DUMP_MAX,
99}; 102};
@@ -230,4 +233,47 @@ iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
230 return (void *)(data->data + le32_to_cpu(data->len)); 233 return (void *)(data->data + le32_to_cpu(data->len));
231} 234}
232 235
236/**
237 * enum iwl_fw_dbg_trigger - triggers available
238 *
239 * @FW_DBG_TRIGGER_USER: trigger log collection by user
240 * This should not be defined as a trigger to the driver, but a value the
241 * driver should set to indicate that the trigger was initiated by the
242 * user.
243 * @FW_DBG_TRIGGER_FW_ASSERT: trigger log collection when the firmware asserts
244 * @FW_DBG_TRIGGER_MISSED_BEACONS: trigger log collection when beacons are
245 * missed.
246 * @FW_DBG_TRIGGER_CHANNEL_SWITCH: trigger log collection upon channel switch.
247 * @FW_DBG_TRIGGER_FW_NOTIF: trigger log collection when the firmware sends a
248 * command response or a notification.
249 * @FW_DB_TRIGGER_RESERVED: reserved
250 * @FW_DBG_TRIGGER_STATS: trigger log collection upon statistics threshold.
251 * @FW_DBG_TRIGGER_RSSI: trigger log collection when the rssi of the beacon
252 * goes below a threshold.
253 */
254enum iwl_fw_dbg_trigger {
255 FW_DBG_TRIGGER_INVALID = 0,
256 FW_DBG_TRIGGER_USER,
257 FW_DBG_TRIGGER_FW_ASSERT,
258 FW_DBG_TRIGGER_MISSED_BEACONS,
259 FW_DBG_TRIGGER_CHANNEL_SWITCH,
260 FW_DBG_TRIGGER_FW_NOTIF,
261 FW_DB_TRIGGER_RESERVED,
262 FW_DBG_TRIGGER_STATS,
263 FW_DBG_TRIGGER_RSSI,
264
265 /* must be last */
266 FW_DBG_TRIGGER_MAX,
267};
268
269/**
270 * struct iwl_fw_error_dump_trigger_desc - describes the trigger condition
271 * @type: %enum iwl_fw_dbg_trigger
272 * @data: raw data about what happened
273 */
274struct iwl_fw_error_dump_trigger_desc {
275 __le32 type;
276 u8 data[];
277};
278
233#endif /* __fw_error_dump_h__ */ 279#endif /* __fw_error_dump_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 016d91384681..5ea381861d5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -66,6 +66,7 @@
66#define __iwl_fw_file_h__ 66#define __iwl_fw_file_h__
67 67
68#include <linux/netdevice.h> 68#include <linux/netdevice.h>
69#include <linux/nl80211.h>
69 70
70/* v1/v2 uCode file layout */ 71/* v1/v2 uCode file layout */
71struct iwl_ucode_header { 72struct iwl_ucode_header {
@@ -133,8 +134,10 @@ enum iwl_ucode_tlv_type {
133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 134 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, 135 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, 136 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
137 IWL_UCODE_TLV_FW_VERSION = 36,
136 IWL_UCODE_TLV_FW_DBG_DEST = 38, 138 IWL_UCODE_TLV_FW_DBG_DEST = 38,
137 IWL_UCODE_TLV_FW_DBG_CONF = 39, 139 IWL_UCODE_TLV_FW_DBG_CONF = 39,
140 IWL_UCODE_TLV_FW_DBG_TRIGGER = 40,
138}; 141};
139 142
140struct iwl_ucode_tlv { 143struct iwl_ucode_tlv {
@@ -156,7 +159,8 @@ struct iwl_tlv_ucode_header {
156 __le32 zero; 159 __le32 zero;
157 __le32 magic; 160 __le32 magic;
158 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 161 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
159 __le32 ver; /* major/minor/API/serial */ 162 /* major/minor/API/serial or major in new format */
163 __le32 ver;
160 __le32 build; 164 __le32 build;
161 __le64 ignore; 165 __le64 ignore;
162 /* 166 /*
@@ -237,7 +241,6 @@ enum iwl_ucode_tlv_flag {
237 * enum iwl_ucode_tlv_api - ucode api 241 * enum iwl_ucode_tlv_api - ucode api
238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 242 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 243 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
240 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
241 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. 244 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
242 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 245 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
243 * longer than the passive one, which is essential for fragmented scan. 246 * longer than the passive one, which is essential for fragmented scan.
@@ -250,11 +253,12 @@ enum iwl_ucode_tlv_flag {
250 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. 253 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too.
251 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported. 254 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
252 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params 255 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
256 * @IWL_UCODE_TLV_API_STATS_V10: uCode supports/uses statistics API version 10
257 * @IWL_UCODE_TLV_API_NEW_VERSION: new versioning format
253 */ 258 */
254enum iwl_ucode_tlv_api { 259enum iwl_ucode_tlv_api {
255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 260 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 261 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 262 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
259 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 263 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
260 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), 264 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
@@ -263,6 +267,8 @@ enum iwl_ucode_tlv_api {
263 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), 267 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16),
264 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17), 268 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17),
265 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18), 269 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18),
270 IWL_UCODE_TLV_API_STATS_V10 = BIT(19),
271 IWL_UCODE_TLV_API_NEW_VERSION = BIT(20),
266}; 272};
267 273
268/** 274/**
@@ -284,6 +290,8 @@ enum iwl_ucode_tlv_api {
284 * which also implies support for the scheduler configuration command 290 * which also implies support for the scheduler configuration command
285 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching 291 * @IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH: supports TDLS channel switching
286 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command 292 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
293 * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics
294 * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running
287 */ 295 */
288enum iwl_ucode_tlv_capa { 296enum iwl_ucode_tlv_capa {
289 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), 297 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
@@ -298,6 +306,8 @@ enum iwl_ucode_tlv_capa {
298 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12), 306 IWL_UCODE_TLV_CAPA_DQA_SUPPORT = BIT(12),
299 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13), 307 IWL_UCODE_TLV_CAPA_TDLS_CHANNEL_SWITCH = BIT(13),
300 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), 308 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
309 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22),
310 IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28),
301}; 311};
302 312
303/* The default calibrate table size if not specified by firmware file */ 313/* The default calibrate table size if not specified by firmware file */
@@ -450,44 +460,129 @@ struct iwl_fw_dbg_conf_hcmd {
450} __packed; 460} __packed;
451 461
452/** 462/**
453 * struct iwl_fw_dbg_trigger - a TLV that describes a debug configuration 463 * enum iwl_fw_dbg_trigger_mode - triggers functionalities
454 * 464 *
455 * @enabled: is this trigger enabled 465 * @IWL_FW_DBG_TRIGGER_START: when trigger occurs re-conf the dbg mechanism
456 * @reserved: 466 * @IWL_FW_DBG_TRIGGER_STOP: when trigger occurs pull the dbg data
457 * @len: length, in bytes, of the %trigger field
458 * @trigger: pointer to a trigger struct
459 */ 467 */
460struct iwl_fw_dbg_trigger { 468enum iwl_fw_dbg_trigger_mode {
461 u8 enabled; 469 IWL_FW_DBG_TRIGGER_START = BIT(0),
462 u8 reserved; 470 IWL_FW_DBG_TRIGGER_STOP = BIT(1),
463 u8 len; 471};
464 u8 trigger[0]; 472
473/**
474 * enum iwl_fw_dbg_trigger_vif_type - define the VIF type for a trigger
475 * @IWL_FW_DBG_CONF_VIF_ANY: any vif type
476 * @IWL_FW_DBG_CONF_VIF_IBSS: IBSS mode
477 * @IWL_FW_DBG_CONF_VIF_STATION: BSS mode
478 * @IWL_FW_DBG_CONF_VIF_AP: AP mode
479 * @IWL_FW_DBG_CONF_VIF_P2P_CLIENT: P2P Client mode
480 * @IWL_FW_DBG_CONF_VIF_P2P_GO: P2P GO mode
481 * @IWL_FW_DBG_CONF_VIF_P2P_DEVICE: P2P device
482 */
483enum iwl_fw_dbg_trigger_vif_type {
484 IWL_FW_DBG_CONF_VIF_ANY = NL80211_IFTYPE_UNSPECIFIED,
485 IWL_FW_DBG_CONF_VIF_IBSS = NL80211_IFTYPE_ADHOC,
486 IWL_FW_DBG_CONF_VIF_STATION = NL80211_IFTYPE_STATION,
487 IWL_FW_DBG_CONF_VIF_AP = NL80211_IFTYPE_AP,
488 IWL_FW_DBG_CONF_VIF_P2P_CLIENT = NL80211_IFTYPE_P2P_CLIENT,
489 IWL_FW_DBG_CONF_VIF_P2P_GO = NL80211_IFTYPE_P2P_GO,
490 IWL_FW_DBG_CONF_VIF_P2P_DEVICE = NL80211_IFTYPE_P2P_DEVICE,
491};
492
493/**
494 * struct iwl_fw_dbg_trigger_tlv - a TLV that describes the trigger
495 * @id: %enum iwl_fw_dbg_trigger
496 * @vif_type: %enum iwl_fw_dbg_trigger_vif_type
497 * @stop_conf_ids: bitmap of configurations this trigger relates to.
498 * if the mode is %IWL_FW_DBG_TRIGGER_STOP, then if the bit corresponding
499 * to the currently running configuration is set, the data should be
500 * collected.
501 * @stop_delay: how many milliseconds to wait before collecting the data
502 * after the STOP trigger fires.
503 * @mode: %enum iwl_fw_dbg_trigger_mode - can be stop / start of both
504 * @start_conf_id: if mode is %IWL_FW_DBG_TRIGGER_START, this defines what
505 * configuration should be applied when the triggers kicks in.
506 * @occurrences: number of occurrences. 0 means the trigger will never fire.
507 */
508struct iwl_fw_dbg_trigger_tlv {
509 __le32 id;
510 __le32 vif_type;
511 __le32 stop_conf_ids;
512 __le32 stop_delay;
513 u8 mode;
514 u8 start_conf_id;
515 __le16 occurrences;
516 __le32 reserved[2];
517
518 u8 data[0];
465} __packed; 519} __packed;
466 520
521#define FW_DBG_START_FROM_ALIVE 0
522#define FW_DBG_CONF_MAX 32
523#define FW_DBG_INVALID 0xff
524
467/** 525/**
468 * enum iwl_fw_dbg_conf - configurations available 526 * struct iwl_fw_dbg_trigger_missed_bcon - configures trigger for missed beacons
469 * 527 * @stop_consec_missed_bcon: stop recording if threshold is crossed.
470 * @FW_DBG_CUSTOM: take this configuration from alive 528 * @stop_consec_missed_bcon_since_rx: stop recording if threshold is crossed.
471 * Note that the trigger is NO-OP for this configuration 529 * @start_consec_missed_bcon: start recording if threshold is crossed.
530 * @start_consec_missed_bcon_since_rx: start recording if threshold is crossed.
531 * @reserved1: reserved
532 * @reserved2: reserved
533 */
534struct iwl_fw_dbg_trigger_missed_bcon {
535 __le32 stop_consec_missed_bcon;
536 __le32 stop_consec_missed_bcon_since_rx;
537 __le32 reserved2[2];
538 __le32 start_consec_missed_bcon;
539 __le32 start_consec_missed_bcon_since_rx;
540 __le32 reserved1[2];
541} __packed;
542
543/**
544 * struct iwl_fw_dbg_trigger_cmd - configures trigger for messages from FW.
545 * cmds: the list of commands to trigger the collection on
472 */ 546 */
473enum iwl_fw_dbg_conf { 547struct iwl_fw_dbg_trigger_cmd {
474 FW_DBG_CUSTOM = 0, 548 struct cmd {
549 u8 cmd_id;
550 u8 group_id;
551 } __packed cmds[16];
552} __packed;
475 553
476 /* must be last */ 554/**
477 FW_DBG_MAX, 555 * iwl_fw_dbg_trigger_stats - configures trigger for statistics
478 FW_DBG_INVALID = 0xff, 556 * @stop_offset: the offset of the value to be monitored
479}; 557 * @stop_threshold: the threshold above which to collect
558 * @start_offset: the offset of the value to be monitored
559 * @start_threshold: the threshold above which to start recording
560 */
561struct iwl_fw_dbg_trigger_stats {
562 __le32 stop_offset;
563 __le32 stop_threshold;
564 __le32 start_offset;
565 __le32 start_threshold;
566} __packed;
480 567
481/** 568/**
482 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration 569 * struct iwl_fw_dbg_trigger_low_rssi - trigger for low beacon RSSI
483 * 570 * @rssi: RSSI value to trigger at
484 * @id: %enum iwl_fw_dbg_conf 571 */
572struct iwl_fw_dbg_trigger_low_rssi {
573 __le32 rssi;
574} __packed;
575
576/**
577 * struct iwl_fw_dbg_conf_tlv - a TLV that describes a debug configuration.
578 * @id: conf id
485 * @usniffer: should the uSniffer image be used 579 * @usniffer: should the uSniffer image be used
486 * @num_of_hcmds: how many HCMDs to send are present here 580 * @num_of_hcmds: how many HCMDs to send are present here
487 * @hcmd: a variable length host command to be sent to apply the configuration. 581 * @hcmd: a variable length host command to be sent to apply the configuration.
488 * If there is more than one HCMD to send, they will appear one after the 582 * If there is more than one HCMD to send, they will appear one after the
489 * other and be sent in the order that they appear in. 583 * other and be sent in the order that they appear in.
490 * This parses IWL_UCODE_TLV_FW_DBG_CONF 584 * This parses IWL_UCODE_TLV_FW_DBG_CONF. The user can add up-to
585 * %FW_DBG_CONF_MAX configuration per run.
491 */ 586 */
492struct iwl_fw_dbg_conf_tlv { 587struct iwl_fw_dbg_conf_tlv {
493 u8 id; 588 u8 id;
@@ -495,8 +590,6 @@ struct iwl_fw_dbg_conf_tlv {
495 u8 reserved; 590 u8 reserved;
496 u8 num_of_hcmds; 591 u8 num_of_hcmds;
497 struct iwl_fw_dbg_conf_hcmd hcmd; 592 struct iwl_fw_dbg_conf_hcmd hcmd;
498
499 /* struct iwl_fw_dbg_trigger sits after all variable length hcmds */
500} __packed; 593} __packed;
501 594
502#endif /* __iwl_fw_file_h__ */ 595#endif /* __iwl_fw_file_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index ffd785cc67d6..cf75bafae51d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -68,6 +68,7 @@
68#include <net/mac80211.h> 68#include <net/mac80211.h>
69 69
70#include "iwl-fw-file.h" 70#include "iwl-fw-file.h"
71#include "iwl-fw-error-dump.h"
71 72
72/** 73/**
73 * enum iwl_ucode_type 74 * enum iwl_ucode_type
@@ -157,6 +158,8 @@ struct iwl_fw_cscheme_list {
157 * @dbg_dest_tlv: points to the destination TLV for debug 158 * @dbg_dest_tlv: points to the destination TLV for debug
158 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 159 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
159 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries 160 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
161 * @dbg_trigger_tlv: array of pointers to triggers TLVs
162 * @dbg_trigger_tlv_len: lengths of the @dbg_trigger_tlv entries
160 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv 163 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
161 */ 164 */
162struct iwl_fw { 165struct iwl_fw {
@@ -186,9 +189,10 @@ struct iwl_fw {
186 u32 sdio_adma_addr; 189 u32 sdio_adma_addr;
187 190
188 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 191 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
189 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 192 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
190 size_t dbg_conf_tlv_len[FW_DBG_MAX]; 193 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
191 194 struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX];
195 size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX];
192 u8 dbg_dest_reg_num; 196 u8 dbg_dest_reg_num;
193}; 197};
194 198
@@ -206,46 +210,29 @@ static inline const char *get_fw_dbg_mode_string(int mode)
206 } 210 }
207} 211}
208 212
209static inline const struct iwl_fw_dbg_trigger * 213static inline bool
210iwl_fw_dbg_conf_get_trigger(const struct iwl_fw *fw, u8 id) 214iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id)
211{ 215{
212 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id]; 216 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id];
213 u8 *ptr;
214 int i;
215 217
216 if (!conf_tlv) 218 if (!conf_tlv)
217 return NULL;
218
219 ptr = (void *)&conf_tlv->hcmd;
220 for (i = 0; i < conf_tlv->num_of_hcmds; i++) {
221 ptr += sizeof(conf_tlv->hcmd);
222 ptr += le16_to_cpu(conf_tlv->hcmd.len);
223 }
224
225 return (const struct iwl_fw_dbg_trigger *)ptr;
226}
227
228static inline bool
229iwl_fw_dbg_conf_enabled(const struct iwl_fw *fw, u8 id)
230{
231 const struct iwl_fw_dbg_trigger *trigger =
232 iwl_fw_dbg_conf_get_trigger(fw, id);
233
234 if (!trigger)
235 return false; 219 return false;
236 220
237 return trigger->enabled; 221 return conf_tlv->usniffer;
238} 222}
239 223
240static inline bool 224#define iwl_fw_dbg_trigger_enabled(fw, id) ({ \
241iwl_fw_dbg_conf_usniffer(const struct iwl_fw *fw, u8 id) 225 void *__dbg_trigger = (fw)->dbg_trigger_tlv[(id)]; \
242{ 226 unlikely(__dbg_trigger); \
243 const struct iwl_fw_dbg_conf_tlv *conf_tlv = fw->dbg_conf_tlv[id]; 227})
244 228
245 if (!conf_tlv) 229static inline struct iwl_fw_dbg_trigger_tlv*
246 return false; 230iwl_fw_dbg_get_trigger(const struct iwl_fw *fw, u8 id)
231{
232 if (WARN_ON(id >= ARRAY_SIZE(fw->dbg_trigger_tlv)))
233 return NULL;
247 234
248 return conf_tlv->usniffer; 235 return fw->dbg_trigger_tlv[id];
249} 236}
250 237
251#endif /* __iwl_fw_h__ */ 238#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
index d4fb5cad07ea..e893c6eb260c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -72,7 +72,7 @@
72#include "iwl-trans.h" 72#include "iwl-trans.h"
73 73
74#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ 74#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
75#define IWL_NUM_PAPD_CH_GROUPS 7 75#define IWL_NUM_PAPD_CH_GROUPS 9
76#define IWL_NUM_TXP_CH_GROUPS 9 76#define IWL_NUM_TXP_CH_GROUPS 9
77 77
78struct iwl_phy_db_entry { 78struct iwl_phy_db_entry {
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6221e4dfc64f..6095088b88d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -370,7 +370,6 @@ enum secure_load_status_reg {
370#define MON_BUFF_CYCLE_CNT (0xa03c48) 370#define MON_BUFF_CYCLE_CNT (0xa03c48)
371 371
372#define DBGC_IN_SAMPLE (0xa03c00) 372#define DBGC_IN_SAMPLE (0xa03c00)
373#define DBGC_OUT_CTRL (0xa03c0c)
374 373
375/* FW chicken bits */ 374/* FW chicken bits */
376#define LMPM_CHICK 0xA01FF8 375#define LMPM_CHICK 0xA01FF8
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index a96bd8db6ceb..542a6810c81c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -595,6 +595,7 @@ enum iwl_d0i3_mode {
595 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI) 595 * @dflt_pwr_limit: default power limit fetched from the platform (ACPI)
596 * @dbg_dest_tlv: points to the destination TLV for debug 596 * @dbg_dest_tlv: points to the destination TLV for debug
597 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 597 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
598 * @dbg_trigger_tlv: array of pointers to triggers TLVs for debug
598 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv 599 * @dbg_dest_reg_num: num of reg_ops in %dbg_dest_tlv
599 */ 600 */
600struct iwl_trans { 601struct iwl_trans {
@@ -628,7 +629,8 @@ struct iwl_trans {
628 u64 dflt_pwr_limit; 629 u64 dflt_pwr_limit;
629 630
630 const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 631 const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
631 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 632 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
633 struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
632 u8 dbg_dest_reg_num; 634 u8 dbg_dest_reg_num;
633 635
634 enum iwl_d0i3_mode d0i3_mode; 636 enum iwl_d0i3_mode d0i3_mode;
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 1ec4d55155f7..ce99572a982d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -611,7 +611,7 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
611 bt_cmd->enabled_modules |= 611 bt_cmd->enabled_modules |=
612 cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED); 612 cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
613 613
614 if (IWL_MVM_BT_COEX_CORUNNING) 614 if (iwl_mvm_bt_is_plcr_supported(mvm))
615 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED); 615 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
616 616
617 if (IWL_MVM_BT_COEX_MPLUT) { 617 if (IWL_MVM_BT_COEX_MPLUT) {
@@ -1234,7 +1234,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1234 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) 1234 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1235 return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd); 1235 return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd);
1236 1236
1237 if (!IWL_MVM_BT_COEX_CORUNNING) 1237 if (!iwl_mvm_bt_is_plcr_supported(mvm))
1238 return 0; 1238 return 0;
1239 1239
1240 lockdep_assert_held(&mvm->mutex); 1240 lockdep_assert_held(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index d530ef3da107..9717ee61928c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -619,7 +619,7 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
619 if (IWL_MVM_BT_COEX_SYNC2SCO) 619 if (IWL_MVM_BT_COEX_SYNC2SCO)
620 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); 620 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
621 621
622 if (IWL_MVM_BT_COEX_CORUNNING) { 622 if (iwl_mvm_bt_is_plcr_supported(mvm)) {
623 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 | 623 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
624 BT_VALID_CORUN_LUT_40); 624 BT_VALID_CORUN_LUT_40);
625 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING); 625 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
@@ -1167,16 +1167,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
1167 return lut_type != BT_COEX_LOOSE_LUT; 1167 return lut_type != BT_COEX_LOOSE_LUT;
1168} 1168}
1169 1169
1170bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant)
1171{
1172 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1173 return ag < BT_HIGH_TRAFFIC;
1174}
1175
1176bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm) 1170bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm)
1177{ 1171{
1178 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading); 1172 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1179 return ag == BT_OFF; 1173 return ag < BT_HIGH_TRAFFIC;
1180} 1174}
1181 1175
1182bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm, 1176bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
@@ -1213,7 +1207,7 @@ int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
1213 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 1207 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1214 }; 1208 };
1215 1209
1216 if (!IWL_MVM_BT_COEX_CORUNNING) 1210 if (!iwl_mvm_bt_is_plcr_supported(mvm))
1217 return 0; 1211 return 0;
1218 1212
1219 lockdep_assert_held(&mvm->mutex); 1213 lockdep_assert_held(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 14e8fd661889..9bdfa95d6ce7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1876,25 +1876,28 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1876 1876
1877 if (mvm->net_detect) { 1877 if (mvm->net_detect) {
1878 iwl_mvm_query_netdetect_reasons(mvm, vif); 1878 iwl_mvm_query_netdetect_reasons(mvm, vif);
1879 /* has unlocked the mutex, so skip that */
1880 goto out;
1879 } else { 1881 } else {
1880 keep = iwl_mvm_query_wakeup_reasons(mvm, vif); 1882 keep = iwl_mvm_query_wakeup_reasons(mvm, vif);
1881#ifdef CONFIG_IWLWIFI_DEBUGFS 1883#ifdef CONFIG_IWLWIFI_DEBUGFS
1882 if (keep) 1884 if (keep)
1883 mvm->keep_vif = vif; 1885 mvm->keep_vif = vif;
1886 /* has unlocked the mutex, so skip that */
1887 goto out_iterate;
1884#endif 1888#endif
1885 } 1889 }
1886 /* has unlocked the mutex, so skip that */
1887 goto out;
1888 1890
1889 out_unlock: 1891 out_unlock:
1890 mutex_unlock(&mvm->mutex); 1892 mutex_unlock(&mvm->mutex);
1891 1893
1892 out: 1894out_iterate:
1893 if (!test) 1895 if (!test)
1894 ieee80211_iterate_active_interfaces_rtnl(mvm->hw, 1896 ieee80211_iterate_active_interfaces_rtnl(mvm->hw,
1895 IEEE80211_IFACE_ITER_NORMAL, 1897 IEEE80211_IFACE_ITER_NORMAL,
1896 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); 1898 iwl_mvm_d3_disconnect_iter, keep ? vif : NULL);
1897 1899
1900out:
1898 /* return 1 to reconfigure the device */ 1901 /* return 1 to reconfigure the device */
1899 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1902 set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1900 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status); 1903 set_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status);
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 5fe14591e1c4..7faad90386b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -545,6 +545,57 @@ static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
545 return ret ? count : -EINVAL; 545 return ret ? count : -EINVAL;
546} 546}
547 547
548static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
549 size_t count, loff_t *ppos)
550{
551 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
552 struct iwl_mvm *mvm = mvmvif->mvm;
553 struct ieee80211_chanctx_conf *chanctx_conf;
554 struct iwl_mvm_phy_ctxt *phy_ctxt;
555 u16 value;
556 int ret;
557
558 ret = kstrtou16(buf, 0, &value);
559 if (ret)
560 return ret;
561
562 mutex_lock(&mvm->mutex);
563 rcu_read_lock();
564
565 chanctx_conf = rcu_dereference(vif->chanctx_conf);
566 /* make sure the channel context is assigned */
567 if (!chanctx_conf) {
568 rcu_read_unlock();
569 mutex_unlock(&mvm->mutex);
570 return -EINVAL;
571 }
572
573 phy_ctxt = &mvm->phy_ctxts[*(u16 *)chanctx_conf->drv_priv];
574 rcu_read_unlock();
575
576 mvm->dbgfs_rx_phyinfo = value;
577
578 ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &chanctx_conf->min_def,
579 chanctx_conf->rx_chains_static,
580 chanctx_conf->rx_chains_dynamic);
581 mutex_unlock(&mvm->mutex);
582
583 return ret ?: count;
584}
585
586static ssize_t iwl_dbgfs_rx_phyinfo_read(struct file *file,
587 char __user *user_buf,
588 size_t count, loff_t *ppos)
589{
590 struct ieee80211_vif *vif = file->private_data;
591 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
592 char buf[8];
593
594 snprintf(buf, sizeof(buf), "0x%04x\n", mvmvif->mvm->dbgfs_rx_phyinfo);
595
596 return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
597}
598
548#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 599#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
549 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif) 600 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
550#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ 601#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -560,6 +611,7 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
560MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); 611MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
561MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); 612MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
562MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20); 613MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
614MVM_DEBUGFS_READ_WRITE_FILE_OPS(rx_phyinfo, 10);
563 615
564void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 616void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
565{ 617{
@@ -595,6 +647,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
595 S_IRUSR | S_IWUSR); 647 S_IRUSR | S_IWUSR);
596 MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir, 648 MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
597 S_IRUSR | S_IWUSR); 649 S_IRUSR | S_IWUSR);
650 MVM_DEBUGFS_ADD_FILE_VIF(rx_phyinfo, mvmvif->dbgfs_dir,
651 S_IRUSR | S_IWUSR);
598 652
599 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 653 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
600 mvmvif == mvm->bf_allowed_vif) 654 mvmvif == mvm->bf_allowed_vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 82c09d86af8c..8cbe77dc1dbb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -942,7 +942,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
942 size_t count, loff_t *ppos) 942 size_t count, loff_t *ppos)
943{ 943{
944 struct iwl_mvm *mvm = file->private_data; 944 struct iwl_mvm *mvm = file->private_data;
945 enum iwl_fw_dbg_conf conf; 945 int conf;
946 char buf[8]; 946 char buf[8];
947 const size_t bufsz = sizeof(buf); 947 const size_t bufsz = sizeof(buf);
948 int pos = 0; 948 int pos = 0;
@@ -966,7 +966,7 @@ static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
966 if (ret) 966 if (ret)
967 return ret; 967 return ret;
968 968
969 if (WARN_ON(conf_id >= FW_DBG_MAX)) 969 if (WARN_ON(conf_id >= FW_DBG_CONF_MAX))
970 return -EINVAL; 970 return -EINVAL;
971 971
972 mutex_lock(&mvm->mutex); 972 mutex_lock(&mvm->mutex);
@@ -985,7 +985,7 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
985 if (ret) 985 if (ret)
986 return ret; 986 return ret;
987 987
988 iwl_mvm_fw_dbg_collect(mvm); 988 iwl_mvm_fw_dbg_collect(mvm, FW_DBG_TRIGGER_USER, NULL, 0, 0);
989 989
990 iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE); 990 iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
991 991
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
index c405cda1025f..aabaedd3b3ee 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h
@@ -70,6 +70,7 @@
70#define MAC_INDEX_AUX 4 70#define MAC_INDEX_AUX 4
71#define MAC_INDEX_MIN_DRIVER 0 71#define MAC_INDEX_MIN_DRIVER 0
72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX 72#define NUM_MAC_INDEX_DRIVER MAC_INDEX_AUX
73#define NUM_MAC_INDEX (MAC_INDEX_AUX + 1)
73 74
74enum iwl_ac { 75enum iwl_ac {
75 AC_BK, 76 AC_BK,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index cfc0e65b34a5..a5fbbd637070 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -70,55 +70,10 @@
70 70
71/* Scan Commands, Responses, Notifications */ 71/* Scan Commands, Responses, Notifications */
72 72
73/* Masks for iwl_scan_channel.type flags */
74#define SCAN_CHANNEL_TYPE_ACTIVE BIT(0)
75#define SCAN_CHANNEL_NARROW_BAND BIT(22)
76
77/* Max number of IEs for direct SSID scans in a command */ 73/* Max number of IEs for direct SSID scans in a command */
78#define PROBE_OPTION_MAX 20 74#define PROBE_OPTION_MAX 20
79 75
80/** 76/**
81 * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table
82 * @channel: band is selected by iwl_scan_cmd "flags" field
83 * @tx_gain: gain for analog radio
84 * @dsp_atten: gain for DSP
85 * @active_dwell: dwell time for active scan in TU, typically 5-50
86 * @passive_dwell: dwell time for passive scan in TU, typically 20-500
87 * @type: type is broken down to these bits:
88 * bit 0: 0 = passive, 1 = active
89 * bits 1-20: SSID direct bit map. If any of these bits is set then
90 * the corresponding SSID IE is transmitted in probe request
91 * (bit i adds IE in position i to the probe request)
92 * bit 22: channel width, 0 = regular, 1 = TGj narrow channel
93 *
94 * @iteration_count:
95 * @iteration_interval:
96 * This struct is used once for each channel in the scan list.
97 * Each channel can independently select:
98 * 1) SSID for directed active scans
99 * 2) Txpower setting (for rate specified within Tx command)
100 * 3) How long to stay on-channel (behavior may be modified by quiet_time,
101 * quiet_plcp_th, good_CRC_th)
102 *
103 * To avoid uCode errors, make sure the following are true (see comments
104 * under struct iwl_scan_cmd about max_out_time and quiet_time):
105 * 1) If using passive_dwell (i.e. passive_dwell != 0):
106 * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0)
107 * 2) quiet_time <= active_dwell
108 * 3) If restricting off-channel time (i.e. max_out_time !=0):
109 * passive_dwell < max_out_time
110 * active_dwell < max_out_time
111 */
112struct iwl_scan_channel {
113 __le32 type;
114 __le16 channel;
115 __le16 iteration_count;
116 __le32 iteration_interval;
117 __le16 active_dwell;
118 __le16 passive_dwell;
119} __packed; /* SCAN_CHANNEL_CONTROL_API_S_VER_1 */
120
121/**
122 * struct iwl_ssid_ie - directed scan network information element 77 * struct iwl_ssid_ie - directed scan network information element
123 * 78 *
124 * Up to 20 of these may appear in REPLY_SCAN_CMD, 79 * Up to 20 of these may appear in REPLY_SCAN_CMD,
@@ -132,152 +87,6 @@ struct iwl_ssid_ie {
132 u8 ssid[IEEE80211_MAX_SSID_LEN]; 87 u8 ssid[IEEE80211_MAX_SSID_LEN];
133} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */ 88} __packed; /* SCAN_DIRECT_SSID_IE_API_S_VER_1 */
134 89
135/**
136 * iwl_scan_flags - masks for scan command flags
137 *@SCAN_FLAGS_PERIODIC_SCAN:
138 *@SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX:
139 *@SCAN_FLAGS_DELAYED_SCAN_LOWBAND:
140 *@SCAN_FLAGS_DELAYED_SCAN_HIGHBAND:
141 *@SCAN_FLAGS_FRAGMENTED_SCAN:
142 *@SCAN_FLAGS_PASSIVE2ACTIVE: use active scan on channels that was active
143 * in the past hour, even if they are marked as passive.
144 */
145enum iwl_scan_flags {
146 SCAN_FLAGS_PERIODIC_SCAN = BIT(0),
147 SCAN_FLAGS_P2P_PUBLIC_ACTION_FRAME_TX = BIT(1),
148 SCAN_FLAGS_DELAYED_SCAN_LOWBAND = BIT(2),
149 SCAN_FLAGS_DELAYED_SCAN_HIGHBAND = BIT(3),
150 SCAN_FLAGS_FRAGMENTED_SCAN = BIT(4),
151 SCAN_FLAGS_PASSIVE2ACTIVE = BIT(5),
152};
153
154/**
155 * enum iwl_scan_type - Scan types for scan command
156 * @SCAN_TYPE_FORCED:
157 * @SCAN_TYPE_BACKGROUND:
158 * @SCAN_TYPE_OS:
159 * @SCAN_TYPE_ROAMING:
160 * @SCAN_TYPE_ACTION:
161 * @SCAN_TYPE_DISCOVERY:
162 * @SCAN_TYPE_DISCOVERY_FORCED:
163 */
164enum iwl_scan_type {
165 SCAN_TYPE_FORCED = 0,
166 SCAN_TYPE_BACKGROUND = 1,
167 SCAN_TYPE_OS = 2,
168 SCAN_TYPE_ROAMING = 3,
169 SCAN_TYPE_ACTION = 4,
170 SCAN_TYPE_DISCOVERY = 5,
171 SCAN_TYPE_DISCOVERY_FORCED = 6,
172}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
173
174/**
175 * struct iwl_scan_cmd - scan request command
176 * ( SCAN_REQUEST_CMD = 0x80 )
177 * @len: command length in bytes
178 * @scan_flags: scan flags from SCAN_FLAGS_*
179 * @channel_count: num of channels in channel list
180 * (1 - ucode_capa.n_scan_channels)
181 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
182 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
183 * this number of packets were received (typically 1)
184 * @passive2active: is auto switching from passive to active during scan allowed
185 * @rxchain_sel_flags: RXON_RX_CHAIN_*
186 * @max_out_time: in TUs, max out of serving channel time
187 * @suspend_time: how long to pause scan when returning to service channel:
188 * bits 0-19: beacon interal in TUs (suspend before executing)
189 * bits 20-23: reserved
190 * bits 24-31: number of beacons (suspend between channels)
191 * @rxon_flags: RXON_FLG_*
192 * @filter_flags: RXON_FILTER_*
193 * @tx_cmd: for active scans (zero for passive), w/o payload,
194 * no RS so specify TX rate
195 * @direct_scan: direct scan SSIDs
196 * @type: one of SCAN_TYPE_*
197 * @repeats: how many time to repeat the scan
198 */
199struct iwl_scan_cmd {
200 __le16 len;
201 u8 scan_flags;
202 u8 channel_count;
203 __le16 quiet_time;
204 __le16 quiet_plcp_th;
205 __le16 passive2active;
206 __le16 rxchain_sel_flags;
207 __le32 max_out_time;
208 __le32 suspend_time;
209 /* RX_ON_FLAGS_API_S_VER_1 */
210 __le32 rxon_flags;
211 __le32 filter_flags;
212 struct iwl_tx_cmd tx_cmd;
213 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
214 __le32 type;
215 __le32 repeats;
216
217 /*
218 * Probe request frame, followed by channel list.
219 *
220 * Size of probe request frame is specified by byte count in tx_cmd.
221 * Channel list follows immediately after probe request frame.
222 * Number of channels in list is specified by channel_count.
223 * Each channel in list is of type:
224 *
225 * struct iwl_scan_channel channels[0];
226 *
227 * NOTE: Only one band of channels can be scanned per pass. You
228 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
229 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
230 * before requesting another scan.
231 */
232 u8 data[0];
233} __packed; /* SCAN_REQUEST_FIXED_PART_API_S_VER_5 */
234
235/* Response to scan request contains only status with one of these values */
236#define SCAN_RESPONSE_OK 0x1
237#define SCAN_RESPONSE_ERROR 0x2
238
239/*
240 * SCAN_ABORT_CMD = 0x81
241 * When scan abort is requested, the command has no fields except the common
242 * header. The response contains only a status with one of these values.
243 */
244#define SCAN_ABORT_POSSIBLE 0x1
245#define SCAN_ABORT_IGNORED 0x2 /* no pending scans */
246
247/* TODO: complete documentation */
248#define SCAN_OWNER_STATUS 0x1
249#define MEASURE_OWNER_STATUS 0x2
250
251/**
252 * struct iwl_scan_start_notif - notifies start of scan in the device
253 * ( SCAN_START_NOTIFICATION = 0x82 )
254 * @tsf_low: TSF timer (lower half) in usecs
255 * @tsf_high: TSF timer (higher half) in usecs
256 * @beacon_timer: structured as follows:
257 * bits 0:19 - beacon interval in usecs
258 * bits 20:23 - reserved (0)
259 * bits 24:31 - number of beacons
260 * @channel: which channel is scanned
261 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
262 * @status: one of *_OWNER_STATUS
263 */
264struct iwl_scan_start_notif {
265 __le32 tsf_low;
266 __le32 tsf_high;
267 __le32 beacon_timer;
268 u8 channel;
269 u8 band;
270 u8 reserved[2];
271 __le32 status;
272} __packed; /* SCAN_START_NTF_API_S_VER_1 */
273
274/* scan results probe_status first bit indicates success */
275#define SCAN_PROBE_STATUS_OK 0
276#define SCAN_PROBE_STATUS_TX_FAILED BIT(0)
277/* error statuses combined with TX_FAILED */
278#define SCAN_PROBE_STATUS_FAIL_TTL BIT(1)
279#define SCAN_PROBE_STATUS_FAIL_BT BIT(2)
280
281/* How many statistics are gathered for each channel */ 90/* How many statistics are gathered for each channel */
282#define SCAN_RESULTS_STATISTICS 1 91#define SCAN_RESULTS_STATISTICS 1
283 92
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
index 928168b18346..709e28d8b1b0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
@@ -65,6 +65,7 @@
65 65
66#ifndef __fw_api_stats_h__ 66#ifndef __fw_api_stats_h__
67#define __fw_api_stats_h__ 67#define __fw_api_stats_h__
68#include "fw-api-mac.h"
68 69
69struct mvm_statistics_dbg { 70struct mvm_statistics_dbg {
70 __le32 burst_check; 71 __le32 burst_check;
@@ -218,7 +219,7 @@ struct mvm_statistics_bt_activity {
218 __le32 lo_priority_rx_denied_cnt; 219 __le32 lo_priority_rx_denied_cnt;
219} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */ 220} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
220 221
221struct mvm_statistics_general { 222struct mvm_statistics_general_v5 {
222 __le32 radio_temperature; 223 __le32 radio_temperature;
223 __le32 radio_voltage; 224 __le32 radio_voltage;
224 struct mvm_statistics_dbg dbg; 225 struct mvm_statistics_dbg dbg;
@@ -244,6 +245,39 @@ struct mvm_statistics_general {
244 struct mvm_statistics_bt_activity bt_activity; 245 struct mvm_statistics_bt_activity bt_activity;
245} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */ 246} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
246 247
248struct mvm_statistics_general_v8 {
249 __le32 radio_temperature;
250 __le32 radio_voltage;
251 struct mvm_statistics_dbg dbg;
252 __le32 sleep_time;
253 __le32 slots_out;
254 __le32 slots_idle;
255 __le32 ttl_timestamp;
256 struct mvm_statistics_div slow_div;
257 __le32 rx_enable_counter;
258 /*
259 * num_of_sos_states:
260 * count the number of times we have to re-tune
261 * in order to get out of bad PHY status
262 */
263 __le32 num_of_sos_states;
264 __le32 beacon_filtered;
265 __le32 missed_beacons;
266 __s8 beacon_filter_average_energy;
267 __s8 beacon_filter_reason;
268 __s8 beacon_filter_current_energy;
269 __s8 beacon_filter_reserved;
270 __le32 beacon_filter_delta_time;
271 struct mvm_statistics_bt_activity bt_activity;
272 __le64 rx_time;
273 __le64 on_time_rf;
274 __le64 on_time_scan;
275 __le64 tx_time;
276 __le32 beacon_counter[NUM_MAC_INDEX];
277 u8 beacon_average_energy[NUM_MAC_INDEX];
278 u8 reserved[4 - (NUM_MAC_INDEX % 4)];
279} __packed; /* STATISTICS_GENERAL_API_S_VER_8 */
280
247struct mvm_statistics_rx { 281struct mvm_statistics_rx {
248 struct mvm_statistics_rx_phy ofdm; 282 struct mvm_statistics_rx_phy ofdm;
249 struct mvm_statistics_rx_phy cck; 283 struct mvm_statistics_rx_phy cck;
@@ -256,22 +290,28 @@ struct mvm_statistics_rx {
256 * 290 *
257 * By default, uCode issues this notification after receiving a beacon 291 * By default, uCode issues this notification after receiving a beacon
258 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the 292 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
259 * REPLY_STATISTICS_CMD 0x9c, above. 293 * STATISTICS_CMD (0x9c), below.
260 *
261 * Statistics counters continue to increment beacon after beacon, but are
262 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
263 * 0x9c with CLEAR_STATS bit set (see above).
264 *
265 * uCode also issues this notification during scans. uCode clears statistics
266 * appropriately so that each notification contains statistics for only the
267 * one channel that has just been scanned.
268 */ 294 */
269 295
270struct iwl_notif_statistics { 296struct iwl_notif_statistics_v8 {
271 __le32 flag; 297 __le32 flag;
272 struct mvm_statistics_rx rx; 298 struct mvm_statistics_rx rx;
273 struct mvm_statistics_tx tx; 299 struct mvm_statistics_tx tx;
274 struct mvm_statistics_general general; 300 struct mvm_statistics_general_v5 general;
275} __packed; /* STATISTICS_NTFY_API_S_VER_8 */ 301} __packed; /* STATISTICS_NTFY_API_S_VER_8 */
276 302
303struct iwl_notif_statistics_v10 {
304 __le32 flag;
305 struct mvm_statistics_rx rx;
306 struct mvm_statistics_tx tx;
307 struct mvm_statistics_general_v8 general;
308} __packed; /* STATISTICS_NTFY_API_S_VER_10 */
309
310#define IWL_STATISTICS_FLG_CLEAR 0x1
311#define IWL_STATISTICS_FLG_DISABLE_NOTIF 0x2
312
313struct iwl_statistics_cmd {
314 __le32 flags;
315} __packed; /* STATISTICS_CMD_API_S_VER_1 */
316
277#endif /* __fw_api_stats_h__ */ 317#endif /* __fw_api_stats_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index b56154fe8ec5..d95b47213731 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -192,6 +192,7 @@ enum {
192 BEACON_NOTIFICATION = 0x90, 192 BEACON_NOTIFICATION = 0x90,
193 BEACON_TEMPLATE_CMD = 0x91, 193 BEACON_TEMPLATE_CMD = 0x91,
194 TX_ANT_CONFIGURATION_CMD = 0x98, 194 TX_ANT_CONFIGURATION_CMD = 0x98,
195 STATISTICS_CMD = 0x9c,
195 STATISTICS_NOTIFICATION = 0x9d, 196 STATISTICS_NOTIFICATION = 0x9d,
196 EOSP_NOTIFICATION = 0x9e, 197 EOSP_NOTIFICATION = 0x9e,
197 REDUCE_TX_POWER_CMD = 0x9f, 198 REDUCE_TX_POWER_CMD = 0x9f,
@@ -431,7 +432,7 @@ enum {
431 432
432#define IWL_ALIVE_FLG_RFKILL BIT(0) 433#define IWL_ALIVE_FLG_RFKILL BIT(0)
433 434
434struct mvm_alive_resp { 435struct mvm_alive_resp_ver1 {
435 __le16 status; 436 __le16 status;
436 __le16 flags; 437 __le16 flags;
437 u8 ucode_minor; 438 u8 ucode_minor;
@@ -482,6 +483,30 @@ struct mvm_alive_resp_ver2 {
482 __le32 dbg_print_buff_addr; 483 __le32 dbg_print_buff_addr;
483} __packed; /* ALIVE_RES_API_S_VER_2 */ 484} __packed; /* ALIVE_RES_API_S_VER_2 */
484 485
486struct mvm_alive_resp {
487 __le16 status;
488 __le16 flags;
489 __le32 ucode_minor;
490 __le32 ucode_major;
491 u8 ver_subtype;
492 u8 ver_type;
493 u8 mac;
494 u8 opt;
495 __le32 timestamp;
496 __le32 error_event_table_ptr; /* SRAM address for error log */
497 __le32 log_event_table_ptr; /* SRAM address for LMAC event log */
498 __le32 cpu_register_ptr;
499 __le32 dbgm_config_ptr;
500 __le32 alive_counter_ptr;
501 __le32 scd_base_ptr; /* SRAM address for SCD */
502 __le32 st_fwrd_addr; /* pointer to Store and forward */
503 __le32 st_fwrd_size;
504 __le32 umac_minor; /* UMAC version: minor */
505 __le32 umac_major; /* UMAC version: major */
506 __le32 error_info_addr; /* SRAM address for UMAC error log */
507 __le32 dbg_print_buff_addr;
508} __packed; /* ALIVE_RES_API_S_VER_3 */
509
485/* Error response/notification */ 510/* Error response/notification */
486enum { 511enum {
487 FW_ERR_UNKNOWN_CMD = 0x0, 512 FW_ERR_UNKNOWN_CMD = 0x0,
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index ca38e9817374..a81da4cde643 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -112,25 +112,27 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
112 struct iwl_mvm *mvm = 112 struct iwl_mvm *mvm =
113 container_of(notif_wait, struct iwl_mvm, notif_wait); 113 container_of(notif_wait, struct iwl_mvm, notif_wait);
114 struct iwl_mvm_alive_data *alive_data = data; 114 struct iwl_mvm_alive_data *alive_data = data;
115 struct mvm_alive_resp *palive; 115 struct mvm_alive_resp_ver1 *palive1;
116 struct mvm_alive_resp_ver2 *palive2; 116 struct mvm_alive_resp_ver2 *palive2;
117 struct mvm_alive_resp *palive;
117 118
118 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) { 119 if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive1)) {
119 palive = (void *)pkt->data; 120 palive1 = (void *)pkt->data;
120 121
121 mvm->support_umac_log = false; 122 mvm->support_umac_log = false;
122 mvm->error_event_table = 123 mvm->error_event_table =
123 le32_to_cpu(palive->error_event_table_ptr); 124 le32_to_cpu(palive1->error_event_table_ptr);
124 mvm->log_event_table = le32_to_cpu(palive->log_event_table_ptr); 125 mvm->log_event_table =
125 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr); 126 le32_to_cpu(palive1->log_event_table_ptr);
127 alive_data->scd_base_addr = le32_to_cpu(palive1->scd_base_ptr);
126 128
127 alive_data->valid = le16_to_cpu(palive->status) == 129 alive_data->valid = le16_to_cpu(palive1->status) ==
128 IWL_ALIVE_STATUS_OK; 130 IWL_ALIVE_STATUS_OK;
129 IWL_DEBUG_FW(mvm, 131 IWL_DEBUG_FW(mvm,
130 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n", 132 "Alive VER1 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
131 le16_to_cpu(palive->status), palive->ver_type, 133 le16_to_cpu(palive1->status), palive1->ver_type,
132 palive->ver_subtype, palive->flags); 134 palive1->ver_subtype, palive1->flags);
133 } else { 135 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive2)) {
134 palive2 = (void *)pkt->data; 136 palive2 = (void *)pkt->data;
135 137
136 mvm->error_event_table = 138 mvm->error_event_table =
@@ -156,6 +158,33 @@ static bool iwl_alive_fn(struct iwl_notif_wait_data *notif_wait,
156 IWL_DEBUG_FW(mvm, 158 IWL_DEBUG_FW(mvm,
157 "UMAC version: Major - 0x%x, Minor - 0x%x\n", 159 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
158 palive2->umac_major, palive2->umac_minor); 160 palive2->umac_major, palive2->umac_minor);
161 } else if (iwl_rx_packet_payload_len(pkt) == sizeof(*palive)) {
162 palive = (void *)pkt->data;
163
164 mvm->error_event_table =
165 le32_to_cpu(palive->error_event_table_ptr);
166 mvm->log_event_table =
167 le32_to_cpu(palive->log_event_table_ptr);
168 alive_data->scd_base_addr = le32_to_cpu(palive->scd_base_ptr);
169 mvm->umac_error_event_table =
170 le32_to_cpu(palive->error_info_addr);
171 mvm->sf_space.addr = le32_to_cpu(palive->st_fwrd_addr);
172 mvm->sf_space.size = le32_to_cpu(palive->st_fwrd_size);
173
174 alive_data->valid = le16_to_cpu(palive->status) ==
175 IWL_ALIVE_STATUS_OK;
176 if (mvm->umac_error_event_table)
177 mvm->support_umac_log = true;
178
179 IWL_DEBUG_FW(mvm,
180 "Alive VER3 ucode status 0x%04x revision 0x%01X 0x%01X flags 0x%01X\n",
181 le16_to_cpu(palive->status), palive->ver_type,
182 palive->ver_subtype, palive->flags);
183
184 IWL_DEBUG_FW(mvm,
185 "UMAC version: Major - 0x%x, Minor - 0x%x\n",
186 le32_to_cpu(palive->umac_major),
187 le32_to_cpu(palive->umac_minor));
159 } 188 }
160 189
161 return true; 190 return true;
@@ -188,8 +217,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
188 struct iwl_sf_region st_fwrd_space; 217 struct iwl_sf_region st_fwrd_space;
189 218
190 if (ucode_type == IWL_UCODE_REGULAR && 219 if (ucode_type == IWL_UCODE_REGULAR &&
191 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_CUSTOM) && 220 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE))
192 iwl_fw_dbg_conf_enabled(mvm->fw, FW_DBG_CUSTOM))
193 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER); 221 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
194 else 222 else
195 fw = iwl_get_ucode_image(mvm, ucode_type); 223 fw = iwl_get_ucode_image(mvm, ucode_type);
@@ -451,20 +479,80 @@ exit:
451 iwl_free_resp(&cmd); 479 iwl_free_resp(&cmd);
452} 480}
453 481
454void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm) 482int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
483 struct iwl_mvm_dump_desc *desc,
484 unsigned int delay)
455{ 485{
486 if (test_and_set_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status))
487 return -EBUSY;
488
489 if (WARN_ON(mvm->fw_dump_desc))
490 iwl_mvm_free_fw_dump_desc(mvm);
491
492 IWL_WARN(mvm, "Collecting data: trigger %d fired.\n",
493 le32_to_cpu(desc->trig_desc.type));
494
495 mvm->fw_dump_desc = desc;
496
456 /* stop recording */ 497 /* stop recording */
457 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 498 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
458 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100); 499 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
459 } else { 500 } else {
460 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0); 501 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
461 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0); 502 /* wait before we collect the data till the DBGC stop */
503 udelay(100);
462 } 504 }
463 505
464 schedule_work(&mvm->fw_error_dump_wk); 506 queue_delayed_work(system_wq, &mvm->fw_dump_wk, delay);
507
508 return 0;
465} 509}
466 510
467int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id) 511int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
512 const char *str, size_t len, unsigned int delay)
513{
514 struct iwl_mvm_dump_desc *desc;
515
516 desc = kzalloc(sizeof(*desc) + len, GFP_ATOMIC);
517 if (!desc)
518 return -ENOMEM;
519
520 desc->len = len;
521 desc->trig_desc.type = cpu_to_le32(trig);
522 memcpy(desc->trig_desc.data, str, len);
523
524 return iwl_mvm_fw_dbg_collect_desc(mvm, desc, delay);
525}
526
527int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
528 struct iwl_fw_dbg_trigger_tlv *trigger,
529 const char *str, size_t len)
530{
531 unsigned int delay = msecs_to_jiffies(le32_to_cpu(trigger->stop_delay));
532 u16 occurrences = le16_to_cpu(trigger->occurrences);
533 int ret;
534
535 if (!occurrences)
536 return 0;
537
538 ret = iwl_mvm_fw_dbg_collect(mvm, le32_to_cpu(trigger->id), str,
539 len, delay);
540 if (ret)
541 return ret;
542
543 trigger->occurrences = cpu_to_le16(occurrences - 1);
544 return 0;
545}
546
547static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
548{
549 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
550 iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
551 else
552 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
553}
554
555int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
468{ 556{
469 u8 *ptr; 557 u8 *ptr;
470 int ret; 558 int ret;
@@ -474,6 +562,14 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
474 "Invalid configuration %d\n", conf_id)) 562 "Invalid configuration %d\n", conf_id))
475 return -EINVAL; 563 return -EINVAL;
476 564
565 /* EARLY START - firmware's configuration is hard coded */
566 if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
567 !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
568 conf_id == FW_DBG_START_FROM_ALIVE) {
569 iwl_mvm_restart_early_start(mvm);
570 return 0;
571 }
572
477 if (!mvm->fw->dbg_conf_tlv[conf_id]) 573 if (!mvm->fw->dbg_conf_tlv[conf_id])
478 return -EINVAL; 574 return -EINVAL;
479 575
@@ -583,7 +679,10 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
583 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 679 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
584 680
585 mvm->fw_dbg_conf = FW_DBG_INVALID; 681 mvm->fw_dbg_conf = FW_DBG_INVALID;
586 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM); 682 /* if we have a destination, assume EARLY START */
683 if (mvm->fw->dbg_dest_tlv)
684 mvm->fw_dbg_conf = FW_DBG_START_FROM_ALIVE;
685 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_START_FROM_ALIVE);
587 686
588 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); 687 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
589 if (ret) 688 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 7bdc6220743f..581b3b8f29f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -244,6 +244,7 @@ static void iwl_mvm_mac_sta_hw_queues_iter(void *_data,
244unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, 244unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
245 struct ieee80211_vif *exclude_vif) 245 struct ieee80211_vif *exclude_vif)
246{ 246{
247 u8 sta_id;
247 struct iwl_mvm_hw_queues_iface_iterator_data data = { 248 struct iwl_mvm_hw_queues_iface_iterator_data data = {
248 .exclude_vif = exclude_vif, 249 .exclude_vif = exclude_vif,
249 .used_hw_queues = 250 .used_hw_queues =
@@ -264,6 +265,13 @@ unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
264 iwl_mvm_mac_sta_hw_queues_iter, 265 iwl_mvm_mac_sta_hw_queues_iter,
265 &data); 266 &data);
266 267
268 /*
269 * Some TDLS stations may be removed but are in the process of being
270 * drained. Don't touch their queues.
271 */
272 for_each_set_bit(sta_id, mvm->sta_drained, IWL_MVM_STATION_COUNT)
273 data.used_hw_queues |= mvm->tfd_drained[sta_id];
274
267 return data.used_hw_queues; 275 return data.used_hw_queues;
268} 276}
269 277
@@ -1367,10 +1375,18 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1367{ 1375{
1368 struct iwl_missed_beacons_notif *missed_beacons = _data; 1376 struct iwl_missed_beacons_notif *missed_beacons = _data;
1369 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 1377 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1378 struct iwl_mvm *mvm = mvmvif->mvm;
1379 struct iwl_fw_dbg_trigger_missed_bcon *bcon_trig;
1380 struct iwl_fw_dbg_trigger_tlv *trigger;
1381 u32 stop_trig_missed_bcon, stop_trig_missed_bcon_since_rx;
1382 u32 rx_missed_bcon, rx_missed_bcon_since_rx;
1370 1383
1371 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id)) 1384 if (mvmvif->id != (u16)le32_to_cpu(missed_beacons->mac_id))
1372 return; 1385 return;
1373 1386
1387 rx_missed_bcon = le32_to_cpu(missed_beacons->consec_missed_beacons);
1388 rx_missed_bcon_since_rx =
1389 le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx);
1374 /* 1390 /*
1375 * TODO: the threshold should be adjusted based on latency conditions, 1391 * TODO: the threshold should be adjusted based on latency conditions,
1376 * and/or in case of a CS flow on one of the other AP vifs. 1392 * and/or in case of a CS flow on one of the other AP vifs.
@@ -1378,6 +1394,26 @@ static void iwl_mvm_beacon_loss_iterator(void *_data, u8 *mac,
1378 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) > 1394 if (le32_to_cpu(missed_beacons->consec_missed_beacons_since_last_rx) >
1379 IWL_MVM_MISSED_BEACONS_THRESHOLD) 1395 IWL_MVM_MISSED_BEACONS_THRESHOLD)
1380 ieee80211_beacon_loss(vif); 1396 ieee80211_beacon_loss(vif);
1397
1398 if (!iwl_fw_dbg_trigger_enabled(mvm->fw,
1399 FW_DBG_TRIGGER_MISSED_BEACONS))
1400 return;
1401
1402 trigger = iwl_fw_dbg_get_trigger(mvm->fw,
1403 FW_DBG_TRIGGER_MISSED_BEACONS);
1404 bcon_trig = (void *)trigger->data;
1405 stop_trig_missed_bcon = le32_to_cpu(bcon_trig->stop_consec_missed_bcon);
1406 stop_trig_missed_bcon_since_rx =
1407 le32_to_cpu(bcon_trig->stop_consec_missed_bcon_since_rx);
1408
1409 /* TODO: implement start trigger */
1410
1411 if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
1412 return;
1413
1414 if (rx_missed_bcon_since_rx >= stop_trig_missed_bcon_since_rx ||
1415 rx_missed_bcon >= stop_trig_missed_bcon)
1416 iwl_mvm_fw_dbg_collect_trig(mvm, trigger, NULL, 0);
1381} 1417}
1382 1418
1383int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm, 1419int iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 1ff7ec08532d..5a5d5c8544fc 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -339,13 +339,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
339 !iwlwifi_mod_params.sw_crypto) 339 !iwlwifi_mod_params.sw_crypto)
340 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 340 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
341 341
342 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || 342 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
343 mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 343 hw->wiphy->features |=
344 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; 344 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
345 hw->wiphy->features |= 345 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
346 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
347 NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
348 }
349 346
350 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 347 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
351 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 348 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
@@ -889,12 +886,23 @@ static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
889 iwl_trans_release_nic_access(mvm->trans, &flags); 886 iwl_trans_release_nic_access(mvm->trans, &flags);
890} 887}
891 888
889void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm)
890{
891 if (mvm->fw_dump_desc == &iwl_mvm_dump_desc_assert ||
892 !mvm->fw_dump_desc)
893 return;
894
895 kfree(mvm->fw_dump_desc);
896 mvm->fw_dump_desc = NULL;
897}
898
892void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 899void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
893{ 900{
894 struct iwl_fw_error_dump_file *dump_file; 901 struct iwl_fw_error_dump_file *dump_file;
895 struct iwl_fw_error_dump_data *dump_data; 902 struct iwl_fw_error_dump_data *dump_data;
896 struct iwl_fw_error_dump_info *dump_info; 903 struct iwl_fw_error_dump_info *dump_info;
897 struct iwl_fw_error_dump_mem *dump_mem; 904 struct iwl_fw_error_dump_mem *dump_mem;
905 struct iwl_fw_error_dump_trigger_desc *dump_trig;
898 struct iwl_mvm_dump_ptrs *fw_error_dump; 906 struct iwl_mvm_dump_ptrs *fw_error_dump;
899 u32 sram_len, sram_ofs; 907 u32 sram_len, sram_ofs;
900 u32 file_len, fifo_data_len = 0; 908 u32 file_len, fifo_data_len = 0;
@@ -964,6 +972,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
964 fifo_data_len + 972 fifo_data_len +
965 sizeof(*dump_info); 973 sizeof(*dump_info);
966 974
975 if (mvm->fw_dump_desc)
976 file_len += sizeof(*dump_data) + sizeof(*dump_trig) +
977 mvm->fw_dump_desc->len;
978
967 /* Make room for the SMEM, if it exists */ 979 /* Make room for the SMEM, if it exists */
968 if (smem_len) 980 if (smem_len)
969 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len; 981 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
@@ -975,6 +987,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
975 dump_file = vzalloc(file_len); 987 dump_file = vzalloc(file_len);
976 if (!dump_file) { 988 if (!dump_file) {
977 kfree(fw_error_dump); 989 kfree(fw_error_dump);
990 iwl_mvm_free_fw_dump_desc(mvm);
978 return; 991 return;
979 } 992 }
980 993
@@ -1003,6 +1016,19 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
1003 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) 1016 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status))
1004 iwl_mvm_dump_fifos(mvm, &dump_data); 1017 iwl_mvm_dump_fifos(mvm, &dump_data);
1005 1018
1019 if (mvm->fw_dump_desc) {
1020 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_ERROR_INFO);
1021 dump_data->len = cpu_to_le32(sizeof(*dump_trig) +
1022 mvm->fw_dump_desc->len);
1023 dump_trig = (void *)dump_data->data;
1024 memcpy(dump_trig, &mvm->fw_dump_desc->trig_desc,
1025 sizeof(*dump_trig) + mvm->fw_dump_desc->len);
1026
1027 /* now we can free this copy */
1028 iwl_mvm_free_fw_dump_desc(mvm);
1029 dump_data = iwl_fw_error_next_data(dump_data);
1030 }
1031
1006 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); 1032 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
1007 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); 1033 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
1008 dump_mem = (void *)dump_data->data; 1034 dump_mem = (void *)dump_data->data;
@@ -1041,16 +1067,26 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
1041 1067
1042 dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0, 1068 dev_coredumpm(mvm->trans->dev, THIS_MODULE, fw_error_dump, 0,
1043 GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump); 1069 GFP_KERNEL, iwl_mvm_read_coredump, iwl_mvm_free_coredump);
1070
1071 clear_bit(IWL_MVM_STATUS_DUMPING_FW_LOG, &mvm->status);
1044} 1072}
1045 1073
1074struct iwl_mvm_dump_desc iwl_mvm_dump_desc_assert = {
1075 .trig_desc = {
1076 .type = cpu_to_le32(FW_DBG_TRIGGER_FW_ASSERT),
1077 },
1078};
1079
1046static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 1080static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1047{ 1081{
1048 /* clear the D3 reconfig, we only need it to avoid dumping a 1082 /* clear the D3 reconfig, we only need it to avoid dumping a
1049 * firmware coredump on reconfiguration, we shouldn't do that 1083 * firmware coredump on reconfiguration, we shouldn't do that
1050 * on D3->D0 transition 1084 * on D3->D0 transition
1051 */ 1085 */
1052 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) 1086 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) {
1087 mvm->fw_dump_desc = &iwl_mvm_dump_desc_assert;
1053 iwl_mvm_fw_error_dump(mvm); 1088 iwl_mvm_fw_error_dump(mvm);
1089 }
1054 1090
1055 /* cleanup all stale references (scan, roc), but keep the 1091 /* cleanup all stale references (scan, roc), but keep the
1056 * ucode_down ref until reconfig is complete 1092 * ucode_down ref until reconfig is complete
@@ -1091,6 +1127,10 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
1091 1127
1092 mvm->vif_count = 0; 1128 mvm->vif_count = 0;
1093 mvm->rx_ba_sessions = 0; 1129 mvm->rx_ba_sessions = 0;
1130 mvm->fw_dbg_conf = FW_DBG_INVALID;
1131
1132 /* keep statistics ticking */
1133 iwl_mvm_accu_radio_stats(mvm);
1094} 1134}
1095 1135
1096int __iwl_mvm_mac_start(struct iwl_mvm *mvm) 1136int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
@@ -1213,6 +1253,11 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
1213{ 1253{
1214 lockdep_assert_held(&mvm->mutex); 1254 lockdep_assert_held(&mvm->mutex);
1215 1255
1256 /* firmware counters are obviously reset now, but we shouldn't
1257 * partially track so also clear the fw_reset_accu counters.
1258 */
1259 memset(&mvm->accu_radio_stats, 0, sizeof(mvm->accu_radio_stats));
1260
1216 /* 1261 /*
1217 * Disallow low power states when the FW is down by taking 1262 * Disallow low power states when the FW is down by taking
1218 * the UCODE_DOWN ref. in case of ongoing hw restart the 1263 * the UCODE_DOWN ref. in case of ongoing hw restart the
@@ -1252,7 +1297,8 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
1252 1297
1253 flush_work(&mvm->d0i3_exit_work); 1298 flush_work(&mvm->d0i3_exit_work);
1254 flush_work(&mvm->async_handlers_wk); 1299 flush_work(&mvm->async_handlers_wk);
1255 flush_work(&mvm->fw_error_dump_wk); 1300 cancel_delayed_work_sync(&mvm->fw_dump_wk);
1301 iwl_mvm_free_fw_dump_desc(mvm);
1256 1302
1257 mutex_lock(&mvm->mutex); 1303 mutex_lock(&mvm->mutex);
1258 __iwl_mvm_mac_stop(mvm); 1304 __iwl_mvm_mac_stop(mvm);
@@ -1317,6 +1363,11 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1317 1363
1318 mutex_lock(&mvm->mutex); 1364 mutex_lock(&mvm->mutex);
1319 1365
1366 /* make sure that beacon statistics don't go backwards with FW reset */
1367 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
1368 mvmvif->beacon_stats.accu_num_beacons +=
1369 mvmvif->beacon_stats.num_beacons;
1370
1320 /* Allocate resources for the MAC context, and add it to the fw */ 1371 /* Allocate resources for the MAC context, and add it to the fw */
1321 ret = iwl_mvm_mac_ctxt_init(mvm, vif); 1372 ret = iwl_mvm_mac_ctxt_init(mvm, vif);
1322 if (ret) 1373 if (ret)
@@ -1810,6 +1861,11 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1810 1861
1811 if (changes & BSS_CHANGED_ASSOC) { 1862 if (changes & BSS_CHANGED_ASSOC) {
1812 if (bss_conf->assoc) { 1863 if (bss_conf->assoc) {
1864 /* clear statistics to get clean beacon counter */
1865 iwl_mvm_request_statistics(mvm, true);
1866 memset(&mvmvif->beacon_stats, 0,
1867 sizeof(mvmvif->beacon_stats));
1868
1813 /* add quota for this interface */ 1869 /* add quota for this interface */
1814 ret = iwl_mvm_update_quotas(mvm, NULL); 1870 ret = iwl_mvm_update_quotas(mvm, NULL);
1815 if (ret) { 1871 if (ret) {
@@ -2196,10 +2252,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2196 2252
2197 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) 2253 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN)
2198 ret = iwl_mvm_scan_umac(mvm, vif, hw_req); 2254 ret = iwl_mvm_scan_umac(mvm, vif, hw_req);
2199 else if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
2200 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2201 else 2255 else
2202 ret = iwl_mvm_scan_request(mvm, vif, req); 2256 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
2203 2257
2204 if (ret) 2258 if (ret)
2205 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 2259 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
@@ -2527,13 +2581,7 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2527 2581
2528 mutex_lock(&mvm->mutex); 2582 mutex_lock(&mvm->mutex);
2529 2583
2530 /* Newest FW fixes sched scan while connected on another interface */ 2584 if (!vif->bss_conf.idle) {
2531 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
2532 if (!vif->bss_conf.idle) {
2533 ret = -EBUSY;
2534 goto out;
2535 }
2536 } else if (!iwl_mvm_is_idle(mvm)) {
2537 ret = -EBUSY; 2585 ret = -EBUSY;
2538 goto out; 2586 goto out;
2539 } 2587 }
@@ -3433,6 +3481,9 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
3433 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n", 3481 IWL_DEBUG_MAC80211(mvm, "pre CSA to freq %d\n",
3434 chsw->chandef.center_freq1); 3482 chsw->chandef.center_freq1);
3435 3483
3484 iwl_fw_dbg_trigger_simple_stop(mvm, vif, FW_DBG_TRIGGER_CHANNEL_SWITCH,
3485 NULL, 0);
3486
3436 switch (vif->type) { 3487 switch (vif->type) {
3437 case NL80211_IFTYPE_AP: 3488 case NL80211_IFTYPE_AP:
3438 csa_vif = 3489 csa_vif =
@@ -3581,6 +3632,95 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
3581 } 3632 }
3582} 3633}
3583 3634
3635static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx,
3636 struct survey_info *survey)
3637{
3638 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3639 int ret;
3640
3641 memset(survey, 0, sizeof(*survey));
3642
3643 /* only support global statistics right now */
3644 if (idx != 0)
3645 return -ENOENT;
3646
3647 if (!(mvm->fw->ucode_capa.capa[0] &
3648 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
3649 return -ENOENT;
3650
3651 mutex_lock(&mvm->mutex);
3652
3653 if (mvm->ucode_loaded) {
3654 ret = iwl_mvm_request_statistics(mvm, false);
3655 if (ret)
3656 goto out;
3657 }
3658
3659 survey->filled = SURVEY_INFO_TIME |
3660 SURVEY_INFO_TIME_RX |
3661 SURVEY_INFO_TIME_TX |
3662 SURVEY_INFO_TIME_SCAN;
3663 survey->time = mvm->accu_radio_stats.on_time_rf +
3664 mvm->radio_stats.on_time_rf;
3665 do_div(survey->time, USEC_PER_MSEC);
3666
3667 survey->time_rx = mvm->accu_radio_stats.rx_time +
3668 mvm->radio_stats.rx_time;
3669 do_div(survey->time_rx, USEC_PER_MSEC);
3670
3671 survey->time_tx = mvm->accu_radio_stats.tx_time +
3672 mvm->radio_stats.tx_time;
3673 do_div(survey->time_tx, USEC_PER_MSEC);
3674
3675 survey->time_scan = mvm->accu_radio_stats.on_time_scan +
3676 mvm->radio_stats.on_time_scan;
3677 do_div(survey->time_scan, USEC_PER_MSEC);
3678
3679 out:
3680 mutex_unlock(&mvm->mutex);
3681 return ret;
3682}
3683
3684static void iwl_mvm_mac_sta_statistics(struct ieee80211_hw *hw,
3685 struct ieee80211_vif *vif,
3686 struct ieee80211_sta *sta,
3687 struct station_info *sinfo)
3688{
3689 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3690 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3691 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3692
3693 if (!(mvm->fw->ucode_capa.capa[0] &
3694 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS))
3695 return;
3696
3697 /* if beacon filtering isn't on mac80211 does it anyway */
3698 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
3699 return;
3700
3701 if (!vif->bss_conf.assoc)
3702 return;
3703
3704 mutex_lock(&mvm->mutex);
3705
3706 if (mvmvif->ap_sta_id != mvmsta->sta_id)
3707 goto unlock;
3708
3709 if (iwl_mvm_request_statistics(mvm, false))
3710 goto unlock;
3711
3712 sinfo->rx_beacon = mvmvif->beacon_stats.num_beacons +
3713 mvmvif->beacon_stats.accu_num_beacons;
3714 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_RX);
3715 if (mvmvif->beacon_stats.avg_signal) {
3716 /* firmware only reports a value after RXing a few beacons */
3717 sinfo->rx_beacon_signal_avg = mvmvif->beacon_stats.avg_signal;
3718 sinfo->filled |= BIT(NL80211_STA_INFO_BEACON_SIGNAL_AVG);
3719 }
3720 unlock:
3721 mutex_unlock(&mvm->mutex);
3722}
3723
3584const struct ieee80211_ops iwl_mvm_hw_ops = { 3724const struct ieee80211_ops iwl_mvm_hw_ops = {
3585 .tx = iwl_mvm_mac_tx, 3725 .tx = iwl_mvm_mac_tx,
3586 .ampdu_action = iwl_mvm_mac_ampdu_action, 3726 .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -3647,4 +3787,6 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
3647#endif 3787#endif
3648 .set_default_unicast_key = iwl_mvm_set_default_unicast_key, 3788 .set_default_unicast_key = iwl_mvm_set_default_unicast_key,
3649#endif 3789#endif
3790 .get_survey = iwl_mvm_mac_get_survey,
3791 .sta_statistics = iwl_mvm_mac_sta_statistics,
3650}; 3792};
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 6c69d0584f6c..f4ecd1bde1cf 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -75,6 +75,7 @@
75#include "iwl-trans.h" 75#include "iwl-trans.h"
76#include "iwl-notif-wait.h" 76#include "iwl-notif-wait.h"
77#include "iwl-eeprom-parse.h" 77#include "iwl-eeprom-parse.h"
78#include "iwl-fw-file.h"
78#include "sta.h" 79#include "sta.h"
79#include "fw-api.h" 80#include "fw-api.h"
80#include "constants.h" 81#include "constants.h"
@@ -145,6 +146,19 @@ struct iwl_mvm_dump_ptrs {
145 u32 op_mode_len; 146 u32 op_mode_len;
146}; 147};
147 148
149/**
150 * struct iwl_mvm_dump_desc - describes the dump
151 * @len: length of trig_desc->data
152 * @trig_desc: the description of the dump
153 */
154struct iwl_mvm_dump_desc {
155 size_t len;
156 /* must be last */
157 struct iwl_fw_error_dump_trigger_desc trig_desc;
158};
159
160extern struct iwl_mvm_dump_desc iwl_mvm_dump_desc_assert;
161
148struct iwl_mvm_phy_ctxt { 162struct iwl_mvm_phy_ctxt {
149 u16 id; 163 u16 id;
150 u16 color; 164 u16 color;
@@ -337,6 +351,9 @@ struct iwl_mvm_vif_bf_data {
337 * @beacon_skb: the skb used to hold the AP/GO beacon template 351 * @beacon_skb: the skb used to hold the AP/GO beacon template
338 * @smps_requests: the SMPS requests of differents parts of the driver, 352 * @smps_requests: the SMPS requests of differents parts of the driver,
339 * combined on update to yield the overall request to mac80211. 353 * combined on update to yield the overall request to mac80211.
354 * @beacon_stats: beacon statistics, containing the # of received beacons,
355 * # of received beacons accumulated over FW restart, and the current
356 * average signal of beacons retrieved from the firmware
340 */ 357 */
341struct iwl_mvm_vif { 358struct iwl_mvm_vif {
342 u16 id; 359 u16 id;
@@ -354,6 +371,11 @@ struct iwl_mvm_vif {
354 bool ps_disabled; 371 bool ps_disabled;
355 struct iwl_mvm_vif_bf_data bf_data; 372 struct iwl_mvm_vif_bf_data bf_data;
356 373
374 struct {
375 u32 num_beacons, accu_num_beacons;
376 u8 avg_signal;
377 } beacon_stats;
378
357 u32 ap_beacon_time; 379 u32 ap_beacon_time;
358 380
359 enum iwl_tsf_id tsf_id; 381 enum iwl_tsf_id tsf_id;
@@ -593,6 +615,13 @@ struct iwl_mvm {
593 615
594 struct mvm_statistics_rx rx_stats; 616 struct mvm_statistics_rx rx_stats;
595 617
618 struct {
619 u64 rx_time;
620 u64 tx_time;
621 u64 on_time_rf;
622 u64 on_time_scan;
623 } radio_stats, accu_radio_stats;
624
596 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES]; 625 u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
597 atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES]; 626 atomic_t mac80211_queue_stop_count[IEEE80211_MAX_QUEUES];
598 627
@@ -666,6 +695,7 @@ struct iwl_mvm {
666 695
667 struct iwl_mvm_frame_stats drv_rx_stats; 696 struct iwl_mvm_frame_stats drv_rx_stats;
668 spinlock_t drv_stats_lock; 697 spinlock_t drv_stats_lock;
698 u16 dbgfs_rx_phyinfo;
669#endif 699#endif
670 700
671 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; 701 struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX];
@@ -687,8 +717,9 @@ struct iwl_mvm {
687 717
688 /* -1 for always, 0 for never, >0 for that many times */ 718 /* -1 for always, 0 for never, >0 for that many times */
689 s8 restart_fw; 719 s8 restart_fw;
690 struct work_struct fw_error_dump_wk; 720 u8 fw_dbg_conf;
691 enum iwl_fw_dbg_conf fw_dbg_conf; 721 struct delayed_work fw_dump_wk;
722 struct iwl_mvm_dump_desc *fw_dump_desc;
692 723
693#ifdef CONFIG_IWLWIFI_LEDS 724#ifdef CONFIG_IWLWIFI_LEDS
694 struct led_classdev led; 725 struct led_classdev led;
@@ -824,6 +855,7 @@ enum iwl_mvm_status {
824 IWL_MVM_STATUS_IN_D0I3, 855 IWL_MVM_STATUS_IN_D0I3,
825 IWL_MVM_STATUS_ROC_AUX_RUNNING, 856 IWL_MVM_STATUS_ROC_AUX_RUNNING,
826 IWL_MVM_STATUS_D3_RECONFIG, 857 IWL_MVM_STATUS_D3_RECONFIG,
858 IWL_MVM_STATUS_DUMPING_FW_LOG,
827}; 859};
828 860
829static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm) 861static inline bool iwl_mvm_is_radio_killed(struct iwl_mvm *mvm)
@@ -883,6 +915,12 @@ static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
883 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG; 915 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG;
884} 916}
885 917
918static inline bool iwl_mvm_bt_is_plcr_supported(struct iwl_mvm *mvm)
919{
920 return (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BT_COEX_PLCR) &&
921 IWL_MVM_BT_COEX_CORUNNING;
922}
923
886extern const u8 iwl_mvm_ac_to_tx_fifo[]; 924extern const u8 iwl_mvm_ac_to_tx_fifo[];
887 925
888struct iwl_rate_info { 926struct iwl_rate_info {
@@ -951,12 +989,13 @@ static inline void iwl_mvm_wait_for_async_handlers(struct iwl_mvm *mvm)
951} 989}
952 990
953/* Statistics */ 991/* Statistics */
954int iwl_mvm_rx_reply_statistics(struct iwl_mvm *mvm, 992void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
955 struct iwl_rx_cmd_buffer *rxb, 993 struct iwl_rx_packet *pkt);
956 struct iwl_device_cmd *cmd);
957int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, 994int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
958 struct iwl_rx_cmd_buffer *rxb, 995 struct iwl_rx_cmd_buffer *rxb,
959 struct iwl_device_cmd *cmd); 996 struct iwl_device_cmd *cmd);
997int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear);
998void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm);
960 999
961/* NVM */ 1000/* NVM */
962int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); 1001int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
@@ -1072,13 +1111,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
1072 1111
1073/* Scanning */ 1112/* Scanning */
1074int iwl_mvm_scan_size(struct iwl_mvm *mvm); 1113int iwl_mvm_scan_size(struct iwl_mvm *mvm);
1075int iwl_mvm_scan_request(struct iwl_mvm *mvm,
1076 struct ieee80211_vif *vif,
1077 struct cfg80211_scan_request *req);
1078int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1079 struct iwl_device_cmd *cmd);
1080int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1081 struct iwl_device_cmd *cmd);
1082int iwl_mvm_cancel_scan(struct iwl_mvm *mvm); 1114int iwl_mvm_cancel_scan(struct iwl_mvm *mvm);
1083int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan); 1115int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);
1084 1116
@@ -1089,14 +1121,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
1089int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 1121int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
1090 struct iwl_rx_cmd_buffer *rxb, 1122 struct iwl_rx_cmd_buffer *rxb,
1091 struct iwl_device_cmd *cmd); 1123 struct iwl_device_cmd *cmd);
1092int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
1093 struct ieee80211_vif *vif,
1094 struct cfg80211_sched_scan_request *req,
1095 struct ieee80211_scan_ies *ies);
1096int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 1124int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
1097 struct cfg80211_sched_scan_request *req); 1125 struct cfg80211_sched_scan_request *req);
1098int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1099 struct cfg80211_sched_scan_request *req);
1100int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 1126int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1101 struct ieee80211_vif *vif, 1127 struct ieee80211_vif *vif,
1102 struct cfg80211_sched_scan_request *req, 1128 struct cfg80211_sched_scan_request *req,
@@ -1238,7 +1264,6 @@ bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
1238u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, 1264u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
1239 struct ieee80211_tx_info *info, u8 ac); 1265 struct ieee80211_tx_info *info, u8 ac);
1240 1266
1241bool iwl_mvm_bt_coex_is_ant_avail_old(struct iwl_mvm *mvm, u8 ant);
1242bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm); 1267bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm);
1243void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm); 1268void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm);
1244int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm); 1269int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm);
@@ -1352,9 +1377,6 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1352 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout); 1377 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1353} 1378}
1354 1379
1355/* Assoc status */
1356bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
1357
1358/* Thermal management and CT-kill */ 1380/* Thermal management and CT-kill */
1359void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1381void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1360void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); 1382void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
@@ -1405,7 +1427,62 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
1405void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); 1427void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1406void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); 1428void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
1407 1429
1408int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id); 1430int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 id);
1409void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm); 1431int iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm, enum iwl_fw_dbg_trigger trig,
1432 const char *str, size_t len, unsigned int delay);
1433int iwl_mvm_fw_dbg_collect_desc(struct iwl_mvm *mvm,
1434 struct iwl_mvm_dump_desc *desc,
1435 unsigned int delay);
1436void iwl_mvm_free_fw_dump_desc(struct iwl_mvm *mvm);
1437int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
1438 struct iwl_fw_dbg_trigger_tlv *trigger,
1439 const char *str, size_t len);
1440
1441static inline bool
1442iwl_fw_dbg_trigger_vif_match(struct iwl_fw_dbg_trigger_tlv *trig,
1443 struct ieee80211_vif *vif)
1444{
1445 u32 trig_vif = le32_to_cpu(trig->vif_type);
1446
1447 return trig_vif == IWL_FW_DBG_CONF_VIF_ANY || vif->type == trig_vif;
1448}
1449
1450static inline bool
1451iwl_fw_dbg_trigger_stop_conf_match(struct iwl_mvm *mvm,
1452 struct iwl_fw_dbg_trigger_tlv *trig)
1453{
1454 return ((trig->mode & IWL_FW_DBG_TRIGGER_STOP) &&
1455 (mvm->fw_dbg_conf == FW_DBG_INVALID ||
1456 (BIT(mvm->fw_dbg_conf) & le32_to_cpu(trig->stop_conf_ids))));
1457}
1458
1459static inline bool
1460iwl_fw_dbg_trigger_check_stop(struct iwl_mvm *mvm,
1461 struct ieee80211_vif *vif,
1462 struct iwl_fw_dbg_trigger_tlv *trig)
1463{
1464 if (vif && !iwl_fw_dbg_trigger_vif_match(trig, vif))
1465 return false;
1466
1467 return iwl_fw_dbg_trigger_stop_conf_match(mvm, trig);
1468}
1469
1470static inline void
1471iwl_fw_dbg_trigger_simple_stop(struct iwl_mvm *mvm,
1472 struct ieee80211_vif *vif,
1473 enum iwl_fw_dbg_trigger trig,
1474 const char *str, size_t len)
1475{
1476 struct iwl_fw_dbg_trigger_tlv *trigger;
1477
1478 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, trig))
1479 return;
1480
1481 trigger = iwl_fw_dbg_get_trigger(mvm->fw, trig);
1482 if (!iwl_fw_dbg_trigger_check_stop(mvm, vif, trigger))
1483 return;
1484
1485 iwl_mvm_fw_dbg_collect_trig(mvm, trigger, str, len);
1486}
1410 1487
1411#endif /* __IWL_MVM_H__ */ 1488#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 2dffc3600ed3..fe40922a6b0d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -237,8 +237,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
237 237
238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), 238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
239 239
240 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
241 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
242 RX_HANDLER(SCAN_ITERATION_COMPLETE, 240 RX_HANDLER(SCAN_ITERATION_COMPLETE,
243 iwl_mvm_rx_scan_offload_iter_complete_notif, false), 241 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
244 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 242 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
@@ -311,6 +309,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
311 CMD(REPLY_RX_MPDU_CMD), 309 CMD(REPLY_RX_MPDU_CMD),
312 CMD(BEACON_NOTIFICATION), 310 CMD(BEACON_NOTIFICATION),
313 CMD(BEACON_TEMPLATE_CMD), 311 CMD(BEACON_TEMPLATE_CMD),
312 CMD(STATISTICS_CMD),
314 CMD(STATISTICS_NOTIFICATION), 313 CMD(STATISTICS_NOTIFICATION),
315 CMD(EOSP_NOTIFICATION), 314 CMD(EOSP_NOTIFICATION),
316 CMD(REDUCE_TX_POWER_CMD), 315 CMD(REDUCE_TX_POWER_CMD),
@@ -456,7 +455,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
456 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); 455 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
457 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); 456 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
458 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); 457 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
459 INIT_WORK(&mvm->fw_error_dump_wk, iwl_mvm_fw_error_dump_wk); 458 INIT_DELAYED_WORK(&mvm->fw_dump_wk, iwl_mvm_fw_error_dump_wk);
460 INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work); 459 INIT_DELAYED_WORK(&mvm->tdls_cs.dwork, iwl_mvm_tdls_ch_switch_work);
461 460
462 spin_lock_init(&mvm->d0i3_tx_lock); 461 spin_lock_init(&mvm->d0i3_tx_lock);
@@ -504,6 +503,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
504 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num; 503 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
505 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv, 504 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
506 sizeof(trans->dbg_conf_tlv)); 505 sizeof(trans->dbg_conf_tlv));
506 trans->dbg_trigger_tlv = mvm->fw->dbg_trigger_tlv;
507 507
508 /* set up notification wait support */ 508 /* set up notification wait support */
509 iwl_notification_wait_init(&mvm->notif_wait); 509 iwl_notification_wait_init(&mvm->notif_wait);
@@ -685,6 +685,38 @@ static void iwl_mvm_async_handlers_wk(struct work_struct *wk)
685 mutex_unlock(&mvm->mutex); 685 mutex_unlock(&mvm->mutex);
686} 686}
687 687
688static inline void iwl_mvm_rx_check_trigger(struct iwl_mvm *mvm,
689 struct iwl_rx_packet *pkt)
690{
691 struct iwl_fw_dbg_trigger_tlv *trig;
692 struct iwl_fw_dbg_trigger_cmd *cmds_trig;
693 char buf[32];
694 int i;
695
696 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF))
697 return;
698
699 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_FW_NOTIF);
700 cmds_trig = (void *)trig->data;
701
702 if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
703 return;
704
705 for (i = 0; i < ARRAY_SIZE(cmds_trig->cmds); i++) {
706 /* don't collect on CMD 0 */
707 if (!cmds_trig->cmds[i].cmd_id)
708 break;
709
710 if (cmds_trig->cmds[i].cmd_id != pkt->hdr.cmd)
711 continue;
712
713 memset(buf, 0, sizeof(buf));
714 snprintf(buf, sizeof(buf), "CMD 0x%02x received", pkt->hdr.cmd);
715 iwl_mvm_fw_dbg_collect_trig(mvm, trig, buf, sizeof(buf));
716 break;
717 }
718}
719
688static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode, 720static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
689 struct iwl_rx_cmd_buffer *rxb, 721 struct iwl_rx_cmd_buffer *rxb,
690 struct iwl_device_cmd *cmd) 722 struct iwl_device_cmd *cmd)
@@ -693,6 +725,8 @@ static int iwl_mvm_rx_dispatch(struct iwl_op_mode *op_mode,
693 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 725 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
694 u8 i; 726 u8 i;
695 727
728 iwl_mvm_rx_check_trigger(mvm, pkt);
729
696 /* 730 /*
697 * Do the notification wait before RX handlers so 731 * Do the notification wait before RX handlers so
698 * even if the RX handler consumes the RXB we have 732 * even if the RX handler consumes the RXB we have
@@ -827,7 +861,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
827static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) 861static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
828{ 862{
829 struct iwl_mvm *mvm = 863 struct iwl_mvm *mvm =
830 container_of(work, struct iwl_mvm, fw_error_dump_wk); 864 container_of(work, struct iwl_mvm, fw_dump_wk.work);
831 865
832 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT)) 866 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
833 return; 867 return;
@@ -879,7 +913,7 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
879 * can't recover this since we're already half suspended. 913 * can't recover this since we're already half suspended.
880 */ 914 */
881 if (!mvm->restart_fw && fw_error) { 915 if (!mvm->restart_fw && fw_error) {
882 schedule_work(&mvm->fw_error_dump_wk); 916 iwl_mvm_fw_dbg_collect_desc(mvm, &iwl_mvm_dump_desc_assert, 0);
883 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, 917 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
884 &mvm->status)) { 918 &mvm->status)) {
885 struct iwl_mvm_reprobe *reprobe; 919 struct iwl_mvm_reprobe *reprobe;
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 5b43616eeb06..1bd10eda01f9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -175,6 +175,8 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
176 cmd->rxchain_info |= cpu_to_le32(active_cnt << 176 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
177 PHY_RX_CHAIN_MIMO_CNT_POS); 177 PHY_RX_CHAIN_MIMO_CNT_POS);
178 if (unlikely(mvm->dbgfs_rx_phyinfo))
179 cmd->rxchain_info = cpu_to_le32(mvm->dbgfs_rx_phyinfo);
178 180
179 cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm)); 181 cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
180} 182}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 194bd1f939ca..6578498dd5af 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -134,9 +134,12 @@ enum rs_column_mode {
134#define MAX_NEXT_COLUMNS 7 134#define MAX_NEXT_COLUMNS 7
135#define MAX_COLUMN_CHECKS 3 135#define MAX_COLUMN_CHECKS 3
136 136
137struct rs_tx_column;
138
137typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, 139typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm,
138 struct ieee80211_sta *sta, 140 struct ieee80211_sta *sta,
139 struct iwl_scale_tbl_info *tbl); 141 struct iwl_scale_tbl_info *tbl,
142 const struct rs_tx_column *next_col);
140 143
141struct rs_tx_column { 144struct rs_tx_column {
142 enum rs_column_mode mode; 145 enum rs_column_mode mode;
@@ -147,14 +150,19 @@ struct rs_tx_column {
147}; 150};
148 151
149static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 152static bool rs_ant_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
150 struct iwl_scale_tbl_info *tbl) 153 struct iwl_scale_tbl_info *tbl,
154 const struct rs_tx_column *next_col)
151{ 155{
152 return iwl_mvm_bt_coex_is_ant_avail(mvm, tbl->rate.ant); 156 return iwl_mvm_bt_coex_is_ant_avail(mvm, next_col->ant);
153} 157}
154 158
155static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 159static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
156 struct iwl_scale_tbl_info *tbl) 160 struct iwl_scale_tbl_info *tbl,
161 const struct rs_tx_column *next_col)
157{ 162{
163 struct iwl_mvm_sta *mvmsta;
164 struct iwl_mvm_vif *mvmvif;
165
158 if (!sta->ht_cap.ht_supported) 166 if (!sta->ht_cap.ht_supported)
159 return false; 167 return false;
160 168
@@ -167,11 +175,17 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
167 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 175 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
168 return false; 176 return false;
169 177
178 mvmsta = iwl_mvm_sta_from_mac80211(sta);
179 mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
180 if (iwl_mvm_vif_low_latency(mvmvif) && mvmsta->vif->p2p)
181 return false;
182
170 return true; 183 return true;
171} 184}
172 185
173static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 186static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
174 struct iwl_scale_tbl_info *tbl) 187 struct iwl_scale_tbl_info *tbl,
188 const struct rs_tx_column *next_col)
175{ 189{
176 if (!sta->ht_cap.ht_supported) 190 if (!sta->ht_cap.ht_supported)
177 return false; 191 return false;
@@ -180,7 +194,8 @@ static bool rs_siso_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
180} 194}
181 195
182static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 196static bool rs_sgi_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
183 struct iwl_scale_tbl_info *tbl) 197 struct iwl_scale_tbl_info *tbl,
198 const struct rs_tx_column *next_col)
184{ 199{
185 struct rs_rate *rate = &tbl->rate; 200 struct rs_rate *rate = &tbl->rate;
186 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 201 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
@@ -800,6 +815,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
800 rate->ldpc = true; 815 rate->ldpc = true;
801 if (ucode_rate & RATE_MCS_VHT_STBC_MSK) 816 if (ucode_rate & RATE_MCS_VHT_STBC_MSK)
802 rate->stbc = true; 817 rate->stbc = true;
818 if (ucode_rate & RATE_MCS_BF_MSK)
819 rate->bfer = true;
803 820
804 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; 821 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
805 822
@@ -809,7 +826,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
809 826
810 if (nss == 1) { 827 if (nss == 1) {
811 rate->type = LQ_HT_SISO; 828 rate->type = LQ_HT_SISO;
812 WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); 829 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,
830 "stbc %d bfer %d",
831 rate->stbc, rate->bfer);
813 } else if (nss == 2) { 832 } else if (nss == 2) {
814 rate->type = LQ_HT_MIMO2; 833 rate->type = LQ_HT_MIMO2;
815 WARN_ON_ONCE(num_of_ant != 2); 834 WARN_ON_ONCE(num_of_ant != 2);
@@ -822,7 +841,9 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
822 841
823 if (nss == 1) { 842 if (nss == 1) {
824 rate->type = LQ_VHT_SISO; 843 rate->type = LQ_VHT_SISO;
825 WARN_ON_ONCE(!rate->stbc && num_of_ant != 1); 844 WARN_ONCE(!rate->stbc && !rate->bfer && num_of_ant != 1,
845 "stbc %d bfer %d",
846 rate->stbc, rate->bfer);
826 } else if (nss == 2) { 847 } else if (nss == 2) {
827 rate->type = LQ_VHT_MIMO2; 848 rate->type = LQ_VHT_MIMO2;
828 WARN_ON_ONCE(num_of_ant != 2); 849 WARN_ON_ONCE(num_of_ant != 2);
@@ -1001,13 +1022,41 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
1001 rs_get_lower_rate_in_column(lq_sta, rate); 1022 rs_get_lower_rate_in_column(lq_sta, rate);
1002} 1023}
1003 1024
1004/* Simple function to compare two rate scale table types */ 1025/* Check if both rates are identical
1005static inline bool rs_rate_match(struct rs_rate *a, 1026 * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B
1006 struct rs_rate *b) 1027 * with a rate indicating STBC/BFER and ANT_AB.
1028 */
1029static inline bool rs_rate_equal(struct rs_rate *a,
1030 struct rs_rate *b,
1031 bool allow_ant_mismatch)
1032
1033{
1034 bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) &&
1035 (a->bfer == b->bfer);
1036
1037 if (allow_ant_mismatch) {
1038 if (a->stbc || a->bfer) {
1039 WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d",
1040 a->stbc, a->bfer, a->ant);
1041 ant_match |= (b->ant == ANT_A || b->ant == ANT_B);
1042 } else if (b->stbc || b->bfer) {
1043 WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d",
1044 b->stbc, b->bfer, b->ant);
1045 ant_match |= (a->ant == ANT_A || a->ant == ANT_B);
1046 }
1047 }
1048
1049 return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) &&
1050 (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match;
1051}
1052
1053/* Check if both rates share the same column */
1054static inline bool rs_rate_column_match(struct rs_rate *a,
1055 struct rs_rate *b)
1007{ 1056{
1008 bool ant_match; 1057 bool ant_match;
1009 1058
1010 if (a->stbc) 1059 if (a->stbc || a->bfer)
1011 ant_match = (b->ant == ANT_A || b->ant == ANT_B); 1060 ant_match = (b->ant == ANT_A || b->ant == ANT_B);
1012 else 1061 else
1013 ant_match = (a->ant == b->ant); 1062 ant_match = (a->ant == b->ant);
@@ -1016,18 +1065,6 @@ static inline bool rs_rate_match(struct rs_rate *a,
1016 && ant_match; 1065 && ant_match;
1017} 1066}
1018 1067
1019static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags)
1020{
1021 if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1022 return RATE_MCS_CHAN_WIDTH_40;
1023 else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
1024 return RATE_MCS_CHAN_WIDTH_80;
1025 else if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
1026 return RATE_MCS_CHAN_WIDTH_160;
1027
1028 return RATE_MCS_CHAN_WIDTH_20;
1029}
1030
1031static u8 rs_get_tid(struct ieee80211_hdr *hdr) 1068static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1032{ 1069{
1033 u8 tid = IWL_MAX_TID_COUNT; 1070 u8 tid = IWL_MAX_TID_COUNT;
@@ -1048,15 +1085,17 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1048{ 1085{
1049 int legacy_success; 1086 int legacy_success;
1050 int retries; 1087 int retries;
1051 int mac_index, i; 1088 int i;
1052 struct iwl_lq_cmd *table; 1089 struct iwl_lq_cmd *table;
1053 enum mac80211_rate_control_flags mac_flags; 1090 u32 lq_hwrate;
1054 u32 ucode_rate; 1091 struct rs_rate lq_rate, tx_resp_rate;
1055 struct rs_rate rate;
1056 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; 1092 struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
1057 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0]; 1093 u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
1094 u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
1058 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1095 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1059 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta; 1096 struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
1097 bool allow_ant_mismatch = mvm->fw->ucode_capa.api[0] &
1098 IWL_UCODE_TLV_API_LQ_SS_PARAMS;
1060 1099
1061 /* Treat uninitialized rate scaling data same as non-existing. */ 1100 /* Treat uninitialized rate scaling data same as non-existing. */
1062 if (!lq_sta) { 1101 if (!lq_sta) {
@@ -1079,39 +1118,6 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1079 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 1118 !(info->flags & IEEE80211_TX_STAT_AMPDU))
1080 return; 1119 return;
1081 1120
1082 /*
1083 * Ignore this Tx frame response if its initial rate doesn't match
1084 * that of latest Link Quality command. There may be stragglers
1085 * from a previous Link Quality command, but we're no longer interested
1086 * in those; they're either from the "active" mode while we're trying
1087 * to check "search" mode, or a prior "search" mode after we've moved
1088 * to a new "search" mode (which might become the new "active" mode).
1089 */
1090 table = &lq_sta->lq;
1091 ucode_rate = le32_to_cpu(table->rs_table[0]);
1092 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1093 if (info->band == IEEE80211_BAND_5GHZ)
1094 rate.index -= IWL_FIRST_OFDM_RATE;
1095 mac_flags = info->status.rates[0].flags;
1096 mac_index = info->status.rates[0].idx;
1097 /* For HT packets, map MCS to PLCP */
1098 if (mac_flags & IEEE80211_TX_RC_MCS) {
1099 /* Remove # of streams */
1100 mac_index &= RATE_HT_MCS_RATE_CODE_MSK;
1101 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
1102 mac_index++;
1103 /*
1104 * mac80211 HT index is always zero-indexed; we need to move
1105 * HT OFDM rates after CCK rates in 2.4 GHz band
1106 */
1107 if (info->band == IEEE80211_BAND_2GHZ)
1108 mac_index += IWL_FIRST_OFDM_RATE;
1109 } else if (mac_flags & IEEE80211_TX_RC_VHT_MCS) {
1110 mac_index &= RATE_VHT_MCS_RATE_CODE_MSK;
1111 if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE))
1112 mac_index++;
1113 }
1114
1115 if (time_after(jiffies, 1121 if (time_after(jiffies,
1116 (unsigned long)(lq_sta->last_tx + 1122 (unsigned long)(lq_sta->last_tx +
1117 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) { 1123 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
@@ -1126,21 +1132,24 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1126 } 1132 }
1127 lq_sta->last_tx = jiffies; 1133 lq_sta->last_tx = jiffies;
1128 1134
1135 /* Ignore this Tx frame response if its initial rate doesn't match
1136 * that of latest Link Quality command. There may be stragglers
1137 * from a previous Link Quality command, but we're no longer interested
1138 * in those; they're either from the "active" mode while we're trying
1139 * to check "search" mode, or a prior "search" mode after we've moved
1140 * to a new "search" mode (which might become the new "active" mode).
1141 */
1142 table = &lq_sta->lq;
1143 lq_hwrate = le32_to_cpu(table->rs_table[0]);
1144 rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
1145 rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
1146
1129 /* Here we actually compare this rate to the latest LQ command */ 1147 /* Here we actually compare this rate to the latest LQ command */
1130 if ((mac_index < 0) || 1148 if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
1131 (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) ||
1132 (rate.bw != rs_ch_width_from_mac_flags(mac_flags)) ||
1133 (rate.ant != info->status.antenna) ||
1134 (!!(ucode_rate & RATE_MCS_HT_MSK) !=
1135 !!(mac_flags & IEEE80211_TX_RC_MCS)) ||
1136 (!!(ucode_rate & RATE_MCS_VHT_MSK) !=
1137 !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) ||
1138 (!!(ucode_rate & RATE_HT_MCS_GF_MSK) !=
1139 !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) ||
1140 (rate.index != mac_index)) {
1141 IWL_DEBUG_RATE(mvm, 1149 IWL_DEBUG_RATE(mvm,
1142 "initial rate %d does not match %d (0x%x)\n", 1150 "initial tx resp rate 0x%x does not match 0x%x\n",
1143 mac_index, rate.index, ucode_rate); 1151 tx_resp_hwrate, lq_hwrate);
1152
1144 /* 1153 /*
1145 * Since rates mis-match, the last LQ command may have failed. 1154 * Since rates mis-match, the last LQ command may have failed.
1146 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with 1155 * After IWL_MISSED_RATE_MAX mis-matches, resync the uCode with
@@ -1168,14 +1177,14 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1168 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1177 other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1169 } 1178 }
1170 1179
1171 if (WARN_ON_ONCE(!rs_rate_match(&rate, &curr_tbl->rate))) { 1180 if (WARN_ON_ONCE(!rs_rate_column_match(&lq_rate, &curr_tbl->rate))) {
1172 IWL_DEBUG_RATE(mvm, 1181 IWL_DEBUG_RATE(mvm,
1173 "Neither active nor search matches tx rate\n"); 1182 "Neither active nor search matches tx rate\n");
1174 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1183 tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1175 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE"); 1184 rs_dump_rate(mvm, &tmp_tbl->rate, "ACTIVE");
1176 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); 1185 tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]);
1177 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH"); 1186 rs_dump_rate(mvm, &tmp_tbl->rate, "SEARCH");
1178 rs_dump_rate(mvm, &rate, "ACTUAL"); 1187 rs_dump_rate(mvm, &lq_rate, "ACTUAL");
1179 1188
1180 /* 1189 /*
1181 * no matching table found, let's by-pass the data collection 1190 * no matching table found, let's by-pass the data collection
@@ -1200,9 +1209,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1200 if (info->status.ampdu_ack_len == 0) 1209 if (info->status.ampdu_ack_len == 0)
1201 info->status.ampdu_len = 1; 1210 info->status.ampdu_len = 1;
1202 1211
1203 ucode_rate = le32_to_cpu(table->rs_table[0]); 1212 rs_collect_tx_data(mvm, lq_sta, curr_tbl, lq_rate.index,
1204 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1205 rs_collect_tx_data(mvm, lq_sta, curr_tbl, rate.index,
1206 info->status.ampdu_len, 1213 info->status.ampdu_len,
1207 info->status.ampdu_ack_len, 1214 info->status.ampdu_ack_len,
1208 reduced_txp); 1215 reduced_txp);
@@ -1225,21 +1232,23 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1225 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK); 1232 legacy_success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1226 /* Collect data for each rate used during failed TX attempts */ 1233 /* Collect data for each rate used during failed TX attempts */
1227 for (i = 0; i <= retries; ++i) { 1234 for (i = 0; i <= retries; ++i) {
1228 ucode_rate = le32_to_cpu(table->rs_table[i]); 1235 lq_hwrate = le32_to_cpu(table->rs_table[i]);
1229 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate); 1236 rs_rate_from_ucode_rate(lq_hwrate, info->band,
1237 &lq_rate);
1230 /* 1238 /*
1231 * Only collect stats if retried rate is in the same RS 1239 * Only collect stats if retried rate is in the same RS
1232 * table as active/search. 1240 * table as active/search.
1233 */ 1241 */
1234 if (rs_rate_match(&rate, &curr_tbl->rate)) 1242 if (rs_rate_column_match(&lq_rate, &curr_tbl->rate))
1235 tmp_tbl = curr_tbl; 1243 tmp_tbl = curr_tbl;
1236 else if (rs_rate_match(&rate, &other_tbl->rate)) 1244 else if (rs_rate_column_match(&lq_rate,
1245 &other_tbl->rate))
1237 tmp_tbl = other_tbl; 1246 tmp_tbl = other_tbl;
1238 else 1247 else
1239 continue; 1248 continue;
1240 1249
1241 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, rate.index, 1, 1250 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, lq_rate.index,
1242 i < retries ? 0 : legacy_success, 1251 1, i < retries ? 0 : legacy_success,
1243 reduced_txp); 1252 reduced_txp);
1244 } 1253 }
1245 1254
@@ -1250,7 +1259,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1250 } 1259 }
1251 } 1260 }
1252 /* The last TX rate is cached in lq_sta; it's set in if/else above */ 1261 /* The last TX rate is cached in lq_sta; it's set in if/else above */
1253 lq_sta->last_rate_n_flags = ucode_rate; 1262 lq_sta->last_rate_n_flags = lq_hwrate;
1254 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp); 1263 IWL_DEBUG_RATE(mvm, "reduced txpower: %d\n", reduced_txp);
1255done: 1264done:
1256 /* See if there's a better rate or modulation mode to try. */ 1265 /* See if there's a better rate or modulation mode to try. */
@@ -1590,7 +1599,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1590 1599
1591 for (j = 0; j < MAX_COLUMN_CHECKS; j++) { 1600 for (j = 0; j < MAX_COLUMN_CHECKS; j++) {
1592 allow_func = next_col->checks[j]; 1601 allow_func = next_col->checks[j];
1593 if (allow_func && !allow_func(mvm, sta, tbl)) 1602 if (allow_func && !allow_func(mvm, sta, tbl, next_col))
1594 break; 1603 break;
1595 } 1604 }
1596 1605
@@ -2536,6 +2545,7 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2536#ifdef CONFIG_MAC80211_DEBUGFS 2545#ifdef CONFIG_MAC80211_DEBUGFS
2537 lq_sta->pers.dbg_fixed_rate = 0; 2546 lq_sta->pers.dbg_fixed_rate = 0;
2538 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID; 2547 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;
2548 lq_sta->pers.ss_force = RS_SS_FORCE_NONE;
2539#endif 2549#endif
2540 lq_sta->pers.chains = 0; 2550 lq_sta->pers.chains = 0;
2541 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal)); 2551 memset(lq_sta->pers.chain_signal, 0, sizeof(lq_sta->pers.chain_signal));
@@ -3058,19 +3068,21 @@ static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
3058 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 3068 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
3059 goto out; 3069 goto out;
3060 3070
3071#ifdef CONFIG_MAC80211_DEBUGFS
3061 /* Check if forcing the decision is configured. 3072 /* Check if forcing the decision is configured.
3062 * Note that SISO is forced by not allowing STBC or BFER 3073 * Note that SISO is forced by not allowing STBC or BFER
3063 */ 3074 */
3064 if (lq_sta->ss_force == RS_SS_FORCE_STBC) 3075 if (lq_sta->pers.ss_force == RS_SS_FORCE_STBC)
3065 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE); 3076 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE);
3066 else if (lq_sta->ss_force == RS_SS_FORCE_BFER) 3077 else if (lq_sta->pers.ss_force == RS_SS_FORCE_BFER)
3067 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE); 3078 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE);
3068 3079
3069 if (lq_sta->ss_force != RS_SS_FORCE_NONE) { 3080 if (lq_sta->pers.ss_force != RS_SS_FORCE_NONE) {
3070 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n", 3081 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n",
3071 lq_sta->ss_force); 3082 lq_sta->pers.ss_force);
3072 goto out; 3083 goto out;
3073 } 3084 }
3085#endif
3074 3086
3075 if (lq_sta->stbc_capable) 3087 if (lq_sta->stbc_capable)
3076 ss_params |= LQ_SS_STBC_1SS_ALLOWED; 3088 ss_params |= LQ_SS_STBC_1SS_ALLOWED;
@@ -3311,6 +3323,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3311 struct iwl_mvm *mvm; 3323 struct iwl_mvm *mvm;
3312 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 3324 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
3313 struct rs_rate *rate = &tbl->rate; 3325 struct rs_rate *rate = &tbl->rate;
3326 u32 ss_params;
3314 mvm = lq_sta->pers.drv; 3327 mvm = lq_sta->pers.drv;
3315 buff = kmalloc(2048, GFP_KERNEL); 3328 buff = kmalloc(2048, GFP_KERNEL);
3316 if (!buff) 3329 if (!buff)
@@ -3357,6 +3370,16 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3357 lq_sta->lq.agg_frame_cnt_limit); 3370 lq_sta->lq.agg_frame_cnt_limit);
3358 3371
3359 desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc); 3372 desc += sprintf(buff+desc, "reduced tpc=%d\n", lq_sta->lq.reduced_tpc);
3373 ss_params = le32_to_cpu(lq_sta->lq.ss_params);
3374 desc += sprintf(buff+desc, "single stream params: %s%s%s%s\n",
3375 (ss_params & LQ_SS_PARAMS_VALID) ?
3376 "VALID," : "INVALID",
3377 (ss_params & LQ_SS_BFER_ALLOWED) ?
3378 "BFER," : "",
3379 (ss_params & LQ_SS_STBC_1SS_ALLOWED) ?
3380 "STBC," : "",
3381 (ss_params & LQ_SS_FORCE) ?
3382 "FORCE" : "");
3360 desc += sprintf(buff+desc, 3383 desc += sprintf(buff+desc,
3361 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n", 3384 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
3362 lq_sta->lq.initial_rate_index[0], 3385 lq_sta->lq.initial_rate_index[0],
@@ -3533,7 +3556,7 @@ static ssize_t iwl_dbgfs_ss_force_read(struct file *file,
3533 }; 3556 };
3534 3557
3535 pos += scnprintf(buf+pos, bufsz-pos, "%s\n", 3558 pos += scnprintf(buf+pos, bufsz-pos, "%s\n",
3536 ss_force_name[lq_sta->ss_force]); 3559 ss_force_name[lq_sta->pers.ss_force]);
3537 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 3560 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3538} 3561}
3539 3562
@@ -3544,12 +3567,12 @@ static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3544 int ret = 0; 3567 int ret = 0;
3545 3568
3546 if (!strncmp("none", buf, 4)) { 3569 if (!strncmp("none", buf, 4)) {
3547 lq_sta->ss_force = RS_SS_FORCE_NONE; 3570 lq_sta->pers.ss_force = RS_SS_FORCE_NONE;
3548 } else if (!strncmp("siso", buf, 4)) { 3571 } else if (!strncmp("siso", buf, 4)) {
3549 lq_sta->ss_force = RS_SS_FORCE_SISO; 3572 lq_sta->pers.ss_force = RS_SS_FORCE_SISO;
3550 } else if (!strncmp("stbc", buf, 4)) { 3573 } else if (!strncmp("stbc", buf, 4)) {
3551 if (lq_sta->stbc_capable) { 3574 if (lq_sta->stbc_capable) {
3552 lq_sta->ss_force = RS_SS_FORCE_STBC; 3575 lq_sta->pers.ss_force = RS_SS_FORCE_STBC;
3553 } else { 3576 } else {
3554 IWL_ERR(mvm, 3577 IWL_ERR(mvm,
3555 "can't force STBC. peer doesn't support\n"); 3578 "can't force STBC. peer doesn't support\n");
@@ -3557,7 +3580,7 @@ static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3557 } 3580 }
3558 } else if (!strncmp("bfer", buf, 4)) { 3581 } else if (!strncmp("bfer", buf, 4)) {
3559 if (lq_sta->bfer_capable) { 3582 if (lq_sta->bfer_capable) {
3560 lq_sta->ss_force = RS_SS_FORCE_BFER; 3583 lq_sta->pers.ss_force = RS_SS_FORCE_BFER;
3561 } else { 3584 } else {
3562 IWL_ERR(mvm, 3585 IWL_ERR(mvm,
3563 "can't force BFER. peer doesn't support\n"); 3586 "can't force BFER. peer doesn't support\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index dc4ef3dfafe1..e4aa9346a231 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -170,6 +170,7 @@ struct rs_rate {
170 bool sgi; 170 bool sgi;
171 bool ldpc; 171 bool ldpc;
172 bool stbc; 172 bool stbc;
173 bool bfer;
173}; 174};
174 175
175 176
@@ -331,14 +332,14 @@ struct iwl_lq_sta {
331 /* tx power reduce for this sta */ 332 /* tx power reduce for this sta */
332 int tpc_reduce; 333 int tpc_reduce;
333 334
334 /* force STBC/BFER/SISO for testing */
335 enum rs_ss_force_opt ss_force;
336
337 /* persistent fields - initialized only once - keep last! */ 335 /* persistent fields - initialized only once - keep last! */
338 struct lq_sta_pers { 336 struct lq_sta_pers {
339#ifdef CONFIG_MAC80211_DEBUGFS 337#ifdef CONFIG_MAC80211_DEBUGFS
340 u32 dbg_fixed_rate; 338 u32 dbg_fixed_rate;
341 u8 dbg_fixed_txp_reduction; 339 u8 dbg_fixed_txp_reduction;
340
341 /* force STBC/BFER/SISO for testing */
342 enum rs_ss_force_opt ss_force;
342#endif 343#endif
343 u8 chains; 344 u8 chains;
344 s8 chain_signal[IEEE80211_MAX_CHAINS]; 345 s8 chain_signal[IEEE80211_MAX_CHAINS];
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index f922131b4eab..6177e24f4c01 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as 12 * it under the terms of version 2 of the GNU General Public License as
@@ -32,7 +32,7 @@
32 * BSD LICENSE 32 * BSD LICENSE
33 * 33 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 35 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
36 * All rights reserved. 36 * All rights reserved.
37 * 37 *
38 * Redistribution and use in source and binary forms, with or without 38 * Redistribution and use in source and binary forms, with or without
@@ -345,6 +345,25 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
345 struct iwl_mvm_sta *mvmsta; 345 struct iwl_mvm_sta *mvmsta;
346 mvmsta = iwl_mvm_sta_from_mac80211(sta); 346 mvmsta = iwl_mvm_sta_from_mac80211(sta);
347 rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status); 347 rs_update_last_rssi(mvm, &mvmsta->lq_sta, rx_status);
348
349 if (iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_RSSI) &&
350 ieee80211_is_beacon(hdr->frame_control)) {
351 struct iwl_fw_dbg_trigger_tlv *trig;
352 struct iwl_fw_dbg_trigger_low_rssi *rssi_trig;
353 bool trig_check;
354 s32 rssi;
355
356 trig = iwl_fw_dbg_get_trigger(mvm->fw,
357 FW_DBG_TRIGGER_RSSI);
358 rssi_trig = (void *)trig->data;
359 rssi = le32_to_cpu(rssi_trig->rssi);
360
361 trig_check =
362 iwl_fw_dbg_trigger_check_stop(mvm, mvmsta->vif,
363 trig);
364 if (trig_check && rx_status->signal < rssi)
365 iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
366 }
348 } 367 }
349 368
350 rcu_read_unlock(); 369 rcu_read_unlock();
@@ -416,35 +435,43 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
416} 435}
417 436
418static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm, 437static void iwl_mvm_update_rx_statistics(struct iwl_mvm *mvm,
419 struct iwl_notif_statistics *stats) 438 struct mvm_statistics_rx *rx_stats)
420{ 439{
421 /*
422 * NOTE FW aggregates the statistics - BUT the statistics are cleared
423 * when the driver issues REPLY_STATISTICS_CMD 0x9c with CLEAR_STATS
424 * bit set.
425 */
426 lockdep_assert_held(&mvm->mutex); 440 lockdep_assert_held(&mvm->mutex);
427 memcpy(&mvm->rx_stats, &stats->rx, sizeof(struct mvm_statistics_rx)); 441
442 mvm->rx_stats = *rx_stats;
428} 443}
429 444
430struct iwl_mvm_stat_data { 445struct iwl_mvm_stat_data {
431 struct iwl_notif_statistics *stats;
432 struct iwl_mvm *mvm; 446 struct iwl_mvm *mvm;
447 __le32 mac_id;
448 __s8 beacon_filter_average_energy;
449 struct mvm_statistics_general_v8 *general;
433}; 450};
434 451
435static void iwl_mvm_stat_iterator(void *_data, u8 *mac, 452static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
436 struct ieee80211_vif *vif) 453 struct ieee80211_vif *vif)
437{ 454{
438 struct iwl_mvm_stat_data *data = _data; 455 struct iwl_mvm_stat_data *data = _data;
439 struct iwl_notif_statistics *stats = data->stats;
440 struct iwl_mvm *mvm = data->mvm; 456 struct iwl_mvm *mvm = data->mvm;
441 int sig = -stats->general.beacon_filter_average_energy; 457 int sig = -data->beacon_filter_average_energy;
442 int last_event; 458 int last_event;
443 int thold = vif->bss_conf.cqm_rssi_thold; 459 int thold = vif->bss_conf.cqm_rssi_thold;
444 int hyst = vif->bss_conf.cqm_rssi_hyst; 460 int hyst = vif->bss_conf.cqm_rssi_hyst;
445 u16 id = le32_to_cpu(stats->rx.general.mac_id); 461 u16 id = le32_to_cpu(data->mac_id);
446 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 462 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
447 463
464 /* This doesn't need the MAC ID check since it's not taking the
465 * data copied into the "data" struct, but rather the data from
466 * the notification directly.
467 */
468 if (data->general) {
469 mvmvif->beacon_stats.num_beacons =
470 le32_to_cpu(data->general->beacon_counter[mvmvif->id]);
471 mvmvif->beacon_stats.avg_signal =
472 -data->general->beacon_average_energy[mvmvif->id];
473 }
474
448 if (mvmvif->id != id) 475 if (mvmvif->id != id)
449 return; 476 return;
450 477
@@ -500,34 +527,101 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac,
500 } 527 }
501} 528}
502 529
503/* 530static inline void
504 * iwl_mvm_rx_statistics - STATISTICS_NOTIFICATION handler 531iwl_mvm_rx_stats_check_trigger(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt)
505 *
506 * TODO: This handler is implemented partially.
507 */
508int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
509 struct iwl_rx_cmd_buffer *rxb,
510 struct iwl_device_cmd *cmd)
511{ 532{
512 struct iwl_rx_packet *pkt = rxb_addr(rxb); 533 struct iwl_fw_dbg_trigger_tlv *trig;
513 struct iwl_notif_statistics *stats = (void *)&pkt->data; 534 struct iwl_fw_dbg_trigger_stats *trig_stats;
535 u32 trig_offset, trig_thold;
536
537 if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_STATS))
538 return;
539
540 trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_STATS);
541 trig_stats = (void *)trig->data;
542
543 if (!iwl_fw_dbg_trigger_check_stop(mvm, NULL, trig))
544 return;
545
546 trig_offset = le32_to_cpu(trig_stats->stop_offset);
547 trig_thold = le32_to_cpu(trig_stats->stop_threshold);
548
549 if (WARN_ON_ONCE(trig_offset >= iwl_rx_packet_payload_len(pkt)))
550 return;
551
552 if (le32_to_cpup((__le32 *) (pkt->data + trig_offset)) < trig_thold)
553 return;
554
555 iwl_mvm_fw_dbg_collect_trig(mvm, trig, NULL, 0);
556}
557
558void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
559 struct iwl_rx_packet *pkt)
560{
561 size_t v8_len = sizeof(struct iwl_notif_statistics_v8);
562 size_t v10_len = sizeof(struct iwl_notif_statistics_v10);
514 struct iwl_mvm_stat_data data = { 563 struct iwl_mvm_stat_data data = {
515 .stats = stats,
516 .mvm = mvm, 564 .mvm = mvm,
517 }; 565 };
566 u32 temperature;
567
568 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_STATS_V10) {
569 struct iwl_notif_statistics_v10 *stats = (void *)&pkt->data;
570
571 if (iwl_rx_packet_payload_len(pkt) != v10_len)
572 goto invalid;
573
574 temperature = le32_to_cpu(stats->general.radio_temperature);
575 data.mac_id = stats->rx.general.mac_id;
576 data.beacon_filter_average_energy =
577 stats->general.beacon_filter_average_energy;
578
579 iwl_mvm_update_rx_statistics(mvm, &stats->rx);
580
581 mvm->radio_stats.rx_time = le64_to_cpu(stats->general.rx_time);
582 mvm->radio_stats.tx_time = le64_to_cpu(stats->general.tx_time);
583 mvm->radio_stats.on_time_rf =
584 le64_to_cpu(stats->general.on_time_rf);
585 mvm->radio_stats.on_time_scan =
586 le64_to_cpu(stats->general.on_time_scan);
587
588 data.general = &stats->general;
589 } else {
590 struct iwl_notif_statistics_v8 *stats = (void *)&pkt->data;
591
592 if (iwl_rx_packet_payload_len(pkt) != v8_len)
593 goto invalid;
594
595 temperature = le32_to_cpu(stats->general.radio_temperature);
596 data.mac_id = stats->rx.general.mac_id;
597 data.beacon_filter_average_energy =
598 stats->general.beacon_filter_average_energy;
599
600 iwl_mvm_update_rx_statistics(mvm, &stats->rx);
601 }
602
603 iwl_mvm_rx_stats_check_trigger(mvm, pkt);
518 604
519 /* Only handle rx statistics temperature changes if async temp 605 /* Only handle rx statistics temperature changes if async temp
520 * notifications are not supported 606 * notifications are not supported
521 */ 607 */
522 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM)) 608 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM))
523 iwl_mvm_tt_temp_changed(mvm, 609 iwl_mvm_tt_temp_changed(mvm, temperature);
524 le32_to_cpu(stats->general.radio_temperature));
525
526 iwl_mvm_update_rx_statistics(mvm, stats);
527 610
528 ieee80211_iterate_active_interfaces(mvm->hw, 611 ieee80211_iterate_active_interfaces(mvm->hw,
529 IEEE80211_IFACE_ITER_NORMAL, 612 IEEE80211_IFACE_ITER_NORMAL,
530 iwl_mvm_stat_iterator, 613 iwl_mvm_stat_iterator,
531 &data); 614 &data);
615 return;
616 invalid:
617 IWL_ERR(mvm, "received invalid statistics size (%d)!\n",
618 iwl_rx_packet_payload_len(pkt));
619}
620
621int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
622 struct iwl_rx_cmd_buffer *rxb,
623 struct iwl_device_cmd *cmd)
624{
625 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb));
532 return 0; 626 return 0;
533} 627}
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 7e9aa3cb3254..f0946b5dd7c8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -82,6 +82,7 @@ struct iwl_mvm_scan_params {
82 struct _dwell { 82 struct _dwell {
83 u16 passive; 83 u16 passive;
84 u16 active; 84 u16 active;
85 u16 fragmented;
85 } dwell[IEEE80211_NUM_BANDS]; 86 } dwell[IEEE80211_NUM_BANDS];
86}; 87};
87 88
@@ -191,101 +192,6 @@ static u16 iwl_mvm_get_passive_dwell(struct iwl_mvm *mvm,
191 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10; 192 return band == IEEE80211_BAND_2GHZ ? 100 + 20 : 100 + 10;
192} 193}
193 194
194static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
195 struct cfg80211_scan_request *req,
196 bool basic_ssid,
197 struct iwl_mvm_scan_params *params)
198{
199 struct iwl_scan_channel *chan = (struct iwl_scan_channel *)
200 (cmd->data + le16_to_cpu(cmd->tx_cmd.len));
201 int i;
202 int type = BIT(req->n_ssids) - 1;
203 enum ieee80211_band band = req->channels[0]->band;
204
205 if (!basic_ssid)
206 type |= BIT(req->n_ssids);
207
208 for (i = 0; i < cmd->channel_count; i++) {
209 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
210 chan->type = cpu_to_le32(type);
211 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
212 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
213 chan->active_dwell = cpu_to_le16(params->dwell[band].active);
214 chan->passive_dwell = cpu_to_le16(params->dwell[band].passive);
215 chan->iteration_count = cpu_to_le16(1);
216 chan++;
217 }
218}
219
220/*
221 * Fill in probe request with the following parameters:
222 * TA is our vif HW address, which mac80211 ensures we have.
223 * Packet is broadcasted, so this is both SA and DA.
224 * The probe request IE is made out of two: first comes the most prioritized
225 * SSID if a directed scan is requested. Second comes whatever extra
226 * information was given to us as the scan request IE.
227 */
228static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
229 int n_ssids, const u8 *ssid, int ssid_len,
230 const u8 *band_ie, int band_ie_len,
231 const u8 *common_ie, int common_ie_len,
232 int left)
233{
234 int len = 0;
235 u8 *pos = NULL;
236
237 /* Make sure there is enough space for the probe request,
238 * two mandatory IEs and the data */
239 left -= 24;
240 if (left < 0)
241 return 0;
242
243 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
244 eth_broadcast_addr(frame->da);
245 memcpy(frame->sa, ta, ETH_ALEN);
246 eth_broadcast_addr(frame->bssid);
247 frame->seq_ctrl = 0;
248
249 len += 24;
250
251 /* for passive scans, no need to fill anything */
252 if (n_ssids == 0)
253 return (u16)len;
254
255 /* points to the payload of the request */
256 pos = &frame->u.probe_req.variable[0];
257
258 /* fill in our SSID IE */
259 left -= ssid_len + 2;
260 if (left < 0)
261 return 0;
262 *pos++ = WLAN_EID_SSID;
263 *pos++ = ssid_len;
264 if (ssid && ssid_len) { /* ssid_len may be == 0 even if ssid is valid */
265 memcpy(pos, ssid, ssid_len);
266 pos += ssid_len;
267 }
268
269 len += ssid_len + 2;
270
271 if (WARN_ON(left < band_ie_len + common_ie_len))
272 return len;
273
274 if (band_ie && band_ie_len) {
275 memcpy(pos, band_ie, band_ie_len);
276 pos += band_ie_len;
277 len += band_ie_len;
278 }
279
280 if (common_ie && common_ie_len) {
281 memcpy(pos, common_ie, common_ie_len);
282 pos += common_ie_len;
283 len += common_ie_len;
284 }
285
286 return (u16)len;
287}
288
289static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac, 195static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
290 struct ieee80211_vif *vif) 196 struct ieee80211_vif *vif)
291{ 197{
@@ -325,7 +231,7 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
325 * If there is more than one active interface make 231 * If there is more than one active interface make
326 * passive scan more fragmented. 232 * passive scan more fragmented.
327 */ 233 */
328 frag_passive_dwell = (global_cnt < 2) ? 40 : 20; 234 frag_passive_dwell = 40;
329 params->max_out_time = frag_passive_dwell; 235 params->max_out_time = frag_passive_dwell;
330 } else { 236 } else {
331 params->suspend_time = 120; 237 params->suspend_time = 120;
@@ -358,10 +264,10 @@ not_bound:
358 264
359 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 265 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
360 if (params->passive_fragmented) 266 if (params->passive_fragmented)
361 params->dwell[band].passive = frag_passive_dwell; 267 params->dwell[band].fragmented = frag_passive_dwell;
362 else 268
363 params->dwell[band].passive = 269 params->dwell[band].passive = iwl_mvm_get_passive_dwell(mvm,
364 iwl_mvm_get_passive_dwell(mvm, band); 270 band);
365 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band, 271 params->dwell[band].active = iwl_mvm_get_active_dwell(mvm, band,
366 n_ssids); 272 n_ssids);
367 } 273 }
@@ -379,20 +285,11 @@ static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm,
379{ 285{
380 int max_probe_len; 286 int max_probe_len;
381 287
382 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 288 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
383 max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
384 else
385 max_probe_len = mvm->fw->ucode_capa.max_probe_length;
386 289
387 /* we create the 802.11 header and SSID element */ 290 /* we create the 802.11 header and SSID element */
388 max_probe_len -= 24 + 2; 291 max_probe_len -= 24 + 2;
389 292
390 /* basic ssid is added only for hw_scan with and old api */
391 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) &&
392 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) &&
393 !is_sched_scan)
394 max_probe_len -= 32;
395
396 /* DS parameter set element is added on 2.4GHZ band if required */ 293 /* DS parameter set element is added on 2.4GHZ band if required */
397 if (iwl_mvm_rrm_scan_needed(mvm)) 294 if (iwl_mvm_rrm_scan_needed(mvm))
398 max_probe_len -= 3; 295 max_probe_len -= 3;
@@ -404,9 +301,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
404{ 301{
405 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan); 302 int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm, is_sched_scan);
406 303
407 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN))
408 return max_ie_len;
409
410 /* TODO: [BUG] This function should return the maximum allowed size of 304 /* TODO: [BUG] This function should return the maximum allowed size of
411 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs 305 * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
412 * in the same command. So the correct implementation of this function 306 * in the same command. So the correct implementation of this function
@@ -420,129 +314,6 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan)
420 return max_ie_len; 314 return max_ie_len;
421} 315}
422 316
423int iwl_mvm_scan_request(struct iwl_mvm *mvm,
424 struct ieee80211_vif *vif,
425 struct cfg80211_scan_request *req)
426{
427 struct iwl_host_cmd hcmd = {
428 .id = SCAN_REQUEST_CMD,
429 .len = { 0, },
430 .data = { mvm->scan_cmd, },
431 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
432 };
433 struct iwl_scan_cmd *cmd = mvm->scan_cmd;
434 int ret;
435 u32 status;
436 int ssid_len = 0;
437 u8 *ssid = NULL;
438 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
439 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
440 struct iwl_mvm_scan_params params = {};
441
442 lockdep_assert_held(&mvm->mutex);
443
444 /* we should have failed registration if scan_cmd was NULL */
445 if (WARN_ON(mvm->scan_cmd == NULL))
446 return -ENOMEM;
447
448 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
449 mvm->scan_status = IWL_MVM_SCAN_OS;
450 memset(cmd, 0, ksize(cmd));
451
452 cmd->channel_count = (u8)req->n_channels;
453 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
454 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
455 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
456
457 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
458 cmd->max_out_time = cpu_to_le32(params.max_out_time);
459 cmd->suspend_time = cpu_to_le32(params.suspend_time);
460 if (params.passive_fragmented)
461 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
462
463 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
464 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
465 MAC_FILTER_IN_BEACON);
466
467 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
468 cmd->type = cpu_to_le32(SCAN_TYPE_DISCOVERY_FORCED);
469 else
470 cmd->type = cpu_to_le32(SCAN_TYPE_FORCED);
471
472 cmd->repeats = cpu_to_le32(1);
473
474 /*
475 * If the user asked for passive scan, don't change to active scan if
476 * you see any activity on the channel - remain passive.
477 */
478 if (req->n_ssids > 0) {
479 cmd->passive2active = cpu_to_le16(1);
480 cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE;
481 if (basic_ssid) {
482 ssid = req->ssids[0].ssid;
483 ssid_len = req->ssids[0].ssid_len;
484 }
485 } else {
486 cmd->passive2active = 0;
487 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
488 }
489
490 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids,
491 basic_ssid ? 1 : 0);
492
493 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
494 3 << TX_CMD_FLG_BT_PRIO_POS);
495
496 cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
497 cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
498 cmd->tx_cmd.rate_n_flags =
499 iwl_mvm_scan_rate_n_flags(mvm, req->channels[0]->band,
500 req->no_cck);
501
502 cmd->tx_cmd.len =
503 cpu_to_le16(iwl_mvm_fill_probe_req(
504 (struct ieee80211_mgmt *)cmd->data,
505 vif->addr,
506 req->n_ssids, ssid, ssid_len,
507 req->ie, req->ie_len, NULL, 0,
508 mvm->fw->ucode_capa.max_probe_length));
509
510 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
511
512 cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) +
513 le16_to_cpu(cmd->tx_cmd.len) +
514 (cmd->channel_count * sizeof(struct iwl_scan_channel)));
515 hcmd.len[0] = le16_to_cpu(cmd->len);
516
517 status = SCAN_RESPONSE_OK;
518 ret = iwl_mvm_send_cmd_status(mvm, &hcmd, &status);
519 if (!ret && status == SCAN_RESPONSE_OK) {
520 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
521 } else {
522 /*
523 * If the scan failed, it usually means that the FW was unable
524 * to allocate the time events. Warn on it, but maybe we
525 * should try to send the command again with different params.
526 */
527 IWL_ERR(mvm, "Scan failed! status 0x%x ret %d\n",
528 status, ret);
529 mvm->scan_status = IWL_MVM_SCAN_NONE;
530 ret = -EIO;
531 }
532 return ret;
533}
534
535int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
536 struct iwl_device_cmd *cmd)
537{
538 struct iwl_rx_packet *pkt = rxb_addr(rxb);
539 struct iwl_cmd_response *resp = (void *)pkt->data;
540
541 IWL_DEBUG_SCAN(mvm, "Scan response received. status 0x%x\n",
542 le32_to_cpu(resp->status));
543 return 0;
544}
545
546int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm, 317int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
547 struct iwl_rx_cmd_buffer *rxb, 318 struct iwl_rx_cmd_buffer *rxb,
548 struct iwl_device_cmd *cmd) 319 struct iwl_device_cmd *cmd)
@@ -556,130 +327,25 @@ int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
556 return 0; 327 return 0;
557} 328}
558 329
559int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
560 struct iwl_device_cmd *cmd)
561{
562 struct iwl_rx_packet *pkt = rxb_addr(rxb);
563 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
564
565 lockdep_assert_held(&mvm->mutex);
566
567 IWL_DEBUG_SCAN(mvm, "Scan complete: status=0x%x scanned channels=%d\n",
568 notif->status, notif->scanned_channels);
569
570 if (mvm->scan_status == IWL_MVM_SCAN_OS)
571 mvm->scan_status = IWL_MVM_SCAN_NONE;
572 ieee80211_scan_completed(mvm->hw, notif->status != SCAN_COMP_STATUS_OK);
573
574 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
575
576 return 0;
577}
578
579int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm, 330int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
580 struct iwl_rx_cmd_buffer *rxb, 331 struct iwl_rx_cmd_buffer *rxb,
581 struct iwl_device_cmd *cmd) 332 struct iwl_device_cmd *cmd)
582{ 333{
583 struct iwl_rx_packet *pkt = rxb_addr(rxb);
584
585 if (!(mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) &&
586 !(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
587 struct iwl_sched_scan_results *notif = (void *)pkt->data;
588
589 if (!(notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN))
590 return 0;
591 }
592
593 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); 334 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
594 ieee80211_sched_scan_results(mvm->hw); 335 ieee80211_sched_scan_results(mvm->hw);
595 336
596 return 0; 337 return 0;
597} 338}
598 339
599static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
600 struct iwl_rx_packet *pkt, void *data)
601{
602 struct iwl_mvm *mvm =
603 container_of(notif_wait, struct iwl_mvm, notif_wait);
604 struct iwl_scan_complete_notif *notif;
605 u32 *resp;
606
607 switch (pkt->hdr.cmd) {
608 case SCAN_ABORT_CMD:
609 resp = (void *)pkt->data;
610 if (*resp == CAN_ABORT_STATUS) {
611 IWL_DEBUG_SCAN(mvm,
612 "Scan can be aborted, wait until completion\n");
613 return false;
614 }
615
616 /*
617 * If scan cannot be aborted, it means that we had a
618 * SCAN_COMPLETE_NOTIFICATION in the pipe and it called
619 * ieee80211_scan_completed already.
620 */
621 IWL_DEBUG_SCAN(mvm, "Scan cannot be aborted, exit now: %d\n",
622 *resp);
623 return true;
624
625 case SCAN_COMPLETE_NOTIFICATION:
626 notif = (void *)pkt->data;
627 IWL_DEBUG_SCAN(mvm, "Scan aborted: status 0x%x\n",
628 notif->status);
629 return true;
630
631 default:
632 WARN_ON(1);
633 return false;
634 };
635}
636
637static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
638{
639 struct iwl_notification_wait wait_scan_abort;
640 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
641 SCAN_COMPLETE_NOTIFICATION };
642 int ret;
643
644 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_abort,
645 scan_abort_notif,
646 ARRAY_SIZE(scan_abort_notif),
647 iwl_mvm_scan_abort_notif, NULL);
648
649 ret = iwl_mvm_send_cmd_pdu(mvm, SCAN_ABORT_CMD, 0, 0, NULL);
650 if (ret) {
651 IWL_ERR(mvm, "Couldn't send SCAN_ABORT_CMD: %d\n", ret);
652 /* mac80211's state will be cleaned in the nic_restart flow */
653 goto out_remove_notif;
654 }
655
656 return iwl_wait_notification(&mvm->notif_wait, &wait_scan_abort, HZ);
657
658out_remove_notif:
659 iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort);
660 return ret;
661}
662
663int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 340int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
664 struct iwl_rx_cmd_buffer *rxb, 341 struct iwl_rx_cmd_buffer *rxb,
665 struct iwl_device_cmd *cmd) 342 struct iwl_device_cmd *cmd)
666{ 343{
667 struct iwl_rx_packet *pkt = rxb_addr(rxb); 344 struct iwl_rx_packet *pkt = rxb_addr(rxb);
668 u8 status, ebs_status; 345 struct iwl_periodic_scan_complete *scan_notif;
669 346
670 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) { 347 scan_notif = (void *)pkt->data;
671 struct iwl_periodic_scan_complete *scan_notif;
672 348
673 scan_notif = (void *)pkt->data;
674 status = scan_notif->status;
675 ebs_status = scan_notif->ebs_status;
676 } else {
677 struct iwl_scan_offload_complete *scan_notif;
678
679 scan_notif = (void *)pkt->data;
680 status = scan_notif->status;
681 ebs_status = scan_notif->ebs_status;
682 }
683 /* scan status must be locked for proper checking */ 349 /* scan status must be locked for proper checking */
684 lockdep_assert_held(&mvm->mutex); 350 lockdep_assert_held(&mvm->mutex);
685 351
@@ -687,9 +353,9 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
687 "%s completed, status %s, EBS status %s\n", 353 "%s completed, status %s, EBS status %s\n",
688 mvm->scan_status == IWL_MVM_SCAN_SCHED ? 354 mvm->scan_status == IWL_MVM_SCAN_SCHED ?
689 "Scheduled scan" : "Scan", 355 "Scheduled scan" : "Scan",
690 status == IWL_SCAN_OFFLOAD_COMPLETED ? 356 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
691 "completed" : "aborted", 357 "completed" : "aborted",
692 ebs_status == IWL_SCAN_EBS_SUCCESS ? 358 scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
693 "success" : "failed"); 359 "success" : "failed");
694 360
695 361
@@ -700,64 +366,16 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
700 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) { 366 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) {
701 mvm->scan_status = IWL_MVM_SCAN_NONE; 367 mvm->scan_status = IWL_MVM_SCAN_NONE;
702 ieee80211_scan_completed(mvm->hw, 368 ieee80211_scan_completed(mvm->hw,
703 status == IWL_SCAN_OFFLOAD_ABORTED); 369 scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 370 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
705 } 371 }
706 372
707 if (ebs_status) 373 if (scan_notif->ebs_status)
708 mvm->last_ebs_successful = false; 374 mvm->last_ebs_successful = false;
709 375
710 return 0; 376 return 0;
711} 377}
712 378
713static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
714 struct ieee80211_vif *vif,
715 struct ieee80211_scan_ies *ies,
716 enum ieee80211_band band,
717 struct iwl_tx_cmd *cmd,
718 u8 *data)
719{
720 u16 cmd_len;
721
722 cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
723 cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
724 cmd->sta_id = mvm->aux_sta.sta_id;
725
726 cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false);
727
728 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
729 vif->addr,
730 1, NULL, 0,
731 ies->ies[band], ies->len[band],
732 ies->common_ies, ies->common_ie_len,
733 SCAN_OFFLOAD_PROBE_REQ_SIZE);
734 cmd->len = cpu_to_le16(cmd_len);
735}
736
737static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
738 struct ieee80211_vif *vif,
739 struct cfg80211_sched_scan_request *req,
740 struct iwl_scan_offload_cmd *scan,
741 struct iwl_mvm_scan_params *params)
742{
743 scan->channel_count = req->n_channels;
744 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
745 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
746 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
747 scan->rx_chain = iwl_mvm_scan_rx_chain(mvm);
748
749 scan->max_out_time = cpu_to_le32(params->max_out_time);
750 scan->suspend_time = cpu_to_le32(params->suspend_time);
751
752 scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
753 MAC_FILTER_IN_BEACON);
754 scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND);
755 scan->rep_count = cpu_to_le32(1);
756
757 if (params->passive_fragmented)
758 scan->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
759}
760
761static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) 379static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
762{ 380{
763 int i; 381 int i;
@@ -815,127 +433,6 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
815 } 433 }
816} 434}
817 435
818static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
819 struct cfg80211_sched_scan_request *req,
820 u8 *channels_buffer,
821 enum ieee80211_band band,
822 int *head,
823 u32 ssid_bitmap,
824 struct iwl_mvm_scan_params *params)
825{
826 u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
827 __le32 *type = (__le32 *)channels_buffer;
828 __le16 *channel_number = (__le16 *)(type + n_channels);
829 __le16 *iter_count = channel_number + n_channels;
830 __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
831 u8 *active_dwell = (u8 *)(iter_interval + n_channels);
832 u8 *passive_dwell = active_dwell + n_channels;
833 int i, index = 0;
834
835 for (i = 0; i < req->n_channels; i++) {
836 struct ieee80211_channel *chan = req->channels[i];
837
838 if (chan->band != band)
839 continue;
840
841 index = *head;
842 (*head)++;
843
844 channel_number[index] = cpu_to_le16(chan->hw_value);
845 active_dwell[index] = params->dwell[band].active;
846 passive_dwell[index] = params->dwell[band].passive;
847
848 iter_count[index] = cpu_to_le16(1);
849 iter_interval[index] = 0;
850
851 if (!(chan->flags & IEEE80211_CHAN_NO_IR))
852 type[index] |=
853 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
854
855 type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
856 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
857
858 if (chan->flags & IEEE80211_CHAN_NO_HT40)
859 type[index] |=
860 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
861
862 /* scan for all SSIDs from req->ssids */
863 type[index] |= cpu_to_le32(ssid_bitmap);
864 }
865}
866
867int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
868 struct ieee80211_vif *vif,
869 struct cfg80211_sched_scan_request *req,
870 struct ieee80211_scan_ies *ies)
871{
872 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
873 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
874 int head = 0;
875 u32 ssid_bitmap;
876 int cmd_len;
877 int ret;
878 u8 *probes;
879 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
880 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
881
882 struct iwl_scan_offload_cfg *scan_cfg;
883 struct iwl_host_cmd cmd = {
884 .id = SCAN_OFFLOAD_CONFIG_CMD,
885 };
886 struct iwl_mvm_scan_params params = {};
887
888 lockdep_assert_held(&mvm->mutex);
889
890 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
891 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
892 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
893
894 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
895 if (!scan_cfg)
896 return -ENOMEM;
897
898 probes = scan_cfg->data +
899 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
900
901 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
902 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
903 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
904
905 iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan,
906 &ssid_bitmap, basic_ssid);
907 /* build tx frames for supported bands */
908 if (band_2ghz) {
909 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
910 IEEE80211_BAND_2GHZ,
911 &scan_cfg->scan_cmd.tx_cmd[0],
912 probes);
913 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
914 IEEE80211_BAND_2GHZ, &head,
915 ssid_bitmap, &params);
916 }
917 if (band_5ghz) {
918 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
919 IEEE80211_BAND_5GHZ,
920 &scan_cfg->scan_cmd.tx_cmd[1],
921 probes +
922 SCAN_OFFLOAD_PROBE_REQ_SIZE);
923 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
924 IEEE80211_BAND_5GHZ, &head,
925 ssid_bitmap, &params);
926 }
927
928 cmd.data[0] = scan_cfg;
929 cmd.len[0] = cmd_len;
930 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
931
932 IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n");
933
934 ret = iwl_mvm_send_cmd(mvm, &cmd);
935 kfree(scan_cfg);
936 return ret;
937}
938
939int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 436int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
940 struct cfg80211_sched_scan_request *req) 437 struct cfg80211_sched_scan_request *req)
941{ 438{
@@ -1018,33 +515,6 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
1018 return true; 515 return true;
1019} 516}
1020 517
1021int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1022 struct cfg80211_sched_scan_request *req)
1023{
1024 struct iwl_scan_offload_req scan_req = {
1025 .watchdog = IWL_SCHED_SCAN_WATCHDOG,
1026
1027 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
1028 .schedule_line[0].delay = cpu_to_le16(req->interval / 1000),
1029 .schedule_line[0].full_scan_mul = 1,
1030
1031 .schedule_line[1].iterations = 0xff,
1032 .schedule_line[1].delay = cpu_to_le16(req->interval / 1000),
1033 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
1034 };
1035
1036 if (iwl_mvm_scan_pass_all(mvm, req))
1037 scan_req.flags |= cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_PASS_ALL);
1038
1039 if (mvm->last_ebs_successful &&
1040 mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT)
1041 scan_req.flags |=
1042 cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_EBS_ACCURATE_MODE);
1043
1044 return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, 0,
1045 sizeof(scan_req), &scan_req);
1046}
1047
1048int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm, 518int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1049 struct ieee80211_vif *vif, 519 struct ieee80211_vif *vif,
1050 struct cfg80211_sched_scan_request *req, 520 struct cfg80211_sched_scan_request *req,
@@ -1057,21 +527,12 @@ int iwl_mvm_scan_offload_start(struct iwl_mvm *mvm,
1057 if (ret) 527 if (ret)
1058 return ret; 528 return ret;
1059 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies); 529 ret = iwl_mvm_sched_scan_umac(mvm, vif, req, ies);
1060 } else if ((mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
1061 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1062 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1063 if (ret)
1064 return ret;
1065 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1066 } else { 530 } else {
1067 mvm->scan_status = IWL_MVM_SCAN_SCHED; 531 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1068 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1069 if (ret)
1070 return ret;
1071 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 532 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1072 if (ret) 533 if (ret)
1073 return ret; 534 return ret;
1074 ret = iwl_mvm_sched_scan_start(mvm, req); 535 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
1075 } 536 }
1076 537
1077 return ret; 538 return ret;
@@ -1088,9 +549,7 @@ static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm)
1088 /* Exit instantly with error when device is not ready 549 /* Exit instantly with error when device is not ready
1089 * to receive scan abort command or it does not perform 550 * to receive scan abort command or it does not perform
1090 * scheduled scan currently */ 551 * scheduled scan currently */
1091 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 552 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1092 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1093 mvm->scan_status != IWL_MVM_SCAN_OS))
1094 return -EIO; 553 return -EIO;
1095 554
1096 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 555 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
@@ -1131,13 +590,6 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1131 if (iwl_mvm_is_radio_killed(mvm)) 590 if (iwl_mvm_is_radio_killed(mvm))
1132 goto out; 591 goto out;
1133 592
1134 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1135 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1136 mvm->scan_status != IWL_MVM_SCAN_OS)) {
1137 IWL_DEBUG_SCAN(mvm, "No scan to stop\n");
1138 return 0;
1139 }
1140
1141 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done, 593 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
1142 scan_done_notif, 594 scan_done_notif,
1143 ARRAY_SIZE(scan_done_notif), 595 ARRAY_SIZE(scan_done_notif),
@@ -1317,7 +769,7 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1317 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 769 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
1318 if (params->passive_fragmented) 770 if (params->passive_fragmented)
1319 cmd->fragmented_dwell = 771 cmd->fragmented_dwell =
1320 params->dwell[IEEE80211_BAND_2GHZ].passive; 772 params->dwell[IEEE80211_BAND_2GHZ].fragmented;
1321 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm); 773 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
1322 cmd->max_out_time = cpu_to_le32(params->max_out_time); 774 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1323 cmd->suspend_time = cpu_to_le32(params->suspend_time); 775 cmd->suspend_time = cpu_to_le32(params->suspend_time);
@@ -1580,9 +1032,7 @@ int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
1580 return 0; 1032 return 0;
1581 } 1033 }
1582 1034
1583 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1035 return iwl_mvm_scan_offload_stop(mvm, true);
1584 return iwl_mvm_scan_offload_stop(mvm, true);
1585 return iwl_mvm_cancel_regular_scan(mvm);
1586} 1036}
1587 1037
1588/* UMAC scan API */ 1038/* UMAC scan API */
@@ -1765,7 +1215,7 @@ iwl_mvm_build_generic_umac_scan_cmd(struct iwl_mvm *mvm,
1765 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive; 1215 cmd->passive_dwell = params->dwell[IEEE80211_BAND_2GHZ].passive;
1766 if (params->passive_fragmented) 1216 if (params->passive_fragmented)
1767 cmd->fragmented_dwell = 1217 cmd->fragmented_dwell =
1768 params->dwell[IEEE80211_BAND_2GHZ].passive; 1218 params->dwell[IEEE80211_BAND_2GHZ].fragmented;
1769 cmd->max_out_time = cpu_to_le32(params->max_out_time); 1219 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1770 cmd->suspend_time = cpu_to_le32(params->suspend_time); 1220 cmd->suspend_time = cpu_to_le32(params->suspend_time);
1771 cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1221 cmd->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
@@ -2159,14 +1609,8 @@ int iwl_mvm_scan_size(struct iwl_mvm *mvm)
2159 mvm->fw->ucode_capa.n_scan_channels + 1609 mvm->fw->ucode_capa.n_scan_channels +
2160 sizeof(struct iwl_scan_req_umac_tail); 1610 sizeof(struct iwl_scan_req_umac_tail);
2161 1611
2162 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) 1612 return sizeof(struct iwl_scan_req_unified_lmac) +
2163 return sizeof(struct iwl_scan_req_unified_lmac) + 1613 sizeof(struct iwl_scan_channel_cfg_lmac) *
2164 sizeof(struct iwl_scan_channel_cfg_lmac) * 1614 mvm->fw->ucode_capa.n_scan_channels +
2165 mvm->fw->ucode_capa.n_scan_channels + 1615 sizeof(struct iwl_scan_probe_req);
2166 sizeof(struct iwl_scan_probe_req);
2167
2168 return sizeof(struct iwl_scan_cmd) +
2169 mvm->fw->ucode_capa.max_probe_length +
2170 mvm->fw->ucode_capa.n_scan_channels *
2171 sizeof(struct iwl_scan_channel);
2172} 1616}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 07304e1fd64a..7906b97c81b9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -664,6 +664,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
664 info->status.rates[0].count = tx_resp->failure_frame + 1; 664 info->status.rates[0].count = tx_resp->failure_frame + 1;
665 iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), 665 iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate),
666 info); 666 info);
667 info->status.status_driver_data[1] =
668 (void *)(uintptr_t)le32_to_cpu(tx_resp->initial_rate);
667 669
668 /* Single frame failure in an AMPDU queue => send BAR */ 670 /* Single frame failure in an AMPDU queue => send BAR */
669 if (txq_id >= mvm->first_agg_queue && 671 if (txq_id >= mvm->first_agg_queue &&
@@ -909,6 +911,8 @@ static void iwl_mvm_tx_info_from_ba_notif(struct ieee80211_tx_info *info,
909 info->status.tx_time = tid_data->tx_time; 911 info->status.tx_time = tid_data->tx_time;
910 info->status.status_driver_data[0] = 912 info->status.status_driver_data[0] =
911 (void *)(uintptr_t)tid_data->reduced_tpc; 913 (void *)(uintptr_t)tid_data->reduced_tpc;
914 info->status.status_driver_data[1] =
915 (void *)(uintptr_t)tid_data->rate_n_flags;
912} 916}
913 917
914int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 918int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 8decf9953229..2b9de63951e6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -332,7 +332,7 @@ static const char *desc_lookup(u32 num)
332 * read with u32-sized accesses, any members with a different size 332 * read with u32-sized accesses, any members with a different size
333 * need to be ordered correctly though! 333 * need to be ordered correctly though!
334 */ 334 */
335struct iwl_error_event_table { 335struct iwl_error_event_table_v1 {
336 u32 valid; /* (nonzero) valid, (0) log is empty */ 336 u32 valid; /* (nonzero) valid, (0) log is empty */
337 u32 error_id; /* type of error */ 337 u32 error_id; /* type of error */
338 u32 pc; /* program counter */ 338 u32 pc; /* program counter */
@@ -377,7 +377,55 @@ struct iwl_error_event_table {
377 u32 u_timestamp; /* indicate when the date and time of the 377 u32 u_timestamp; /* indicate when the date and time of the
378 * compilation */ 378 * compilation */
379 u32 flow_handler; /* FH read/write pointers, RX credit */ 379 u32 flow_handler; /* FH read/write pointers, RX credit */
380} __packed; 380} __packed /* LOG_ERROR_TABLE_API_S_VER_1 */;
381
382struct iwl_error_event_table {
383 u32 valid; /* (nonzero) valid, (0) log is empty */
384 u32 error_id; /* type of error */
385 u32 pc; /* program counter */
386 u32 blink1; /* branch link */
387 u32 blink2; /* branch link */
388 u32 ilink1; /* interrupt link */
389 u32 ilink2; /* interrupt link */
390 u32 data1; /* error-specific data */
391 u32 data2; /* error-specific data */
392 u32 data3; /* error-specific data */
393 u32 bcon_time; /* beacon timer */
394 u32 tsf_low; /* network timestamp function timer */
395 u32 tsf_hi; /* network timestamp function timer */
396 u32 gp1; /* GP1 timer register */
397 u32 gp2; /* GP2 timer register */
398 u32 gp3; /* GP3 timer register */
399 u32 major; /* uCode version major */
400 u32 minor; /* uCode version minor */
401 u32 hw_ver; /* HW Silicon version */
402 u32 brd_ver; /* HW board version */
403 u32 log_pc; /* log program counter */
404 u32 frame_ptr; /* frame pointer */
405 u32 stack_ptr; /* stack pointer */
406 u32 hcmd; /* last host command header */
407 u32 isr0; /* isr status register LMPM_NIC_ISR0:
408 * rxtx_flag */
409 u32 isr1; /* isr status register LMPM_NIC_ISR1:
410 * host_flag */
411 u32 isr2; /* isr status register LMPM_NIC_ISR2:
412 * enc_flag */
413 u32 isr3; /* isr status register LMPM_NIC_ISR3:
414 * time_flag */
415 u32 isr4; /* isr status register LMPM_NIC_ISR4:
416 * wico interrupt */
417 u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
418 u32 wait_event; /* wait event() caller address */
419 u32 l2p_control; /* L2pControlField */
420 u32 l2p_duration; /* L2pDurationField */
421 u32 l2p_mhvalid; /* L2pMhValidBits */
422 u32 l2p_addr_match; /* L2pAddrMatchStat */
423 u32 lmpm_pmg_sel; /* indicate which clocks are turned on
424 * (LMPM_PMG_SEL) */
425 u32 u_timestamp; /* indicate when the date and time of the
426 * compilation */
427 u32 flow_handler; /* FH read/write pointers, RX credit */
428} __packed /* LOG_ERROR_TABLE_API_S_VER_2 */;
381 429
382/* 430/*
383 * UMAC error struct - relevant starting from family 8000 chip. 431 * UMAC error struct - relevant starting from family 8000 chip.
@@ -396,11 +444,11 @@ struct iwl_umac_error_event_table {
396 u32 data1; /* error-specific data */ 444 u32 data1; /* error-specific data */
397 u32 data2; /* error-specific data */ 445 u32 data2; /* error-specific data */
398 u32 data3; /* error-specific data */ 446 u32 data3; /* error-specific data */
399 u32 umac_fw_ver; /* UMAC version */ 447 u32 umac_major;
400 u32 umac_fw_api_ver; /* UMAC FW API ver */ 448 u32 umac_minor;
401 u32 frame_pointer; /* core register 27*/ 449 u32 frame_pointer; /* core register 27*/
402 u32 stack_pointer; /* core register 28 */ 450 u32 stack_pointer; /* core register 28 */
403 u32 cmd_header; /* latest host cmd sent to UMAC */ 451 u32 cmd_header; /* latest host cmd sent to UMAC */
404 u32 nic_isr_pref; /* ISR status register */ 452 u32 nic_isr_pref; /* ISR status register */
405} __packed; 453} __packed;
406 454
@@ -441,18 +489,18 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
441 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1); 489 IWL_ERR(mvm, "0x%08X | umac data1\n", table.data1);
442 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2); 490 IWL_ERR(mvm, "0x%08X | umac data2\n", table.data2);
443 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3); 491 IWL_ERR(mvm, "0x%08X | umac data3\n", table.data3);
444 IWL_ERR(mvm, "0x%08X | umac version\n", table.umac_fw_ver); 492 IWL_ERR(mvm, "0x%08X | umac major\n", table.umac_major);
445 IWL_ERR(mvm, "0x%08X | umac api version\n", table.umac_fw_api_ver); 493 IWL_ERR(mvm, "0x%08X | umac minor\n", table.umac_minor);
446 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer); 494 IWL_ERR(mvm, "0x%08X | frame pointer\n", table.frame_pointer);
447 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer); 495 IWL_ERR(mvm, "0x%08X | stack pointer\n", table.stack_pointer);
448 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header); 496 IWL_ERR(mvm, "0x%08X | last host cmd\n", table.cmd_header);
449 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref); 497 IWL_ERR(mvm, "0x%08X | isr status reg\n", table.nic_isr_pref);
450} 498}
451 499
452void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) 500static void iwl_mvm_dump_nic_error_log_old(struct iwl_mvm *mvm)
453{ 501{
454 struct iwl_trans *trans = mvm->trans; 502 struct iwl_trans *trans = mvm->trans;
455 struct iwl_error_event_table table; 503 struct iwl_error_event_table_v1 table;
456 u32 base; 504 u32 base;
457 505
458 base = mvm->error_event_table; 506 base = mvm->error_event_table;
@@ -489,7 +537,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
489 table.data1, table.data2, table.data3, 537 table.data1, table.data2, table.data3,
490 table.blink1, table.blink2, table.ilink1, 538 table.blink1, table.blink2, table.ilink1,
491 table.ilink2, table.bcon_time, table.gp1, 539 table.ilink2, table.bcon_time, table.gp1,
492 table.gp2, table.gp3, table.ucode_ver, 540 table.gp2, table.gp3, table.ucode_ver, 0,
493 table.hw_ver, table.brd_ver); 541 table.hw_ver, table.brd_ver);
494 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 542 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
495 desc_lookup(table.error_id)); 543 desc_lookup(table.error_id));
@@ -530,6 +578,92 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
530 iwl_mvm_dump_umac_error_log(mvm); 578 iwl_mvm_dump_umac_error_log(mvm);
531} 579}
532 580
581void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
582{
583 struct iwl_trans *trans = mvm->trans;
584 struct iwl_error_event_table table;
585 u32 base;
586
587 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_NEW_VERSION)) {
588 iwl_mvm_dump_nic_error_log_old(mvm);
589 return;
590 }
591
592 base = mvm->error_event_table;
593 if (mvm->cur_ucode == IWL_UCODE_INIT) {
594 if (!base)
595 base = mvm->fw->init_errlog_ptr;
596 } else {
597 if (!base)
598 base = mvm->fw->inst_errlog_ptr;
599 }
600
601 if (base < 0x800000) {
602 IWL_ERR(mvm,
603 "Not valid error log pointer 0x%08X for %s uCode\n",
604 base,
605 (mvm->cur_ucode == IWL_UCODE_INIT)
606 ? "Init" : "RT");
607 return;
608 }
609
610 iwl_trans_read_mem_bytes(trans, base, &table, sizeof(table));
611
612 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
613 IWL_ERR(trans, "Start IWL Error Log Dump:\n");
614 IWL_ERR(trans, "Status: 0x%08lX, count: %d\n",
615 mvm->status, table.valid);
616 }
617
618 /* Do not change this output - scripts rely on it */
619
620 IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
621
622 trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
623 table.data1, table.data2, table.data3,
624 table.blink1, table.blink2, table.ilink1,
625 table.ilink2, table.bcon_time, table.gp1,
626 table.gp2, table.gp3, table.major,
627 table.minor, table.hw_ver, table.brd_ver);
628 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id,
629 desc_lookup(table.error_id));
630 IWL_ERR(mvm, "0x%08X | uPc\n", table.pc);
631 IWL_ERR(mvm, "0x%08X | branchlink1\n", table.blink1);
632 IWL_ERR(mvm, "0x%08X | branchlink2\n", table.blink2);
633 IWL_ERR(mvm, "0x%08X | interruptlink1\n", table.ilink1);
634 IWL_ERR(mvm, "0x%08X | interruptlink2\n", table.ilink2);
635 IWL_ERR(mvm, "0x%08X | data1\n", table.data1);
636 IWL_ERR(mvm, "0x%08X | data2\n", table.data2);
637 IWL_ERR(mvm, "0x%08X | data3\n", table.data3);
638 IWL_ERR(mvm, "0x%08X | beacon time\n", table.bcon_time);
639 IWL_ERR(mvm, "0x%08X | tsf low\n", table.tsf_low);
640 IWL_ERR(mvm, "0x%08X | tsf hi\n", table.tsf_hi);
641 IWL_ERR(mvm, "0x%08X | time gp1\n", table.gp1);
642 IWL_ERR(mvm, "0x%08X | time gp2\n", table.gp2);
643 IWL_ERR(mvm, "0x%08X | time gp3\n", table.gp3);
644 IWL_ERR(mvm, "0x%08X | uCode version major\n", table.major);
645 IWL_ERR(mvm, "0x%08X | uCode version minor\n", table.minor);
646 IWL_ERR(mvm, "0x%08X | hw version\n", table.hw_ver);
647 IWL_ERR(mvm, "0x%08X | board version\n", table.brd_ver);
648 IWL_ERR(mvm, "0x%08X | hcmd\n", table.hcmd);
649 IWL_ERR(mvm, "0x%08X | isr0\n", table.isr0);
650 IWL_ERR(mvm, "0x%08X | isr1\n", table.isr1);
651 IWL_ERR(mvm, "0x%08X | isr2\n", table.isr2);
652 IWL_ERR(mvm, "0x%08X | isr3\n", table.isr3);
653 IWL_ERR(mvm, "0x%08X | isr4\n", table.isr4);
654 IWL_ERR(mvm, "0x%08X | isr_pref\n", table.isr_pref);
655 IWL_ERR(mvm, "0x%08X | wait_event\n", table.wait_event);
656 IWL_ERR(mvm, "0x%08X | l2p_control\n", table.l2p_control);
657 IWL_ERR(mvm, "0x%08X | l2p_duration\n", table.l2p_duration);
658 IWL_ERR(mvm, "0x%08X | l2p_mhvalid\n", table.l2p_mhvalid);
659 IWL_ERR(mvm, "0x%08X | l2p_addr_match\n", table.l2p_addr_match);
660 IWL_ERR(mvm, "0x%08X | lmpm_pmg_sel\n", table.lmpm_pmg_sel);
661 IWL_ERR(mvm, "0x%08X | timestamp\n", table.u_timestamp);
662 IWL_ERR(mvm, "0x%08X | flow_handler\n", table.flow_handler);
663
664 if (mvm->support_umac_log)
665 iwl_mvm_dump_umac_error_log(mvm);
666}
533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 667void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
534 const struct iwl_trans_txq_scd_cfg *cfg, 668 const struct iwl_trans_txq_scd_cfg *cfg,
535 unsigned int wdg_timeout) 669 unsigned int wdg_timeout)
@@ -643,6 +777,40 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
643 ieee80211_request_smps(vif, smps_mode); 777 ieee80211_request_smps(vif, smps_mode);
644} 778}
645 779
780int iwl_mvm_request_statistics(struct iwl_mvm *mvm, bool clear)
781{
782 struct iwl_statistics_cmd scmd = {
783 .flags = clear ? cpu_to_le32(IWL_STATISTICS_FLG_CLEAR) : 0,
784 };
785 struct iwl_host_cmd cmd = {
786 .id = STATISTICS_CMD,
787 .len[0] = sizeof(scmd),
788 .data[0] = &scmd,
789 .flags = CMD_WANT_SKB,
790 };
791 int ret;
792
793 ret = iwl_mvm_send_cmd(mvm, &cmd);
794 if (ret)
795 return ret;
796
797 iwl_mvm_handle_rx_statistics(mvm, cmd.resp_pkt);
798 iwl_free_resp(&cmd);
799
800 if (clear)
801 iwl_mvm_accu_radio_stats(mvm);
802
803 return 0;
804}
805
806void iwl_mvm_accu_radio_stats(struct iwl_mvm *mvm)
807{
808 mvm->accu_radio_stats.rx_time += mvm->radio_stats.rx_time;
809 mvm->accu_radio_stats.tx_time += mvm->radio_stats.tx_time;
810 mvm->accu_radio_stats.on_time_rf += mvm->radio_stats.on_time_rf;
811 mvm->accu_radio_stats.on_time_scan += mvm->radio_stats.on_time_scan;
812}
813
646static void iwl_mvm_diversity_iter(void *_data, u8 *mac, 814static void iwl_mvm_diversity_iter(void *_data, u8 *mac,
647 struct ieee80211_vif *vif) 815 struct ieee80211_vif *vif)
648{ 816{
@@ -717,25 +885,6 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
717 return result; 885 return result;
718} 886}
719 887
720static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
721{
722 bool *idle = _data;
723
724 if (!vif->bss_conf.idle)
725 *idle = false;
726}
727
728bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
729{
730 bool idle = true;
731
732 ieee80211_iterate_active_interfaces_atomic(
733 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
734 iwl_mvm_idle_iter, &idle);
735
736 return idle;
737}
738
739struct iwl_bss_iter_data { 888struct iwl_bss_iter_data {
740 struct ieee80211_vif *vif; 889 struct ieee80211_vif *vif;
741 bool error; 890 bool error;
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 69935aa5a1b3..f31a94160771 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -898,6 +898,9 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
898 IWL_DEBUG_FW(trans, "working with %s CPU\n", 898 IWL_DEBUG_FW(trans, "working with %s CPU\n",
899 image->is_dual_cpus ? "Dual" : "Single"); 899 image->is_dual_cpus ? "Dual" : "Single");
900 900
901 if (trans->dbg_dest_tlv)
902 iwl_pcie_apply_destination(trans);
903
901 /* configure the ucode to be ready to get the secured image */ 904 /* configure the ucode to be ready to get the secured image */
902 /* release CPU reset */ 905 /* release CPU reset */
903 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); 906 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -914,9 +917,6 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
914 if (ret) 917 if (ret)
915 return ret; 918 return ret;
916 919
917 if (trans->dbg_dest_tlv)
918 iwl_pcie_apply_destination(trans);
919
920 /* wait for image verification to complete */ 920 /* wait for image verification to complete */
921 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, 921 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
922 LMPM_SECURE_BOOT_STATUS_SUCCESS, 922 LMPM_SECURE_BOOT_STATUS_SUCCESS,
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index cc6a0a586f0b..26cbf1dcc662 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -742,8 +742,7 @@ void lbs_debugfs_init(void)
742 742
743void lbs_debugfs_remove(void) 743void lbs_debugfs_remove(void)
744{ 744{
745 if (lbs_dir) 745 debugfs_remove(lbs_dir);
746 debugfs_remove(lbs_dir);
747} 746}
748 747
749void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev) 748void lbs_debugfs_init_one(struct lbs_private *priv, struct net_device *dev)
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 7c3ca2f50186..8e1f681f960b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -2397,7 +2397,6 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2398} 2398}
2399 2399
2400#define MWIFIEX_MAX_WQ_LEN 30
2401/* 2400/*
2402 * create a new virtual interface with the given name 2401 * create a new virtual interface with the given name
2403 */ 2402 */
@@ -2411,7 +2410,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2411 struct mwifiex_private *priv; 2410 struct mwifiex_private *priv;
2412 struct net_device *dev; 2411 struct net_device *dev;
2413 void *mdev_priv; 2412 void *mdev_priv;
2414 char dfs_cac_str[MWIFIEX_MAX_WQ_LEN], dfs_chsw_str[MWIFIEX_MAX_WQ_LEN];
2415 2413
2416 if (!adapter) 2414 if (!adapter)
2417 return ERR_PTR(-EFAULT); 2415 return ERR_PTR(-EFAULT);
@@ -2576,12 +2574,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2576 return ERR_PTR(-EFAULT); 2574 return ERR_PTR(-EFAULT);
2577 } 2575 }
2578 2576
2579 strcpy(dfs_cac_str, "MWIFIEX_DFS_CAC"); 2577 priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC%s",
2580 strcat(dfs_cac_str, name);
2581 priv->dfs_cac_workqueue = alloc_workqueue(dfs_cac_str,
2582 WQ_HIGHPRI | 2578 WQ_HIGHPRI |
2583 WQ_MEM_RECLAIM | 2579 WQ_MEM_RECLAIM |
2584 WQ_UNBOUND, 1); 2580 WQ_UNBOUND, 1, name);
2585 if (!priv->dfs_cac_workqueue) { 2581 if (!priv->dfs_cac_workqueue) {
2586 wiphy_err(wiphy, "cannot register virtual network device\n"); 2582 wiphy_err(wiphy, "cannot register virtual network device\n");
2587 free_netdev(dev); 2583 free_netdev(dev);
@@ -2594,11 +2590,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2594 2590
2595 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue); 2591 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
2596 2592
2597 strcpy(dfs_chsw_str, "MWIFIEX_DFS_CHSW"); 2593 priv->dfs_chan_sw_workqueue = alloc_workqueue("MWIFIEX_DFS_CHSW%s",
2598 strcat(dfs_chsw_str, name);
2599 priv->dfs_chan_sw_workqueue = alloc_workqueue(dfs_chsw_str,
2600 WQ_HIGHPRI | WQ_UNBOUND | 2594 WQ_HIGHPRI | WQ_UNBOUND |
2601 WQ_MEM_RECLAIM, 1); 2595 WQ_MEM_RECLAIM, 1, name);
2602 if (!priv->dfs_chan_sw_workqueue) { 2596 if (!priv->dfs_chan_sw_workqueue) {
2603 wiphy_err(wiphy, "cannot register virtual network device\n"); 2597 wiphy_err(wiphy, "cannot register virtual network device\n");
2604 free_netdev(dev); 2598 free_netdev(dev);
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 88d0eade6bb1..cf2fa110e251 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -33,6 +33,7 @@
33#define MWIFIEX_MAX_BSS_NUM (3) 33#define MWIFIEX_MAX_BSS_NUM (3)
34 34
35#define MWIFIEX_DMA_ALIGN_SZ 64 35#define MWIFIEX_DMA_ALIGN_SZ 64
36#define MWIFIEX_RX_HEADROOM 64
36#define MAX_TXPD_SZ 32 37#define MAX_TXPD_SZ 32
37#define INTF_HDR_ALIGN 4 38#define INTF_HDR_ALIGN 4
38 39
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 0978b1cc58b6..0153ce6d5879 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -296,7 +296,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
296 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 296 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
297 adapter->arp_filter_size = 0; 297 adapter->arp_filter_size = 0;
298 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 298 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
299 adapter->ext_scan = false;
300 adapter->key_api_major_ver = 0; 299 adapter->key_api_major_ver = 0;
301 adapter->key_api_minor_ver = 0; 300 adapter->key_api_minor_ver = 0;
302 eth_broadcast_addr(adapter->perm_addr); 301 eth_broadcast_addr(adapter->perm_addr);
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 7e74b4fccddd..74488aba92bd 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -190,14 +190,16 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
190 190
191 /* Check if already processing */ 191 /* Check if already processing */
192 if (adapter->mwifiex_processing) { 192 if (adapter->mwifiex_processing) {
193 adapter->more_task_flag = true;
193 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 194 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
194 goto exit_main_proc; 195 goto exit_main_proc;
195 } else { 196 } else {
196 adapter->mwifiex_processing = true; 197 adapter->mwifiex_processing = true;
197 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
198 } 198 }
199process_start: 199process_start:
200 do { 200 do {
201 adapter->more_task_flag = false;
202 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
201 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) || 203 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
202 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) 204 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
203 break; 205 break;
@@ -238,6 +240,7 @@ process_start:
238 adapter->pm_wakeup_fw_try = true; 240 adapter->pm_wakeup_fw_try = true;
239 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3)); 241 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
240 adapter->if_ops.wakeup(adapter); 242 adapter->if_ops.wakeup(adapter);
243 spin_lock_irqsave(&adapter->main_proc_lock, flags);
241 continue; 244 continue;
242 } 245 }
243 246
@@ -295,8 +298,10 @@ process_start:
295 if ((adapter->ps_state == PS_STATE_SLEEP) || 298 if ((adapter->ps_state == PS_STATE_SLEEP) ||
296 (adapter->ps_state == PS_STATE_PRE_SLEEP) || 299 (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
297 (adapter->ps_state == PS_STATE_SLEEP_CFM) || 300 (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
298 adapter->tx_lock_flag) 301 adapter->tx_lock_flag){
302 spin_lock_irqsave(&adapter->main_proc_lock, flags);
299 continue; 303 continue;
304 }
300 305
301 if (!adapter->cmd_sent && !adapter->curr_cmd) { 306 if (!adapter->cmd_sent && !adapter->curr_cmd) {
302 if (mwifiex_exec_next_cmd(adapter) == -1) { 307 if (mwifiex_exec_next_cmd(adapter) == -1) {
@@ -330,15 +335,12 @@ process_start:
330 } 335 }
331 break; 336 break;
332 } 337 }
338 spin_lock_irqsave(&adapter->main_proc_lock, flags);
333 } while (true); 339 } while (true);
334 340
335 spin_lock_irqsave(&adapter->main_proc_lock, flags); 341 spin_lock_irqsave(&adapter->main_proc_lock, flags);
336 if (!adapter->delay_main_work && 342 if (adapter->more_task_flag)
337 (adapter->int_status || IS_CARD_RX_RCVD(adapter))) {
338 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
339 goto process_start; 343 goto process_start;
340 }
341
342 adapter->mwifiex_processing = false; 344 adapter->mwifiex_processing = false;
343 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 345 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
344 346
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index f0a6af179af0..16be45e9a66a 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -140,6 +140,9 @@ enum {
140 140
141#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000 141#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000
142 142
143/* Address alignment */
144#define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
145
143struct mwifiex_dbg { 146struct mwifiex_dbg {
144 u32 num_cmd_host_to_card_failure; 147 u32 num_cmd_host_to_card_failure;
145 u32 num_cmd_sleep_cfm_host_to_card_failure; 148 u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -774,6 +777,7 @@ struct mwifiex_adapter {
774 /* spin lock for main process */ 777 /* spin lock for main process */
775 spinlock_t main_proc_lock; 778 spinlock_t main_proc_lock;
776 u32 mwifiex_processing; 779 u32 mwifiex_processing;
780 u8 more_task_flag;
777 u16 tx_buf_size; 781 u16 tx_buf_size;
778 u16 curr_tx_buf_size; 782 u16 curr_tx_buf_size;
779 u32 ioport; 783 u32 ioport;
@@ -1417,6 +1421,7 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1417 u8 rx_rate, u8 ht_info); 1421 u8 rx_rate, u8 ht_info);
1418 1422
1419void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); 1423void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1424void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags);
1420 1425
1421#ifdef CONFIG_DEBUG_FS 1426#ifdef CONFIG_DEBUG_FS
1422void mwifiex_debugfs_init(void); 1427void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index a5828da59365..4b463c3b9906 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -203,7 +203,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
203 card->pcie.reg = data->reg; 203 card->pcie.reg = data->reg;
204 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 204 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
205 card->pcie.tx_buf_size = data->tx_buf_size; 205 card->pcie.tx_buf_size = data->tx_buf_size;
206 card->pcie.supports_fw_dump = data->supports_fw_dump; 206 card->pcie.can_dump_fw = data->can_dump_fw;
207 card->pcie.can_ext_scan = data->can_ext_scan; 207 card->pcie.can_ext_scan = data->can_ext_scan;
208 } 208 }
209 209
@@ -498,7 +498,8 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
498 498
499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { 499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
500 /* Allocate skb here so that firmware can DMA data from it */ 500 /* Allocate skb here so that firmware can DMA data from it */
501 skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); 501 skb = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
502 GFP_KERNEL | GFP_DMA);
502 if (!skb) { 503 if (!skb) {
503 dev_err(adapter->dev, 504 dev_err(adapter->dev,
504 "Unable to allocate skb for RX ring.\n"); 505 "Unable to allocate skb for RX ring.\n");
@@ -1297,7 +1298,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1297 } 1298 }
1298 } 1299 }
1299 1300
1300 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); 1301 skb_tmp = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1302 GFP_KERNEL | GFP_DMA);
1301 if (!skb_tmp) { 1303 if (!skb_tmp) {
1302 dev_err(adapter->dev, 1304 dev_err(adapter->dev,
1303 "Unable to allocate skb.\n"); 1305 "Unable to allocate skb.\n");
@@ -2271,7 +2273,7 @@ static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2271 int ret; 2273 int ret;
2272 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL }; 2274 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2273 2275
2274 if (!card->pcie.supports_fw_dump) 2276 if (!card->pcie.can_dump_fw)
2275 return; 2277 return;
2276 2278
2277 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) { 2279 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 666d40e9dbc3..0e7ee8b72358 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -205,7 +205,7 @@ struct mwifiex_pcie_device {
205 const struct mwifiex_pcie_card_reg *reg; 205 const struct mwifiex_pcie_card_reg *reg;
206 u16 blksz_fw_dl; 206 u16 blksz_fw_dl;
207 u16 tx_buf_size; 207 u16 tx_buf_size;
208 bool supports_fw_dump; 208 bool can_dump_fw;
209 bool can_ext_scan; 209 bool can_ext_scan;
210}; 210};
211 211
@@ -214,7 +214,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
214 .reg = &mwifiex_reg_8766, 214 .reg = &mwifiex_reg_8766,
215 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 215 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
216 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 216 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
217 .supports_fw_dump = false, 217 .can_dump_fw = false,
218 .can_ext_scan = true, 218 .can_ext_scan = true,
219}; 219};
220 220
@@ -223,7 +223,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
223 .reg = &mwifiex_reg_8897, 223 .reg = &mwifiex_reg_8897,
224 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 224 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
225 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 225 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
226 .supports_fw_dump = true, 226 .can_dump_fw = true,
227 .can_ext_scan = true, 227 .can_ext_scan = true,
228}; 228};
229 229
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 91e36cda9543..57d85ab442bf 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -105,8 +105,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
105 card->tx_buf_size = data->tx_buf_size; 105 card->tx_buf_size = data->tx_buf_size;
106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; 106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; 107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
108 card->supports_fw_dump = data->supports_fw_dump; 108 card->can_dump_fw = data->can_dump_fw;
109 card->auto_tdls = data->auto_tdls; 109 card->can_auto_tdls = data->can_auto_tdls;
110 card->can_ext_scan = data->can_ext_scan; 110 card->can_ext_scan = data->can_ext_scan;
111 } 111 }
112 112
@@ -1357,7 +1357,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1357 return -1; 1357 return -1;
1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1359 1359
1360 skb = dev_alloc_skb(rx_len); 1360 skb = mwifiex_alloc_rx_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) 1361 if (!skb)
1362 return -1; 1362 return -1;
1363 1363
@@ -1454,7 +1454,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1454 } 1454 }
1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1456 1456
1457 skb = dev_alloc_skb(rx_len); 1457 skb = mwifiex_alloc_rx_buf(rx_len,
1458 GFP_KERNEL | GFP_DMA);
1458 1459
1459 if (!skb) { 1460 if (!skb) {
1460 dev_err(adapter->dev, "%s: failed to alloc skb", 1461 dev_err(adapter->dev, "%s: failed to alloc skb",
@@ -1887,7 +1888,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1887 return -1; 1888 return -1;
1888 } 1889 }
1889 1890
1890 adapter->auto_tdls = card->auto_tdls; 1891 adapter->auto_tdls = card->can_auto_tdls;
1891 adapter->ext_scan = card->can_ext_scan; 1892 adapter->ext_scan = card->can_ext_scan;
1892 return ret; 1893 return ret;
1893} 1894}
@@ -2032,7 +2033,7 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2032 2033
2033 mwifiex_dump_drv_info(adapter); 2034 mwifiex_dump_drv_info(adapter);
2034 2035
2035 if (!card->supports_fw_dump) 2036 if (!card->can_dump_fw)
2036 return; 2037 return;
2037 2038
2038 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) { 2039 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 957cca246618..c636944c77bc 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -238,9 +238,6 @@ struct sdio_mmc_card {
238 const struct mwifiex_sdio_card_reg *reg; 238 const struct mwifiex_sdio_card_reg *reg;
239 u8 max_ports; 239 u8 max_ports;
240 u8 mp_agg_pkt_limit; 240 u8 mp_agg_pkt_limit;
241 bool supports_sdio_new_mode;
242 bool has_control_mask;
243 bool supports_fw_dump;
244 u16 tx_buf_size; 241 u16 tx_buf_size;
245 u32 mp_tx_agg_buf_size; 242 u32 mp_tx_agg_buf_size;
246 u32 mp_rx_agg_buf_size; 243 u32 mp_rx_agg_buf_size;
@@ -255,7 +252,10 @@ struct sdio_mmc_card {
255 u8 curr_wr_port; 252 u8 curr_wr_port;
256 253
257 u8 *mp_regs; 254 u8 *mp_regs;
258 u8 auto_tdls; 255 bool supports_sdio_new_mode;
256 bool has_control_mask;
257 bool can_dump_fw;
258 bool can_auto_tdls;
259 bool can_ext_scan; 259 bool can_ext_scan;
260 260
261 struct mwifiex_sdio_mpa_tx mpa_tx; 261 struct mwifiex_sdio_mpa_tx mpa_tx;
@@ -267,13 +267,13 @@ struct mwifiex_sdio_device {
267 const struct mwifiex_sdio_card_reg *reg; 267 const struct mwifiex_sdio_card_reg *reg;
268 u8 max_ports; 268 u8 max_ports;
269 u8 mp_agg_pkt_limit; 269 u8 mp_agg_pkt_limit;
270 bool supports_sdio_new_mode;
271 bool has_control_mask;
272 bool supports_fw_dump;
273 u16 tx_buf_size; 270 u16 tx_buf_size;
274 u32 mp_tx_agg_buf_size; 271 u32 mp_tx_agg_buf_size;
275 u32 mp_rx_agg_buf_size; 272 u32 mp_rx_agg_buf_size;
276 u8 auto_tdls; 273 bool supports_sdio_new_mode;
274 bool has_control_mask;
275 bool can_dump_fw;
276 bool can_auto_tdls;
277 bool can_ext_scan; 277 bool can_ext_scan;
278}; 278};
279 279
@@ -412,13 +412,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
412 .reg = &mwifiex_reg_sd87xx, 412 .reg = &mwifiex_reg_sd87xx,
413 .max_ports = 16, 413 .max_ports = 16,
414 .mp_agg_pkt_limit = 8, 414 .mp_agg_pkt_limit = 8,
415 .supports_sdio_new_mode = false,
416 .has_control_mask = true,
417 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 415 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
418 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 416 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
419 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 417 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
420 .supports_fw_dump = false, 418 .supports_sdio_new_mode = false,
421 .auto_tdls = false, 419 .has_control_mask = true,
420 .can_dump_fw = false,
421 .can_auto_tdls = false,
422 .can_ext_scan = false, 422 .can_ext_scan = false,
423}; 423};
424 424
@@ -427,13 +427,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
427 .reg = &mwifiex_reg_sd87xx, 427 .reg = &mwifiex_reg_sd87xx,
428 .max_ports = 16, 428 .max_ports = 16,
429 .mp_agg_pkt_limit = 8, 429 .mp_agg_pkt_limit = 8,
430 .supports_sdio_new_mode = false,
431 .has_control_mask = true,
432 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 430 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
433 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 431 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
434 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 432 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
435 .supports_fw_dump = false, 433 .supports_sdio_new_mode = false,
436 .auto_tdls = false, 434 .has_control_mask = true,
435 .can_dump_fw = false,
436 .can_auto_tdls = false,
437 .can_ext_scan = true, 437 .can_ext_scan = true,
438}; 438};
439 439
@@ -442,13 +442,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
442 .reg = &mwifiex_reg_sd87xx, 442 .reg = &mwifiex_reg_sd87xx,
443 .max_ports = 16, 443 .max_ports = 16,
444 .mp_agg_pkt_limit = 8, 444 .mp_agg_pkt_limit = 8,
445 .supports_sdio_new_mode = false,
446 .has_control_mask = true,
447 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 445 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
448 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 446 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
449 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 447 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
450 .supports_fw_dump = false, 448 .supports_sdio_new_mode = false,
451 .auto_tdls = false, 449 .has_control_mask = true,
450 .can_dump_fw = false,
451 .can_auto_tdls = false,
452 .can_ext_scan = true, 452 .can_ext_scan = true,
453}; 453};
454 454
@@ -457,13 +457,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
457 .reg = &mwifiex_reg_sd8897, 457 .reg = &mwifiex_reg_sd8897,
458 .max_ports = 32, 458 .max_ports = 32,
459 .mp_agg_pkt_limit = 16, 459 .mp_agg_pkt_limit = 16,
460 .supports_sdio_new_mode = true,
461 .has_control_mask = false,
462 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 460 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
463 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 461 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
464 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 462 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
465 .supports_fw_dump = true, 463 .supports_sdio_new_mode = true,
466 .auto_tdls = false, 464 .has_control_mask = false,
465 .can_dump_fw = true,
466 .can_auto_tdls = false,
467 .can_ext_scan = true, 467 .can_ext_scan = true,
468}; 468};
469 469
@@ -472,13 +472,13 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
472 .reg = &mwifiex_reg_sd8887, 472 .reg = &mwifiex_reg_sd8887,
473 .max_ports = 32, 473 .max_ports = 32,
474 .mp_agg_pkt_limit = 16, 474 .mp_agg_pkt_limit = 16,
475 .supports_sdio_new_mode = true, 475 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
476 .has_control_mask = false,
477 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
478 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 476 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
479 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 477 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
480 .supports_fw_dump = false, 478 .supports_sdio_new_mode = true,
481 .auto_tdls = true, 479 .has_control_mask = false,
480 .can_dump_fw = false,
481 .can_auto_tdls = true,
482 .can_ext_scan = true, 482 .can_ext_scan = true,
483}; 483};
484 484
@@ -492,8 +492,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
492 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 492 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
493 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 493 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
494 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 494 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
495 .supports_fw_dump = false, 495 .can_dump_fw = false,
496 .auto_tdls = false, 496 .can_auto_tdls = false,
497 .can_ext_scan = true, 497 .can_ext_scan = true,
498}; 498};
499 499
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index ac93557cbdc9..ea4549f0e0b9 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -80,11 +80,13 @@ EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
80int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, 80int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
81 struct mwifiex_tx_param *tx_param) 81 struct mwifiex_tx_param *tx_param)
82{ 82{
83 int ret = -1; 83 int hroom, ret = -1;
84 struct mwifiex_adapter *adapter = priv->adapter; 84 struct mwifiex_adapter *adapter = priv->adapter;
85 u8 *head_ptr; 85 u8 *head_ptr;
86 struct txpd *local_tx_pd = NULL; 86 struct txpd *local_tx_pd = NULL;
87 87
88 hroom = (adapter->iface_type == MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
89
88 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 90 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
89 head_ptr = mwifiex_process_uap_txpd(priv, skb); 91 head_ptr = mwifiex_process_uap_txpd(priv, skb);
90 else 92 else
@@ -92,11 +94,9 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
92 94
93 if (head_ptr) { 95 if (head_ptr) {
94 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 96 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
95 local_tx_pd = 97 local_tx_pd = (struct txpd *)(head_ptr + hroom);
96 (struct txpd *) (head_ptr + INTF_HEADER_LEN);
97 if (adapter->iface_type == MWIFIEX_USB) { 98 if (adapter->iface_type == MWIFIEX_USB) {
98 adapter->data_sent = true; 99 adapter->data_sent = true;
99 skb_pull(skb, INTF_HEADER_LEN);
100 ret = adapter->if_ops.host_to_card(adapter, 100 ret = adapter->if_ops.host_to_card(adapter,
101 MWIFIEX_USB_EP_DATA, 101 MWIFIEX_USB_EP_DATA,
102 skb, NULL); 102 skb, NULL);
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 308550611f22..2148a573396b 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -367,6 +367,13 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
367 if (!skb) 367 if (!skb)
368 return -1; 368 return -1;
369 369
370 if (!priv->mgmt_frame_mask ||
371 priv->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
372 dev_dbg(priv->adapter->dev,
373 "do not receive mgmt frames on uninitialized intf");
374 return -1;
375 }
376
370 rx_pd = (struct rxpd *)skb->data; 377 rx_pd = (struct rxpd *)skb->data;
371 378
372 skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); 379 skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
@@ -624,3 +631,26 @@ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
624 for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++) 631 for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++)
625 atomic_set(&phist_data->sig_str[ix], 0); 632 atomic_set(&phist_data->sig_str[ix], 0);
626} 633}
634
635void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags)
636{
637 struct sk_buff *skb;
638 int buf_len, pad;
639
640 buf_len = rx_len + MWIFIEX_RX_HEADROOM + MWIFIEX_DMA_ALIGN_SZ;
641
642 skb = __dev_alloc_skb(buf_len, flags);
643
644 if (!skb)
645 return NULL;
646
647 skb_reserve(skb, MWIFIEX_RX_HEADROOM);
648
649 pad = MWIFIEX_ALIGN_ADDR(skb->data, MWIFIEX_DMA_ALIGN_SZ) -
650 (long)skb->data;
651
652 skb_reserve(skb, pad);
653
654 return skb;
655}
656EXPORT_SYMBOL_GPL(mwifiex_alloc_rx_buf);
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index c6cb49c3ee32..dee4ac2f27e2 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -45,9 +45,6 @@ enum ap_peer {
45#define RTL_TX_DESC_SIZE 32 45#define RTL_TX_DESC_SIZE 32
46#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE) 46#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
47 47
48#define HT_AMSDU_SIZE_4K 3839
49#define HT_AMSDU_SIZE_8K 7935
50
51#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */ 48#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
52#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */ 49#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
53 50
@@ -61,9 +58,6 @@ enum ap_peer {
61#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */ 58#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS9 390 /* Mbps */
62#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */ 59#define MAX_BIT_RATE_LONG_GI_1NSS_80MHZ_MCS7 293 /* Mbps */
63 60
64#define RTL_RATE_COUNT_LEGACY 12
65#define RTL_CHANNEL_COUNT 14
66
67#define FRAME_OFFSET_FRAME_CONTROL 0 61#define FRAME_OFFSET_FRAME_CONTROL 0
68#define FRAME_OFFSET_DURATION 2 62#define FRAME_OFFSET_DURATION 2
69#define FRAME_OFFSET_ADDRESS1 4 63#define FRAME_OFFSET_ADDRESS1 4
diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h
index 35508087c0c5..e2e647d511c1 100644
--- a/drivers/net/wireless/rtlwifi/cam.h
+++ b/drivers/net/wireless/rtlwifi/cam.h
@@ -28,13 +28,11 @@
28 28
29#define CAM_CONTENT_COUNT 8 29#define CAM_CONTENT_COUNT 8
30 30
31#define CFG_DEFAULT_KEY BIT(5)
32#define CFG_VALID BIT(15) 31#define CFG_VALID BIT(15)
33 32
34#define PAIRWISE_KEYIDX 0 33#define PAIRWISE_KEYIDX 0
35#define CAM_PAIRWISE_KEY_POSITION 4 34#define CAM_PAIRWISE_KEY_POSITION 4
36 35
37#define CAM_CONFIG_USEDK 1
38#define CAM_CONFIG_NO_USEDK 0 36#define CAM_CONFIG_NO_USEDK 0
39 37
40void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); 38void rtl_cam_reset_all_entry(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 7b64e34f421e..82733c6b8c46 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -33,8 +33,6 @@
33 FIF_FCSFAIL | \ 33 FIF_FCSFAIL | \
34 FIF_BCN_PRBRESP_PROMISC) 34 FIF_BCN_PRBRESP_PROMISC)
35 35
36#define RTL_SUPPORTED_CTRL_FILTER 0xFF
37
38#define DM_DIG_THRESH_HIGH 40 36#define DM_DIG_THRESH_HIGH 40
39#define DM_DIG_THRESH_LOW 35 37#define DM_DIG_THRESH_LOW 35
40#define DM_FALSEALARM_THRESH_LOW 400 38#define DM_FALSEALARM_THRESH_LOW 400
diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h
index fdab8240a5d7..be02e7894c61 100644
--- a/drivers/net/wireless/rtlwifi/efuse.h
+++ b/drivers/net/wireless/rtlwifi/efuse.h
@@ -40,12 +40,6 @@
40#define PG_STATE_WORD_3 0x10 40#define PG_STATE_WORD_3 0x10
41#define PG_STATE_DATA 0x20 41#define PG_STATE_DATA 0x20
42 42
43#define PG_SWBYTE_H 0x01
44#define PG_SWBYTE_L 0x02
45
46#define _POWERON_DELAY_
47#define _PRE_EXECUTE_READ_CMD_
48
49#define EFUSE_REPEAT_THRESHOLD_ 3 43#define EFUSE_REPEAT_THRESHOLD_ 3
50#define EFUSE_ERROE_HANDLE 1 44#define EFUSE_ERROE_HANDLE 1
51 45
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
index d9ea9d0c79a5..0532b9852444 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/def.h
@@ -26,53 +26,12 @@
26#ifndef __RTL92C_DEF_H__ 26#ifndef __RTL92C_DEF_H__
27#define __RTL92C_DEF_H__ 27#define __RTL92C_DEF_H__
28 28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 29#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1 30#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2 31#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69 32
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0 33#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1 34#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76 35
77#define C2H_RX_CMD_HDR_LEN 8 36#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 37#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index f2b9713c456e..edc2cbb6253c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -566,7 +566,7 @@ void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
566 acm_ctrl &= (~ACMHW_VIQEN); 566 acm_ctrl &= (~ACMHW_VIQEN);
567 break; 567 break;
568 case AC3_VO: 568 case AC3_VO:
569 acm_ctrl &= (~ACMHW_BEQEN); 569 acm_ctrl &= (~ACMHW_VOQEN);
570 break; 570 break;
571 default: 571 default:
572 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 572 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
index 3f6c59cdeaba..a2bb02c7b837 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c
@@ -452,9 +452,10 @@ static void handle_branch1(struct ieee80211_hw *hw, u16 arraylen,
452 READ_NEXT_PAIR(v1, v2, i); 452 READ_NEXT_PAIR(v1, v2, i);
453 while (v2 != 0xDEAD && 453 while (v2 != 0xDEAD &&
454 v2 != 0xCDEF && 454 v2 != 0xCDEF &&
455 v2 != 0xCDCD && i < arraylen - 2) 455 v2 != 0xCDCD && i < arraylen - 2) {
456 _rtl8188e_config_bb_reg(hw, v1, v2); 456 _rtl8188e_config_bb_reg(hw, v1, v2);
457 READ_NEXT_PAIR(v1, v2, i); 457 READ_NEXT_PAIR(v1, v2, i);
458 }
458 459
459 while (v2 != 0xDEAD && i < arraylen - 2) 460 while (v2 != 0xDEAD && i < arraylen - 2)
460 READ_NEXT_PAIR(v1, v2, i); 461 READ_NEXT_PAIR(v1, v2, i);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
index 5c1472d88fd4..0eca030e3238 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/rf.h
@@ -27,7 +27,6 @@
27#define __RTL92C_RF_H__ 27#define __RTL92C_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl88e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
index 9b660df6fd71..690a7a1675e2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
@@ -30,59 +30,18 @@
30#ifndef __RTL92C_DEF_H__ 30#ifndef __RTL92C_DEF_H__
31#define __RTL92C_DEF_H__ 31#define __RTL92C_DEF_H__
32 32
33#define HAL_RETRY_LIMIT_INFRA 48
34#define HAL_RETRY_LIMIT_AP_ADHOC 7
35
36#define PHY_RSSI_SLID_WIN_MAX 100 33#define PHY_RSSI_SLID_WIN_MAX 100
37#define PHY_LINKQUALITY_SLID_WIN_MAX 20 34#define PHY_LINKQUALITY_SLID_WIN_MAX 20
38#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 35#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
39 36
40#define RESET_DELAY_8185 20
41
42#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
43#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
44
45#define NUM_OF_FIRMWARE_QUEUE 10
46#define NUM_OF_PAGES_IN_FW 0x100
47#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
48#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
49#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
50#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
51#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
52#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
53#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
54#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
55#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
56#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
57
58#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
59#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
60#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
61#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
62#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
63
64#define MAX_LINES_HWCONFIG_TXT 1000
65#define MAX_BYTES_LINE_HWCONFIG_TXT 256
66
67#define SW_THREE_WIRE 0
68#define HW_THREE_WIRE 2
69
70#define BT_DEMO_BOARD 0
71#define BT_QA_BOARD 1
72#define BT_FPGA 2
73
74#define RX_SMOOTH_FACTOR 20 37#define RX_SMOOTH_FACTOR 20
75 38
76#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 39#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
77#define HAL_PRIME_CHNL_OFFSET_LOWER 1 40#define HAL_PRIME_CHNL_OFFSET_LOWER 1
78#define HAL_PRIME_CHNL_OFFSET_UPPER 2 41#define HAL_PRIME_CHNL_OFFSET_UPPER 2
79 42
80#define MAX_H2C_QUEUE_NUM 10
81
82#define RX_MPDU_QUEUE 0 43#define RX_MPDU_QUEUE 0
83#define RX_CMD_QUEUE 1 44#define RX_CMD_QUEUE 1
84#define RX_MAX_QUEUE 2
85#define AC2QUEUEID(_AC) (_AC)
86 45
87#define C2H_RX_CMD_HDR_LEN 8 46#define C2H_RX_CMD_HDR_LEN 8
88#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 47#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 303b299376c9..04eb5c3f8464 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -363,7 +363,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
363 acm_ctrl &= (~AcmHw_ViqEn); 363 acm_ctrl &= (~AcmHw_ViqEn);
364 break; 364 break;
365 case AC3_VO: 365 case AC3_VO:
366 acm_ctrl &= (~AcmHw_BeqEn); 366 acm_ctrl &= (~AcmHw_VoqEn);
367 break; 367 break;
368 default: 368 default:
369 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 369 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
index d8fe68b389d2..ebd72cae10b6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
@@ -31,7 +31,6 @@
31#define __RTL92C_RF_H__ 31#define __RTL92C_RF_H__
32 32
33#define RF6052_MAX_TX_PWR 0x3F 33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35#define RF6052_MAX_PATH 2 34#define RF6052_MAX_PATH 2
36 35
37void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); 36void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index fe4b699a12f5..0c20dd74d6ec 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1589,6 +1589,8 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1589 case HW_VAR_DATA_FILTER: 1589 case HW_VAR_DATA_FILTER:
1590 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); 1590 *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
1591 break; 1591 break;
1592 case HAL_DEF_WOWLAN:
1593 break;
1592 default: 1594 default:
1593 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1595 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1594 "switch case not processed\n"); 1596 "switch case not processed\n");
@@ -1871,7 +1873,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1871 acm_ctrl &= (~AcmHw_ViqEn); 1873 acm_ctrl &= (~AcmHw_ViqEn);
1872 break; 1874 break;
1873 case AC3_VO: 1875 case AC3_VO:
1874 acm_ctrl &= (~AcmHw_BeqEn); 1876 acm_ctrl &= (~AcmHw_VoqEn);
1875 break; 1877 break;
1876 default: 1878 default:
1877 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1879 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
index c1e33b0228c0..67588083e6cc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
@@ -32,8 +32,6 @@
32 32
33#define H2C_RA_MASK 6 33#define H2C_RA_MASK 6
34 34
35#define LLT_POLLING_LLT_THRESHOLD 20
36#define LLT_POLLING_READY_TIMEOUT_COUNT 100
37#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 35#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255
38 36
39#define RX_PAGE_SIZE_REG_VALUE PBP_128 37#define RX_PAGE_SIZE_REG_VALUE PBP_128
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
index 11b439d6b671..6f987de5b441 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
@@ -31,7 +31,6 @@
31#define __RTL92CU_RF_H__ 31#define __RTL92CU_RF_H__
32 32
33#define RF6052_MAX_TX_PWR 0x3F 33#define RF6052_MAX_TX_PWR 0x3F
34#define RF6052_MAX_REG 0x3F
35#define RF6052_MAX_PATH 2 34#define RF6052_MAX_PATH 2
36 35
37void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); 36void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
index 939c905f547f..0a443ed17cf4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h
@@ -35,61 +35,22 @@
35#define MAX_MSS_DENSITY_1T 0x0A 35#define MAX_MSS_DENSITY_1T 0x0A
36 36
37#define RF6052_MAX_TX_PWR 0x3F 37#define RF6052_MAX_TX_PWR 0x3F
38#define RF6052_MAX_REG 0x3F
39#define RF6052_MAX_PATH 2 38#define RF6052_MAX_PATH 2
40 39
41#define HAL_RETRY_LIMIT_INFRA 48
42#define HAL_RETRY_LIMIT_AP_ADHOC 7
43
44#define PHY_RSSI_SLID_WIN_MAX 100 40#define PHY_RSSI_SLID_WIN_MAX 100
45#define PHY_LINKQUALITY_SLID_WIN_MAX 20 41#define PHY_LINKQUALITY_SLID_WIN_MAX 20
46#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 42#define PHY_BEACON_RSSI_SLID_WIN_MAX 10
47 43
48#define RESET_DELAY_8185 20
49
50#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
51#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK) 44#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
52 45
53#define NUM_OF_FIRMWARE_QUEUE 10
54#define NUM_OF_PAGES_IN_FW 0x100
55#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
56#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
57#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
58#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
59#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
60#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
61#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
62#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
63#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
64#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
65
66#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
67#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
68#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
69#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
70#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
71
72#define MAX_LINES_HWCONFIG_TXT 1000
73#define MAX_BYTES_LINE_HWCONFIG_TXT 256
74
75#define SW_THREE_WIRE 0
76#define HW_THREE_WIRE 2
77
78#define BT_DEMO_BOARD 0
79#define BT_QA_BOARD 1
80#define BT_FPGA 2
81
82#define RX_SMOOTH_FACTOR 20 46#define RX_SMOOTH_FACTOR 20
83 47
84#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 48#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
85#define HAL_PRIME_CHNL_OFFSET_LOWER 1 49#define HAL_PRIME_CHNL_OFFSET_LOWER 1
86#define HAL_PRIME_CHNL_OFFSET_UPPER 2 50#define HAL_PRIME_CHNL_OFFSET_UPPER 2
87 51
88#define MAX_H2C_QUEUE_NUM 10
89
90#define RX_MPDU_QUEUE 0 52#define RX_MPDU_QUEUE 0
91#define RX_CMD_QUEUE 1 53#define RX_CMD_QUEUE 1
92#define RX_MAX_QUEUE 2
93 54
94#define C2H_RX_CMD_HDR_LEN 8 55#define C2H_RX_CMD_HDR_LEN 8
95#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 56#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
index b461b3128da5..db230a3f0137 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
@@ -562,7 +562,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
562 acm_ctrl &= (~ACMHW_VIQEN); 562 acm_ctrl &= (~ACMHW_VIQEN);
563 break; 563 break;
564 case AC3_VO: 564 case AC3_VO:
565 acm_ctrl &= (~ACMHW_BEQEN); 565 acm_ctrl &= (~ACMHW_VOQEN);
566 break; 566 break;
567 default: 567 default:
568 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, 568 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
index 8bdeed3c064e..039c0133ad6b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/rf.h
@@ -27,7 +27,6 @@
27#define __RTL92E_RF_H__ 27#define __RTL92E_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index ef87c09b77d0..41466f957cdc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -31,7 +31,6 @@
31 31
32#define RX_MPDU_QUEUE 0 32#define RX_MPDU_QUEUE 0
33#define RX_CMD_QUEUE 1 33#define RX_CMD_QUEUE 1
34#define RX_MAX_QUEUE 2
35 34
36#define SHORT_SLOT_TIME 9 35#define SHORT_SLOT_TIME 9
37#define NON_SHORT_SLOT_TIME 20 36#define NON_SHORT_SLOT_TIME 20
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 5761d5b49e39..dee88a80bee1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -293,7 +293,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
293 acm_ctrl &= (~AcmHw_ViqEn); 293 acm_ctrl &= (~AcmHw_ViqEn);
294 break; 294 break;
295 case AC3_VO: 295 case AC3_VO:
296 acm_ctrl &= (~AcmHw_BeqEn); 296 acm_ctrl &= (~AcmHw_VoqEn);
297 break; 297 break;
298 default: 298 default:
299 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 299 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
index 94bdd4bbca5d..bcdf2273688e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h
@@ -26,53 +26,12 @@
26#ifndef __RTL8723E_DEF_H__ 26#ifndef __RTL8723E_DEF_H__
27#define __RTL8723E_DEF_H__ 27#define __RTL8723E_DEF_H__
28 28
29#define HAL_RETRY_LIMIT_INFRA 48
30#define HAL_RETRY_LIMIT_AP_ADHOC 7
31
32#define RESET_DELAY_8185 20
33
34#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
35#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
36
37#define NUM_OF_FIRMWARE_QUEUE 10
38#define NUM_OF_PAGES_IN_FW 0x100
39#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
40#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
41#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
42#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
43#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
44#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
45#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
46#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
47#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
48#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
49
50#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
51#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
52#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
53#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
54#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
55
56#define MAX_LINES_HWCONFIG_TXT 1000
57#define MAX_BYTES_LINE_HWCONFIG_TXT 256
58
59#define SW_THREE_WIRE 0
60#define HW_THREE_WIRE 2
61
62#define BT_DEMO_BOARD 0
63#define BT_QA_BOARD 1
64#define BT_FPGA 2
65
66#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 29#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
67#define HAL_PRIME_CHNL_OFFSET_LOWER 1 30#define HAL_PRIME_CHNL_OFFSET_LOWER 1
68#define HAL_PRIME_CHNL_OFFSET_UPPER 2 31#define HAL_PRIME_CHNL_OFFSET_UPPER 2
69 32
70#define MAX_H2C_QUEUE_NUM 10
71
72#define RX_MPDU_QUEUE 0 33#define RX_MPDU_QUEUE 0
73#define RX_CMD_QUEUE 1 34#define RX_CMD_QUEUE 1
74#define RX_MAX_QUEUE 2
75#define AC2QUEUEID(_AC) (_AC)
76 35
77#define C2H_RX_CMD_HDR_LEN 8 36#define C2H_RX_CMD_HDR_LEN 8
78#define GET_C2H_CMD_CMD_LEN(__prxhdr) \ 37#define GET_C2H_CMD_CMD_LEN(__prxhdr) \
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index aa085462d0e9..b3b094759f6d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -362,7 +362,7 @@ void rtl8723e_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
362 acm_ctrl &= (~ACMHW_VIQEN); 362 acm_ctrl &= (~ACMHW_VIQEN);
363 break; 363 break;
364 case AC3_VO: 364 case AC3_VO:
365 acm_ctrl &= (~ACMHW_BEQEN); 365 acm_ctrl &= (~ACMHW_VOQEN);
366 break; 366 break;
367 default: 367 default:
368 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 368 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
index f3f45b16361f..7b44ebc0fac9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8723E_RF_H__ 27#define __RTL8723E_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8723e_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
index 6dad28e77bbb..b46998341c40 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -603,7 +603,7 @@ void rtl8723be_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
603 acm_ctrl &= (~ACMHW_VIQEN); 603 acm_ctrl &= (~ACMHW_VIQEN);
604 break; 604 break;
605 case AC3_VO: 605 case AC3_VO:
606 acm_ctrl &= (~ACMHW_BEQEN); 606 acm_ctrl &= (~ACMHW_VOQEN);
607 break; 607 break;
608 default: 608 default:
609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 609 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
index a6fea106ced4..f423e157020f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8723BE_RF_H__ 27#define __RTL8723BE_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8723be_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
index ee7c208bd070..dfbdf539de1a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
@@ -118,55 +118,14 @@
118#define WIFI_NAV_UPPER_US 30000 118#define WIFI_NAV_UPPER_US 30000
119#define HAL_92C_NAV_UPPER_UNIT 128 119#define HAL_92C_NAV_UPPER_UNIT 128
120 120
121#define HAL_RETRY_LIMIT_INFRA 48
122#define HAL_RETRY_LIMIT_AP_ADHOC 7
123
124#define RESET_DELAY_8185 20
125
126#define RT_IBSS_INT_MASKS (IMR_BCNINT | IMR_TBDOK | IMR_TBDER)
127#define RT_AC_INT_MASKS (IMR_VIDOK | IMR_VODOK | IMR_BEDOK|IMR_BKDOK)
128
129#define NUM_OF_FIRMWARE_QUEUE 10
130#define NUM_OF_PAGES_IN_FW 0x100
131#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x07
132#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x07
133#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x07
134#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x07
135#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0x0
136#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x0
137#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x02
138#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0x02
139#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x2
140#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xA1
141
142#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026
143#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048
144#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048
145#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026
146#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00
147
148#define MAX_RX_DMA_BUFFER_SIZE 0x3E80 121#define MAX_RX_DMA_BUFFER_SIZE 0x3E80
149 122
150#define MAX_LINES_HWCONFIG_TXT 1000
151#define MAX_BYTES_LINE_HWCONFIG_TXT 256
152
153#define SW_THREE_WIRE 0
154#define HW_THREE_WIRE 2
155
156#define BT_DEMO_BOARD 0
157#define BT_QA_BOARD 1
158#define BT_FPGA 2
159
160#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 123#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0
161#define HAL_PRIME_CHNL_OFFSET_LOWER 1 124#define HAL_PRIME_CHNL_OFFSET_LOWER 1
162#define HAL_PRIME_CHNL_OFFSET_UPPER 2 125#define HAL_PRIME_CHNL_OFFSET_UPPER 2
163 126
164#define MAX_H2C_QUEUE_NUM 10
165
166#define RX_MPDU_QUEUE 0 127#define RX_MPDU_QUEUE 0
167#define RX_CMD_QUEUE 1 128#define RX_CMD_QUEUE 1
168#define RX_MAX_QUEUE 2
169#define AC2QUEUEID(_AC) (_AC)
170 129
171#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80 130#define MAX_RX_DMA_BUFFER_SIZE_8812 0x3E80
172 131
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index 8ec8200002c7..2a0a71bac00c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -667,7 +667,7 @@ void rtl8821ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
667 acm_ctrl &= (~ACMHW_VIQEN); 667 acm_ctrl &= (~ACMHW_VIQEN);
668 break; 668 break;
669 case AC3_VO: 669 case AC3_VO:
670 acm_ctrl &= (~ACMHW_BEQEN); 670 acm_ctrl &= (~ACMHW_VOQEN);
671 break; 671 break;
672 default: 672 default:
673 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 673 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
@@ -1515,7 +1515,7 @@ static bool _rtl8821ae_dynamic_rqpn(struct ieee80211_hw *hw, u32 boundary,
1515 (u8 *)(&support_remote_wakeup)); 1515 (u8 *)(&support_remote_wakeup));
1516 1516
1517 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1517 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1518 "boundary=0x%#X, NPQ_RQPNValue=0x%#X, RQPNValue=0x%#X\n", 1518 "boundary=%#X, NPQ_RQPNValue=%#X, RQPNValue=%#X\n",
1519 boundary, npq_rqpn_value, rqpn_val); 1519 boundary, npq_rqpn_value, rqpn_val);
1520 1520
1521 /* stop PCIe DMA 1521 /* stop PCIe DMA
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
index d9582ee1c335..efd22bd0b139 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/rf.h
@@ -27,7 +27,6 @@
27#define __RTL8821AE_RF_H__ 27#define __RTL8821AE_RF_H__
28 28
29#define RF6052_MAX_TX_PWR 0x3F 29#define RF6052_MAX_TX_PWR 0x3F
30#define RF6052_MAX_REG 0x3F
31 30
32void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, 31void rtl8821ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
33 u8 bandwidth); 32 u8 bandwidth);
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 46ee956d0235..f0188c83c79f 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -701,12 +701,18 @@ free:
701 701
702static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw) 702static void _rtl_usb_cleanup_rx(struct ieee80211_hw *hw)
703{ 703{
704 struct rtl_priv *rtlpriv = rtl_priv(hw);
704 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 705 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
705 struct urb *urb; 706 struct urb *urb;
706 707
707 usb_kill_anchored_urbs(&rtlusb->rx_submitted); 708 usb_kill_anchored_urbs(&rtlusb->rx_submitted);
708 709
709 tasklet_kill(&rtlusb->rx_work_tasklet); 710 tasklet_kill(&rtlusb->rx_work_tasklet);
711 cancel_work_sync(&rtlpriv->works.lps_change_work);
712
713 flush_workqueue(rtlpriv->works.rtl_wq);
714 destroy_workqueue(rtlpriv->works.rtl_wq);
715
710 skb_queue_purge(&rtlusb->rx_queue); 716 skb_queue_purge(&rtlusb->rx_queue);
711 717
712 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { 718 while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) {
@@ -794,8 +800,6 @@ static void rtl_usb_cleanup(struct ieee80211_hw *hw)
794 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 800 struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
795 struct ieee80211_tx_info *txinfo; 801 struct ieee80211_tx_info *txinfo;
796 802
797 SET_USB_STOP(rtlusb);
798
799 /* clean up rx stuff. */ 803 /* clean up rx stuff. */
800 _rtl_usb_cleanup_rx(hw); 804 _rtl_usb_cleanup_rx(hw);
801 805
@@ -834,7 +838,6 @@ static void rtl_usb_stop(struct ieee80211_hw *hw)
834 cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); 838 cancel_work_sync(&rtlpriv->works.fill_h2c_cmd);
835 /* Enable software */ 839 /* Enable software */
836 SET_USB_STOP(rtlusb); 840 SET_USB_STOP(rtlusb);
837 rtl_usb_deinit(hw);
838 rtlpriv->cfg->ops->hw_disable(hw); 841 rtlpriv->cfg->ops->hw_disable(hw);
839} 842}
840 843
@@ -1147,9 +1150,9 @@ void rtl_usb_disconnect(struct usb_interface *intf)
1147 1150
1148 if (unlikely(!rtlpriv)) 1151 if (unlikely(!rtlpriv))
1149 return; 1152 return;
1150
1151 /* just in case driver is removed before firmware callback */ 1153 /* just in case driver is removed before firmware callback */
1152 wait_for_completion(&rtlpriv->firmware_loading_complete); 1154 wait_for_completion(&rtlpriv->firmware_loading_complete);
1155 clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
1153 /*ieee80211_unregister_hw will call ops_stop */ 1156 /*ieee80211_unregister_hw will call ops_stop */
1154 if (rtlmac->mac80211_registered == 1) { 1157 if (rtlmac->mac80211_registered == 1) {
1155 ieee80211_unregister_hw(hw); 1158 ieee80211_unregister_hw(hw);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 1e180c400f17..a48a7439a206 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -1135,6 +1135,8 @@ static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
1135 case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */ 1135 case SSB_IDLOW_SSBREV_25: /* TODO - find the proper REJECT bit */
1136 case SSB_IDLOW_SSBREV_27: /* same here */ 1136 case SSB_IDLOW_SSBREV_27: /* same here */
1137 return SSB_TMSLOW_REJECT; /* this is a guess */ 1137 return SSB_TMSLOW_REJECT; /* this is a guess */
1138 case SSB_IDLOW_SSBREV:
1139 break;
1138 default: 1140 default:
1139 WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev); 1141 WARN(1, KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
1140 } 1142 }
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 994739da827f..44057b45ed32 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -434,6 +434,18 @@ static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus,
434 return bcma_find_core_unit(bus, coreid, 0); 434 return bcma_find_core_unit(bus, coreid, 0);
435} 435}
436 436
437#ifdef CONFIG_BCMA_HOST_PCI
438extern void bcma_host_pci_up(struct bcma_bus *bus);
439extern void bcma_host_pci_down(struct bcma_bus *bus);
440#else
441static inline void bcma_host_pci_up(struct bcma_bus *bus)
442{
443}
444static inline void bcma_host_pci_down(struct bcma_bus *bus)
445{
446}
447#endif
448
437extern bool bcma_core_is_enabled(struct bcma_device *core); 449extern bool bcma_core_is_enabled(struct bcma_device *core);
438extern void bcma_core_disable(struct bcma_device *core, u32 flags); 450extern void bcma_core_disable(struct bcma_device *core, u32 flags);
439extern int bcma_core_enable(struct bcma_device *core, u32 flags); 451extern int bcma_core_enable(struct bcma_device *core, u32 flags);
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index db6fa217f98b..6cceedf65ca2 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -663,14 +663,6 @@ struct bcma_drv_cc_b {
663#define bcma_cc_maskset32(cc, offset, mask, set) \ 663#define bcma_cc_maskset32(cc, offset, mask, set) \
664 bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set)) 664 bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
665 665
666extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
667extern void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
668
669extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
670extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
671
672void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
673
674extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks); 666extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
675 667
676extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc); 668extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc);
@@ -690,9 +682,6 @@ u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value);
690u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value); 682u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value);
691 683
692/* PMU support */ 684/* PMU support */
693extern void bcma_pmu_init(struct bcma_drv_cc *cc);
694extern void bcma_pmu_early_init(struct bcma_drv_cc *cc);
695
696extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, 685extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
697 u32 value); 686 u32 value);
698extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, 687extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
diff --git a/include/linux/bcma/bcma_driver_gmac_cmn.h b/include/linux/bcma/bcma_driver_gmac_cmn.h
index 4dd1f33e36a2..4354d4ea6713 100644
--- a/include/linux/bcma/bcma_driver_gmac_cmn.h
+++ b/include/linux/bcma/bcma_driver_gmac_cmn.h
@@ -91,10 +91,4 @@ struct bcma_drv_gmac_cmn {
91#define gmac_cmn_write16(gc, offset, val) bcma_write16((gc)->core, offset, val) 91#define gmac_cmn_write16(gc, offset, val) bcma_write16((gc)->core, offset, val)
92#define gmac_cmn_write32(gc, offset, val) bcma_write32((gc)->core, offset, val) 92#define gmac_cmn_write32(gc, offset, val) bcma_write32((gc)->core, offset, val)
93 93
94#ifdef CONFIG_BCMA_DRIVER_GMAC_CMN
95extern void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc);
96#else
97static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) { }
98#endif
99
100#endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */ 94#endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */
diff --git a/include/linux/bcma/bcma_driver_mips.h b/include/linux/bcma/bcma_driver_mips.h
index 0b3b32aeeb8a..8eea7f9e33b4 100644
--- a/include/linux/bcma/bcma_driver_mips.h
+++ b/include/linux/bcma/bcma_driver_mips.h
@@ -39,21 +39,6 @@ struct bcma_drv_mips {
39 u8 early_setup_done:1; 39 u8 early_setup_done:1;
40}; 40};
41 41
42#ifdef CONFIG_BCMA_DRIVER_MIPS
43extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
44extern void bcma_core_mips_early_init(struct bcma_drv_mips *mcore);
45
46extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
47#else
48static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
49static inline void bcma_core_mips_early_init(struct bcma_drv_mips *mcore) { }
50
51static inline unsigned int bcma_core_mips_irq(struct bcma_device *dev)
52{
53 return 0;
54}
55#endif
56
57extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore); 42extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
58 43
59#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */ 44#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
diff --git a/include/linux/bcma/bcma_driver_pci.h b/include/linux/bcma/bcma_driver_pci.h
index 3f809ae372c4..8e90004fdfd7 100644
--- a/include/linux/bcma/bcma_driver_pci.h
+++ b/include/linux/bcma/bcma_driver_pci.h
@@ -238,12 +238,8 @@ struct bcma_drv_pci {
238#define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val) 238#define pcicore_write16(pc, offset, val) bcma_write16((pc)->core, offset, val)
239#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val) 239#define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
240 240
241extern void bcma_core_pci_early_init(struct bcma_drv_pci *pc); 241extern int bcma_core_pci_irq_ctl(struct bcma_bus *bus,
242extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
243extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
244 struct bcma_device *core, bool enable); 242 struct bcma_device *core, bool enable);
245extern void bcma_core_pci_up(struct bcma_bus *bus);
246extern void bcma_core_pci_down(struct bcma_bus *bus);
247extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up); 243extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
248 244
249extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); 245extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
diff --git a/include/linux/bcma/bcma_driver_pcie2.h b/include/linux/bcma/bcma_driver_pcie2.h
index 5988b05781c3..31e6d17ab798 100644
--- a/include/linux/bcma/bcma_driver_pcie2.h
+++ b/include/linux/bcma/bcma_driver_pcie2.h
@@ -143,6 +143,8 @@
143 143
144struct bcma_drv_pcie2 { 144struct bcma_drv_pcie2 {
145 struct bcma_device *core; 145 struct bcma_device *core;
146
147 u16 reqsize;
146}; 148};
147 149
148#define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset) 150#define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset)
@@ -153,6 +155,4 @@ struct bcma_drv_pcie2 {
153#define pcie2_set32(pcie2, offset, set) bcma_set32((pcie2)->core, offset, set) 155#define pcie2_set32(pcie2, offset, set) bcma_set32((pcie2)->core, offset, set)
154#define pcie2_mask32(pcie2, offset, mask) bcma_mask32((pcie2)->core, offset, mask) 156#define pcie2_mask32(pcie2, offset, mask) bcma_mask32((pcie2)->core, offset, mask)
155 157
156void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2);
157
158#endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */ 158#endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */