aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-03-13 15:03:34 -0400
committerDavid S. Miller <davem@davemloft.net>2016-03-13 15:03:34 -0400
commit00e3d2ef184d005db4e14d64f5870d556183e638 (patch)
tree25412f18891e3f09e358c436a2251bccc61429af
parentf22f5f6060584ac66a7a43f644788fda8fc7b1f8 (diff)
parent836856e3bd61d0644e5178a2c1b51d90459e2788 (diff)
Merge tag 'wireless-drivers-next-for-davem-2016-03-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers patches for 4.6 Major changes: ath10k * dt: add bindings for ipq4019 wifi block * start adding support for qca4019 chip ath9k * add device ID for Toshiba WLM-20U2/GN-1080 * allow more than one interface on DFS channels bcma * move flash detection code to ChipCommon core driver brcmfmac * IPv6 Neighbor discovery offload * driver settings that can be populated from different sources * country code setting in firmware * length checks to validate firmware events * new way to determine device memory size needed for BCM4366 * various offloads during Wake on Wireless LAN (WoWLAN) * full Management Frame Protection (MFP) support iwlwifi * add support for thermal device / cooling device * improvements in scheduled scan without profiles * new firmware support (-21.ucode) * add MSIX support for 9000 devices * enable MU-MIMO and take care of firmware restart * add support for large SKBs in mvm to reach A-MSDU * add support for filtering frames from a BA session * start implementing the new Rx path for 9000 devices * enable the new Radio Resource Management (RRM) nl80211 feature flag * add a new module paramater to disable VHT * build infrastructure for Dynamic Queue Allocation ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt89
-rw-r--r--drivers/bcma/Kconfig5
-rw-r--r--drivers/bcma/Makefile1
-rw-r--r--drivers/bcma/bcma_private.h18
-rw-r--r--drivers/bcma/driver_chipcommon.c30
-rw-r--r--drivers/bcma/driver_chipcommon_pflash.c49
-rw-r--r--drivers/bcma/driver_mips.c63
-rw-r--r--drivers/bcma/main.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/Kconfig6
-rw-r--r--drivers/net/wireless/ath/ath10k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath10k/ahb.c933
-rw-r--r--drivers/net/wireless/ath/ath10k/ahb.h87
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c48
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h20
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c46
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c41
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c8
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h169
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c54
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c146
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c39
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h24
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c57
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c171
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h49
-rw-r--r--drivers/net/wireless/ath/ath10k/targaddrs.h3
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h15
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c162
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h92
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_aic.c79
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_aic.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h65
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/ath/carl9170/fwcmd.h8
-rw-r--r--drivers/net/wireless/ath/carl9170/fwdesc.h6
-rw-r--r--drivers/net/wireless/ath/carl9170/hw.h73
-rw-r--r--drivers/net/wireless/ath/carl9170/version.h6
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c162
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c6
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c112
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c5
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c46
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h11
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c174
-rw-r--r--drivers/net/wireless/atmel/at76c50x-usb.c2
-rw-r--r--drivers/net/wireless/broadcom/b43/main.c6
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c105
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c617
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h20
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c152
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h43
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c180
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h9
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c14
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c38
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h20
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c57
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h68
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h29
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c11
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c22
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h4
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c26
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c206
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c103
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h2
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c16
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-7000.c4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-8000.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-9000.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-csr.h49
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h4
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-drv.c7
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-fh.h24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h10
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c5
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-prph.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-trans.h1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/d3.c6
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h52
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h126
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/fw.c28
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c84
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mvm.h106
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ops.c92
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rs.c25
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rx.c63
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c146
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/scan.c36
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.c34
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/sta.h23
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tt.c461
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c186
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/drv.c41
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/internal.h100
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/rx.c206
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/trans.c277
-rw-r--r--drivers/net/wireless/intel/iwlwifi/pcie/tx.c10
-rw-r--r--drivers/net/wireless/marvell/mwifiex/11h.c6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/cfg80211.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/ioctl.h6
-rw-r--r--drivers/net/wireless/marvell/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/marvell/mwifiex/pcie.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sdio.c16
-rw-r--r--drivers/net/wireless/marvell/mwifiex/sta_ioctl.c1
-rw-r--r--drivers/net/wireless/marvell/mwifiex/tdls.c7
-rw-r--r--drivers/net/wireless/marvell/mwifiex/uap_cmd.c2
-rw-r--r--drivers/net/wireless/marvell/mwifiex/usb.c4
-rw-r--r--drivers/net/wireless/marvell/mwifiex/util.c20
-rw-r--r--drivers/net/wireless/mediatek/mt7601u/mcu.c4
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2800usb.c1
-rw-r--r--drivers/net/wireless/ralink/rt2x00/rt2x00debug.c5
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/Kconfig2
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c183
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h2
-rw-r--r--drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h55
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/core.c60
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/pci.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rc.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c23
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c12
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c6
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c20
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c27
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c4
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/wifi.h22
-rw-r--r--drivers/net/wireless/st/cw1200/cw1200_spi.c9
-rw-r--r--drivers/net/wireless/st/cw1200/pm.h9
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h11
-rw-r--r--include/linux/platform_data/brcmfmac-sdio.h135
-rw-r--r--include/linux/platform_data/brcmfmac.h185
162 files changed, 6422 insertions, 1819 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
index edefc26c6204..96aae6b4f736 100644
--- a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -1,17 +1,46 @@
1* Qualcomm Atheros ath10k wireless devices 1* Qualcomm Atheros ath10k wireless devices
2 2
3For ath10k devices the calibration data can be provided through Device
4Tree. The node is a child node of the PCI controller.
5
6Required properties: 3Required properties:
7-compatible : Should be "qcom,ath10k" 4- compatible: Should be one of the following:
5 * "qcom,ath10k"
6 * "qcom,ipq4019-wifi"
7
8PCI based devices uses compatible string "qcom,ath10k" and takes only
9calibration data via "qcom,ath10k-calibration-data". Rest of the properties
10are not applicable for PCI based devices.
11
12AHB based devices (i.e. ipq4019) uses compatible string "qcom,ipq4019-wifi"
13and also uses most of the properties defined in this doc.
8 14
9Optional properties: 15Optional properties:
16- reg: Address and length of the register set for the device.
17- resets: Must contain an entry for each entry in reset-names.
18 See ../reset/reseti.txt for details.
19- reset-names: Must include the list of following reset names,
20 "wifi_cpu_init"
21 "wifi_radio_srif"
22 "wifi_radio_warm"
23 "wifi_radio_cold"
24 "wifi_core_warm"
25 "wifi_core_cold"
26- clocks: List of clock specifiers, must contain an entry for each required
27 entry in clock-names.
28- clock-names: Should contain the clock names "wifi_wcss_cmd", "wifi_wcss_ref",
29 "wifi_wcss_rtc".
30- interrupts: List of interrupt lines. Must contain an entry
31 for each entry in the interrupt-names property.
32- interrupt-names: Must include the entries for MSI interrupt
33 names ("msi0" to "msi15") and legacy interrupt
34 name ("legacy"),
35- qcom,msi_addr: MSI interrupt address.
36- qcom,msi_base: Base value to add before writing MSI data into
37 MSI address register.
10- qcom,ath10k-calibration-data : calibration data as an array, the 38- qcom,ath10k-calibration-data : calibration data as an array, the
11 length can vary between hw versions 39 length can vary between hw versions
12 40
41Example (to supply the calibration data alone):
13 42
14Example: 43In this example, the node is defined as child node of the PCI controller.
15 44
16pci { 45pci {
17 pcie@0 { 46 pcie@0 {
@@ -28,3 +57,53 @@ pci {
28 }; 57 };
29 }; 58 };
30}; 59};
60
61Example (to supply ipq4019 SoC wifi block details):
62
63wifi0: wifi@a000000 {
64 compatible = "qcom,ipq4019-wifi";
65 reg = <0xa000000 0x200000>;
66 resets = <&gcc WIFI0_CPU_INIT_RESET>,
67 <&gcc WIFI0_RADIO_SRIF_RESET>,
68 <&gcc WIFI0_RADIO_WARM_RESET>,
69 <&gcc WIFI0_RADIO_COLD_RESET>,
70 <&gcc WIFI0_CORE_WARM_RESET>,
71 <&gcc WIFI0_CORE_COLD_RESET>;
72 reset-names = "wifi_cpu_init",
73 "wifi_radio_srif",
74 "wifi_radio_warm",
75 "wifi_radio_cold",
76 "wifi_core_warm",
77 "wifi_core_cold";
78 clocks = <&gcc GCC_WCSS2G_CLK>,
79 <&gcc GCC_WCSS2G_REF_CLK>,
80 <&gcc GCC_WCSS2G_RTC_CLK>;
81 clock-names = "wifi_wcss_cmd",
82 "wifi_wcss_ref",
83 "wifi_wcss_rtc";
84 interrupts = <0 0x20 0x1>,
85 <0 0x21 0x1>,
86 <0 0x22 0x1>,
87 <0 0x23 0x1>,
88 <0 0x24 0x1>,
89 <0 0x25 0x1>,
90 <0 0x26 0x1>,
91 <0 0x27 0x1>,
92 <0 0x28 0x1>,
93 <0 0x29 0x1>,
94 <0 0x2a 0x1>,
95 <0 0x2b 0x1>,
96 <0 0x2c 0x1>,
97 <0 0x2d 0x1>,
98 <0 0x2e 0x1>,
99 <0 0x2f 0x1>,
100 <0 0xa8 0x0>;
101 interrupt-names = "msi0", "msi1", "msi2", "msi3",
102 "msi4", "msi5", "msi6", "msi7",
103 "msi8", "msi9", "msi10", "msi11",
104 "msi12", "msi13", "msi14", "msi15",
105 "legacy";
106 qcom,msi_addr = <0x0b006040>;
107 qcom,msi_base = <0x40>;
108 qcom,ath10k-calibration-data = [ 01 02 03 ... ];
109};
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index 023d448ed3fa..efdc2ae8441a 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -70,6 +70,11 @@ config BCMA_DRIVER_MIPS
70 70
71 If unsure, say N 71 If unsure, say N
72 72
73config BCMA_PFLASH
74 bool
75 depends on BCMA_DRIVER_MIPS
76 default y
77
73config BCMA_SFLASH 78config BCMA_SFLASH
74 bool 79 bool
75 depends on BCMA_DRIVER_MIPS 80 depends on BCMA_DRIVER_MIPS
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index f32af9b76bcd..087948a1d20d 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -1,6 +1,7 @@
1bcma-y += main.o scan.o core.o sprom.o 1bcma-y += main.o scan.o core.o sprom.o
2bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o 2bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
3bcma-y += driver_chipcommon_b.o 3bcma-y += driver_chipcommon_b.o
4bcma-$(CONFIG_BCMA_PFLASH) += driver_chipcommon_pflash.o
4bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o 5bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
5bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o 6bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
6bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o 7bcma-$(CONFIG_BCMA_DRIVER_PCI) += driver_pci.o
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 7e4ddfb076d3..eda09090cb52 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -47,9 +47,6 @@ int bcma_sprom_get(struct bcma_bus *bus);
47void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc); 47void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc);
48void bcma_core_chipcommon_init(struct bcma_drv_cc *cc); 48void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
49void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); 49void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
50#ifdef CONFIG_BCMA_DRIVER_MIPS
51extern struct platform_device bcma_pflash_dev;
52#endif /* CONFIG_BCMA_DRIVER_MIPS */
53 50
54/* driver_chipcommon_b.c */ 51/* driver_chipcommon_b.c */
55int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb); 52int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb);
@@ -61,6 +58,21 @@ void bcma_pmu_init(struct bcma_drv_cc *cc);
61u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); 58u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
62u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); 59u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
63 60
61/**************************************************
62 * driver_chipcommon_sflash.c
63 **************************************************/
64
65#ifdef CONFIG_BCMA_PFLASH
66extern struct platform_device bcma_pflash_dev;
67int bcma_pflash_init(struct bcma_drv_cc *cc);
68#else
69static inline int bcma_pflash_init(struct bcma_drv_cc *cc)
70{
71 bcma_err(cc->core->bus, "Parallel flash not supported\n");
72 return 0;
73}
74#endif /* CONFIG_BCMA_PFLASH */
75
64#ifdef CONFIG_BCMA_SFLASH 76#ifdef CONFIG_BCMA_SFLASH
65/* driver_chipcommon_sflash.c */ 77/* driver_chipcommon_sflash.c */
66int bcma_sflash_init(struct bcma_drv_cc *cc); 78int bcma_sflash_init(struct bcma_drv_cc *cc);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index b0f44a2937b9..921ce1834673 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -115,6 +115,33 @@ int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
115 return 0; 115 return 0;
116} 116}
117 117
118static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc)
119{
120 struct bcma_bus *bus = cc->core->bus;
121
122 switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
123 case BCMA_CC_FLASHT_STSER:
124 case BCMA_CC_FLASHT_ATSER:
125 bcma_debug(bus, "Found serial flash\n");
126 bcma_sflash_init(cc);
127 break;
128 case BCMA_CC_FLASHT_PARA:
129 bcma_debug(bus, "Found parallel flash\n");
130 bcma_pflash_init(cc);
131 break;
132 default:
133 bcma_err(bus, "Flash type not supported\n");
134 }
135
136 if (cc->core->id.rev == 38 ||
137 bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
138 if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
139 bcma_debug(bus, "Found NAND flash\n");
140 bcma_nflash_init(cc);
141 }
142 }
143}
144
118void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) 145void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
119{ 146{
120 struct bcma_bus *bus = cc->core->bus; 147 struct bcma_bus *bus = cc->core->bus;
@@ -136,6 +163,9 @@ void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
136 if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC) 163 if (IS_BUILTIN(CONFIG_BCM47XX) && bus->hosttype == BCMA_HOSTTYPE_SOC)
137 bcma_chipco_serial_init(cc); 164 bcma_chipco_serial_init(cc);
138 165
166 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
167 bcma_core_chipcommon_flash_detect(cc);
168
139 cc->early_setup_done = true; 169 cc->early_setup_done = true;
140} 170}
141 171
diff --git a/drivers/bcma/driver_chipcommon_pflash.c b/drivers/bcma/driver_chipcommon_pflash.c
new file mode 100644
index 000000000000..3b497c9ee0d4
--- /dev/null
+++ b/drivers/bcma/driver_chipcommon_pflash.c
@@ -0,0 +1,49 @@
1/*
2 * Broadcom specific AMBA
3 * ChipCommon parallel flash
4 *
5 * Licensed under the GNU/GPL. See COPYING for details.
6 */
7
8#include "bcma_private.h"
9
10#include <linux/bcma/bcma.h>
11#include <linux/mtd/physmap.h>
12#include <linux/platform_device.h>
13
14static const char * const part_probes[] = { "bcm47xxpart", NULL };
15
16static struct physmap_flash_data bcma_pflash_data = {
17 .part_probe_types = part_probes,
18};
19
20static struct resource bcma_pflash_resource = {
21 .name = "bcma_pflash",
22 .flags = IORESOURCE_MEM,
23};
24
25struct platform_device bcma_pflash_dev = {
26 .name = "physmap-flash",
27 .dev = {
28 .platform_data = &bcma_pflash_data,
29 },
30 .resource = &bcma_pflash_resource,
31 .num_resources = 1,
32};
33
34int bcma_pflash_init(struct bcma_drv_cc *cc)
35{
36 struct bcma_pflash *pflash = &cc->pflash;
37
38 pflash->present = true;
39
40 if (!(bcma_read32(cc->core, BCMA_CC_FLASH_CFG) & BCMA_CC_FLASH_CFG_DS))
41 bcma_pflash_data.width = 1;
42 else
43 bcma_pflash_data.width = 2;
44
45 bcma_pflash_resource.start = BCMA_SOC_FLASH2;
46 bcma_pflash_resource.end = BCMA_SOC_FLASH2 + BCMA_SOC_FLASH2_SZ;
47
48 return 0;
49}
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c
index a40a203314db..96f171328200 100644
--- a/drivers/bcma/driver_mips.c
+++ b/drivers/bcma/driver_mips.c
@@ -14,8 +14,6 @@
14 14
15#include <linux/bcma/bcma.h> 15#include <linux/bcma/bcma.h>
16 16
17#include <linux/mtd/physmap.h>
18#include <linux/platform_device.h>
19#include <linux/serial.h> 17#include <linux/serial.h>
20#include <linux/serial_core.h> 18#include <linux/serial_core.h>
21#include <linux/serial_reg.h> 19#include <linux/serial_reg.h>
@@ -32,26 +30,6 @@ enum bcma_boot_dev {
32 BCMA_BOOT_DEV_NAND, 30 BCMA_BOOT_DEV_NAND,
33}; 31};
34 32
35static const char * const part_probes[] = { "bcm47xxpart", NULL };
36
37static struct physmap_flash_data bcma_pflash_data = {
38 .part_probe_types = part_probes,
39};
40
41static struct resource bcma_pflash_resource = {
42 .name = "bcma_pflash",
43 .flags = IORESOURCE_MEM,
44};
45
46struct platform_device bcma_pflash_dev = {
47 .name = "physmap-flash",
48 .dev = {
49 .platform_data = &bcma_pflash_data,
50 },
51 .resource = &bcma_pflash_resource,
52 .num_resources = 1,
53};
54
55/* The 47162a0 hangs when reading MIPS DMP registers registers */ 33/* The 47162a0 hangs when reading MIPS DMP registers registers */
56static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev) 34static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
57{ 35{
@@ -272,48 +250,11 @@ static enum bcma_boot_dev bcma_boot_dev(struct bcma_bus *bus)
272 return BCMA_BOOT_DEV_SERIAL; 250 return BCMA_BOOT_DEV_SERIAL;
273} 251}
274 252
275static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) 253static void bcma_core_mips_nvram_init(struct bcma_drv_mips *mcore)
276{ 254{
277 struct bcma_bus *bus = mcore->core->bus; 255 struct bcma_bus *bus = mcore->core->bus;
278 struct bcma_drv_cc *cc = &bus->drv_cc;
279 struct bcma_pflash *pflash = &cc->pflash;
280 enum bcma_boot_dev boot_dev; 256 enum bcma_boot_dev boot_dev;
281 257
282 switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
283 case BCMA_CC_FLASHT_STSER:
284 case BCMA_CC_FLASHT_ATSER:
285 bcma_debug(bus, "Found serial flash\n");
286 bcma_sflash_init(cc);
287 break;
288 case BCMA_CC_FLASHT_PARA:
289 bcma_debug(bus, "Found parallel flash\n");
290 pflash->present = true;
291 pflash->window = BCMA_SOC_FLASH2;
292 pflash->window_size = BCMA_SOC_FLASH2_SZ;
293
294 if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
295 BCMA_CC_FLASH_CFG_DS) == 0)
296 pflash->buswidth = 1;
297 else
298 pflash->buswidth = 2;
299
300 bcma_pflash_data.width = pflash->buswidth;
301 bcma_pflash_resource.start = pflash->window;
302 bcma_pflash_resource.end = pflash->window + pflash->window_size;
303
304 break;
305 default:
306 bcma_err(bus, "Flash type not supported\n");
307 }
308
309 if (cc->core->id.rev == 38 ||
310 bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
311 if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
312 bcma_debug(bus, "Found NAND flash\n");
313 bcma_nflash_init(cc);
314 }
315 }
316
317 /* Determine flash type this SoC boots from */ 258 /* Determine flash type this SoC boots from */
318 boot_dev = bcma_boot_dev(bus); 259 boot_dev = bcma_boot_dev(bus);
319 switch (boot_dev) { 260 switch (boot_dev) {
@@ -340,7 +281,7 @@ void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
340 if (mcore->early_setup_done) 281 if (mcore->early_setup_done)
341 return; 282 return;
342 283
343 bcma_core_mips_flash_detect(mcore); 284 bcma_core_mips_nvram_init(mcore);
344 285
345 mcore->early_setup_done = true; 286 mcore->early_setup_done = true;
346} 287}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index c466f752b067..786be8fed39e 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -350,7 +350,7 @@ static int bcma_register_devices(struct bcma_bus *bus)
350 bcma_register_core(bus, core); 350 bcma_register_core(bus, core);
351 } 351 }
352 352
353#ifdef CONFIG_BCMA_DRIVER_MIPS 353#ifdef CONFIG_BCMA_PFLASH
354 if (bus->drv_cc.pflash.present) { 354 if (bus->drv_cc.pflash.present) {
355 err = platform_device_register(&bcma_pflash_dev); 355 err = platform_device_register(&bcma_pflash_dev);
356 if (err) 356 if (err)
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
index 03aa35f999a1..db1ca629cbd6 100644
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -15,6 +15,12 @@ config ATH10K_PCI
15 ---help--- 15 ---help---
16 This module adds support for PCIE bus 16 This module adds support for PCIE bus
17 17
18config ATH10K_AHB
19 bool "Atheros ath10k AHB support"
20 depends on ATH10K_PCI && OF && RESET_CONTROLLER
21 ---help---
22 This module adds support for AHB bus
23
18config ATH10K_DEBUG 24config ATH10K_DEBUG
19 bool "Atheros ath10k debugging" 25 bool "Atheros ath10k debugging"
20 depends on ATH10K 26 depends on ATH10K
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
index c04fb00e7930..930fadd940d8 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -25,5 +25,7 @@ obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
25ath10k_pci-y += pci.o \ 25ath10k_pci-y += pci.o \
26 ce.o 26 ce.o
27 27
28ath10k_pci-$(CONFIG_ATH10K_AHB) += ahb.o
29
28# for tracing framework to find trace.h 30# for tracing framework to find trace.h
29CFLAGS_trace.o := -I$(src) 31CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/ath10k/ahb.c b/drivers/net/wireless/ath/ath10k/ahb.c
new file mode 100644
index 000000000000..bd62bc19e758
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/ahb.c
@@ -0,0 +1,933 @@
1/*
2 * Copyright (c) 2016 Qualcomm Atheros, Inc. All rights reserved.
3 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_device.h>
20#include <linux/clk.h>
21#include <linux/reset.h>
22#include "core.h"
23#include "debug.h"
24#include "pci.h"
25#include "ahb.h"
26
27static const struct of_device_id ath10k_ahb_of_match[] = {
28 /* TODO: enable this entry once everything in place.
29 * { .compatible = "qcom,ipq4019-wifi",
30 * .data = (void *)ATH10K_HW_QCA4019 },
31 */
32 { }
33};
34
35MODULE_DEVICE_TABLE(of, ath10k_ahb_of_match);
36
37static inline struct ath10k_ahb *ath10k_ahb_priv(struct ath10k *ar)
38{
39 return &((struct ath10k_pci *)ar->drv_priv)->ahb[0];
40}
41
42static void ath10k_ahb_write32(struct ath10k *ar, u32 offset, u32 value)
43{
44 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
45
46 iowrite32(value, ar_ahb->mem + offset);
47}
48
49static u32 ath10k_ahb_read32(struct ath10k *ar, u32 offset)
50{
51 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
52
53 return ioread32(ar_ahb->mem + offset);
54}
55
56static u32 ath10k_ahb_gcc_read32(struct ath10k *ar, u32 offset)
57{
58 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
59
60 return ioread32(ar_ahb->gcc_mem + offset);
61}
62
63static void ath10k_ahb_tcsr_write32(struct ath10k *ar, u32 offset, u32 value)
64{
65 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
66
67 iowrite32(value, ar_ahb->tcsr_mem + offset);
68}
69
70static u32 ath10k_ahb_tcsr_read32(struct ath10k *ar, u32 offset)
71{
72 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
73
74 return ioread32(ar_ahb->tcsr_mem + offset);
75}
76
77static u32 ath10k_ahb_soc_read32(struct ath10k *ar, u32 addr)
78{
79 return ath10k_ahb_read32(ar, RTC_SOC_BASE_ADDRESS + addr);
80}
81
82static int ath10k_ahb_get_num_banks(struct ath10k *ar)
83{
84 if (ar->hw_rev == ATH10K_HW_QCA4019)
85 return 1;
86
87 ath10k_warn(ar, "unknown number of banks, assuming 1\n");
88 return 1;
89}
90
91static int ath10k_ahb_clock_init(struct ath10k *ar)
92{
93 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
94 struct device *dev;
95 int ret;
96
97 dev = &ar_ahb->pdev->dev;
98
99 ar_ahb->cmd_clk = clk_get(dev, "wifi_wcss_cmd");
100 if (IS_ERR_OR_NULL(ar_ahb->cmd_clk)) {
101 ath10k_err(ar, "failed to get cmd clk: %ld\n",
102 PTR_ERR(ar_ahb->cmd_clk));
103 ret = ar_ahb->cmd_clk ? PTR_ERR(ar_ahb->cmd_clk) : -ENODEV;
104 goto out;
105 }
106
107 ar_ahb->ref_clk = clk_get(dev, "wifi_wcss_ref");
108 if (IS_ERR_OR_NULL(ar_ahb->ref_clk)) {
109 ath10k_err(ar, "failed to get ref clk: %ld\n",
110 PTR_ERR(ar_ahb->ref_clk));
111 ret = ar_ahb->ref_clk ? PTR_ERR(ar_ahb->ref_clk) : -ENODEV;
112 goto err_cmd_clk_put;
113 }
114
115 ar_ahb->rtc_clk = clk_get(dev, "wifi_wcss_rtc");
116 if (IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {
117 ath10k_err(ar, "failed to get rtc clk: %ld\n",
118 PTR_ERR(ar_ahb->rtc_clk));
119 ret = ar_ahb->rtc_clk ? PTR_ERR(ar_ahb->rtc_clk) : -ENODEV;
120 goto err_ref_clk_put;
121 }
122
123 return 0;
124
125err_ref_clk_put:
126 clk_put(ar_ahb->ref_clk);
127
128err_cmd_clk_put:
129 clk_put(ar_ahb->cmd_clk);
130
131out:
132 return ret;
133}
134
135static void ath10k_ahb_clock_deinit(struct ath10k *ar)
136{
137 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
138
139 if (!IS_ERR_OR_NULL(ar_ahb->cmd_clk))
140 clk_put(ar_ahb->cmd_clk);
141
142 if (!IS_ERR_OR_NULL(ar_ahb->ref_clk))
143 clk_put(ar_ahb->ref_clk);
144
145 if (!IS_ERR_OR_NULL(ar_ahb->rtc_clk))
146 clk_put(ar_ahb->rtc_clk);
147
148 ar_ahb->cmd_clk = NULL;
149 ar_ahb->ref_clk = NULL;
150 ar_ahb->rtc_clk = NULL;
151}
152
153static int ath10k_ahb_clock_enable(struct ath10k *ar)
154{
155 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
156 struct device *dev;
157 int ret;
158
159 dev = &ar_ahb->pdev->dev;
160
161 if (IS_ERR_OR_NULL(ar_ahb->cmd_clk) ||
162 IS_ERR_OR_NULL(ar_ahb->ref_clk) ||
163 IS_ERR_OR_NULL(ar_ahb->rtc_clk)) {
164 ath10k_err(ar, "clock(s) is/are not initialized\n");
165 ret = -EIO;
166 goto out;
167 }
168
169 ret = clk_prepare_enable(ar_ahb->cmd_clk);
170 if (ret) {
171 ath10k_err(ar, "failed to enable cmd clk: %d\n", ret);
172 goto out;
173 }
174
175 ret = clk_prepare_enable(ar_ahb->ref_clk);
176 if (ret) {
177 ath10k_err(ar, "failed to enable ref clk: %d\n", ret);
178 goto err_cmd_clk_disable;
179 }
180
181 ret = clk_prepare_enable(ar_ahb->rtc_clk);
182 if (ret) {
183 ath10k_err(ar, "failed to enable rtc clk: %d\n", ret);
184 goto err_ref_clk_disable;
185 }
186
187 return 0;
188
189err_ref_clk_disable:
190 clk_disable_unprepare(ar_ahb->ref_clk);
191
192err_cmd_clk_disable:
193 clk_disable_unprepare(ar_ahb->cmd_clk);
194
195out:
196 return ret;
197}
198
199static void ath10k_ahb_clock_disable(struct ath10k *ar)
200{
201 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
202
203 if (!IS_ERR_OR_NULL(ar_ahb->cmd_clk))
204 clk_disable_unprepare(ar_ahb->cmd_clk);
205
206 if (!IS_ERR_OR_NULL(ar_ahb->ref_clk))
207 clk_disable_unprepare(ar_ahb->ref_clk);
208
209 if (!IS_ERR_OR_NULL(ar_ahb->rtc_clk))
210 clk_disable_unprepare(ar_ahb->rtc_clk);
211}
212
213static int ath10k_ahb_rst_ctrl_init(struct ath10k *ar)
214{
215 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
216 struct device *dev;
217 int ret;
218
219 dev = &ar_ahb->pdev->dev;
220
221 ar_ahb->core_cold_rst = reset_control_get(dev, "wifi_core_cold");
222 if (IS_ERR_OR_NULL(ar_ahb->core_cold_rst)) {
223 ath10k_err(ar, "failed to get core cold rst ctrl: %ld\n",
224 PTR_ERR(ar_ahb->core_cold_rst));
225 ret = ar_ahb->core_cold_rst ?
226 PTR_ERR(ar_ahb->core_cold_rst) : -ENODEV;
227 goto out;
228 }
229
230 ar_ahb->radio_cold_rst = reset_control_get(dev, "wifi_radio_cold");
231 if (IS_ERR_OR_NULL(ar_ahb->radio_cold_rst)) {
232 ath10k_err(ar, "failed to get radio cold rst ctrl: %ld\n",
233 PTR_ERR(ar_ahb->radio_cold_rst));
234 ret = ar_ahb->radio_cold_rst ?
235 PTR_ERR(ar_ahb->radio_cold_rst) : -ENODEV;
236 goto err_core_cold_rst_put;
237 }
238
239 ar_ahb->radio_warm_rst = reset_control_get(dev, "wifi_radio_warm");
240 if (IS_ERR_OR_NULL(ar_ahb->radio_warm_rst)) {
241 ath10k_err(ar, "failed to get radio warm rst ctrl: %ld\n",
242 PTR_ERR(ar_ahb->radio_warm_rst));
243 ret = ar_ahb->radio_warm_rst ?
244 PTR_ERR(ar_ahb->radio_warm_rst) : -ENODEV;
245 goto err_radio_cold_rst_put;
246 }
247
248 ar_ahb->radio_srif_rst = reset_control_get(dev, "wifi_radio_srif");
249 if (IS_ERR_OR_NULL(ar_ahb->radio_srif_rst)) {
250 ath10k_err(ar, "failed to get radio srif rst ctrl: %ld\n",
251 PTR_ERR(ar_ahb->radio_srif_rst));
252 ret = ar_ahb->radio_srif_rst ?
253 PTR_ERR(ar_ahb->radio_srif_rst) : -ENODEV;
254 goto err_radio_warm_rst_put;
255 }
256
257 ar_ahb->cpu_init_rst = reset_control_get(dev, "wifi_cpu_init");
258 if (IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {
259 ath10k_err(ar, "failed to get cpu init rst ctrl: %ld\n",
260 PTR_ERR(ar_ahb->cpu_init_rst));
261 ret = ar_ahb->cpu_init_rst ?
262 PTR_ERR(ar_ahb->cpu_init_rst) : -ENODEV;
263 goto err_radio_srif_rst_put;
264 }
265
266 return 0;
267
268err_radio_srif_rst_put:
269 reset_control_put(ar_ahb->radio_srif_rst);
270
271err_radio_warm_rst_put:
272 reset_control_put(ar_ahb->radio_warm_rst);
273
274err_radio_cold_rst_put:
275 reset_control_put(ar_ahb->radio_cold_rst);
276
277err_core_cold_rst_put:
278 reset_control_put(ar_ahb->core_cold_rst);
279
280out:
281 return ret;
282}
283
284static void ath10k_ahb_rst_ctrl_deinit(struct ath10k *ar)
285{
286 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
287
288 if (!IS_ERR_OR_NULL(ar_ahb->core_cold_rst))
289 reset_control_put(ar_ahb->core_cold_rst);
290
291 if (!IS_ERR_OR_NULL(ar_ahb->radio_cold_rst))
292 reset_control_put(ar_ahb->radio_cold_rst);
293
294 if (!IS_ERR_OR_NULL(ar_ahb->radio_warm_rst))
295 reset_control_put(ar_ahb->radio_warm_rst);
296
297 if (!IS_ERR_OR_NULL(ar_ahb->radio_srif_rst))
298 reset_control_put(ar_ahb->radio_srif_rst);
299
300 if (!IS_ERR_OR_NULL(ar_ahb->cpu_init_rst))
301 reset_control_put(ar_ahb->cpu_init_rst);
302
303 ar_ahb->core_cold_rst = NULL;
304 ar_ahb->radio_cold_rst = NULL;
305 ar_ahb->radio_warm_rst = NULL;
306 ar_ahb->radio_srif_rst = NULL;
307 ar_ahb->cpu_init_rst = NULL;
308}
309
310static int ath10k_ahb_release_reset(struct ath10k *ar)
311{
312 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
313 int ret;
314
315 if (IS_ERR_OR_NULL(ar_ahb->radio_cold_rst) ||
316 IS_ERR_OR_NULL(ar_ahb->radio_warm_rst) ||
317 IS_ERR_OR_NULL(ar_ahb->radio_srif_rst) ||
318 IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {
319 ath10k_err(ar, "rst ctrl(s) is/are not initialized\n");
320 return -EINVAL;
321 }
322
323 ret = reset_control_deassert(ar_ahb->radio_cold_rst);
324 if (ret) {
325 ath10k_err(ar, "failed to deassert radio cold rst: %d\n", ret);
326 return ret;
327 }
328
329 ret = reset_control_deassert(ar_ahb->radio_warm_rst);
330 if (ret) {
331 ath10k_err(ar, "failed to deassert radio warm rst: %d\n", ret);
332 return ret;
333 }
334
335 ret = reset_control_deassert(ar_ahb->radio_srif_rst);
336 if (ret) {
337 ath10k_err(ar, "failed to deassert radio srif rst: %d\n", ret);
338 return ret;
339 }
340
341 ret = reset_control_deassert(ar_ahb->cpu_init_rst);
342 if (ret) {
343 ath10k_err(ar, "failed to deassert cpu init rst: %d\n", ret);
344 return ret;
345 }
346
347 return 0;
348}
349
350static void ath10k_ahb_halt_axi_bus(struct ath10k *ar, u32 haltreq_reg,
351 u32 haltack_reg)
352{
353 unsigned long timeout;
354 u32 val;
355
356 /* Issue halt axi bus request */
357 val = ath10k_ahb_tcsr_read32(ar, haltreq_reg);
358 val |= AHB_AXI_BUS_HALT_REQ;
359 ath10k_ahb_tcsr_write32(ar, haltreq_reg, val);
360
361 /* Wait for axi bus halted ack */
362 timeout = jiffies + msecs_to_jiffies(ATH10K_AHB_AXI_BUS_HALT_TIMEOUT);
363 do {
364 val = ath10k_ahb_tcsr_read32(ar, haltack_reg);
365 if (val & AHB_AXI_BUS_HALT_ACK)
366 break;
367
368 mdelay(1);
369 } while (time_before(jiffies, timeout));
370
371 if (!(val & AHB_AXI_BUS_HALT_ACK)) {
372 ath10k_err(ar, "failed to halt axi bus: %d\n", val);
373 return;
374 }
375
376 ath10k_dbg(ar, ATH10K_DBG_AHB, "axi bus halted\n");
377}
378
379static void ath10k_ahb_halt_chip(struct ath10k *ar)
380{
381 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
382 u32 core_id, glb_cfg_reg, haltreq_reg, haltack_reg;
383 u32 val;
384 int ret;
385
386 if (IS_ERR_OR_NULL(ar_ahb->core_cold_rst) ||
387 IS_ERR_OR_NULL(ar_ahb->radio_cold_rst) ||
388 IS_ERR_OR_NULL(ar_ahb->radio_warm_rst) ||
389 IS_ERR_OR_NULL(ar_ahb->radio_srif_rst) ||
390 IS_ERR_OR_NULL(ar_ahb->cpu_init_rst)) {
391 ath10k_err(ar, "rst ctrl(s) is/are not initialized\n");
392 return;
393 }
394
395 core_id = ath10k_ahb_read32(ar, ATH10K_AHB_WLAN_CORE_ID_REG);
396
397 switch (core_id) {
398 case 0:
399 glb_cfg_reg = ATH10K_AHB_TCSR_WIFI0_GLB_CFG;
400 haltreq_reg = ATH10K_AHB_TCSR_WCSS0_HALTREQ;
401 haltack_reg = ATH10K_AHB_TCSR_WCSS0_HALTACK;
402 break;
403 case 1:
404 glb_cfg_reg = ATH10K_AHB_TCSR_WIFI1_GLB_CFG;
405 haltreq_reg = ATH10K_AHB_TCSR_WCSS1_HALTREQ;
406 haltack_reg = ATH10K_AHB_TCSR_WCSS1_HALTACK;
407 break;
408 default:
409 ath10k_err(ar, "invalid core id %d found, skipping reset sequence\n",
410 core_id);
411 return;
412 }
413
414 ath10k_ahb_halt_axi_bus(ar, haltreq_reg, haltack_reg);
415
416 val = ath10k_ahb_tcsr_read32(ar, glb_cfg_reg);
417 val |= TCSR_WIFIX_GLB_CFG_DISABLE_CORE_CLK;
418 ath10k_ahb_tcsr_write32(ar, glb_cfg_reg, val);
419
420 ret = reset_control_assert(ar_ahb->core_cold_rst);
421 if (ret)
422 ath10k_err(ar, "failed to assert core cold rst: %d\n", ret);
423 msleep(1);
424
425 ret = reset_control_assert(ar_ahb->radio_cold_rst);
426 if (ret)
427 ath10k_err(ar, "failed to assert radio cold rst: %d\n", ret);
428 msleep(1);
429
430 ret = reset_control_assert(ar_ahb->radio_warm_rst);
431 if (ret)
432 ath10k_err(ar, "failed to assert radio warm rst: %d\n", ret);
433 msleep(1);
434
435 ret = reset_control_assert(ar_ahb->radio_srif_rst);
436 if (ret)
437 ath10k_err(ar, "failed to assert radio srif rst: %d\n", ret);
438 msleep(1);
439
440 ret = reset_control_assert(ar_ahb->cpu_init_rst);
441 if (ret)
442 ath10k_err(ar, "failed to assert cpu init rst: %d\n", ret);
443 msleep(10);
444
445 /* Clear halt req and core clock disable req before
446 * deasserting wifi core reset.
447 */
448 val = ath10k_ahb_tcsr_read32(ar, haltreq_reg);
449 val &= ~AHB_AXI_BUS_HALT_REQ;
450 ath10k_ahb_tcsr_write32(ar, haltreq_reg, val);
451
452 val = ath10k_ahb_tcsr_read32(ar, glb_cfg_reg);
453 val &= ~TCSR_WIFIX_GLB_CFG_DISABLE_CORE_CLK;
454 ath10k_ahb_tcsr_write32(ar, glb_cfg_reg, val);
455
456 ret = reset_control_deassert(ar_ahb->core_cold_rst);
457 if (ret)
458 ath10k_err(ar, "failed to deassert core cold rst: %d\n", ret);
459
460 ath10k_dbg(ar, ATH10K_DBG_AHB, "core %d reset done\n", core_id);
461}
462
463static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg)
464{
465 struct ath10k *ar = arg;
466 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
467
468 if (!ath10k_pci_irq_pending(ar))
469 return IRQ_NONE;
470
471 ath10k_pci_disable_and_clear_legacy_irq(ar);
472 tasklet_schedule(&ar_pci->intr_tq);
473
474 return IRQ_HANDLED;
475}
476
477static int ath10k_ahb_request_irq_legacy(struct ath10k *ar)
478{
479 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
480 int ret;
481
482 ret = request_irq(ar_ahb->irq,
483 ath10k_ahb_interrupt_handler,
484 IRQF_SHARED, "ath10k_ahb", ar);
485 if (ret) {
486 ath10k_warn(ar, "failed to request legacy irq %d: %d\n",
487 ar_ahb->irq, ret);
488 return ret;
489 }
490
491 return 0;
492}
493
494static void ath10k_ahb_release_irq_legacy(struct ath10k *ar)
495{
496 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
497
498 free_irq(ar_ahb->irq, ar);
499}
500
501static void ath10k_ahb_irq_disable(struct ath10k *ar)
502{
503 ath10k_ce_disable_interrupts(ar);
504 ath10k_pci_disable_and_clear_legacy_irq(ar);
505}
506
507static int ath10k_ahb_resource_init(struct ath10k *ar)
508{
509 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
510 struct platform_device *pdev;
511 struct device *dev;
512 struct resource *res;
513 int ret;
514
515 pdev = ar_ahb->pdev;
516 dev = &pdev->dev;
517
518 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
519 if (!res) {
520 ath10k_err(ar, "failed to get memory resource\n");
521 ret = -ENXIO;
522 goto out;
523 }
524
525 ar_ahb->mem = devm_ioremap_resource(&pdev->dev, res);
526 if (IS_ERR(ar_ahb->mem)) {
527 ath10k_err(ar, "mem ioremap error\n");
528 ret = PTR_ERR(ar_ahb->mem);
529 goto out;
530 }
531
532 ar_ahb->mem_len = resource_size(res);
533
534 ar_ahb->gcc_mem = ioremap_nocache(ATH10K_GCC_REG_BASE,
535 ATH10K_GCC_REG_SIZE);
536 if (!ar_ahb->gcc_mem) {
537 ath10k_err(ar, "gcc mem ioremap error\n");
538 ret = -ENOMEM;
539 goto err_mem_unmap;
540 }
541
542 ar_ahb->tcsr_mem = ioremap_nocache(ATH10K_TCSR_REG_BASE,
543 ATH10K_TCSR_REG_SIZE);
544 if (!ar_ahb->tcsr_mem) {
545 ath10k_err(ar, "tcsr mem ioremap error\n");
546 ret = -ENOMEM;
547 goto err_gcc_mem_unmap;
548 }
549
550 ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
551 if (ret) {
552 ath10k_err(ar, "failed to set 32-bit dma mask: %d\n", ret);
553 goto err_tcsr_mem_unmap;
554 }
555
556 ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
557 if (ret) {
558 ath10k_err(ar, "failed to set 32-bit consistent dma: %d\n",
559 ret);
560 goto err_tcsr_mem_unmap;
561 }
562
563 ret = ath10k_ahb_clock_init(ar);
564 if (ret)
565 goto err_tcsr_mem_unmap;
566
567 ret = ath10k_ahb_rst_ctrl_init(ar);
568 if (ret)
569 goto err_clock_deinit;
570
571 ar_ahb->irq = platform_get_irq_byname(pdev, "legacy");
572 if (ar_ahb->irq < 0) {
573 ath10k_err(ar, "failed to get irq number: %d\n", ar_ahb->irq);
574 goto err_clock_deinit;
575 }
576
577 ath10k_dbg(ar, ATH10K_DBG_BOOT, "irq: %d\n", ar_ahb->irq);
578
579 ath10k_dbg(ar, ATH10K_DBG_BOOT, "mem: 0x%p mem_len: %lu gcc mem: 0x%p tcsr_mem: 0x%p\n",
580 ar_ahb->mem, ar_ahb->mem_len,
581 ar_ahb->gcc_mem, ar_ahb->tcsr_mem);
582 return 0;
583
584err_clock_deinit:
585 ath10k_ahb_clock_deinit(ar);
586
587err_tcsr_mem_unmap:
588 iounmap(ar_ahb->tcsr_mem);
589
590err_gcc_mem_unmap:
591 ar_ahb->tcsr_mem = NULL;
592 iounmap(ar_ahb->gcc_mem);
593
594err_mem_unmap:
595 ar_ahb->gcc_mem = NULL;
596 devm_iounmap(&pdev->dev, ar_ahb->mem);
597
598out:
599 ar_ahb->mem = NULL;
600 return ret;
601}
602
603static void ath10k_ahb_resource_deinit(struct ath10k *ar)
604{
605 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
606 struct device *dev;
607
608 dev = &ar_ahb->pdev->dev;
609
610 if (ar_ahb->mem)
611 devm_iounmap(dev, ar_ahb->mem);
612
613 if (ar_ahb->gcc_mem)
614 iounmap(ar_ahb->gcc_mem);
615
616 if (ar_ahb->tcsr_mem)
617 iounmap(ar_ahb->tcsr_mem);
618
619 ar_ahb->mem = NULL;
620 ar_ahb->gcc_mem = NULL;
621 ar_ahb->tcsr_mem = NULL;
622
623 ath10k_ahb_clock_deinit(ar);
624 ath10k_ahb_rst_ctrl_deinit(ar);
625}
626
627static int ath10k_ahb_prepare_device(struct ath10k *ar)
628{
629 u32 val;
630 int ret;
631
632 ret = ath10k_ahb_clock_enable(ar);
633 if (ret) {
634 ath10k_err(ar, "failed to enable clocks\n");
635 return ret;
636 }
637
638 /* Clock for the target is supplied from outside of target (ie,
639 * external clock module controlled by the host). Target needs
640 * to know what frequency target cpu is configured which is needed
641 * for target internal use. Read target cpu frequency info from
642 * gcc register and write into target's scratch register where
643 * target expects this information.
644 */
645 val = ath10k_ahb_gcc_read32(ar, ATH10K_AHB_GCC_FEPLL_PLL_DIV);
646 ath10k_ahb_write32(ar, ATH10K_AHB_WIFI_SCRATCH_5_REG, val);
647
648 ret = ath10k_ahb_release_reset(ar);
649 if (ret)
650 goto err_clk_disable;
651
652 ath10k_ahb_irq_disable(ar);
653
654 ath10k_ahb_write32(ar, FW_INDICATOR_ADDRESS, FW_IND_HOST_READY);
655
656 ret = ath10k_pci_wait_for_target_init(ar);
657 if (ret)
658 goto err_halt_chip;
659
660 return 0;
661
662err_halt_chip:
663 ath10k_ahb_halt_chip(ar);
664
665err_clk_disable:
666 ath10k_ahb_clock_disable(ar);
667
668 return ret;
669}
670
671static int ath10k_ahb_chip_reset(struct ath10k *ar)
672{
673 int ret;
674
675 ath10k_ahb_halt_chip(ar);
676 ath10k_ahb_clock_disable(ar);
677
678 ret = ath10k_ahb_prepare_device(ar);
679 if (ret)
680 return ret;
681
682 return 0;
683}
684
685static int ath10k_ahb_wake_target_cpu(struct ath10k *ar)
686{
687 u32 addr, val;
688
689 addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS;
690 val = ath10k_ahb_read32(ar, addr);
691 val |= ATH10K_AHB_CORE_CTRL_CPU_INTR_MASK;
692 ath10k_ahb_write32(ar, addr, val);
693
694 return 0;
695}
696
697static int ath10k_ahb_hif_start(struct ath10k *ar)
698{
699 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif start\n");
700
701 ath10k_ce_enable_interrupts(ar);
702 ath10k_pci_enable_legacy_irq(ar);
703
704 ath10k_pci_rx_post(ar);
705
706 return 0;
707}
708
709static void ath10k_ahb_hif_stop(struct ath10k *ar)
710{
711 struct ath10k_ahb *ar_ahb = ath10k_ahb_priv(ar);
712
713 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif stop\n");
714
715 ath10k_ahb_irq_disable(ar);
716 synchronize_irq(ar_ahb->irq);
717
718 ath10k_pci_flush(ar);
719}
720
721static int ath10k_ahb_hif_power_up(struct ath10k *ar)
722{
723 int ret;
724
725 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot ahb hif power up\n");
726
727 ret = ath10k_ahb_chip_reset(ar);
728 if (ret) {
729 ath10k_err(ar, "failed to reset chip: %d\n", ret);
730 goto out;
731 }
732
733 ret = ath10k_pci_init_pipes(ar);
734 if (ret) {
735 ath10k_err(ar, "failed to initialize CE: %d\n", ret);
736 goto out;
737 }
738
739 ret = ath10k_pci_init_config(ar);
740 if (ret) {
741 ath10k_err(ar, "failed to setup init config: %d\n", ret);
742 goto err_ce_deinit;
743 }
744
745 ret = ath10k_ahb_wake_target_cpu(ar);
746 if (ret) {
747 ath10k_err(ar, "could not wake up target CPU: %d\n", ret);
748 goto err_ce_deinit;
749 }
750
751 return 0;
752
753err_ce_deinit:
754 ath10k_pci_ce_deinit(ar);
755out:
756 return ret;
757}
758
759static const struct ath10k_hif_ops ath10k_ahb_hif_ops = {
760 .tx_sg = ath10k_pci_hif_tx_sg,
761 .diag_read = ath10k_pci_hif_diag_read,
762 .diag_write = ath10k_pci_diag_write_mem,
763 .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg,
764 .start = ath10k_ahb_hif_start,
765 .stop = ath10k_ahb_hif_stop,
766 .map_service_to_pipe = ath10k_pci_hif_map_service_to_pipe,
767 .get_default_pipe = ath10k_pci_hif_get_default_pipe,
768 .send_complete_check = ath10k_pci_hif_send_complete_check,
769 .get_free_queue_number = ath10k_pci_hif_get_free_queue_number,
770 .power_up = ath10k_ahb_hif_power_up,
771 .power_down = ath10k_pci_hif_power_down,
772 .read32 = ath10k_ahb_read32,
773 .write32 = ath10k_ahb_write32,
774};
775
776static const struct ath10k_bus_ops ath10k_ahb_bus_ops = {
777 .read32 = ath10k_ahb_read32,
778 .write32 = ath10k_ahb_write32,
779 .get_num_banks = ath10k_ahb_get_num_banks,
780};
781
782static int ath10k_ahb_probe(struct platform_device *pdev)
783{
784 struct ath10k *ar;
785 struct ath10k_ahb *ar_ahb;
786 struct ath10k_pci *ar_pci;
787 const struct of_device_id *of_id;
788 enum ath10k_hw_rev hw_rev;
789 size_t size;
790 int ret;
791 u32 chip_id;
792
793 of_id = of_match_device(ath10k_ahb_of_match, &pdev->dev);
794 if (!of_id) {
795 dev_err(&pdev->dev, "failed to find matching device tree id\n");
796 return -EINVAL;
797 }
798
799 hw_rev = (enum ath10k_hw_rev)of_id->data;
800
801 size = sizeof(*ar_pci) + sizeof(*ar_ahb);
802 ar = ath10k_core_create(size, &pdev->dev, ATH10K_BUS_AHB,
803 hw_rev, &ath10k_ahb_hif_ops);
804 if (!ar) {
805 dev_err(&pdev->dev, "failed to allocate core\n");
806 return -ENOMEM;
807 }
808
809 ath10k_dbg(ar, ATH10K_DBG_BOOT, "ahb probe\n");
810
811 ar_pci = ath10k_pci_priv(ar);
812 ar_ahb = ath10k_ahb_priv(ar);
813
814 ar_ahb->pdev = pdev;
815 platform_set_drvdata(pdev, ar);
816
817 ret = ath10k_ahb_resource_init(ar);
818 if (ret)
819 goto err_core_destroy;
820
821 ar->dev_id = 0;
822 ar_pci->mem = ar_ahb->mem;
823 ar_pci->mem_len = ar_ahb->mem_len;
824 ar_pci->ar = ar;
825 ar_pci->bus_ops = &ath10k_ahb_bus_ops;
826
827 ret = ath10k_pci_setup_resource(ar);
828 if (ret) {
829 ath10k_err(ar, "failed to setup resource: %d\n", ret);
830 goto err_resource_deinit;
831 }
832
833 ath10k_pci_init_irq_tasklets(ar);
834
835 ret = ath10k_ahb_request_irq_legacy(ar);
836 if (ret)
837 goto err_free_pipes;
838
839 ret = ath10k_ahb_prepare_device(ar);
840 if (ret)
841 goto err_free_irq;
842
843 ath10k_pci_ce_deinit(ar);
844
845 chip_id = ath10k_ahb_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
846 if (chip_id == 0xffffffff) {
847 ath10k_err(ar, "failed to get chip id\n");
848 goto err_halt_device;
849 }
850
851 ret = ath10k_core_register(ar, chip_id);
852 if (ret) {
853 ath10k_err(ar, "failed to register driver core: %d\n", ret);
854 goto err_halt_device;
855 }
856
857 return 0;
858
859err_halt_device:
860 ath10k_ahb_halt_chip(ar);
861 ath10k_ahb_clock_disable(ar);
862
863err_free_irq:
864 ath10k_ahb_release_irq_legacy(ar);
865
866err_free_pipes:
867 ath10k_pci_free_pipes(ar);
868
869err_resource_deinit:
870 ath10k_ahb_resource_deinit(ar);
871
872err_core_destroy:
873 ath10k_core_destroy(ar);
874 platform_set_drvdata(pdev, NULL);
875
876 return ret;
877}
878
879static int ath10k_ahb_remove(struct platform_device *pdev)
880{
881 struct ath10k *ar = platform_get_drvdata(pdev);
882 struct ath10k_ahb *ar_ahb;
883
884 if (!ar)
885 return -EINVAL;
886
887 ar_ahb = ath10k_ahb_priv(ar);
888
889 if (!ar_ahb)
890 return -EINVAL;
891
892 ath10k_dbg(ar, ATH10K_DBG_AHB, "ahb remove\n");
893
894 ath10k_core_unregister(ar);
895 ath10k_ahb_irq_disable(ar);
896 ath10k_ahb_release_irq_legacy(ar);
897 ath10k_pci_release_resource(ar);
898 ath10k_ahb_halt_chip(ar);
899 ath10k_ahb_clock_disable(ar);
900 ath10k_ahb_resource_deinit(ar);
901 ath10k_core_destroy(ar);
902
903 platform_set_drvdata(pdev, NULL);
904
905 return 0;
906}
907
908static struct platform_driver ath10k_ahb_driver = {
909 .driver = {
910 .name = "ath10k_ahb",
911 .of_match_table = ath10k_ahb_of_match,
912 },
913 .probe = ath10k_ahb_probe,
914 .remove = ath10k_ahb_remove,
915};
916
917int ath10k_ahb_init(void)
918{
919 int ret;
920
921 printk(KERN_ERR "AHB support is still work in progress\n");
922
923 ret = platform_driver_register(&ath10k_ahb_driver);
924 if (ret)
925 printk(KERN_ERR "failed to register ath10k ahb driver: %d\n",
926 ret);
927 return ret;
928}
929
930void ath10k_ahb_exit(void)
931{
932 platform_driver_unregister(&ath10k_ahb_driver);
933}
diff --git a/drivers/net/wireless/ath/ath10k/ahb.h b/drivers/net/wireless/ath/ath10k/ahb.h
new file mode 100644
index 000000000000..d43e375215c8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/ahb.h
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) 2016 Qualcomm Atheros, Inc. All rights reserved.
3 * Copyright (c) 2015 The Linux Foundation. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef _AHB_H_
19#define _AHB_H_
20
21#include <linux/platform_device.h>
22
23struct ath10k_ahb {
24 struct platform_device *pdev;
25 void __iomem *mem;
26 unsigned long mem_len;
27 void __iomem *gcc_mem;
28 void __iomem *tcsr_mem;
29
30 int irq;
31
32 struct clk *cmd_clk;
33 struct clk *ref_clk;
34 struct clk *rtc_clk;
35
36 struct reset_control *core_cold_rst;
37 struct reset_control *radio_cold_rst;
38 struct reset_control *radio_warm_rst;
39 struct reset_control *radio_srif_rst;
40 struct reset_control *cpu_init_rst;
41};
42
43#ifdef CONFIG_ATH10K_AHB
44
45#define ATH10K_GCC_REG_BASE 0x1800000
46#define ATH10K_GCC_REG_SIZE 0x60000
47
48#define ATH10K_TCSR_REG_BASE 0x1900000
49#define ATH10K_TCSR_REG_SIZE 0x80000
50
51#define ATH10K_AHB_GCC_FEPLL_PLL_DIV 0x2f020
52#define ATH10K_AHB_WIFI_SCRATCH_5_REG 0x4f014
53
54#define ATH10K_AHB_WLAN_CORE_ID_REG 0x82030
55
56#define ATH10K_AHB_TCSR_WIFI0_GLB_CFG 0x49000
57#define ATH10K_AHB_TCSR_WIFI1_GLB_CFG 0x49004
58#define TCSR_WIFIX_GLB_CFG_DISABLE_CORE_CLK BIT(25)
59
60#define ATH10K_AHB_TCSR_WCSS0_HALTREQ 0x52000
61#define ATH10K_AHB_TCSR_WCSS1_HALTREQ 0x52010
62#define ATH10K_AHB_TCSR_WCSS0_HALTACK 0x52004
63#define ATH10K_AHB_TCSR_WCSS1_HALTACK 0x52014
64
65#define ATH10K_AHB_AXI_BUS_HALT_TIMEOUT 10 /* msec */
66#define AHB_AXI_BUS_HALT_REQ 1
67#define AHB_AXI_BUS_HALT_ACK 1
68
69#define ATH10K_AHB_CORE_CTRL_CPU_INTR_MASK 1
70
71int ath10k_ahb_init(void);
72void ath10k_ahb_exit(void);
73
74#else /* CONFIG_ATH10K_AHB */
75
76static inline int ath10k_ahb_init(void)
77{
78 return 0;
79}
80
81static inline void ath10k_ahb_exit(void)
82{
83}
84
85#endif /* CONFIG_ATH10K_AHB */
86
87#endif /* _AHB_H_ */
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index b41eb3f4ee56..c84c2d30ef1f 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -156,6 +156,11 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
156 .channel_counters_freq_hz = 150000, 156 .channel_counters_freq_hz = 150000,
157 .max_probe_resp_desc_thres = 24, 157 .max_probe_resp_desc_thres = 24,
158 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE, 158 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
159 .num_msdu_desc = 1424,
160 .qcache_active_peers = 50,
161 .tx_chain_mask = 0xf,
162 .rx_chain_mask = 0xf,
163 .max_spatial_stream = 4,
159 .fw = { 164 .fw = {
160 .dir = QCA99X0_HW_2_0_FW_DIR, 165 .dir = QCA99X0_HW_2_0_FW_DIR,
161 .fw = QCA99X0_HW_2_0_FW_FILE, 166 .fw = QCA99X0_HW_2_0_FW_FILE,
@@ -201,6 +206,31 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
201 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ, 206 .board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
202 }, 207 },
203 }, 208 },
209 {
210 .id = QCA4019_HW_1_0_DEV_VERSION,
211 .dev_id = 0,
212 .name = "qca4019 hw1.0",
213 .patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
214 .uart_pin = 7,
215 .otp_exe_param = 0x0010000,
216 .continuous_frag_desc = true,
217 .channel_counters_freq_hz = 125000,
218 .max_probe_resp_desc_thres = 24,
219 .hw_4addr_pad = ATH10K_HW_4ADDR_PAD_BEFORE,
220 .num_msdu_desc = 2500,
221 .qcache_active_peers = 35,
222 .tx_chain_mask = 0x3,
223 .rx_chain_mask = 0x3,
224 .max_spatial_stream = 2,
225 .fw = {
226 .dir = QCA4019_HW_1_0_FW_DIR,
227 .fw = QCA4019_HW_1_0_FW_FILE,
228 .otp = QCA4019_HW_1_0_OTP_FILE,
229 .board = QCA4019_HW_1_0_BOARD_DATA_FILE,
230 .board_size = QCA4019_BOARD_DATA_SZ,
231 .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
232 },
233 },
204}; 234};
205 235
206static const char *const ath10k_core_fw_feature_str[] = { 236static const char *const ath10k_core_fw_feature_str[] = {
@@ -217,6 +247,7 @@ static const char *const ath10k_core_fw_feature_str[] = {
217 [ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode", 247 [ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
218 [ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca", 248 [ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
219 [ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp", 249 [ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
250 [ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
220}; 251};
221 252
222static unsigned int ath10k_core_get_fw_feature_str(char *buf, 253static unsigned int ath10k_core_get_fw_feature_str(char *buf,
@@ -1478,8 +1509,13 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
1478 case ATH10K_FW_WMI_OP_VERSION_10_1: 1509 case ATH10K_FW_WMI_OP_VERSION_10_1:
1479 case ATH10K_FW_WMI_OP_VERSION_10_2: 1510 case ATH10K_FW_WMI_OP_VERSION_10_2:
1480 case ATH10K_FW_WMI_OP_VERSION_10_2_4: 1511 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
1481 ar->max_num_peers = TARGET_10X_NUM_PEERS; 1512 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
1482 ar->max_num_stations = TARGET_10X_NUM_STATIONS; 1513 ar->max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
1514 ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
1515 } else {
1516 ar->max_num_peers = TARGET_10X_NUM_PEERS;
1517 ar->max_num_stations = TARGET_10X_NUM_STATIONS;
1518 }
1483 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS; 1519 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
1484 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC; 1520 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
1485 ar->fw_stats_req_mask = WMI_STAT_PEER; 1521 ar->fw_stats_req_mask = WMI_STAT_PEER;
@@ -1502,9 +1538,9 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
1502 ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS; 1538 ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
1503 ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS; 1539 ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
1504 ar->num_tids = TARGET_10_4_TGT_NUM_TIDS; 1540 ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;
1505 ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC; 1541 ar->htt.max_num_pending_tx = ar->hw_params.num_msdu_desc;
1506 ar->fw_stats_req_mask = WMI_STAT_PEER; 1542 ar->fw_stats_req_mask = WMI_STAT_PEER;
1507 ar->max_spatial_stream = WMI_10_4_MAX_SPATIAL_STREAM; 1543 ar->max_spatial_stream = ar->hw_params.max_spatial_stream;
1508 break; 1544 break;
1509 case ATH10K_FW_WMI_OP_VERSION_UNSET: 1545 case ATH10K_FW_WMI_OP_VERSION_UNSET:
1510 case ATH10K_FW_WMI_OP_VERSION_MAX: 1546 case ATH10K_FW_WMI_OP_VERSION_MAX:
@@ -1979,6 +2015,10 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1979 ar->regs = &qca99x0_regs; 2015 ar->regs = &qca99x0_regs;
1980 ar->hw_values = &qca99x0_values; 2016 ar->hw_values = &qca99x0_values;
1981 break; 2017 break;
2018 case ATH10K_HW_QCA4019:
2019 ar->regs = &qca4019_regs;
2020 ar->hw_values = &qca4019_values;
2021 break;
1982 default: 2022 default:
1983 ath10k_err(ar, "unsupported core hardware revision %d\n", 2023 ath10k_err(ar, "unsupported core hardware revision %d\n",
1984 hw_rev); 2024 hw_rev);
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 7840cf3ef7a6..a62b62a62266 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -69,6 +69,7 @@ struct ath10k;
69 69
70enum ath10k_bus { 70enum ath10k_bus {
71 ATH10K_BUS_PCI, 71 ATH10K_BUS_PCI,
72 ATH10K_BUS_AHB,
72}; 73};
73 74
74static inline const char *ath10k_bus_str(enum ath10k_bus bus) 75static inline const char *ath10k_bus_str(enum ath10k_bus bus)
@@ -76,6 +77,8 @@ static inline const char *ath10k_bus_str(enum ath10k_bus bus)
76 switch (bus) { 77 switch (bus) {
77 case ATH10K_BUS_PCI: 78 case ATH10K_BUS_PCI:
78 return "pci"; 79 return "pci";
80 case ATH10K_BUS_AHB:
81 return "ahb";
79 } 82 }
80 83
81 return "unknown"; 84 return "unknown";
@@ -159,6 +162,7 @@ struct ath10k_fw_stats_peer {
159 u32 peer_rssi; 162 u32 peer_rssi;
160 u32 peer_tx_rate; 163 u32 peer_tx_rate;
161 u32 peer_rx_rate; /* 10x only */ 164 u32 peer_rx_rate; /* 10x only */
165 u32 rx_duration;
162}; 166};
163 167
164struct ath10k_fw_stats_vdev { 168struct ath10k_fw_stats_vdev {
@@ -315,6 +319,7 @@ struct ath10k_sta {
315#ifdef CONFIG_MAC80211_DEBUGFS 319#ifdef CONFIG_MAC80211_DEBUGFS
316 /* protected by conf_mutex */ 320 /* protected by conf_mutex */
317 bool aggr_mode; 321 bool aggr_mode;
322 u64 rx_duration;
318#endif 323#endif
319}; 324};
320 325
@@ -510,6 +515,15 @@ enum ath10k_fw_features {
510 /* Firmware supports management frame protection */ 515 /* Firmware supports management frame protection */
511 ATH10K_FW_FEATURE_MFP_SUPPORT = 12, 516 ATH10K_FW_FEATURE_MFP_SUPPORT = 12,
512 517
518 /* Firmware supports pull-push model where host shares it's software
519 * queue state with firmware and firmware generates fetch requests
520 * telling host which queues to dequeue tx from.
521 *
522 * Primary function of this is improved MU-MIMO performance with
523 * multiple clients.
524 */
525 ATH10K_FW_FEATURE_PEER_FLOW_CONTROL = 13,
526
513 /* keep last */ 527 /* keep last */
514 ATH10K_FW_FEATURE_COUNT, 528 ATH10K_FW_FEATURE_COUNT,
515}; 529};
@@ -666,6 +680,12 @@ struct ath10k {
666 /* The padding bytes's location is different on various chips */ 680 /* The padding bytes's location is different on various chips */
667 enum ath10k_hw_4addr_pad hw_4addr_pad; 681 enum ath10k_hw_4addr_pad hw_4addr_pad;
668 682
683 u32 num_msdu_desc;
684 u32 qcache_active_peers;
685 u32 tx_chain_mask;
686 u32 rx_chain_mask;
687 u32 max_spatial_stream;
688
669 struct ath10k_hw_params_fw { 689 struct ath10k_hw_params_fw {
670 const char *dir; 690 const char *dir;
671 const char *fw; 691 const char *fw;
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 2bdf5408b0d9..076d29b53ddf 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -276,7 +276,7 @@ static const struct file_operations fops_wmi_services = {
276 .llseek = default_llseek, 276 .llseek = default_llseek,
277}; 277};
278 278
279static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head) 279static void ath10k_fw_stats_pdevs_free(struct list_head *head)
280{ 280{
281 struct ath10k_fw_stats_pdev *i, *tmp; 281 struct ath10k_fw_stats_pdev *i, *tmp;
282 282
@@ -286,7 +286,7 @@ static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head)
286 } 286 }
287} 287}
288 288
289static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head) 289static void ath10k_fw_stats_vdevs_free(struct list_head *head)
290{ 290{
291 struct ath10k_fw_stats_vdev *i, *tmp; 291 struct ath10k_fw_stats_vdev *i, *tmp;
292 292
@@ -296,7 +296,7 @@ static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head)
296 } 296 }
297} 297}
298 298
299static void ath10k_debug_fw_stats_peers_free(struct list_head *head) 299static void ath10k_fw_stats_peers_free(struct list_head *head)
300{ 300{
301 struct ath10k_fw_stats_peer *i, *tmp; 301 struct ath10k_fw_stats_peer *i, *tmp;
302 302
@@ -310,16 +310,16 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
310{ 310{
311 spin_lock_bh(&ar->data_lock); 311 spin_lock_bh(&ar->data_lock);
312 ar->debug.fw_stats_done = false; 312 ar->debug.fw_stats_done = false;
313 ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); 313 ath10k_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs);
314 ath10k_debug_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); 314 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
315 ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); 315 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
316 spin_unlock_bh(&ar->data_lock); 316 spin_unlock_bh(&ar->data_lock);
317} 317}
318 318
319void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) 319void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
320{ 320{
321 struct ath10k_fw_stats stats = {}; 321 struct ath10k_fw_stats stats = {};
322 bool is_start, is_started, is_end; 322 bool is_start, is_started, is_end, peer_stats_svc;
323 size_t num_peers; 323 size_t num_peers;
324 size_t num_vdevs; 324 size_t num_vdevs;
325 int ret; 325 int ret;
@@ -347,8 +347,14 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
347 * delivered which is treated as end-of-data and is itself discarded 347 * delivered which is treated as end-of-data and is itself discarded
348 */ 348 */
349 349
350 peer_stats_svc = test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map);
351 if (peer_stats_svc)
352 ath10k_sta_update_rx_duration(ar, &stats.peers);
353
350 if (ar->debug.fw_stats_done) { 354 if (ar->debug.fw_stats_done) {
351 ath10k_warn(ar, "received unsolicited stats update event\n"); 355 if (!peer_stats_svc)
356 ath10k_warn(ar, "received unsolicited stats update event\n");
357
352 goto free; 358 goto free;
353 } 359 }
354 360
@@ -372,11 +378,13 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
372 /* Although this is unlikely impose a sane limit to 378 /* Although this is unlikely impose a sane limit to
373 * prevent firmware from DoS-ing the host. 379 * prevent firmware from DoS-ing the host.
374 */ 380 */
381 ath10k_fw_stats_peers_free(&ar->debug.fw_stats.peers);
375 ath10k_warn(ar, "dropping fw peer stats\n"); 382 ath10k_warn(ar, "dropping fw peer stats\n");
376 goto free; 383 goto free;
377 } 384 }
378 385
379 if (num_vdevs >= BITS_PER_LONG) { 386 if (num_vdevs >= BITS_PER_LONG) {
387 ath10k_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs);
380 ath10k_warn(ar, "dropping fw vdev stats\n"); 388 ath10k_warn(ar, "dropping fw vdev stats\n");
381 goto free; 389 goto free;
382 } 390 }
@@ -391,9 +399,9 @@ free:
391 /* In some cases lists have been spliced and cleared. Free up 399 /* In some cases lists have been spliced and cleared. Free up
392 * resources if that is not the case. 400 * resources if that is not the case.
393 */ 401 */
394 ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); 402 ath10k_fw_stats_pdevs_free(&stats.pdevs);
395 ath10k_debug_fw_stats_vdevs_free(&stats.vdevs); 403 ath10k_fw_stats_vdevs_free(&stats.vdevs);
396 ath10k_debug_fw_stats_peers_free(&stats.peers); 404 ath10k_fw_stats_peers_free(&stats.peers);
397 405
398 spin_unlock_bh(&ar->data_lock); 406 spin_unlock_bh(&ar->data_lock);
399} 407}
@@ -2106,6 +2114,7 @@ static ssize_t ath10k_write_btcoex(struct file *file,
2106 struct ath10k *ar = file->private_data; 2114 struct ath10k *ar = file->private_data;
2107 char buf[32]; 2115 char buf[32];
2108 size_t buf_size; 2116 size_t buf_size;
2117 int ret = 0;
2109 bool val; 2118 bool val;
2110 2119
2111 buf_size = min(count, (sizeof(buf) - 1)); 2120 buf_size = min(count, (sizeof(buf) - 1));
@@ -2119,6 +2128,12 @@ static ssize_t ath10k_write_btcoex(struct file *file,
2119 2128
2120 mutex_lock(&ar->conf_mutex); 2129 mutex_lock(&ar->conf_mutex);
2121 2130
2131 if (ar->state != ATH10K_STATE_ON &&
2132 ar->state != ATH10K_STATE_RESTARTED) {
2133 ret = -ENETDOWN;
2134 goto exit;
2135 }
2136
2122 if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val)) 2137 if (!(test_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags) ^ val))
2123 goto exit; 2138 goto exit;
2124 2139
@@ -2127,17 +2142,15 @@ static ssize_t ath10k_write_btcoex(struct file *file,
2127 else 2142 else
2128 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags); 2143 clear_bit(ATH10K_FLAG_BTCOEX, &ar->dev_flags);
2129 2144
2130 if (ar->state != ATH10K_STATE_ON)
2131 goto exit;
2132
2133 ath10k_info(ar, "restarting firmware due to btcoex change"); 2145 ath10k_info(ar, "restarting firmware due to btcoex change");
2134 2146
2135 queue_work(ar->workqueue, &ar->restart_work); 2147 queue_work(ar->workqueue, &ar->restart_work);
2148 ret = count;
2136 2149
2137exit: 2150exit:
2138 mutex_unlock(&ar->conf_mutex); 2151 mutex_unlock(&ar->conf_mutex);
2139 2152
2140 return count; 2153 return ret;
2141} 2154}
2142 2155
2143static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf, 2156static ssize_t ath10k_read_btcoex(struct file *file, char __user *ubuf,
@@ -2176,9 +2189,6 @@ static ssize_t ath10k_debug_fw_checksums_read(struct file *file,
2176 2189
2177 mutex_lock(&ar->conf_mutex); 2190 mutex_lock(&ar->conf_mutex);
2178 2191
2179 if (len > buf_len)
2180 len = buf_len;
2181
2182 len += scnprintf(buf + len, buf_len - len, 2192 len += scnprintf(buf + len, buf_len - len,
2183 "firmware-N.bin\t\t%08x\n", 2193 "firmware-N.bin\t\t%08x\n",
2184 crc32_le(0, ar->firmware->data, ar->firmware->size)); 2194 crc32_le(0, ar->firmware->data, ar->firmware->size));
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 814719cf4f22..6206edd7c49f 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -37,6 +37,7 @@ enum ath10k_debug_mask {
37 ATH10K_DBG_TESTMODE = 0x00001000, 37 ATH10K_DBG_TESTMODE = 0x00001000,
38 ATH10K_DBG_WMI_PRINT = 0x00002000, 38 ATH10K_DBG_WMI_PRINT = 0x00002000,
39 ATH10K_DBG_PCI_PS = 0x00004000, 39 ATH10K_DBG_PCI_PS = 0x00004000,
40 ATH10K_DBG_AHB = 0x00008000,
40 ATH10K_DBG_ANY = 0xffffffff, 41 ATH10K_DBG_ANY = 0xffffffff,
41}; 42};
42 43
@@ -153,6 +154,12 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
153#ifdef CONFIG_MAC80211_DEBUGFS 154#ifdef CONFIG_MAC80211_DEBUGFS
154void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 155void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
155 struct ieee80211_sta *sta, struct dentry *dir); 156 struct ieee80211_sta *sta, struct dentry *dir);
157void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *peer);
158#else
159static inline void ath10k_sta_update_rx_duration(struct ath10k *ar,
160 struct list_head *peer)
161{
162}
156#endif /* CONFIG_MAC80211_DEBUGFS */ 163#endif /* CONFIG_MAC80211_DEBUGFS */
157 164
158#ifdef CONFIG_ATH10K_DEBUG 165#ifdef CONFIG_ATH10K_DEBUG
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index 95b5c49374e0..67ef75b60567 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -18,6 +18,23 @@
18#include "wmi-ops.h" 18#include "wmi-ops.h"
19#include "debug.h" 19#include "debug.h"
20 20
21void ath10k_sta_update_rx_duration(struct ath10k *ar, struct list_head *head)
22{ struct ieee80211_sta *sta;
23 struct ath10k_fw_stats_peer *peer;
24 struct ath10k_sta *arsta;
25
26 rcu_read_lock();
27 list_for_each_entry(peer, head, list) {
28 sta = ieee80211_find_sta_by_ifaddr(ar->hw, peer->peer_macaddr,
29 NULL);
30 if (!sta)
31 continue;
32 arsta = (struct ath10k_sta *)sta->drv_priv;
33 arsta->rx_duration += (u64)peer->rx_duration;
34 }
35 rcu_read_unlock();
36}
37
21static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, 38static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
22 char __user *user_buf, 39 char __user *user_buf,
23 size_t count, loff_t *ppos) 40 size_t count, loff_t *ppos)
@@ -232,6 +249,28 @@ static const struct file_operations fops_delba = {
232 .llseek = default_llseek, 249 .llseek = default_llseek,
233}; 250};
234 251
252static ssize_t ath10k_dbg_sta_read_rx_duration(struct file *file,
253 char __user *user_buf,
254 size_t count, loff_t *ppos)
255{
256 struct ieee80211_sta *sta = file->private_data;
257 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
258 char buf[100];
259 int len = 0;
260
261 len = scnprintf(buf, sizeof(buf),
262 "%llu usecs\n", arsta->rx_duration);
263
264 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
265}
266
267static const struct file_operations fops_rx_duration = {
268 .read = ath10k_dbg_sta_read_rx_duration,
269 .open = simple_open,
270 .owner = THIS_MODULE,
271 .llseek = default_llseek,
272};
273
235void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 274void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
236 struct ieee80211_sta *sta, struct dentry *dir) 275 struct ieee80211_sta *sta, struct dentry *dir)
237{ 276{
@@ -240,4 +279,6 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
240 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); 279 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
241 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); 280 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
242 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); 281 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
282 debugfs_create_file("rx_duration", S_IRUGO, dir, sta,
283 &fops_rx_duration);
243} 284}
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 3e6ba63dfdff..7561f22f10f9 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -131,12 +131,12 @@ static const enum htt_t2h_msg_type htt_10_4_t2h_msg_types[] = {
131 [HTT_10_4_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF, 131 [HTT_10_4_T2H_MSG_TYPE_AGGR_CONF] = HTT_T2H_MSG_TYPE_AGGR_CONF,
132 [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND] = 132 [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND] =
133 HTT_T2H_MSG_TYPE_TX_FETCH_IND, 133 HTT_T2H_MSG_TYPE_TX_FETCH_IND,
134 [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONF] = 134 [HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONFIRM] =
135 HTT_T2H_MSG_TYPE_TX_FETCH_CONF, 135 HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
136 [HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD] = 136 [HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD] =
137 HTT_T2H_MSG_TYPE_STATS_NOUPLOAD, 137 HTT_T2H_MSG_TYPE_STATS_NOUPLOAD,
138 [HTT_10_4_T2H_MSG_TYPE_TX_LOW_LATENCY_IND] = 138 [HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND] =
139 HTT_T2H_MSG_TYPE_TX_LOW_LATENCY_IND, 139 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
140}; 140};
141 141
142int ath10k_htt_connect(struct ath10k_htt *htt) 142int ath10k_htt_connect(struct ath10k_htt *htt)
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 47ca048feaf0..13391ea4422d 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -52,6 +52,7 @@ enum htt_h2t_msg_type { /* host-to-target */
52 /* This command is used for sending management frames in HTT < 3.0. 52 /* This command is used for sending management frames in HTT < 3.0.
53 * HTT >= 3.0 uses TX_FRM for everything. */ 53 * HTT >= 3.0 uses TX_FRM for everything. */
54 HTT_H2T_MSG_TYPE_MGMT_TX = 7, 54 HTT_H2T_MSG_TYPE_MGMT_TX = 7,
55 HTT_H2T_MSG_TYPE_TX_FETCH_RESP = 11,
55 56
56 HTT_H2T_NUM_MSGS /* keep this last */ 57 HTT_H2T_NUM_MSGS /* keep this last */
57}; 58};
@@ -413,10 +414,10 @@ enum htt_10_4_t2h_msg_type {
413 HTT_10_4_T2H_MSG_TYPE_EN_STATS = 0x14, 414 HTT_10_4_T2H_MSG_TYPE_EN_STATS = 0x14,
414 HTT_10_4_T2H_MSG_TYPE_AGGR_CONF = 0x15, 415 HTT_10_4_T2H_MSG_TYPE_AGGR_CONF = 0x15,
415 HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND = 0x16, 416 HTT_10_4_T2H_MSG_TYPE_TX_FETCH_IND = 0x16,
416 HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONF = 0x17, 417 HTT_10_4_T2H_MSG_TYPE_TX_FETCH_CONFIRM = 0x17,
417 HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18, 418 HTT_10_4_T2H_MSG_TYPE_STATS_NOUPLOAD = 0x18,
418 /* 0x19 to 0x2f are reserved */ 419 /* 0x19 to 0x2f are reserved */
419 HTT_10_4_T2H_MSG_TYPE_TX_LOW_LATENCY_IND = 0x30, 420 HTT_10_4_T2H_MSG_TYPE_TX_MODE_SWITCH_IND = 0x30,
420 /* keep this last */ 421 /* keep this last */
421 HTT_10_4_T2H_NUM_MSGS 422 HTT_10_4_T2H_NUM_MSGS
422}; 423};
@@ -449,8 +450,8 @@ enum htt_t2h_msg_type {
449 HTT_T2H_MSG_TYPE_TEST, 450 HTT_T2H_MSG_TYPE_TEST,
450 HTT_T2H_MSG_TYPE_EN_STATS, 451 HTT_T2H_MSG_TYPE_EN_STATS,
451 HTT_T2H_MSG_TYPE_TX_FETCH_IND, 452 HTT_T2H_MSG_TYPE_TX_FETCH_IND,
452 HTT_T2H_MSG_TYPE_TX_FETCH_CONF, 453 HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM,
453 HTT_T2H_MSG_TYPE_TX_LOW_LATENCY_IND, 454 HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND,
454 /* keep this last */ 455 /* keep this last */
455 HTT_T2H_NUM_MSGS 456 HTT_T2H_NUM_MSGS
456}; 457};
@@ -1306,9 +1307,43 @@ struct htt_frag_desc_bank_id {
1306 * so we use a conservatively safe value for now */ 1307 * so we use a conservatively safe value for now */
1307#define HTT_FRAG_DESC_BANK_MAX 4 1308#define HTT_FRAG_DESC_BANK_MAX 4
1308 1309
1309#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_MASK 0x03 1310#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_MASK 0x03
1310#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_LSB 0 1311#define HTT_FRAG_DESC_BANK_CFG_INFO_PDEV_ID_LSB 0
1311#define HTT_FRAG_DESC_BANK_CFG_INFO_SWAP (1 << 2) 1312#define HTT_FRAG_DESC_BANK_CFG_INFO_SWAP BIT(2)
1313#define HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_VALID BIT(3)
1314#define HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_DEPTH_TYPE_MASK BIT(4)
1315#define HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_DEPTH_TYPE_LSB 4
1316
1317enum htt_q_depth_type {
1318 HTT_Q_DEPTH_TYPE_BYTES = 0,
1319 HTT_Q_DEPTH_TYPE_MSDUS = 1,
1320};
1321
1322#define HTT_TX_Q_STATE_NUM_PEERS (TARGET_10_4_NUM_QCACHE_PEERS_MAX + \
1323 TARGET_10_4_NUM_VDEVS)
1324#define HTT_TX_Q_STATE_NUM_TIDS 8
1325#define HTT_TX_Q_STATE_ENTRY_SIZE 1
1326#define HTT_TX_Q_STATE_ENTRY_MULTIPLIER 0
1327
1328/**
1329 * htt_q_state_conf - part of htt_frag_desc_bank_cfg for host q state config
1330 *
1331 * Defines host q state format and behavior. See htt_q_state.
1332 *
1333 * @record_size: Defines the size of each host q entry in bytes. In practice
1334 * however firmware (at least 10.4.3-00191) ignores this host
1335 * configuration value and uses hardcoded value of 1.
1336 * @record_multiplier: This is valid only when q depth type is MSDUs. It
1337 * defines the exponent for the power of 2 multiplication.
1338 */
1339struct htt_q_state_conf {
1340 __le32 paddr;
1341 __le16 num_peers;
1342 __le16 num_tids;
1343 u8 record_size;
1344 u8 record_multiplier;
1345 u8 pad[2];
1346} __packed;
1312 1347
1313struct htt_frag_desc_bank_cfg { 1348struct htt_frag_desc_bank_cfg {
1314 u8 info; /* HTT_FRAG_DESC_BANK_CFG_INFO_ */ 1349 u8 info; /* HTT_FRAG_DESC_BANK_CFG_INFO_ */
@@ -1316,6 +1351,114 @@ struct htt_frag_desc_bank_cfg {
1316 u8 desc_size; 1351 u8 desc_size;
1317 __le32 bank_base_addrs[HTT_FRAG_DESC_BANK_MAX]; 1352 __le32 bank_base_addrs[HTT_FRAG_DESC_BANK_MAX];
1318 struct htt_frag_desc_bank_id bank_id[HTT_FRAG_DESC_BANK_MAX]; 1353 struct htt_frag_desc_bank_id bank_id[HTT_FRAG_DESC_BANK_MAX];
1354 struct htt_q_state_conf q_state;
1355} __packed;
1356
1357#define HTT_TX_Q_STATE_ENTRY_COEFFICIENT 128
1358#define HTT_TX_Q_STATE_ENTRY_FACTOR_MASK 0x3f
1359#define HTT_TX_Q_STATE_ENTRY_FACTOR_LSB 0
1360#define HTT_TX_Q_STATE_ENTRY_EXP_MASK 0xc0
1361#define HTT_TX_Q_STATE_ENTRY_EXP_LSB 6
1362
1363/**
1364 * htt_q_state - shared between host and firmware via DMA
1365 *
1366 * This structure is used for the host to expose it's software queue state to
1367 * firmware so that its rate control can schedule fetch requests for optimized
1368 * performance. This is most notably used for MU-MIMO aggregation when multiple
1369 * MU clients are connected.
1370 *
1371 * @count: Each element defines the host queue depth. When q depth type was
1372 * configured as HTT_Q_DEPTH_TYPE_BYTES then each entry is defined as:
1373 * FACTOR * 128 * 8^EXP (see HTT_TX_Q_STATE_ENTRY_FACTOR_MASK and
1374 * HTT_TX_Q_STATE_ENTRY_EXP_MASK). When q depth type was configured as
1375 * HTT_Q_DEPTH_TYPE_MSDUS the number of packets is scaled by 2 **
1376 * record_multiplier (see htt_q_state_conf).
1377 * @map: Used by firmware to quickly check which host queues are not empty. It
1378 * is a bitmap simply saying.
1379 * @seq: Used by firmware to quickly check if the host queues were updated
1380 * since it last checked.
1381 *
1382 * FIXME: Is the q_state map[] size calculation really correct?
1383 */
1384struct htt_q_state {
1385 u8 count[HTT_TX_Q_STATE_NUM_TIDS][HTT_TX_Q_STATE_NUM_PEERS];
1386 u32 map[HTT_TX_Q_STATE_NUM_TIDS][(HTT_TX_Q_STATE_NUM_PEERS + 31) / 32];
1387 __le32 seq;
1388} __packed;
1389
1390#define HTT_TX_FETCH_RECORD_INFO_PEER_ID_MASK 0x0fff
1391#define HTT_TX_FETCH_RECORD_INFO_PEER_ID_LSB 0
1392#define HTT_TX_FETCH_RECORD_INFO_TID_MASK 0xf000
1393#define HTT_TX_FETCH_RECORD_INFO_TID_LSB 12
1394
1395struct htt_tx_fetch_record {
1396 __le16 info; /* HTT_TX_FETCH_IND_RECORD_INFO_ */
1397 __le16 num_msdus;
1398 __le32 num_bytes;
1399} __packed;
1400
1401struct htt_tx_fetch_ind {
1402 u8 pad0;
1403 __le16 fetch_seq_num;
1404 __le32 token;
1405 __le16 num_resp_ids;
1406 __le16 num_records;
1407 struct htt_tx_fetch_record records[0];
1408 __le32 resp_ids[0]; /* ath10k_htt_get_tx_fetch_ind_resp_ids() */
1409} __packed;
1410
1411static inline void *
1412ath10k_htt_get_tx_fetch_ind_resp_ids(struct htt_tx_fetch_ind *ind)
1413{
1414 return (void *)&ind->records[le16_to_cpu(ind->num_records)];
1415}
1416
1417struct htt_tx_fetch_resp {
1418 u8 pad0;
1419 __le16 resp_id;
1420 __le16 fetch_seq_num;
1421 __le16 num_records;
1422 __le32 token;
1423 struct htt_tx_fetch_record records[0];
1424} __packed;
1425
1426struct htt_tx_fetch_confirm {
1427 u8 pad0;
1428 __le16 num_resp_ids;
1429 __le32 resp_ids[0];
1430} __packed;
1431
1432enum htt_tx_mode_switch_mode {
1433 HTT_TX_MODE_SWITCH_PUSH = 0,
1434 HTT_TX_MODE_SWITCH_PUSH_PULL = 1,
1435};
1436
1437#define HTT_TX_MODE_SWITCH_IND_INFO0_ENABLE BIT(0)
1438#define HTT_TX_MODE_SWITCH_IND_INFO0_NUM_RECORDS_MASK 0xfffe
1439#define HTT_TX_MODE_SWITCH_IND_INFO0_NUM_RECORDS_LSB 1
1440
1441#define HTT_TX_MODE_SWITCH_IND_INFO1_MODE_MASK 0x0003
1442#define HTT_TX_MODE_SWITCH_IND_INFO1_MODE_LSB 0
1443#define HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD_MASK 0xfffc
1444#define HTT_TX_MODE_SWITCH_IND_INFO1_THRESHOLD_LSB 2
1445
1446#define HTT_TX_MODE_SWITCH_RECORD_INFO0_PEER_ID_MASK 0x0fff
1447#define HTT_TX_MODE_SWITCH_RECORD_INFO0_PEER_ID_LSB 0
1448#define HTT_TX_MODE_SWITCH_RECORD_INFO0_TID_MASK 0xf000
1449#define HTT_TX_MODE_SWITCH_RECORD_INFO0_TID_LSB 12
1450
1451struct htt_tx_mode_switch_record {
1452 __le16 info0; /* HTT_TX_MODE_SWITCH_RECORD_INFO0_ */
1453 __le16 num_max_msdus;
1454} __packed;
1455
1456struct htt_tx_mode_switch_ind {
1457 u8 pad0;
1458 __le16 info0; /* HTT_TX_MODE_SWITCH_IND_INFO0_ */
1459 __le16 info1; /* HTT_TX_MODE_SWITCH_IND_INFO1_ */
1460 u8 pad1[2];
1461 struct htt_tx_mode_switch_record records[0];
1319} __packed; 1462} __packed;
1320 1463
1321union htt_rx_pn_t { 1464union htt_rx_pn_t {
@@ -1340,6 +1483,7 @@ struct htt_cmd {
1340 struct htt_oob_sync_req oob_sync_req; 1483 struct htt_oob_sync_req oob_sync_req;
1341 struct htt_aggr_conf aggr_conf; 1484 struct htt_aggr_conf aggr_conf;
1342 struct htt_frag_desc_bank_cfg frag_desc_bank_cfg; 1485 struct htt_frag_desc_bank_cfg frag_desc_bank_cfg;
1486 struct htt_tx_fetch_resp tx_fetch_resp;
1343 }; 1487 };
1344} __packed; 1488} __packed;
1345 1489
@@ -1364,6 +1508,9 @@ struct htt_resp {
1364 struct htt_rx_pn_ind rx_pn_ind; 1508 struct htt_rx_pn_ind rx_pn_ind;
1365 struct htt_rx_offload_ind rx_offload_ind; 1509 struct htt_rx_offload_ind rx_offload_ind;
1366 struct htt_rx_in_ord_ind rx_in_ord_ind; 1510 struct htt_rx_in_ord_ind rx_in_ord_ind;
1511 struct htt_tx_fetch_ind tx_fetch_ind;
1512 struct htt_tx_fetch_confirm tx_fetch_confirm;
1513 struct htt_tx_mode_switch_ind tx_mode_switch_ind;
1367 }; 1514 };
1368} __packed; 1515} __packed;
1369 1516
@@ -1518,6 +1665,14 @@ struct ath10k_htt {
1518 dma_addr_t paddr; 1665 dma_addr_t paddr;
1519 struct ath10k_htt_txbuf *vaddr; 1666 struct ath10k_htt_txbuf *vaddr;
1520 } txbuf; 1667 } txbuf;
1668
1669 struct {
1670 struct htt_q_state *vaddr;
1671 dma_addr_t paddr;
1672 u16 num_peers;
1673 u16 num_tids;
1674 enum htt_q_depth_type type;
1675 } tx_q_state;
1521}; 1676};
1522 1677
1523#define RX_HTT_HDR_STATUS_LEN 64 1678#define RX_HTT_HDR_STATUS_LEN 64
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 91afa3ae414c..ae9b686a4e91 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2011,9 +2011,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2011 break; 2011 break;
2012 } 2012 }
2013 case HTT_T2H_MSG_TYPE_RX_IND: 2013 case HTT_T2H_MSG_TYPE_RX_IND:
2014 spin_lock_bh(&htt->rx_ring.lock); 2014 skb_queue_tail(&htt->rx_compl_q, skb);
2015 __skb_queue_tail(&htt->rx_compl_q, skb);
2016 spin_unlock_bh(&htt->rx_ring.lock);
2017 tasklet_schedule(&htt->txrx_compl_task); 2015 tasklet_schedule(&htt->txrx_compl_task);
2018 return; 2016 return;
2019 case HTT_T2H_MSG_TYPE_PEER_MAP: { 2017 case HTT_T2H_MSG_TYPE_PEER_MAP: {
@@ -2111,9 +2109,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2111 break; 2109 break;
2112 } 2110 }
2113 case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: { 2111 case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: {
2114 spin_lock_bh(&htt->rx_ring.lock); 2112 skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
2115 __skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
2116 spin_unlock_bh(&htt->rx_ring.lock);
2117 tasklet_schedule(&htt->txrx_compl_task); 2113 tasklet_schedule(&htt->txrx_compl_task);
2118 return; 2114 return;
2119 } 2115 }
@@ -2123,10 +2119,12 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
2123 break; 2119 break;
2124 case HTT_T2H_MSG_TYPE_AGGR_CONF: 2120 case HTT_T2H_MSG_TYPE_AGGR_CONF:
2125 break; 2121 break;
2126 case HTT_T2H_MSG_TYPE_EN_STATS:
2127 case HTT_T2H_MSG_TYPE_TX_FETCH_IND: 2122 case HTT_T2H_MSG_TYPE_TX_FETCH_IND:
2128 case HTT_T2H_MSG_TYPE_TX_FETCH_CONF: 2123 case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM:
2129 case HTT_T2H_MSG_TYPE_TX_LOW_LATENCY_IND: 2124 case HTT_T2H_MSG_TYPE_TX_MODE_SWITCH_IND:
2125 /* TODO: Implement pull-push logic */
2126 break;
2127 case HTT_T2H_MSG_TYPE_EN_STATS:
2130 default: 2128 default:
2131 ath10k_warn(ar, "htt event (%d) not handled\n", 2129 ath10k_warn(ar, "htt event (%d) not handled\n",
2132 resp->hdr.msg_type); 2130 resp->hdr.msg_type);
@@ -2143,11 +2141,7 @@ EXPORT_SYMBOL(ath10k_htt_t2h_msg_handler);
2143void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, 2141void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
2144 struct sk_buff *skb) 2142 struct sk_buff *skb)
2145{ 2143{
2146 struct ath10k_pktlog_10_4_hdr *hdr = 2144 trace_ath10k_htt_pktlog(ar, skb->data, skb->len);
2147 (struct ath10k_pktlog_10_4_hdr *)skb->data;
2148
2149 trace_ath10k_htt_pktlog(ar, hdr->payload,
2150 sizeof(*hdr) + __le16_to_cpu(hdr->size));
2151 dev_kfree_skb_any(skb); 2145 dev_kfree_skb_any(skb);
2152} 2146}
2153EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); 2147EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler);
@@ -2156,24 +2150,46 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
2156{ 2150{
2157 struct ath10k_htt *htt = (struct ath10k_htt *)ptr; 2151 struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
2158 struct ath10k *ar = htt->ar; 2152 struct ath10k *ar = htt->ar;
2153 struct sk_buff_head tx_q;
2154 struct sk_buff_head rx_q;
2155 struct sk_buff_head rx_ind_q;
2159 struct htt_resp *resp; 2156 struct htt_resp *resp;
2160 struct sk_buff *skb; 2157 struct sk_buff *skb;
2158 unsigned long flags;
2159
2160 __skb_queue_head_init(&tx_q);
2161 __skb_queue_head_init(&rx_q);
2162 __skb_queue_head_init(&rx_ind_q);
2161 2163
2162 while ((skb = skb_dequeue(&htt->tx_compl_q))) { 2164 spin_lock_irqsave(&htt->tx_compl_q.lock, flags);
2165 skb_queue_splice_init(&htt->tx_compl_q, &tx_q);
2166 spin_unlock_irqrestore(&htt->tx_compl_q.lock, flags);
2167
2168 spin_lock_irqsave(&htt->rx_compl_q.lock, flags);
2169 skb_queue_splice_init(&htt->rx_compl_q, &rx_q);
2170 spin_unlock_irqrestore(&htt->rx_compl_q.lock, flags);
2171
2172 spin_lock_irqsave(&htt->rx_in_ord_compl_q.lock, flags);
2173 skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q);
2174 spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags);
2175
2176 while ((skb = __skb_dequeue(&tx_q))) {
2163 ath10k_htt_rx_frm_tx_compl(htt->ar, skb); 2177 ath10k_htt_rx_frm_tx_compl(htt->ar, skb);
2164 dev_kfree_skb_any(skb); 2178 dev_kfree_skb_any(skb);
2165 } 2179 }
2166 2180
2167 spin_lock_bh(&htt->rx_ring.lock); 2181 while ((skb = __skb_dequeue(&rx_q))) {
2168 while ((skb = __skb_dequeue(&htt->rx_compl_q))) {
2169 resp = (struct htt_resp *)skb->data; 2182 resp = (struct htt_resp *)skb->data;
2183 spin_lock_bh(&htt->rx_ring.lock);
2170 ath10k_htt_rx_handler(htt, &resp->rx_ind); 2184 ath10k_htt_rx_handler(htt, &resp->rx_ind);
2185 spin_unlock_bh(&htt->rx_ring.lock);
2171 dev_kfree_skb_any(skb); 2186 dev_kfree_skb_any(skb);
2172 } 2187 }
2173 2188
2174 while ((skb = __skb_dequeue(&htt->rx_in_ord_compl_q))) { 2189 while ((skb = __skb_dequeue(&rx_ind_q))) {
2190 spin_lock_bh(&htt->rx_ring.lock);
2175 ath10k_htt_rx_in_ord_ind(ar, skb); 2191 ath10k_htt_rx_in_ord_ind(ar, skb);
2192 spin_unlock_bh(&htt->rx_ring.lock);
2176 dev_kfree_skb_any(skb); 2193 dev_kfree_skb_any(skb);
2177 } 2194 }
2178 spin_unlock_bh(&htt->rx_ring.lock);
2179} 2195}
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index b3adadb5f824..95acb727c068 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -97,6 +97,85 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
97 idr_remove(&htt->pending_tx, msdu_id); 97 idr_remove(&htt->pending_tx, msdu_id);
98} 98}
99 99
100static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt)
101{
102 size_t size;
103
104 if (!htt->frag_desc.vaddr)
105 return;
106
107 size = htt->max_num_pending_tx * sizeof(struct htt_msdu_ext_desc);
108
109 dma_free_coherent(htt->ar->dev,
110 size,
111 htt->frag_desc.vaddr,
112 htt->frag_desc.paddr);
113}
114
115static int ath10k_htt_tx_alloc_cont_frag_desc(struct ath10k_htt *htt)
116{
117 struct ath10k *ar = htt->ar;
118 size_t size;
119
120 if (!ar->hw_params.continuous_frag_desc)
121 return 0;
122
123 size = htt->max_num_pending_tx * sizeof(struct htt_msdu_ext_desc);
124 htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size,
125 &htt->frag_desc.paddr,
126 GFP_KERNEL);
127 if (!htt->frag_desc.vaddr) {
128 ath10k_err(ar, "failed to alloc fragment desc memory\n");
129 return -ENOMEM;
130 }
131
132 return 0;
133}
134
135static void ath10k_htt_tx_free_txq(struct ath10k_htt *htt)
136{
137 struct ath10k *ar = htt->ar;
138 size_t size;
139
140 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features))
141 return;
142
143 size = sizeof(*htt->tx_q_state.vaddr);
144
145 dma_unmap_single(ar->dev, htt->tx_q_state.paddr, size, DMA_TO_DEVICE);
146 kfree(htt->tx_q_state.vaddr);
147}
148
149static int ath10k_htt_tx_alloc_txq(struct ath10k_htt *htt)
150{
151 struct ath10k *ar = htt->ar;
152 size_t size;
153 int ret;
154
155 if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features))
156 return 0;
157
158 htt->tx_q_state.num_peers = HTT_TX_Q_STATE_NUM_PEERS;
159 htt->tx_q_state.num_tids = HTT_TX_Q_STATE_NUM_TIDS;
160 htt->tx_q_state.type = HTT_Q_DEPTH_TYPE_BYTES;
161
162 size = sizeof(*htt->tx_q_state.vaddr);
163 htt->tx_q_state.vaddr = kzalloc(size, GFP_KERNEL);
164 if (!htt->tx_q_state.vaddr)
165 return -ENOMEM;
166
167 htt->tx_q_state.paddr = dma_map_single(ar->dev, htt->tx_q_state.vaddr,
168 size, DMA_TO_DEVICE);
169 ret = dma_mapping_error(ar->dev, htt->tx_q_state.paddr);
170 if (ret) {
171 ath10k_warn(ar, "failed to dma map tx_q_state: %d\n", ret);
172 kfree(htt->tx_q_state.vaddr);
173 return -EIO;
174 }
175
176 return 0;
177}
178
100int ath10k_htt_tx_alloc(struct ath10k_htt *htt) 179int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
101{ 180{
102 struct ath10k *ar = htt->ar; 181 struct ath10k *ar = htt->ar;
@@ -118,29 +197,32 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
118 goto free_idr_pending_tx; 197 goto free_idr_pending_tx;
119 } 198 }
120 199
121 if (!ar->hw_params.continuous_frag_desc) 200 ret = ath10k_htt_tx_alloc_cont_frag_desc(htt);
122 goto skip_frag_desc_alloc; 201 if (ret) {
123 202 ath10k_err(ar, "failed to alloc cont frag desc: %d\n", ret);
124 size = htt->max_num_pending_tx * sizeof(struct htt_msdu_ext_desc);
125 htt->frag_desc.vaddr = dma_alloc_coherent(ar->dev, size,
126 &htt->frag_desc.paddr,
127 GFP_KERNEL);
128 if (!htt->frag_desc.vaddr) {
129 ath10k_warn(ar, "failed to alloc fragment desc memory\n");
130 ret = -ENOMEM;
131 goto free_txbuf; 203 goto free_txbuf;
132 } 204 }
133 205
134skip_frag_desc_alloc: 206 ret = ath10k_htt_tx_alloc_txq(htt);
207 if (ret) {
208 ath10k_err(ar, "failed to alloc txq: %d\n", ret);
209 goto free_frag_desc;
210 }
211
135 return 0; 212 return 0;
136 213
214free_frag_desc:
215 ath10k_htt_tx_free_cont_frag_desc(htt);
216
137free_txbuf: 217free_txbuf:
138 size = htt->max_num_pending_tx * 218 size = htt->max_num_pending_tx *
139 sizeof(struct ath10k_htt_txbuf); 219 sizeof(struct ath10k_htt_txbuf);
140 dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr, 220 dma_free_coherent(htt->ar->dev, size, htt->txbuf.vaddr,
141 htt->txbuf.paddr); 221 htt->txbuf.paddr);
222
142free_idr_pending_tx: 223free_idr_pending_tx:
143 idr_destroy(&htt->pending_tx); 224 idr_destroy(&htt->pending_tx);
225
144 return ret; 226 return ret;
145} 227}
146 228
@@ -174,12 +256,8 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
174 htt->txbuf.paddr); 256 htt->txbuf.paddr);
175 } 257 }
176 258
177 if (htt->frag_desc.vaddr) { 259 ath10k_htt_tx_free_txq(htt);
178 size = htt->max_num_pending_tx * 260 ath10k_htt_tx_free_cont_frag_desc(htt);
179 sizeof(struct htt_msdu_ext_desc);
180 dma_free_coherent(htt->ar->dev, size, htt->frag_desc.vaddr,
181 htt->frag_desc.paddr);
182 }
183} 261}
184 262
185void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) 263void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
@@ -268,7 +346,9 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt)
268 struct ath10k *ar = htt->ar; 346 struct ath10k *ar = htt->ar;
269 struct sk_buff *skb; 347 struct sk_buff *skb;
270 struct htt_cmd *cmd; 348 struct htt_cmd *cmd;
349 struct htt_frag_desc_bank_cfg *cfg;
271 int ret, size; 350 int ret, size;
351 u8 info;
272 352
273 if (!ar->hw_params.continuous_frag_desc) 353 if (!ar->hw_params.continuous_frag_desc)
274 return 0; 354 return 0;
@@ -286,14 +366,30 @@ int ath10k_htt_send_frag_desc_bank_cfg(struct ath10k_htt *htt)
286 skb_put(skb, size); 366 skb_put(skb, size);
287 cmd = (struct htt_cmd *)skb->data; 367 cmd = (struct htt_cmd *)skb->data;
288 cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG; 368 cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG;
289 cmd->frag_desc_bank_cfg.info = 0; 369
290 cmd->frag_desc_bank_cfg.num_banks = 1; 370 info = 0;
291 cmd->frag_desc_bank_cfg.desc_size = sizeof(struct htt_msdu_ext_desc); 371 info |= SM(htt->tx_q_state.type,
292 cmd->frag_desc_bank_cfg.bank_base_addrs[0] = 372 HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_DEPTH_TYPE);
293 __cpu_to_le32(htt->frag_desc.paddr); 373
294 cmd->frag_desc_bank_cfg.bank_id[0].bank_min_id = 0; 374 if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, ar->fw_features))
295 cmd->frag_desc_bank_cfg.bank_id[0].bank_max_id = 375 info |= HTT_FRAG_DESC_BANK_CFG_INFO_Q_STATE_VALID;
296 __cpu_to_le16(htt->max_num_pending_tx - 1); 376
377 cfg = &cmd->frag_desc_bank_cfg;
378 cfg->info = info;
379 cfg->num_banks = 1;
380 cfg->desc_size = sizeof(struct htt_msdu_ext_desc);
381 cfg->bank_base_addrs[0] = __cpu_to_le32(htt->frag_desc.paddr);
382 cfg->bank_id[0].bank_min_id = 0;
383 cfg->bank_id[0].bank_max_id = __cpu_to_le16(htt->max_num_pending_tx -
384 1);
385
386 cfg->q_state.paddr = cpu_to_le32(htt->tx_q_state.paddr);
387 cfg->q_state.num_peers = cpu_to_le16(htt->tx_q_state.num_peers);
388 cfg->q_state.num_tids = cpu_to_le16(htt->tx_q_state.num_tids);
389 cfg->q_state.record_size = HTT_TX_Q_STATE_ENTRY_SIZE;
390 cfg->q_state.record_multiplier = HTT_TX_Q_STATE_ENTRY_MULTIPLIER;
391
392 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt frag desc bank cmd\n");
297 393
298 ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); 394 ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
299 if (ret) { 395 if (ret) {
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
index 7b84d08a5154..f544d48518c3 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -109,6 +109,38 @@ const struct ath10k_hw_regs qca99x0_regs = {
109 .pcie_intr_clr_address = 0x00000010, 109 .pcie_intr_clr_address = 0x00000010,
110}; 110};
111 111
112const struct ath10k_hw_regs qca4019_regs = {
113 .rtc_soc_base_address = 0x00080000,
114 .soc_core_base_address = 0x00082000,
115 .ce_wrapper_base_address = 0x0004d000,
116 .ce0_base_address = 0x0004a000,
117 .ce1_base_address = 0x0004a400,
118 .ce2_base_address = 0x0004a800,
119 .ce3_base_address = 0x0004ac00,
120 .ce4_base_address = 0x0004b000,
121 .ce5_base_address = 0x0004b400,
122 .ce6_base_address = 0x0004b800,
123 .ce7_base_address = 0x0004bc00,
124 /* qca4019 supports upto 12 copy engines. Since base address
125 * of ce8 to ce11 are not directly referred in the code,
126 * no need have them in separate members in this table.
127 * Copy Engine Address
128 * CE8 0x0004c000
129 * CE9 0x0004c400
130 * CE10 0x0004c800
131 * CE11 0x0004cc00
132 */
133 .soc_reset_control_si0_rst_mask = 0x00000001,
134 .soc_reset_control_ce_rst_mask = 0x00000100,
135 .soc_chip_id_address = 0x000000ec,
136 .fw_indicator_address = 0x0004f00c,
137 .ce_wrap_intr_sum_host_msi_lsb = 0x0000000c,
138 .ce_wrap_intr_sum_host_msi_mask = 0x00fff000,
139 .pcie_intr_fw_mask = 0x00100000,
140 .pcie_intr_ce_mask_all = 0x000fff00,
141 .pcie_intr_clr_address = 0x00000010,
142};
143
112const struct ath10k_hw_values qca988x_values = { 144const struct ath10k_hw_values qca988x_values = {
113 .rtc_state_val_on = 3, 145 .rtc_state_val_on = 3,
114 .ce_count = 8, 146 .ce_count = 8,
@@ -136,6 +168,13 @@ const struct ath10k_hw_values qca99x0_values = {
136 .ce_desc_meta_data_lsb = 4, 168 .ce_desc_meta_data_lsb = 4,
137}; 169};
138 170
171const struct ath10k_hw_values qca4019_values = {
172 .ce_count = 12,
173 .num_target_ce_config_wlan = 10,
174 .ce_desc_meta_data_mask = 0xFFF0,
175 .ce_desc_meta_data_lsb = 4,
176};
177
139void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, 178void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
140 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev) 179 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
141{ 180{
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index 0678831e8671..f0cfbc745c97 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -106,6 +106,14 @@ enum qca9377_chip_id_rev {
106#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin" 106#define QCA9377_HW_1_0_BOARD_DATA_FILE "board.bin"
107#define QCA9377_HW_1_0_PATCH_LOAD_ADDR 0x1234 107#define QCA9377_HW_1_0_PATCH_LOAD_ADDR 0x1234
108 108
109/* QCA4019 1.0 definitions */
110#define QCA4019_HW_1_0_DEV_VERSION 0x01000000
111#define QCA4019_HW_1_0_FW_DIR ATH10K_FW_DIR "/QCA4019/hw1.0"
112#define QCA4019_HW_1_0_FW_FILE "firmware.bin"
113#define QCA4019_HW_1_0_OTP_FILE "otp.bin"
114#define QCA4019_HW_1_0_BOARD_DATA_FILE "board.bin"
115#define QCA4019_HW_1_0_PATCH_LOAD_ADDR 0x1234
116
109#define ATH10K_FW_API2_FILE "firmware-2.bin" 117#define ATH10K_FW_API2_FILE "firmware-2.bin"
110#define ATH10K_FW_API3_FILE "firmware-3.bin" 118#define ATH10K_FW_API3_FILE "firmware-3.bin"
111 119
@@ -200,6 +208,7 @@ enum ath10k_hw_rev {
200 ATH10K_HW_QCA6174, 208 ATH10K_HW_QCA6174,
201 ATH10K_HW_QCA99X0, 209 ATH10K_HW_QCA99X0,
202 ATH10K_HW_QCA9377, 210 ATH10K_HW_QCA9377,
211 ATH10K_HW_QCA4019,
203}; 212};
204 213
205struct ath10k_hw_regs { 214struct ath10k_hw_regs {
@@ -232,6 +241,7 @@ struct ath10k_hw_regs {
232extern const struct ath10k_hw_regs qca988x_regs; 241extern const struct ath10k_hw_regs qca988x_regs;
233extern const struct ath10k_hw_regs qca6174_regs; 242extern const struct ath10k_hw_regs qca6174_regs;
234extern const struct ath10k_hw_regs qca99x0_regs; 243extern const struct ath10k_hw_regs qca99x0_regs;
244extern const struct ath10k_hw_regs qca4019_regs;
235 245
236struct ath10k_hw_values { 246struct ath10k_hw_values {
237 u32 rtc_state_val_on; 247 u32 rtc_state_val_on;
@@ -245,6 +255,7 @@ struct ath10k_hw_values {
245extern const struct ath10k_hw_values qca988x_values; 255extern const struct ath10k_hw_values qca988x_values;
246extern const struct ath10k_hw_values qca6174_values; 256extern const struct ath10k_hw_values qca6174_values;
247extern const struct ath10k_hw_values qca99x0_values; 257extern const struct ath10k_hw_values qca99x0_values;
258extern const struct ath10k_hw_values qca4019_values;
248 259
249void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey, 260void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
250 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev); 261 u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev);
@@ -253,6 +264,7 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
253#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) 264#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
254#define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0) 265#define QCA_REV_99X0(ar) ((ar)->hw_rev == ATH10K_HW_QCA99X0)
255#define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377) 266#define QCA_REV_9377(ar) ((ar)->hw_rev == ATH10K_HW_QCA9377)
267#define QCA_REV_40XX(ar) ((ar)->hw_rev == ATH10K_HW_QCA4019)
256 268
257/* Known pecularities: 269/* Known pecularities:
258 * - raw appears in nwifi decap, raw and nwifi appear in ethernet decap 270 * - raw appears in nwifi decap, raw and nwifi appear in ethernet decap
@@ -363,14 +375,19 @@ enum ath10k_hw_4addr_pad {
363#define TARGET_10X_MAC_AGGR_DELIM 0 375#define TARGET_10X_MAC_AGGR_DELIM 0
364#define TARGET_10X_AST_SKID_LIMIT 128 376#define TARGET_10X_AST_SKID_LIMIT 128
365#define TARGET_10X_NUM_STATIONS 128 377#define TARGET_10X_NUM_STATIONS 128
378#define TARGET_10X_TX_STATS_NUM_STATIONS 118
366#define TARGET_10X_NUM_PEERS ((TARGET_10X_NUM_STATIONS) + \ 379#define TARGET_10X_NUM_PEERS ((TARGET_10X_NUM_STATIONS) + \
367 (TARGET_10X_NUM_VDEVS)) 380 (TARGET_10X_NUM_VDEVS))
381#define TARGET_10X_TX_STATS_NUM_PEERS ((TARGET_10X_TX_STATS_NUM_STATIONS) + \
382 (TARGET_10X_NUM_VDEVS))
368#define TARGET_10X_NUM_OFFLOAD_PEERS 0 383#define TARGET_10X_NUM_OFFLOAD_PEERS 0
369#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 384#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0
370#define TARGET_10X_NUM_PEER_KEYS 2 385#define TARGET_10X_NUM_PEER_KEYS 2
371#define TARGET_10X_NUM_TIDS_MAX 256 386#define TARGET_10X_NUM_TIDS_MAX 256
372#define TARGET_10X_NUM_TIDS min((TARGET_10X_NUM_TIDS_MAX), \ 387#define TARGET_10X_NUM_TIDS min((TARGET_10X_NUM_TIDS_MAX), \
373 (TARGET_10X_NUM_PEERS) * 2) 388 (TARGET_10X_NUM_PEERS) * 2)
389#define TARGET_10X_TX_STATS_NUM_TIDS min((TARGET_10X_NUM_TIDS_MAX), \
390 (TARGET_10X_TX_STATS_NUM_PEERS) * 2)
374#define TARGET_10X_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) 391#define TARGET_10X_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2))
375#define TARGET_10X_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) 392#define TARGET_10X_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2))
376#define TARGET_10X_RX_TIMEOUT_LO_PRI 100 393#define TARGET_10X_RX_TIMEOUT_LO_PRI 100
@@ -414,16 +431,11 @@ enum ath10k_hw_4addr_pad {
414#define TARGET_10_4_ACTIVE_PEERS 0 431#define TARGET_10_4_ACTIVE_PEERS 0
415 432
416#define TARGET_10_4_NUM_QCACHE_PEERS_MAX 512 433#define TARGET_10_4_NUM_QCACHE_PEERS_MAX 512
417#define TARGET_10_4_QCACHE_ACTIVE_PEERS 50
418#define TARGET_10_4_NUM_OFFLOAD_PEERS 0 434#define TARGET_10_4_NUM_OFFLOAD_PEERS 0
419#define TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS 0 435#define TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS 0
420#define TARGET_10_4_NUM_PEER_KEYS 2 436#define TARGET_10_4_NUM_PEER_KEYS 2
421#define TARGET_10_4_TGT_NUM_TIDS ((TARGET_10_4_NUM_PEERS) * 2) 437#define TARGET_10_4_TGT_NUM_TIDS ((TARGET_10_4_NUM_PEERS) * 2)
422#define TARGET_10_4_AST_SKID_LIMIT 32 438#define TARGET_10_4_AST_SKID_LIMIT 32
423#define TARGET_10_4_TX_CHAIN_MASK (BIT(0) | BIT(1) | \
424 BIT(2) | BIT(3))
425#define TARGET_10_4_RX_CHAIN_MASK (BIT(0) | BIT(1) | \
426 BIT(2) | BIT(3))
427 439
428/* 100 ms for video, best-effort, and background */ 440/* 100 ms for video, best-effort, and background */
429#define TARGET_10_4_RX_TIMEOUT_LO_PRI 100 441#define TARGET_10_4_RX_TIMEOUT_LO_PRI 100
@@ -449,7 +461,6 @@ enum ath10k_hw_4addr_pad {
449#define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1 461#define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
450#define TARGET_10_4_VOW_CONFIG 0 462#define TARGET_10_4_VOW_CONFIG 0
451#define TARGET_10_4_GTK_OFFLOAD_MAX_VDEV 3 463#define TARGET_10_4_GTK_OFFLOAD_MAX_VDEV 3
452#define TARGET_10_4_NUM_MSDU_DESC (1024 + 400)
453#define TARGET_10_4_11AC_TX_MAX_FRAGS 2 464#define TARGET_10_4_11AC_TX_MAX_FRAGS 2
454#define TARGET_10_4_MAX_PEER_EXT_STATS 16 465#define TARGET_10_4_MAX_PEER_EXT_STATS 16
455#define TARGET_10_4_SMART_ANT_CAP 0 466#define TARGET_10_4_SMART_ANT_CAP 0
@@ -601,6 +612,7 @@ enum ath10k_hw_4addr_pad {
601#define FW_INDICATOR_ADDRESS ar->regs->fw_indicator_address 612#define FW_INDICATOR_ADDRESS ar->regs->fw_indicator_address
602#define FW_IND_EVENT_PENDING 1 613#define FW_IND_EVENT_PENDING 1
603#define FW_IND_INITIALIZED 2 614#define FW_IND_INITIALIZED 2
615#define FW_IND_HOST_READY 0x80000000
604 616
605/* HOST_REG interrupt from firmware */ 617/* HOST_REG interrupt from firmware */
606#define PCIE_INTR_FIRMWARE_MASK ar->regs->pcie_intr_fw_mask 618#define PCIE_INTR_FIRMWARE_MASK ar->regs->pcie_intr_fw_mask
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 368de5e5a04f..78999c9de23b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1358,10 +1358,7 @@ static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
1358 const u8 *p2p_ie; 1358 const u8 *p2p_ie;
1359 int ret; 1359 int ret;
1360 1360
1361 if (arvif->vdev_type != WMI_VDEV_TYPE_AP) 1361 if (arvif->vif->type != NL80211_IFTYPE_AP || !arvif->vif->p2p)
1362 return 0;
1363
1364 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
1365 return 0; 1362 return 0;
1366 1363
1367 mgmt = (void *)bcn->data; 1364 mgmt = (void *)bcn->data;
@@ -3259,8 +3256,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
3259 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 3256 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3260 3257
3261 /* This is case only for P2P_GO */ 3258 /* This is case only for P2P_GO */
3262 if (arvif->vdev_type != WMI_VDEV_TYPE_AP || 3259 if (vif->type != NL80211_IFTYPE_AP || !vif->p2p)
3263 arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
3264 return; 3260 return;
3265 3261
3266 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) { 3262 if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
@@ -3988,7 +3984,7 @@ static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
3988static int ath10k_start(struct ieee80211_hw *hw) 3984static int ath10k_start(struct ieee80211_hw *hw)
3989{ 3985{
3990 struct ath10k *ar = hw->priv; 3986 struct ath10k *ar = hw->priv;
3991 u32 burst_enable; 3987 u32 param;
3992 int ret = 0; 3988 int ret = 0;
3993 3989
3994 /* 3990 /*
@@ -4031,13 +4027,15 @@ static int ath10k_start(struct ieee80211_hw *hw)
4031 goto err_power_down; 4027 goto err_power_down;
4032 } 4028 }
4033 4029
4034 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); 4030 param = ar->wmi.pdev_param->pmf_qos;
4031 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4035 if (ret) { 4032 if (ret) {
4036 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret); 4033 ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
4037 goto err_core_stop; 4034 goto err_core_stop;
4038 } 4035 }
4039 4036
4040 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); 4037 param = ar->wmi.pdev_param->dynamic_bw;
4038 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4041 if (ret) { 4039 if (ret) {
4042 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret); 4040 ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
4043 goto err_core_stop; 4041 goto err_core_stop;
@@ -4053,8 +4051,8 @@ static int ath10k_start(struct ieee80211_hw *hw)
4053 } 4051 }
4054 4052
4055 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) { 4053 if (test_bit(WMI_SERVICE_BURST, ar->wmi.svc_map)) {
4056 burst_enable = ar->wmi.pdev_param->burst_enable; 4054 param = ar->wmi.pdev_param->burst_enable;
4057 ret = ath10k_wmi_pdev_set_param(ar, burst_enable, 0); 4055 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4058 if (ret) { 4056 if (ret) {
4059 ath10k_warn(ar, "failed to disable burst: %d\n", ret); 4057 ath10k_warn(ar, "failed to disable burst: %d\n", ret);
4060 goto err_core_stop; 4058 goto err_core_stop;
@@ -4072,8 +4070,8 @@ static int ath10k_start(struct ieee80211_hw *hw)
4072 * this problem. 4070 * this problem.
4073 */ 4071 */
4074 4072
4075 ret = ath10k_wmi_pdev_set_param(ar, 4073 param = ar->wmi.pdev_param->arp_ac_override;
4076 ar->wmi.pdev_param->arp_ac_override, 0); 4074 ret = ath10k_wmi_pdev_set_param(ar, param, 0);
4077 if (ret) { 4075 if (ret) {
4078 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n", 4076 ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
4079 ret); 4077 ret);
@@ -4092,8 +4090,8 @@ static int ath10k_start(struct ieee80211_hw *hw)
4092 } 4090 }
4093 } 4091 }
4094 4092
4095 ret = ath10k_wmi_pdev_set_param(ar, 4093 param = ar->wmi.pdev_param->ani_enable;
4096 ar->wmi.pdev_param->ani_enable, 1); 4094 ret = ath10k_wmi_pdev_set_param(ar, param, 1);
4097 if (ret) { 4095 if (ret) {
4098 ath10k_warn(ar, "failed to enable ani by default: %d\n", 4096 ath10k_warn(ar, "failed to enable ani by default: %d\n",
4099 ret); 4097 ret);
@@ -4102,6 +4100,18 @@ static int ath10k_start(struct ieee80211_hw *hw)
4102 4100
4103 ar->ani_enabled = true; 4101 ar->ani_enabled = true;
4104 4102
4103 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
4104 param = ar->wmi.pdev_param->peer_stats_update_period;
4105 ret = ath10k_wmi_pdev_set_param(ar, param,
4106 PEER_DEFAULT_STATS_UPDATE_PERIOD);
4107 if (ret) {
4108 ath10k_warn(ar,
4109 "failed to set peer stats period : %d\n",
4110 ret);
4111 goto err_core_stop;
4112 }
4113 }
4114
4105 ar->num_started_vdevs = 0; 4115 ar->num_started_vdevs = 0;
4106 ath10k_regd_update(ar); 4116 ath10k_regd_update(ar);
4107 4117
@@ -4349,25 +4359,29 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
4349 bit, ar->free_vdev_map); 4359 bit, ar->free_vdev_map);
4350 4360
4351 arvif->vdev_id = bit; 4361 arvif->vdev_id = bit;
4352 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; 4362 arvif->vdev_subtype =
4363 ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
4353 4364
4354 switch (vif->type) { 4365 switch (vif->type) {
4355 case NL80211_IFTYPE_P2P_DEVICE: 4366 case NL80211_IFTYPE_P2P_DEVICE:
4356 arvif->vdev_type = WMI_VDEV_TYPE_STA; 4367 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4357 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; 4368 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4369 (ar, WMI_VDEV_SUBTYPE_P2P_DEVICE);
4358 break; 4370 break;
4359 case NL80211_IFTYPE_UNSPECIFIED: 4371 case NL80211_IFTYPE_UNSPECIFIED:
4360 case NL80211_IFTYPE_STATION: 4372 case NL80211_IFTYPE_STATION:
4361 arvif->vdev_type = WMI_VDEV_TYPE_STA; 4373 arvif->vdev_type = WMI_VDEV_TYPE_STA;
4362 if (vif->p2p) 4374 if (vif->p2p)
4363 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_CLIENT; 4375 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4376 (ar, WMI_VDEV_SUBTYPE_P2P_CLIENT);
4364 break; 4377 break;
4365 case NL80211_IFTYPE_ADHOC: 4378 case NL80211_IFTYPE_ADHOC:
4366 arvif->vdev_type = WMI_VDEV_TYPE_IBSS; 4379 arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
4367 break; 4380 break;
4368 case NL80211_IFTYPE_MESH_POINT: 4381 case NL80211_IFTYPE_MESH_POINT:
4369 if (test_bit(WMI_SERVICE_MESH, ar->wmi.svc_map)) { 4382 if (test_bit(WMI_SERVICE_MESH_11S, ar->wmi.svc_map)) {
4370 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH; 4383 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4384 (ar, WMI_VDEV_SUBTYPE_MESH_11S);
4371 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) { 4385 } else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
4372 ret = -EINVAL; 4386 ret = -EINVAL;
4373 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n"); 4387 ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
@@ -4379,7 +4393,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
4379 arvif->vdev_type = WMI_VDEV_TYPE_AP; 4393 arvif->vdev_type = WMI_VDEV_TYPE_AP;
4380 4394
4381 if (vif->p2p) 4395 if (vif->p2p)
4382 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_GO; 4396 arvif->vdev_subtype = ath10k_wmi_get_vdev_subtype
4397 (ar, WMI_VDEV_SUBTYPE_P2P_GO);
4383 break; 4398 break;
4384 case NL80211_IFTYPE_MONITOR: 4399 case NL80211_IFTYPE_MONITOR:
4385 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR; 4400 arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index ee925c618535..b3cff1d3364a 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -94,7 +94,6 @@ static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
94static void ath10k_pci_buffer_cleanup(struct ath10k *ar); 94static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
95static int ath10k_pci_cold_reset(struct ath10k *ar); 95static int ath10k_pci_cold_reset(struct ath10k *ar);
96static int ath10k_pci_safe_chip_reset(struct ath10k *ar); 96static int ath10k_pci_safe_chip_reset(struct ath10k *ar);
97static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
98static int ath10k_pci_init_irq(struct ath10k *ar); 97static int ath10k_pci_init_irq(struct ath10k *ar);
99static int ath10k_pci_deinit_irq(struct ath10k *ar); 98static int ath10k_pci_deinit_irq(struct ath10k *ar);
100static int ath10k_pci_request_irq(struct ath10k *ar); 99static int ath10k_pci_request_irq(struct ath10k *ar);
@@ -620,7 +619,7 @@ static void ath10k_pci_sleep_sync(struct ath10k *ar)
620 spin_unlock_irqrestore(&ar_pci->ps_lock, flags); 619 spin_unlock_irqrestore(&ar_pci->ps_lock, flags);
621} 620}
622 621
623void ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value) 622static void ath10k_bus_pci_write32(struct ath10k *ar, u32 offset, u32 value)
624{ 623{
625 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 624 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
626 int ret; 625 int ret;
@@ -642,7 +641,7 @@ void ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value)
642 ath10k_pci_sleep(ar); 641 ath10k_pci_sleep(ar);
643} 642}
644 643
645u32 ath10k_pci_read32(struct ath10k *ar, u32 offset) 644static u32 ath10k_bus_pci_read32(struct ath10k *ar, u32 offset)
646{ 645{
647 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 646 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
648 u32 val; 647 u32 val;
@@ -667,6 +666,20 @@ u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
667 return val; 666 return val;
668} 667}
669 668
669inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value)
670{
671 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
672
673 ar_pci->bus_ops->write32(ar, offset, value);
674}
675
676inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset)
677{
678 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
679
680 return ar_pci->bus_ops->read32(ar, offset);
681}
682
670u32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr) 683u32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr)
671{ 684{
672 return ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + addr); 685 return ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + addr);
@@ -687,7 +700,7 @@ void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val)
687 ath10k_pci_write32(ar, PCIE_LOCAL_BASE_ADDRESS + addr, val); 700 ath10k_pci_write32(ar, PCIE_LOCAL_BASE_ADDRESS + addr, val);
688} 701}
689 702
690static bool ath10k_pci_irq_pending(struct ath10k *ar) 703bool ath10k_pci_irq_pending(struct ath10k *ar)
691{ 704{
692 u32 cause; 705 u32 cause;
693 706
@@ -700,7 +713,7 @@ static bool ath10k_pci_irq_pending(struct ath10k *ar)
700 return false; 713 return false;
701} 714}
702 715
703static void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar) 716void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar)
704{ 717{
705 /* IMPORTANT: INTR_CLR register has to be set after 718 /* IMPORTANT: INTR_CLR register has to be set after
706 * INTR_ENABLE is set to 0, otherwise interrupt can not be 719 * INTR_ENABLE is set to 0, otherwise interrupt can not be
@@ -716,7 +729,7 @@ static void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar)
716 PCIE_INTR_ENABLE_ADDRESS); 729 PCIE_INTR_ENABLE_ADDRESS);
717} 730}
718 731
719static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) 732void ath10k_pci_enable_legacy_irq(struct ath10k *ar)
720{ 733{
721 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + 734 ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS +
722 PCIE_INTR_ENABLE_ADDRESS, 735 PCIE_INTR_ENABLE_ADDRESS,
@@ -809,7 +822,7 @@ static void ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe)
809 } 822 }
810} 823}
811 824
812static void ath10k_pci_rx_post(struct ath10k *ar) 825void ath10k_pci_rx_post(struct ath10k *ar)
813{ 826{
814 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 827 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
815 int i; 828 int i;
@@ -818,7 +831,7 @@ static void ath10k_pci_rx_post(struct ath10k *ar)
818 ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]); 831 ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]);
819} 832}
820 833
821static void ath10k_pci_rx_replenish_retry(unsigned long ptr) 834void ath10k_pci_rx_replenish_retry(unsigned long ptr)
822{ 835{
823 struct ath10k *ar = (void *)ptr; 836 struct ath10k *ar = (void *)ptr;
824 837
@@ -838,6 +851,7 @@ static u32 ath10k_pci_targ_cpu_to_ce_addr(struct ath10k *ar, u32 addr)
838 0x7ff) << 21; 851 0x7ff) << 21;
839 break; 852 break;
840 case ATH10K_HW_QCA99X0: 853 case ATH10K_HW_QCA99X0:
854 case ATH10K_HW_QCA4019:
841 val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS); 855 val = ath10k_pci_read32(ar, PCIE_BAR_REG_ADDRESS);
842 break; 856 break;
843 } 857 }
@@ -1007,8 +1021,8 @@ static int __ath10k_pci_diag_read_hi(struct ath10k *ar, void *dest,
1007#define ath10k_pci_diag_read_hi(ar, dest, src, len) \ 1021#define ath10k_pci_diag_read_hi(ar, dest, src, len) \
1008 __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len) 1022 __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len)
1009 1023
1010static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, 1024int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
1011 const void *data, int nbytes) 1025 const void *data, int nbytes)
1012{ 1026{
1013 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1027 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1014 int ret = 0; 1028 int ret = 0;
@@ -1263,8 +1277,8 @@ static void ath10k_pci_htt_rx_cb(struct ath10k_ce_pipe *ce_state)
1263 ath10k_pci_process_rx_cb(ce_state, ath10k_pci_htt_rx_deliver); 1277 ath10k_pci_process_rx_cb(ce_state, ath10k_pci_htt_rx_deliver);
1264} 1278}
1265 1279
1266static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, 1280int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
1267 struct ath10k_hif_sg_item *items, int n_items) 1281 struct ath10k_hif_sg_item *items, int n_items)
1268{ 1282{
1269 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1283 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1270 struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id]; 1284 struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id];
@@ -1332,13 +1346,13 @@ err:
1332 return err; 1346 return err;
1333} 1347}
1334 1348
1335static int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf, 1349int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
1336 size_t buf_len) 1350 size_t buf_len)
1337{ 1351{
1338 return ath10k_pci_diag_read_mem(ar, address, buf, buf_len); 1352 return ath10k_pci_diag_read_mem(ar, address, buf, buf_len);
1339} 1353}
1340 1354
1341static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) 1355u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe)
1342{ 1356{
1343 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1357 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1344 1358
@@ -1406,8 +1420,8 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar)
1406 queue_work(ar->workqueue, &ar->restart_work); 1420 queue_work(ar->workqueue, &ar->restart_work);
1407} 1421}
1408 1422
1409static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, 1423void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
1410 int force) 1424 int force)
1411{ 1425{
1412 ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif send complete check\n"); 1426 ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif send complete check\n");
1413 1427
@@ -1432,7 +1446,7 @@ static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
1432 ath10k_ce_per_engine_service(ar, pipe); 1446 ath10k_ce_per_engine_service(ar, pipe);
1433} 1447}
1434 1448
1435static void ath10k_pci_kill_tasklet(struct ath10k *ar) 1449void ath10k_pci_kill_tasklet(struct ath10k *ar)
1436{ 1450{
1437 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1451 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1438 int i; 1452 int i;
@@ -1446,8 +1460,8 @@ static void ath10k_pci_kill_tasklet(struct ath10k *ar)
1446 del_timer_sync(&ar_pci->rx_post_retry); 1460 del_timer_sync(&ar_pci->rx_post_retry);
1447} 1461}
1448 1462
1449static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id, 1463int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
1450 u8 *ul_pipe, u8 *dl_pipe) 1464 u8 *ul_pipe, u8 *dl_pipe)
1451{ 1465{
1452 const struct service_to_pipe *entry; 1466 const struct service_to_pipe *entry;
1453 bool ul_set = false, dl_set = false; 1467 bool ul_set = false, dl_set = false;
@@ -1491,8 +1505,8 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
1491 return 0; 1505 return 0;
1492} 1506}
1493 1507
1494static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, 1508void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
1495 u8 *ul_pipe, u8 *dl_pipe) 1509 u8 *ul_pipe, u8 *dl_pipe)
1496{ 1510{
1497 ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get default pipe\n"); 1511 ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get default pipe\n");
1498 1512
@@ -1516,6 +1530,7 @@ static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar)
1516 CORE_CTRL_ADDRESS, val); 1530 CORE_CTRL_ADDRESS, val);
1517 break; 1531 break;
1518 case ATH10K_HW_QCA99X0: 1532 case ATH10K_HW_QCA99X0:
1533 case ATH10K_HW_QCA4019:
1519 /* TODO: Find appropriate register configuration for QCA99X0 1534 /* TODO: Find appropriate register configuration for QCA99X0
1520 * to mask irq/MSI. 1535 * to mask irq/MSI.
1521 */ 1536 */
@@ -1538,6 +1553,7 @@ static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar)
1538 CORE_CTRL_ADDRESS, val); 1553 CORE_CTRL_ADDRESS, val);
1539 break; 1554 break;
1540 case ATH10K_HW_QCA99X0: 1555 case ATH10K_HW_QCA99X0:
1556 case ATH10K_HW_QCA4019:
1541 /* TODO: Find appropriate register configuration for QCA99X0 1557 /* TODO: Find appropriate register configuration for QCA99X0
1542 * to unmask irq/MSI. 1558 * to unmask irq/MSI.
1543 */ 1559 */
@@ -1668,7 +1684,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar)
1668 } 1684 }
1669} 1685}
1670 1686
1671static void ath10k_pci_ce_deinit(struct ath10k *ar) 1687void ath10k_pci_ce_deinit(struct ath10k *ar)
1672{ 1688{
1673 int i; 1689 int i;
1674 1690
@@ -1676,7 +1692,7 @@ static void ath10k_pci_ce_deinit(struct ath10k *ar)
1676 ath10k_ce_deinit_pipe(ar, i); 1692 ath10k_ce_deinit_pipe(ar, i);
1677} 1693}
1678 1694
1679static void ath10k_pci_flush(struct ath10k *ar) 1695void ath10k_pci_flush(struct ath10k *ar)
1680{ 1696{
1681 ath10k_pci_kill_tasklet(ar); 1697 ath10k_pci_kill_tasklet(ar);
1682 ath10k_pci_buffer_cleanup(ar); 1698 ath10k_pci_buffer_cleanup(ar);
@@ -1711,9 +1727,9 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
1711 spin_unlock_irqrestore(&ar_pci->ps_lock, flags); 1727 spin_unlock_irqrestore(&ar_pci->ps_lock, flags);
1712} 1728}
1713 1729
1714static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, 1730int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
1715 void *req, u32 req_len, 1731 void *req, u32 req_len,
1716 void *resp, u32 *resp_len) 1732 void *resp, u32 *resp_len)
1717{ 1733{
1718 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 1734 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1719 struct ath10k_pci_pipe *pci_tx = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG]; 1735 struct ath10k_pci_pipe *pci_tx = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG];
@@ -1756,7 +1772,7 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
1756 DMA_FROM_DEVICE); 1772 DMA_FROM_DEVICE);
1757 ret = dma_mapping_error(ar->dev, resp_paddr); 1773 ret = dma_mapping_error(ar->dev, resp_paddr);
1758 if (ret) { 1774 if (ret) {
1759 ret = EIO; 1775 ret = -EIO;
1760 goto err_req; 1776 goto err_req;
1761 } 1777 }
1762 1778
@@ -1907,7 +1923,14 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
1907 return 1; 1923 return 1;
1908} 1924}
1909 1925
1910static int ath10k_pci_init_config(struct ath10k *ar) 1926static int ath10k_bus_get_num_banks(struct ath10k *ar)
1927{
1928 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1929
1930 return ar_pci->bus_ops->get_num_banks(ar);
1931}
1932
1933int ath10k_pci_init_config(struct ath10k *ar)
1911{ 1934{
1912 u32 interconnect_targ_addr; 1935 u32 interconnect_targ_addr;
1913 u32 pcie_state_targ_addr = 0; 1936 u32 pcie_state_targ_addr = 0;
@@ -2018,7 +2041,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
2018 /* first bank is switched to IRAM */ 2041 /* first bank is switched to IRAM */
2019 ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) & 2042 ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) &
2020 HI_EARLY_ALLOC_MAGIC_MASK); 2043 HI_EARLY_ALLOC_MAGIC_MASK);
2021 ealloc_value |= ((ath10k_pci_get_num_banks(ar) << 2044 ealloc_value |= ((ath10k_bus_get_num_banks(ar) <<
2022 HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & 2045 HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) &
2023 HI_EARLY_ALLOC_IRAM_BANKS_MASK); 2046 HI_EARLY_ALLOC_IRAM_BANKS_MASK);
2024 2047
@@ -2071,7 +2094,7 @@ static void ath10k_pci_override_ce_config(struct ath10k *ar)
2071 target_service_to_ce_map_wlan[15].pipenum = __cpu_to_le32(1); 2094 target_service_to_ce_map_wlan[15].pipenum = __cpu_to_le32(1);
2072} 2095}
2073 2096
2074static int ath10k_pci_alloc_pipes(struct ath10k *ar) 2097int ath10k_pci_alloc_pipes(struct ath10k *ar)
2075{ 2098{
2076 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2099 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2077 struct ath10k_pci_pipe *pipe; 2100 struct ath10k_pci_pipe *pipe;
@@ -2102,7 +2125,7 @@ static int ath10k_pci_alloc_pipes(struct ath10k *ar)
2102 return 0; 2125 return 0;
2103} 2126}
2104 2127
2105static void ath10k_pci_free_pipes(struct ath10k *ar) 2128void ath10k_pci_free_pipes(struct ath10k *ar)
2106{ 2129{
2107 int i; 2130 int i;
2108 2131
@@ -2110,7 +2133,7 @@ static void ath10k_pci_free_pipes(struct ath10k *ar)
2110 ath10k_ce_free_pipe(ar, i); 2133 ath10k_ce_free_pipe(ar, i);
2111} 2134}
2112 2135
2113static int ath10k_pci_init_pipes(struct ath10k *ar) 2136int ath10k_pci_init_pipes(struct ath10k *ar)
2114{ 2137{
2115 int i, ret; 2138 int i, ret;
2116 2139
@@ -2453,7 +2476,7 @@ err_sleep:
2453 return ret; 2476 return ret;
2454} 2477}
2455 2478
2456static void ath10k_pci_hif_power_down(struct ath10k *ar) 2479void ath10k_pci_hif_power_down(struct ath10k *ar)
2457{ 2480{
2458 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); 2481 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n");
2459 2482
@@ -2722,7 +2745,7 @@ static void ath10k_pci_free_irq(struct ath10k *ar)
2722 free_irq(ar_pci->pdev->irq + i, ar); 2745 free_irq(ar_pci->pdev->irq + i, ar);
2723} 2746}
2724 2747
2725static void ath10k_pci_init_irq_tasklets(struct ath10k *ar) 2748void ath10k_pci_init_irq_tasklets(struct ath10k *ar)
2726{ 2749{
2727 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2750 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2728 int i; 2751 int i;
@@ -2808,7 +2831,7 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar)
2808 return 0; 2831 return 0;
2809} 2832}
2810 2833
2811static int ath10k_pci_wait_for_target_init(struct ath10k *ar) 2834int ath10k_pci_wait_for_target_init(struct ath10k *ar)
2812{ 2835{
2813 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2836 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2814 unsigned long timeout; 2837 unsigned long timeout;
@@ -2989,6 +3012,43 @@ static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id)
2989 return false; 3012 return false;
2990} 3013}
2991 3014
3015int ath10k_pci_setup_resource(struct ath10k *ar)
3016{
3017 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
3018 int ret;
3019
3020 spin_lock_init(&ar_pci->ce_lock);
3021 spin_lock_init(&ar_pci->ps_lock);
3022
3023 setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry,
3024 (unsigned long)ar);
3025
3026 if (QCA_REV_6174(ar))
3027 ath10k_pci_override_ce_config(ar);
3028
3029 ret = ath10k_pci_alloc_pipes(ar);
3030 if (ret) {
3031 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
3032 ret);
3033 return ret;
3034 }
3035
3036 return 0;
3037}
3038
3039void ath10k_pci_release_resource(struct ath10k *ar)
3040{
3041 ath10k_pci_kill_tasklet(ar);
3042 ath10k_pci_ce_deinit(ar);
3043 ath10k_pci_free_pipes(ar);
3044}
3045
3046static const struct ath10k_bus_ops ath10k_pci_bus_ops = {
3047 .read32 = ath10k_bus_pci_read32,
3048 .write32 = ath10k_bus_pci_write32,
3049 .get_num_banks = ath10k_pci_get_num_banks,
3050};
3051
2992static int ath10k_pci_probe(struct pci_dev *pdev, 3052static int ath10k_pci_probe(struct pci_dev *pdev,
2993 const struct pci_device_id *pci_dev) 3053 const struct pci_device_id *pci_dev)
2994{ 3054{
@@ -3039,40 +3099,32 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
3039 ar_pci->ar = ar; 3099 ar_pci->ar = ar;
3040 ar->dev_id = pci_dev->device; 3100 ar->dev_id = pci_dev->device;
3041 ar_pci->pci_ps = pci_ps; 3101 ar_pci->pci_ps = pci_ps;
3102 ar_pci->bus_ops = &ath10k_pci_bus_ops;
3042 3103
3043 ar->id.vendor = pdev->vendor; 3104 ar->id.vendor = pdev->vendor;
3044 ar->id.device = pdev->device; 3105 ar->id.device = pdev->device;
3045 ar->id.subsystem_vendor = pdev->subsystem_vendor; 3106 ar->id.subsystem_vendor = pdev->subsystem_vendor;
3046 ar->id.subsystem_device = pdev->subsystem_device; 3107 ar->id.subsystem_device = pdev->subsystem_device;
3047 3108
3048 spin_lock_init(&ar_pci->ce_lock);
3049 spin_lock_init(&ar_pci->ps_lock);
3050
3051 setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry,
3052 (unsigned long)ar);
3053 setup_timer(&ar_pci->ps_timer, ath10k_pci_ps_timer, 3109 setup_timer(&ar_pci->ps_timer, ath10k_pci_ps_timer,
3054 (unsigned long)ar); 3110 (unsigned long)ar);
3055 3111
3056 ret = ath10k_pci_claim(ar); 3112 ret = ath10k_pci_setup_resource(ar);
3057 if (ret) { 3113 if (ret) {
3058 ath10k_err(ar, "failed to claim device: %d\n", ret); 3114 ath10k_err(ar, "failed to setup resource: %d\n", ret);
3059 goto err_core_destroy; 3115 goto err_core_destroy;
3060 } 3116 }
3061 3117
3062 if (QCA_REV_6174(ar)) 3118 ret = ath10k_pci_claim(ar);
3063 ath10k_pci_override_ce_config(ar);
3064
3065 ret = ath10k_pci_alloc_pipes(ar);
3066 if (ret) { 3119 if (ret) {
3067 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", 3120 ath10k_err(ar, "failed to claim device: %d\n", ret);
3068 ret); 3121 goto err_free_pipes;
3069 goto err_sleep;
3070 } 3122 }
3071 3123
3072 ret = ath10k_pci_force_wake(ar); 3124 ret = ath10k_pci_force_wake(ar);
3073 if (ret) { 3125 if (ret) {
3074 ath10k_warn(ar, "failed to wake up device : %d\n", ret); 3126 ath10k_warn(ar, "failed to wake up device : %d\n", ret);
3075 goto err_free_pipes; 3127 goto err_sleep;
3076 } 3128 }
3077 3129
3078 ath10k_pci_ce_deinit(ar); 3130 ath10k_pci_ce_deinit(ar);
@@ -3081,7 +3133,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
3081 ret = ath10k_pci_init_irq(ar); 3133 ret = ath10k_pci_init_irq(ar);
3082 if (ret) { 3134 if (ret) {
3083 ath10k_err(ar, "failed to init irqs: %d\n", ret); 3135 ath10k_err(ar, "failed to init irqs: %d\n", ret);
3084 goto err_free_pipes; 3136 goto err_sleep;
3085 } 3137 }
3086 3138
3087 ath10k_info(ar, "pci irq %s interrupts %d irq_mode %d reset_mode %d\n", 3139 ath10k_info(ar, "pci irq %s interrupts %d irq_mode %d reset_mode %d\n",
@@ -3127,13 +3179,13 @@ err_free_irq:
3127err_deinit_irq: 3179err_deinit_irq:
3128 ath10k_pci_deinit_irq(ar); 3180 ath10k_pci_deinit_irq(ar);
3129 3181
3130err_free_pipes:
3131 ath10k_pci_free_pipes(ar);
3132
3133err_sleep: 3182err_sleep:
3134 ath10k_pci_sleep_sync(ar); 3183 ath10k_pci_sleep_sync(ar);
3135 ath10k_pci_release(ar); 3184 ath10k_pci_release(ar);
3136 3185
3186err_free_pipes:
3187 ath10k_pci_free_pipes(ar);
3188
3137err_core_destroy: 3189err_core_destroy:
3138 ath10k_core_destroy(ar); 3190 ath10k_core_destroy(ar);
3139 3191
@@ -3157,10 +3209,8 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
3157 3209
3158 ath10k_core_unregister(ar); 3210 ath10k_core_unregister(ar);
3159 ath10k_pci_free_irq(ar); 3211 ath10k_pci_free_irq(ar);
3160 ath10k_pci_kill_tasklet(ar);
3161 ath10k_pci_deinit_irq(ar); 3212 ath10k_pci_deinit_irq(ar);
3162 ath10k_pci_ce_deinit(ar); 3213 ath10k_pci_release_resource(ar);
3163 ath10k_pci_free_pipes(ar);
3164 ath10k_pci_sleep_sync(ar); 3214 ath10k_pci_sleep_sync(ar);
3165 ath10k_pci_release(ar); 3215 ath10k_pci_release(ar);
3166 ath10k_core_destroy(ar); 3216 ath10k_core_destroy(ar);
@@ -3184,6 +3234,10 @@ static int __init ath10k_pci_init(void)
3184 printk(KERN_ERR "failed to register ath10k pci driver: %d\n", 3234 printk(KERN_ERR "failed to register ath10k pci driver: %d\n",
3185 ret); 3235 ret);
3186 3236
3237 ret = ath10k_ahb_init();
3238 if (ret)
3239 printk(KERN_ERR "ahb init failed: %d\n", ret);
3240
3187 return ret; 3241 return ret;
3188} 3242}
3189module_init(ath10k_pci_init); 3243module_init(ath10k_pci_init);
@@ -3191,6 +3245,7 @@ module_init(ath10k_pci_init);
3191static void __exit ath10k_pci_exit(void) 3245static void __exit ath10k_pci_exit(void)
3192{ 3246{
3193 pci_unregister_driver(&ath10k_pci_driver); 3247 pci_unregister_driver(&ath10k_pci_driver);
3248 ath10k_ahb_exit();
3194} 3249}
3195 3250
3196module_exit(ath10k_pci_exit); 3251module_exit(ath10k_pci_exit);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index f91bf333cb75..249c73a69800 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -22,6 +22,7 @@
22 22
23#include "hw.h" 23#include "hw.h"
24#include "ce.h" 24#include "ce.h"
25#include "ahb.h"
25 26
26/* 27/*
27 * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite 28 * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite
@@ -157,6 +158,12 @@ struct ath10k_pci_supp_chip {
157 u32 rev_id; 158 u32 rev_id;
158}; 159};
159 160
161struct ath10k_bus_ops {
162 u32 (*read32)(struct ath10k *ar, u32 offset);
163 void (*write32)(struct ath10k *ar, u32 offset, u32 value);
164 int (*get_num_banks)(struct ath10k *ar);
165};
166
160struct ath10k_pci { 167struct ath10k_pci {
161 struct pci_dev *pdev; 168 struct pci_dev *pdev;
162 struct device *dev; 169 struct device *dev;
@@ -225,6 +232,14 @@ struct ath10k_pci {
225 * on MMIO read/write. 232 * on MMIO read/write.
226 */ 233 */
227 bool pci_ps; 234 bool pci_ps;
235
236 const struct ath10k_bus_ops *bus_ops;
237
238 /* Keep this entry in the last, memory for struct ath10k_ahb is
239 * allocated (ahb support enabled case) in the continuation of
240 * this struct.
241 */
242 struct ath10k_ahb ahb[0];
228}; 243};
229 244
230static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) 245static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
@@ -253,6 +268,40 @@ u32 ath10k_pci_read32(struct ath10k *ar, u32 offset);
253u32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr); 268u32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr);
254u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr); 269u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr);
255 270
271int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
272 struct ath10k_hif_sg_item *items, int n_items);
273int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
274 size_t buf_len);
275int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
276 const void *data, int nbytes);
277int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, void *req, u32 req_len,
278 void *resp, u32 *resp_len);
279int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
280 u8 *ul_pipe, u8 *dl_pipe);
281void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, u8 *ul_pipe,
282 u8 *dl_pipe);
283void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
284 int force);
285u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe);
286void ath10k_pci_hif_power_down(struct ath10k *ar);
287int ath10k_pci_alloc_pipes(struct ath10k *ar);
288void ath10k_pci_free_pipes(struct ath10k *ar);
289void ath10k_pci_free_pipes(struct ath10k *ar);
290void ath10k_pci_rx_replenish_retry(unsigned long ptr);
291void ath10k_pci_ce_deinit(struct ath10k *ar);
292void ath10k_pci_init_irq_tasklets(struct ath10k *ar);
293void ath10k_pci_kill_tasklet(struct ath10k *ar);
294int ath10k_pci_init_pipes(struct ath10k *ar);
295int ath10k_pci_init_config(struct ath10k *ar);
296void ath10k_pci_rx_post(struct ath10k *ar);
297void ath10k_pci_flush(struct ath10k *ar);
298void ath10k_pci_enable_legacy_irq(struct ath10k *ar);
299bool ath10k_pci_irq_pending(struct ath10k *ar);
300void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar);
301int ath10k_pci_wait_for_target_init(struct ath10k *ar);
302int ath10k_pci_setup_resource(struct ath10k *ar);
303void ath10k_pci_release_resource(struct ath10k *ar);
304
256/* QCA6174 is known to have Tx/Rx issues when SOC_WAKE register is poked too 305/* QCA6174 is known to have Tx/Rx issues when SOC_WAKE register is poked too
257 * frequently. To avoid this put SoC to sleep after a very conservative grace 306 * frequently. To avoid this put SoC to sleep after a very conservative grace
258 * period. Adjust with great care. 307 * period. Adjust with great care.
diff --git a/drivers/net/wireless/ath/ath10k/targaddrs.h b/drivers/net/wireless/ath/ath10k/targaddrs.h
index 05a421bc322a..361f143b019c 100644
--- a/drivers/net/wireless/ath/ath10k/targaddrs.h
+++ b/drivers/net/wireless/ath/ath10k/targaddrs.h
@@ -456,4 +456,7 @@ Fw Mode/SubMode Mask
456#define QCA99X0_BOARD_DATA_SZ 12288 456#define QCA99X0_BOARD_DATA_SZ 12288
457#define QCA99X0_BOARD_EXT_DATA_SZ 0 457#define QCA99X0_BOARD_EXT_DATA_SZ 0
458 458
459#define QCA4019_BOARD_DATA_SZ 12064
460#define QCA4019_BOARD_EXT_DATA_SZ 0
461
459#endif /* __TARGADDRS_H__ */ 462#endif /* __TARGADDRS_H__ */
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index 71bdb368813d..e0d00cef0bd8 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -250,6 +250,7 @@ TRACE_EVENT(ath10k_wmi_dbglog,
250 TP_STRUCT__entry( 250 TP_STRUCT__entry(
251 __string(device, dev_name(ar->dev)) 251 __string(device, dev_name(ar->dev))
252 __string(driver, dev_driver_string(ar->dev)) 252 __string(driver, dev_driver_string(ar->dev))
253 __field(u8, hw_type);
253 __field(size_t, buf_len) 254 __field(size_t, buf_len)
254 __dynamic_array(u8, buf, buf_len) 255 __dynamic_array(u8, buf, buf_len)
255 ), 256 ),
@@ -257,14 +258,16 @@ TRACE_EVENT(ath10k_wmi_dbglog,
257 TP_fast_assign( 258 TP_fast_assign(
258 __assign_str(device, dev_name(ar->dev)); 259 __assign_str(device, dev_name(ar->dev));
259 __assign_str(driver, dev_driver_string(ar->dev)); 260 __assign_str(driver, dev_driver_string(ar->dev));
261 __entry->hw_type = ar->hw_rev;
260 __entry->buf_len = buf_len; 262 __entry->buf_len = buf_len;
261 memcpy(__get_dynamic_array(buf), buf, buf_len); 263 memcpy(__get_dynamic_array(buf), buf, buf_len);
262 ), 264 ),
263 265
264 TP_printk( 266 TP_printk(
265 "%s %s len %zu", 267 "%s %s %d len %zu",
266 __get_str(driver), 268 __get_str(driver),
267 __get_str(device), 269 __get_str(device),
270 __entry->hw_type,
268 __entry->buf_len 271 __entry->buf_len
269 ) 272 )
270); 273);
@@ -277,6 +280,7 @@ TRACE_EVENT(ath10k_htt_pktlog,
277 TP_STRUCT__entry( 280 TP_STRUCT__entry(
278 __string(device, dev_name(ar->dev)) 281 __string(device, dev_name(ar->dev))
279 __string(driver, dev_driver_string(ar->dev)) 282 __string(driver, dev_driver_string(ar->dev))
283 __field(u8, hw_type);
280 __field(u16, buf_len) 284 __field(u16, buf_len)
281 __dynamic_array(u8, pktlog, buf_len) 285 __dynamic_array(u8, pktlog, buf_len)
282 ), 286 ),
@@ -284,14 +288,16 @@ TRACE_EVENT(ath10k_htt_pktlog,
284 TP_fast_assign( 288 TP_fast_assign(
285 __assign_str(device, dev_name(ar->dev)); 289 __assign_str(device, dev_name(ar->dev));
286 __assign_str(driver, dev_driver_string(ar->dev)); 290 __assign_str(driver, dev_driver_string(ar->dev));
291 __entry->hw_type = ar->hw_rev;
287 __entry->buf_len = buf_len; 292 __entry->buf_len = buf_len;
288 memcpy(__get_dynamic_array(pktlog), buf, buf_len); 293 memcpy(__get_dynamic_array(pktlog), buf, buf_len);
289 ), 294 ),
290 295
291 TP_printk( 296 TP_printk(
292 "%s %s size %hu", 297 "%s %s %d size %hu",
293 __get_str(driver), 298 __get_str(driver),
294 __get_str(device), 299 __get_str(device),
300 __entry->hw_type,
295 __entry->buf_len 301 __entry->buf_len
296 ) 302 )
297); 303);
@@ -440,6 +446,7 @@ TRACE_EVENT(ath10k_htt_rx_desc,
440 TP_STRUCT__entry( 446 TP_STRUCT__entry(
441 __string(device, dev_name(ar->dev)) 447 __string(device, dev_name(ar->dev))
442 __string(driver, dev_driver_string(ar->dev)) 448 __string(driver, dev_driver_string(ar->dev))
449 __field(u8, hw_type);
443 __field(u16, len) 450 __field(u16, len)
444 __dynamic_array(u8, rxdesc, len) 451 __dynamic_array(u8, rxdesc, len)
445 ), 452 ),
@@ -447,14 +454,16 @@ TRACE_EVENT(ath10k_htt_rx_desc,
447 TP_fast_assign( 454 TP_fast_assign(
448 __assign_str(device, dev_name(ar->dev)); 455 __assign_str(device, dev_name(ar->dev));
449 __assign_str(driver, dev_driver_string(ar->dev)); 456 __assign_str(driver, dev_driver_string(ar->dev));
457 __entry->hw_type = ar->hw_rev;
450 __entry->len = len; 458 __entry->len = len;
451 memcpy(__get_dynamic_array(rxdesc), data, len); 459 memcpy(__get_dynamic_array(rxdesc), data, len);
452 ), 460 ),
453 461
454 TP_printk( 462 TP_printk(
455 "%s %s rxdesc len %d", 463 "%s %s %d rxdesc len %d",
456 __get_str(driver), 464 __get_str(driver),
457 __get_str(device), 465 __get_str(device),
466 __entry->hw_type,
458 __entry->len 467 __entry->len
459 ) 468 )
460); 469);
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 8f4f6a892581..32ab34edceb5 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -186,6 +186,8 @@ struct wmi_ops {
186 u8 enable, 186 u8 enable,
187 u32 detect_level, 187 u32 detect_level,
188 u32 detect_margin); 188 u32 detect_margin);
189 int (*get_vdev_subtype)(struct ath10k *ar,
190 enum wmi_vdev_subtype subtype);
189}; 191};
190 192
191int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 193int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1327,4 +1329,13 @@ ath10k_wmi_pdev_enable_adaptive_cca(struct ath10k *ar, u8 enable,
1327 ar->wmi.cmd->pdev_enable_adaptive_cca_cmdid); 1329 ar->wmi.cmd->pdev_enable_adaptive_cca_cmdid);
1328} 1330}
1329 1331
1332static inline int
1333ath10k_wmi_get_vdev_subtype(struct ath10k *ar, enum wmi_vdev_subtype subtype)
1334{
1335 if (!ar->wmi.ops->get_vdev_subtype)
1336 return -EOPNOTSUPP;
1337
1338 return ar->wmi.ops->get_vdev_subtype(ar, subtype);
1339}
1340
1330#endif 1341#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index 3b3a27b859f3..108593202052 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3483,6 +3483,7 @@ static const struct wmi_ops wmi_tlv_ops = {
3483 .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update, 3483 .gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
3484 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs, 3484 .gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
3485 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 3485 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
3486 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
3486}; 3487};
3487 3488
3488static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = { 3489static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index a7c3d299639b..70261387d1a5 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -2862,11 +2862,20 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
2862 /* fw doesn't implement vdev stats */ 2862 /* fw doesn't implement vdev stats */
2863 2863
2864 for (i = 0; i < num_peer_stats; i++) { 2864 for (i = 0; i < num_peer_stats; i++) {
2865 const struct wmi_10_2_4_peer_stats *src; 2865 const struct wmi_10_2_4_ext_peer_stats *src;
2866 struct ath10k_fw_stats_peer *dst; 2866 struct ath10k_fw_stats_peer *dst;
2867 int stats_len;
2868 bool ext_peer_stats_support;
2869
2870 ext_peer_stats_support = test_bit(WMI_SERVICE_PEER_STATS,
2871 ar->wmi.svc_map);
2872 if (ext_peer_stats_support)
2873 stats_len = sizeof(struct wmi_10_2_4_ext_peer_stats);
2874 else
2875 stats_len = sizeof(struct wmi_10_2_4_peer_stats);
2867 2876
2868 src = (void *)skb->data; 2877 src = (void *)skb->data;
2869 if (!skb_pull(skb, sizeof(*src))) 2878 if (!skb_pull(skb, stats_len))
2870 return -EPROTO; 2879 return -EPROTO;
2871 2880
2872 dst = kzalloc(sizeof(*dst), GFP_ATOMIC); 2881 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
@@ -2876,6 +2885,9 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
2876 ath10k_wmi_pull_peer_stats(&src->common.old, dst); 2885 ath10k_wmi_pull_peer_stats(&src->common.old, dst);
2877 2886
2878 dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate); 2887 dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate);
2888
2889 if (ext_peer_stats_support)
2890 dst->rx_duration = __le32_to_cpu(src->rx_duration);
2879 /* FIXME: expose 10.2 specific values */ 2891 /* FIXME: expose 10.2 specific values */
2880 2892
2881 list_add_tail(&dst->list, &stats->peers); 2893 list_add_tail(&dst->list, &stats->peers);
@@ -3184,7 +3196,7 @@ static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
3184 struct sk_buff *bcn, 3196 struct sk_buff *bcn,
3185 const struct wmi_p2p_noa_info *noa) 3197 const struct wmi_p2p_noa_info *noa)
3186{ 3198{
3187 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) 3199 if (!arvif->vif->p2p)
3188 return; 3200 return;
3189 3201
3190 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); 3202 ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed);
@@ -3244,6 +3256,50 @@ static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
3244 return 0; 3256 return 0;
3245} 3257}
3246 3258
3259static int ath10k_wmi_10_2_4_op_pull_swba_ev(struct ath10k *ar,
3260 struct sk_buff *skb,
3261 struct wmi_swba_ev_arg *arg)
3262{
3263 struct wmi_10_2_4_host_swba_event *ev = (void *)skb->data;
3264 u32 map;
3265 size_t i;
3266
3267 if (skb->len < sizeof(*ev))
3268 return -EPROTO;
3269
3270 skb_pull(skb, sizeof(*ev));
3271 arg->vdev_map = ev->vdev_map;
3272
3273 for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
3274 if (!(map & BIT(0)))
3275 continue;
3276
3277 /* If this happens there were some changes in firmware and
3278 * ath10k should update the max size of tim_info array.
3279 */
3280 if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
3281 break;
3282
3283 if (__le32_to_cpu(ev->bcn_info[i].tim_info.tim_len) >
3284 sizeof(ev->bcn_info[i].tim_info.tim_bitmap)) {
3285 ath10k_warn(ar, "refusing to parse invalid swba structure\n");
3286 return -EPROTO;
3287 }
3288
3289 arg->tim_info[i].tim_len = ev->bcn_info[i].tim_info.tim_len;
3290 arg->tim_info[i].tim_mcast = ev->bcn_info[i].tim_info.tim_mcast;
3291 arg->tim_info[i].tim_bitmap =
3292 ev->bcn_info[i].tim_info.tim_bitmap;
3293 arg->tim_info[i].tim_changed =
3294 ev->bcn_info[i].tim_info.tim_changed;
3295 arg->tim_info[i].tim_num_ps_pending =
3296 ev->bcn_info[i].tim_info.tim_num_ps_pending;
3297 i++;
3298 }
3299
3300 return 0;
3301}
3302
3247static int ath10k_wmi_10_4_op_pull_swba_ev(struct ath10k *ar, 3303static int ath10k_wmi_10_4_op_pull_swba_ev(struct ath10k *ar,
3248 struct sk_buff *skb, 3304 struct sk_buff *skb,
3249 struct wmi_swba_ev_arg *arg) 3305 struct wmi_swba_ev_arg *arg)
@@ -4562,9 +4618,9 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
4562 4618
4563 if (test_bit(WMI_SERVICE_PEER_CACHING, ar->wmi.svc_map)) { 4619 if (test_bit(WMI_SERVICE_PEER_CACHING, ar->wmi.svc_map)) {
4564 ar->max_num_peers = TARGET_10_4_NUM_QCACHE_PEERS_MAX + 4620 ar->max_num_peers = TARGET_10_4_NUM_QCACHE_PEERS_MAX +
4565 TARGET_10_4_NUM_VDEVS; 4621 ar->max_num_vdevs;
4566 ar->num_active_peers = TARGET_10_4_QCACHE_ACTIVE_PEERS + 4622 ar->num_active_peers = ar->hw_params.qcache_active_peers +
4567 TARGET_10_4_NUM_VDEVS; 4623 ar->max_num_vdevs;
4568 ar->num_tids = ar->num_active_peers * 2; 4624 ar->num_tids = ar->num_active_peers * 2;
4569 ar->max_num_stations = TARGET_10_4_NUM_QCACHE_PEERS_MAX; 4625 ar->max_num_stations = TARGET_10_4_NUM_QCACHE_PEERS_MAX;
4570 } 4626 }
@@ -5460,9 +5516,15 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
5460 u32 len, val, features; 5516 u32 len, val, features;
5461 5517
5462 config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); 5518 config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
5463 config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
5464 config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); 5519 config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS);
5465 config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); 5520 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map)) {
5521 config.num_peers = __cpu_to_le32(TARGET_10X_TX_STATS_NUM_PEERS);
5522 config.num_tids = __cpu_to_le32(TARGET_10X_TX_STATS_NUM_TIDS);
5523 } else {
5524 config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
5525 config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS);
5526 }
5527
5466 config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); 5528 config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT);
5467 config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); 5529 config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK);
5468 config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); 5530 config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK);
@@ -5517,6 +5579,9 @@ static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
5517 test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map)) 5579 test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map))
5518 features |= WMI_10_2_COEX_GPIO; 5580 features |= WMI_10_2_COEX_GPIO;
5519 5581
5582 if (test_bit(WMI_SERVICE_PEER_STATS, ar->wmi.svc_map))
5583 features |= WMI_10_2_PEER_STATS;
5584
5520 cmd->resource_config.feature_mask = __cpu_to_le32(features); 5585 cmd->resource_config.feature_mask = __cpu_to_le32(features);
5521 5586
5522 memcpy(&cmd->resource_config.common, &config, sizeof(config)); 5587 memcpy(&cmd->resource_config.common, &config, sizeof(config));
@@ -5543,8 +5608,8 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
5543 __cpu_to_le32(TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS); 5608 __cpu_to_le32(TARGET_10_4_NUM_OFFLOAD_REORDER_BUFFS);
5544 config.num_peer_keys = __cpu_to_le32(TARGET_10_4_NUM_PEER_KEYS); 5609 config.num_peer_keys = __cpu_to_le32(TARGET_10_4_NUM_PEER_KEYS);
5545 config.ast_skid_limit = __cpu_to_le32(TARGET_10_4_AST_SKID_LIMIT); 5610 config.ast_skid_limit = __cpu_to_le32(TARGET_10_4_AST_SKID_LIMIT);
5546 config.tx_chain_mask = __cpu_to_le32(TARGET_10_4_TX_CHAIN_MASK); 5611 config.tx_chain_mask = __cpu_to_le32(ar->hw_params.tx_chain_mask);
5547 config.rx_chain_mask = __cpu_to_le32(TARGET_10_4_RX_CHAIN_MASK); 5612 config.rx_chain_mask = __cpu_to_le32(ar->hw_params.rx_chain_mask);
5548 5613
5549 config.rx_timeout_pri[0] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI); 5614 config.rx_timeout_pri[0] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
5550 config.rx_timeout_pri[1] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI); 5615 config.rx_timeout_pri[1] = __cpu_to_le32(TARGET_10_4_RX_TIMEOUT_LO_PRI);
@@ -5575,7 +5640,7 @@ static struct sk_buff *ath10k_wmi_10_4_op_gen_init(struct ath10k *ar)
5575 config.vow_config = __cpu_to_le32(TARGET_10_4_VOW_CONFIG); 5640 config.vow_config = __cpu_to_le32(TARGET_10_4_VOW_CONFIG);
5576 config.gtk_offload_max_vdev = 5641 config.gtk_offload_max_vdev =
5577 __cpu_to_le32(TARGET_10_4_GTK_OFFLOAD_MAX_VDEV); 5642 __cpu_to_le32(TARGET_10_4_GTK_OFFLOAD_MAX_VDEV);
5578 config.num_msdu_desc = __cpu_to_le32(TARGET_10_4_NUM_MSDU_DESC); 5643 config.num_msdu_desc = __cpu_to_le32(ar->htt.max_num_pending_tx);
5579 config.max_frag_entries = __cpu_to_le32(TARGET_10_4_11AC_TX_MAX_FRAGS); 5644 config.max_frag_entries = __cpu_to_le32(TARGET_10_4_11AC_TX_MAX_FRAGS);
5580 config.max_peer_ext_stats = 5645 config.max_peer_ext_stats =
5581 __cpu_to_le32(TARGET_10_4_MAX_PEER_EXT_STATS); 5646 __cpu_to_le32(TARGET_10_4_MAX_PEER_EXT_STATS);
@@ -7126,6 +7191,9 @@ ath10k_wmi_fw_peer_stats_fill(const struct ath10k_fw_stats_peer *peer,
7126 "Peer TX rate", peer->peer_tx_rate); 7191 "Peer TX rate", peer->peer_tx_rate);
7127 len += scnprintf(buf + len, buf_len - len, "%30s %u\n", 7192 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
7128 "Peer RX rate", peer->peer_rx_rate); 7193 "Peer RX rate", peer->peer_rx_rate);
7194 len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
7195 "Peer RX duration", peer->rx_duration);
7196
7129 len += scnprintf(buf + len, buf_len - len, "\n"); 7197 len += scnprintf(buf + len, buf_len - len, "\n");
7130 *length = len; 7198 *length = len;
7131} 7199}
@@ -7351,6 +7419,71 @@ unlock:
7351 buf[len] = 0; 7419 buf[len] = 0;
7352} 7420}
7353 7421
7422int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
7423 enum wmi_vdev_subtype subtype)
7424{
7425 switch (subtype) {
7426 case WMI_VDEV_SUBTYPE_NONE:
7427 return WMI_VDEV_SUBTYPE_LEGACY_NONE;
7428 case WMI_VDEV_SUBTYPE_P2P_DEVICE:
7429 return WMI_VDEV_SUBTYPE_LEGACY_P2P_DEV;
7430 case WMI_VDEV_SUBTYPE_P2P_CLIENT:
7431 return WMI_VDEV_SUBTYPE_LEGACY_P2P_CLI;
7432 case WMI_VDEV_SUBTYPE_P2P_GO:
7433 return WMI_VDEV_SUBTYPE_LEGACY_P2P_GO;
7434 case WMI_VDEV_SUBTYPE_PROXY_STA:
7435 return WMI_VDEV_SUBTYPE_LEGACY_PROXY_STA;
7436 case WMI_VDEV_SUBTYPE_MESH_11S:
7437 case WMI_VDEV_SUBTYPE_MESH_NON_11S:
7438 return -ENOTSUPP;
7439 }
7440 return -ENOTSUPP;
7441}
7442
7443static int ath10k_wmi_10_2_4_op_get_vdev_subtype(struct ath10k *ar,
7444 enum wmi_vdev_subtype subtype)
7445{
7446 switch (subtype) {
7447 case WMI_VDEV_SUBTYPE_NONE:
7448 return WMI_VDEV_SUBTYPE_10_2_4_NONE;
7449 case WMI_VDEV_SUBTYPE_P2P_DEVICE:
7450 return WMI_VDEV_SUBTYPE_10_2_4_P2P_DEV;
7451 case WMI_VDEV_SUBTYPE_P2P_CLIENT:
7452 return WMI_VDEV_SUBTYPE_10_2_4_P2P_CLI;
7453 case WMI_VDEV_SUBTYPE_P2P_GO:
7454 return WMI_VDEV_SUBTYPE_10_2_4_P2P_GO;
7455 case WMI_VDEV_SUBTYPE_PROXY_STA:
7456 return WMI_VDEV_SUBTYPE_10_2_4_PROXY_STA;
7457 case WMI_VDEV_SUBTYPE_MESH_11S:
7458 return WMI_VDEV_SUBTYPE_10_2_4_MESH_11S;
7459 case WMI_VDEV_SUBTYPE_MESH_NON_11S:
7460 return -ENOTSUPP;
7461 }
7462 return -ENOTSUPP;
7463}
7464
7465static int ath10k_wmi_10_4_op_get_vdev_subtype(struct ath10k *ar,
7466 enum wmi_vdev_subtype subtype)
7467{
7468 switch (subtype) {
7469 case WMI_VDEV_SUBTYPE_NONE:
7470 return WMI_VDEV_SUBTYPE_10_4_NONE;
7471 case WMI_VDEV_SUBTYPE_P2P_DEVICE:
7472 return WMI_VDEV_SUBTYPE_10_4_P2P_DEV;
7473 case WMI_VDEV_SUBTYPE_P2P_CLIENT:
7474 return WMI_VDEV_SUBTYPE_10_4_P2P_CLI;
7475 case WMI_VDEV_SUBTYPE_P2P_GO:
7476 return WMI_VDEV_SUBTYPE_10_4_P2P_GO;
7477 case WMI_VDEV_SUBTYPE_PROXY_STA:
7478 return WMI_VDEV_SUBTYPE_10_4_PROXY_STA;
7479 case WMI_VDEV_SUBTYPE_MESH_11S:
7480 return WMI_VDEV_SUBTYPE_10_4_MESH_11S;
7481 case WMI_VDEV_SUBTYPE_MESH_NON_11S:
7482 return WMI_VDEV_SUBTYPE_10_4_MESH_NON_11S;
7483 }
7484 return -ENOTSUPP;
7485}
7486
7354static const struct wmi_ops wmi_ops = { 7487static const struct wmi_ops wmi_ops = {
7355 .rx = ath10k_wmi_op_rx, 7488 .rx = ath10k_wmi_op_rx,
7356 .map_svc = wmi_main_svc_map, 7489 .map_svc = wmi_main_svc_map,
@@ -7410,6 +7543,7 @@ static const struct wmi_ops wmi_ops = {
7410 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7543 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
7411 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7544 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7412 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill, 7545 .fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
7546 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
7413 /* .gen_bcn_tmpl not implemented */ 7547 /* .gen_bcn_tmpl not implemented */
7414 /* .gen_prb_tmpl not implemented */ 7548 /* .gen_prb_tmpl not implemented */
7415 /* .gen_p2p_go_bcn_ie not implemented */ 7549 /* .gen_p2p_go_bcn_ie not implemented */
@@ -7477,6 +7611,7 @@ static const struct wmi_ops wmi_10_1_ops = {
7477 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7611 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
7478 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7612 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7479 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, 7613 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
7614 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
7480 /* .gen_bcn_tmpl not implemented */ 7615 /* .gen_bcn_tmpl not implemented */
7481 /* .gen_prb_tmpl not implemented */ 7616 /* .gen_prb_tmpl not implemented */
7482 /* .gen_p2p_go_bcn_ie not implemented */ 7617 /* .gen_p2p_go_bcn_ie not implemented */
@@ -7545,6 +7680,7 @@ static const struct wmi_ops wmi_10_2_ops = {
7545 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, 7680 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
7546 .gen_delba_send = ath10k_wmi_op_gen_delba_send, 7681 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
7547 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, 7682 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
7683 .get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
7548 /* .gen_pdev_enable_adaptive_cca not implemented */ 7684 /* .gen_pdev_enable_adaptive_cca not implemented */
7549}; 7685};
7550 7686
@@ -7566,7 +7702,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
7566 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, 7702 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
7567 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, 7703 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
7568 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, 7704 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
7569 .pull_swba = ath10k_wmi_op_pull_swba_ev, 7705 .pull_swba = ath10k_wmi_10_2_4_op_pull_swba_ev,
7570 .pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr, 7706 .pull_phyerr_hdr = ath10k_wmi_op_pull_phyerr_ev_hdr,
7571 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, 7707 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
7572 .pull_rdy = ath10k_wmi_op_pull_rdy_ev, 7708 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
@@ -7611,6 +7747,7 @@ static const struct wmi_ops wmi_10_2_4_ops = {
7611 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill, 7747 .fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
7612 .gen_pdev_enable_adaptive_cca = 7748 .gen_pdev_enable_adaptive_cca =
7613 ath10k_wmi_op_gen_pdev_enable_adaptive_cca, 7749 ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
7750 .get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
7614 /* .gen_bcn_tmpl not implemented */ 7751 /* .gen_bcn_tmpl not implemented */
7615 /* .gen_prb_tmpl not implemented */ 7752 /* .gen_prb_tmpl not implemented */
7616 /* .gen_p2p_go_bcn_ie not implemented */ 7753 /* .gen_p2p_go_bcn_ie not implemented */
@@ -7677,6 +7814,7 @@ static const struct wmi_ops wmi_10_4_ops = {
7677 /* shared with 10.2 */ 7814 /* shared with 10.2 */
7678 .gen_request_stats = ath10k_wmi_op_gen_request_stats, 7815 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
7679 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, 7816 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
7817 .get_vdev_subtype = ath10k_wmi_10_4_op_get_vdev_subtype,
7680}; 7818};
7681 7819
7682int ath10k_wmi_attach(struct ath10k *ar) 7820int ath10k_wmi_attach(struct ath10k *ar)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index d85ad7855d20..4d3cbc44fcd2 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -176,7 +176,10 @@ enum wmi_service {
176 WMI_SERVICE_AUX_CHAN_LOAD_INTF, 176 WMI_SERVICE_AUX_CHAN_LOAD_INTF,
177 WMI_SERVICE_BSS_CHANNEL_INFO_64, 177 WMI_SERVICE_BSS_CHANNEL_INFO_64,
178 WMI_SERVICE_EXT_RES_CFG_SUPPORT, 178 WMI_SERVICE_EXT_RES_CFG_SUPPORT,
179 WMI_SERVICE_MESH, 179 WMI_SERVICE_MESH_11S,
180 WMI_SERVICE_MESH_NON_11S,
181 WMI_SERVICE_PEER_STATS,
182 WMI_SERVICE_RESTRT_CHNL_SUPPORT,
180 183
181 /* keep last */ 184 /* keep last */
182 WMI_SERVICE_MAX, 185 WMI_SERVICE_MAX,
@@ -213,6 +216,7 @@ enum wmi_10x_service {
213 WMI_10X_SERVICE_BSS_CHANNEL_INFO_64, 216 WMI_10X_SERVICE_BSS_CHANNEL_INFO_64,
214 WMI_10X_SERVICE_MESH, 217 WMI_10X_SERVICE_MESH,
215 WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT, 218 WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT,
219 WMI_10X_SERVICE_PEER_STATS,
216}; 220};
217 221
218enum wmi_main_service { 222enum wmi_main_service {
@@ -294,7 +298,10 @@ enum wmi_10_4_service {
294 WMI_10_4_SERVICE_AUX_CHAN_LOAD_INTF, 298 WMI_10_4_SERVICE_AUX_CHAN_LOAD_INTF,
295 WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64, 299 WMI_10_4_SERVICE_BSS_CHANNEL_INFO_64,
296 WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT, 300 WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
297 WMI_10_4_SERVICE_MESH, 301 WMI_10_4_SERVICE_MESH_NON_11S,
302 WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT,
303 WMI_10_4_SERVICE_PEER_STATS,
304 WMI_10_4_SERVICE_MESH_11S,
298}; 305};
299 306
300static inline char *wmi_service_name(int service_id) 307static inline char *wmi_service_name(int service_id)
@@ -385,7 +392,10 @@ static inline char *wmi_service_name(int service_id)
385 SVCSTR(WMI_SERVICE_AUX_CHAN_LOAD_INTF); 392 SVCSTR(WMI_SERVICE_AUX_CHAN_LOAD_INTF);
386 SVCSTR(WMI_SERVICE_BSS_CHANNEL_INFO_64); 393 SVCSTR(WMI_SERVICE_BSS_CHANNEL_INFO_64);
387 SVCSTR(WMI_SERVICE_EXT_RES_CFG_SUPPORT); 394 SVCSTR(WMI_SERVICE_EXT_RES_CFG_SUPPORT);
388 SVCSTR(WMI_SERVICE_MESH); 395 SVCSTR(WMI_SERVICE_MESH_11S);
396 SVCSTR(WMI_SERVICE_MESH_NON_11S);
397 SVCSTR(WMI_SERVICE_PEER_STATS);
398 SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT);
389 default: 399 default:
390 return NULL; 400 return NULL;
391 } 401 }
@@ -460,9 +470,11 @@ static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out,
460 SVCMAP(WMI_10X_SERVICE_BSS_CHANNEL_INFO_64, 470 SVCMAP(WMI_10X_SERVICE_BSS_CHANNEL_INFO_64,
461 WMI_SERVICE_BSS_CHANNEL_INFO_64, len); 471 WMI_SERVICE_BSS_CHANNEL_INFO_64, len);
462 SVCMAP(WMI_10X_SERVICE_MESH, 472 SVCMAP(WMI_10X_SERVICE_MESH,
463 WMI_SERVICE_MESH, len); 473 WMI_SERVICE_MESH_11S, len);
464 SVCMAP(WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT, 474 SVCMAP(WMI_10X_SERVICE_EXT_RES_CFG_SUPPORT,
465 WMI_SERVICE_EXT_RES_CFG_SUPPORT, len); 475 WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
476 SVCMAP(WMI_10X_SERVICE_PEER_STATS,
477 WMI_SERVICE_PEER_STATS, len);
466} 478}
467 479
468static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, 480static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out,
@@ -623,8 +635,14 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
623 WMI_SERVICE_BSS_CHANNEL_INFO_64, len); 635 WMI_SERVICE_BSS_CHANNEL_INFO_64, len);
624 SVCMAP(WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT, 636 SVCMAP(WMI_10_4_SERVICE_EXT_RES_CFG_SUPPORT,
625 WMI_SERVICE_EXT_RES_CFG_SUPPORT, len); 637 WMI_SERVICE_EXT_RES_CFG_SUPPORT, len);
626 SVCMAP(WMI_10_4_SERVICE_MESH, 638 SVCMAP(WMI_10_4_SERVICE_MESH_NON_11S,
627 WMI_SERVICE_MESH, len); 639 WMI_SERVICE_MESH_NON_11S, len);
640 SVCMAP(WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT,
641 WMI_SERVICE_RESTRT_CHNL_SUPPORT, len);
642 SVCMAP(WMI_10_4_SERVICE_PEER_STATS,
643 WMI_SERVICE_PEER_STATS, len);
644 SVCMAP(WMI_10_4_SERVICE_MESH_11S,
645 WMI_SERVICE_MESH_11S, len);
628} 646}
629 647
630#undef SVCMAP 648#undef SVCMAP
@@ -1800,7 +1818,6 @@ enum wmi_channel_change_cause {
1800#define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13) 1818#define WMI_CHANNEL_CHANGE_CAUSE_CSA (1 << 13)
1801 1819
1802#define WMI_MAX_SPATIAL_STREAM 3 /* default max ss */ 1820#define WMI_MAX_SPATIAL_STREAM 3 /* default max ss */
1803#define WMI_10_4_MAX_SPATIAL_STREAM 4
1804 1821
1805/* HT Capabilities*/ 1822/* HT Capabilities*/
1806#define WMI_HT_CAP_ENABLED 0x0001 /* HT Enabled/ disabled */ 1823#define WMI_HT_CAP_ENABLED 0x0001 /* HT Enabled/ disabled */
@@ -2417,6 +2434,7 @@ enum wmi_10_2_feature_mask {
2417 WMI_10_2_RX_BATCH_MODE = BIT(0), 2434 WMI_10_2_RX_BATCH_MODE = BIT(0),
2418 WMI_10_2_ATF_CONFIG = BIT(1), 2435 WMI_10_2_ATF_CONFIG = BIT(1),
2419 WMI_10_2_COEX_GPIO = BIT(3), 2436 WMI_10_2_COEX_GPIO = BIT(3),
2437 WMI_10_2_PEER_STATS = BIT(7),
2420}; 2438};
2421 2439
2422struct wmi_resource_config_10_2 { 2440struct wmi_resource_config_10_2 {
@@ -4227,7 +4245,13 @@ struct wmi_10_2_peer_stats {
4227 4245
4228struct wmi_10_2_4_peer_stats { 4246struct wmi_10_2_4_peer_stats {
4229 struct wmi_10_2_peer_stats common; 4247 struct wmi_10_2_peer_stats common;
4230 __le32 unknown_value; /* FIXME: what is this word? */ 4248 __le32 peer_rssi_changed;
4249} __packed;
4250
4251struct wmi_10_2_4_ext_peer_stats {
4252 struct wmi_10_2_peer_stats common;
4253 __le32 peer_rssi_changed;
4254 __le32 rx_duration;
4231} __packed; 4255} __packed;
4232 4256
4233struct wmi_10_4_peer_stats { 4257struct wmi_10_4_peer_stats {
@@ -4270,12 +4294,40 @@ enum wmi_vdev_type {
4270}; 4294};
4271 4295
4272enum wmi_vdev_subtype { 4296enum wmi_vdev_subtype {
4273 WMI_VDEV_SUBTYPE_NONE = 0, 4297 WMI_VDEV_SUBTYPE_NONE,
4274 WMI_VDEV_SUBTYPE_P2P_DEVICE = 1, 4298 WMI_VDEV_SUBTYPE_P2P_DEVICE,
4275 WMI_VDEV_SUBTYPE_P2P_CLIENT = 2, 4299 WMI_VDEV_SUBTYPE_P2P_CLIENT,
4276 WMI_VDEV_SUBTYPE_P2P_GO = 3, 4300 WMI_VDEV_SUBTYPE_P2P_GO,
4277 WMI_VDEV_SUBTYPE_PROXY_STA = 4, 4301 WMI_VDEV_SUBTYPE_PROXY_STA,
4278 WMI_VDEV_SUBTYPE_MESH = 5, 4302 WMI_VDEV_SUBTYPE_MESH_11S,
4303 WMI_VDEV_SUBTYPE_MESH_NON_11S,
4304};
4305
4306enum wmi_vdev_subtype_legacy {
4307 WMI_VDEV_SUBTYPE_LEGACY_NONE = 0,
4308 WMI_VDEV_SUBTYPE_LEGACY_P2P_DEV = 1,
4309 WMI_VDEV_SUBTYPE_LEGACY_P2P_CLI = 2,
4310 WMI_VDEV_SUBTYPE_LEGACY_P2P_GO = 3,
4311 WMI_VDEV_SUBTYPE_LEGACY_PROXY_STA = 4,
4312};
4313
4314enum wmi_vdev_subtype_10_2_4 {
4315 WMI_VDEV_SUBTYPE_10_2_4_NONE = 0,
4316 WMI_VDEV_SUBTYPE_10_2_4_P2P_DEV = 1,
4317 WMI_VDEV_SUBTYPE_10_2_4_P2P_CLI = 2,
4318 WMI_VDEV_SUBTYPE_10_2_4_P2P_GO = 3,
4319 WMI_VDEV_SUBTYPE_10_2_4_PROXY_STA = 4,
4320 WMI_VDEV_SUBTYPE_10_2_4_MESH_11S = 5,
4321};
4322
4323enum wmi_vdev_subtype_10_4 {
4324 WMI_VDEV_SUBTYPE_10_4_NONE = 0,
4325 WMI_VDEV_SUBTYPE_10_4_P2P_DEV = 1,
4326 WMI_VDEV_SUBTYPE_10_4_P2P_CLI = 2,
4327 WMI_VDEV_SUBTYPE_10_4_P2P_GO = 3,
4328 WMI_VDEV_SUBTYPE_10_4_PROXY_STA = 4,
4329 WMI_VDEV_SUBTYPE_10_4_MESH_NON_11S = 5,
4330 WMI_VDEV_SUBTYPE_10_4_MESH_11S = 6,
4279}; 4331};
4280 4332
4281/* values for vdev_subtype */ 4333/* values for vdev_subtype */
@@ -5442,6 +5494,16 @@ struct wmi_host_swba_event {
5442 struct wmi_bcn_info bcn_info[0]; 5494 struct wmi_bcn_info bcn_info[0];
5443} __packed; 5495} __packed;
5444 5496
5497struct wmi_10_2_4_bcn_info {
5498 struct wmi_tim_info tim_info;
5499 /* The 10.2.4 FW doesn't have p2p NOA info */
5500} __packed;
5501
5502struct wmi_10_2_4_host_swba_event {
5503 __le32 vdev_map;
5504 struct wmi_10_2_4_bcn_info bcn_info[0];
5505} __packed;
5506
5445/* 16 words = 512 client + 1 word = for guard */ 5507/* 16 words = 512 client + 1 word = for guard */
5446#define WMI_10_4_TIM_BITMAP_ARRAY_SIZE 17 5508#define WMI_10_4_TIM_BITMAP_ARRAY_SIZE 17
5447 5509
@@ -6436,5 +6498,7 @@ size_t ath10k_wmi_fw_stats_num_vdevs(struct list_head *head);
6436void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar, 6498void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
6437 struct ath10k_fw_stats *fw_stats, 6499 struct ath10k_fw_stats *fw_stats,
6438 char *buf); 6500 char *buf);
6501int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
6502 enum wmi_vdev_subtype subtype);
6439 6503
6440#endif /* _WMI_H_ */ 6504#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 25e45e4d1a60..815efe9fd208 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -126,12 +126,8 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah,
126 126
127static void ath9k_ani_restart(struct ath_hw *ah) 127static void ath9k_ani_restart(struct ath_hw *ah)
128{ 128{
129 struct ar5416AniState *aniState; 129 struct ar5416AniState *aniState = &ah->ani;
130
131 if (!ah->curchan)
132 return;
133 130
134 aniState = &ah->ani;
135 aniState->listenTime = 0; 131 aniState->listenTime = 0;
136 132
137 ENABLE_REGWRITE_BUFFER(ah); 133 ENABLE_REGWRITE_BUFFER(ah);
@@ -221,12 +217,7 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
221 217
222static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) 218static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
223{ 219{
224 struct ar5416AniState *aniState; 220 struct ar5416AniState *aniState = &ah->ani;
225
226 if (!ah->curchan)
227 return;
228
229 aniState = &ah->ani;
230 221
231 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) 222 if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
232 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); 223 ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false);
@@ -281,12 +272,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
281 272
282static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) 273static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
283{ 274{
284 struct ar5416AniState *aniState; 275 struct ar5416AniState *aniState = &ah->ani;
285
286 if (!ah->curchan)
287 return;
288
289 aniState = &ah->ani;
290 276
291 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) 277 if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
292 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, 278 ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1,
@@ -299,9 +285,7 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
299 */ 285 */
300static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) 286static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
301{ 287{
302 struct ar5416AniState *aniState; 288 struct ar5416AniState *aniState = &ah->ani;
303
304 aniState = &ah->ani;
305 289
306 /* lower OFDM noise immunity */ 290 /* lower OFDM noise immunity */
307 if (aniState->ofdmNoiseImmunityLevel > 0 && 291 if (aniState->ofdmNoiseImmunityLevel > 0 &&
@@ -329,7 +313,7 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning)
329 struct ath_common *common = ath9k_hw_common(ah); 313 struct ath_common *common = ath9k_hw_common(ah);
330 int ofdm_nil, cck_nil; 314 int ofdm_nil, cck_nil;
331 315
332 if (!ah->curchan) 316 if (!chan)
333 return; 317 return;
334 318
335 BUG_ON(aniState == NULL); 319 BUG_ON(aniState == NULL);
@@ -416,14 +400,10 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah)
416 400
417void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) 401void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
418{ 402{
419 struct ar5416AniState *aniState; 403 struct ar5416AniState *aniState = &ah->ani;
420 struct ath_common *common = ath9k_hw_common(ah); 404 struct ath_common *common = ath9k_hw_common(ah);
421 u32 ofdmPhyErrRate, cckPhyErrRate; 405 u32 ofdmPhyErrRate, cckPhyErrRate;
422 406
423 if (!ah->curchan)
424 return;
425
426 aniState = &ah->ani;
427 if (!ath9k_hw_ani_read_counters(ah)) 407 if (!ath9k_hw_ani_read_counters(ah))
428 return; 408 return;
429 409
@@ -450,7 +430,9 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan)
450 } else if (cckPhyErrRate > ah->config.cck_trig_high) { 430 } else if (cckPhyErrRate > ah->config.cck_trig_high) {
451 ath9k_hw_ani_cck_err_trigger(ah); 431 ath9k_hw_ani_cck_err_trigger(ah);
452 aniState->ofdmsTurn = true; 432 aniState->ofdmsTurn = true;
453 } 433 } else
434 return;
435
454 ath9k_ani_restart(ah); 436 ath9k_ani_restart(ah);
455 } 437 }
456} 438}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_aic.c b/drivers/net/wireless/ath/ath9k/ar9003_aic.c
index 1db119d77783..547cd46da260 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_aic.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_aic.c
@@ -53,19 +53,19 @@ static bool ar9003_hw_is_aic_enabled(struct ath_hw *ah)
53 return true; 53 return true;
54} 54}
55 55
56static int16_t ar9003_aic_find_valid(struct ath_aic_sram_info *cal_sram, 56static int16_t ar9003_aic_find_valid(bool *cal_sram_valid,
57 bool dir, u8 index) 57 bool dir, u8 index)
58{ 58{
59 int16_t i; 59 int16_t i;
60 60
61 if (dir) { 61 if (dir) {
62 for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 62 for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
63 if (cal_sram[i].valid) 63 if (cal_sram_valid[i])
64 break; 64 break;
65 } 65 }
66 } else { 66 } else {
67 for (i = index - 1; i >= 0; i--) { 67 for (i = index - 1; i >= 0; i--) {
68 if (cal_sram[i].valid) 68 if (cal_sram_valid[i])
69 break; 69 break;
70 } 70 }
71 } 71 }
@@ -264,7 +264,7 @@ static u8 ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count)
264static bool ar9003_aic_cal_post_process(struct ath_hw *ah) 264static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
265{ 265{
266 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic; 266 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
267 struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL]; 267 bool cal_sram_valid[ATH_AIC_MAX_BT_CHANNEL];
268 struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL]; 268 struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL];
269 u32 dir_path_gain_idx, quad_path_gain_idx, value; 269 u32 dir_path_gain_idx, quad_path_gain_idx, value;
270 u32 fixed_com_att_db; 270 u32 fixed_com_att_db;
@@ -272,33 +272,34 @@ static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
272 int16_t i; 272 int16_t i;
273 bool ret = true; 273 bool ret = true;
274 274
275 memset(&cal_sram, 0, sizeof(cal_sram)); 275 memset(&cal_sram_valid, 0, sizeof(cal_sram_valid));
276 memset(&aic_sram, 0, sizeof(aic_sram)); 276 memset(&aic_sram, 0, sizeof(aic_sram));
277 277
278 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 278 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
279 struct ath_aic_sram_info sram;
279 value = aic->aic_sram[i]; 280 value = aic->aic_sram[i];
280 281
281 cal_sram[i].valid = 282 cal_sram_valid[i] = sram.valid =
282 MS(value, AR_PHY_AIC_SRAM_VALID); 283 MS(value, AR_PHY_AIC_SRAM_VALID);
283 cal_sram[i].rot_quad_att_db = 284 sram.rot_quad_att_db =
284 MS(value, AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB); 285 MS(value, AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB);
285 cal_sram[i].vga_quad_sign = 286 sram.vga_quad_sign =
286 MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN); 287 MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN);
287 cal_sram[i].rot_dir_att_db = 288 sram.rot_dir_att_db =
288 MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB); 289 MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB);
289 cal_sram[i].vga_dir_sign = 290 sram.vga_dir_sign =
290 MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN); 291 MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN);
291 cal_sram[i].com_att_6db = 292 sram.com_att_6db =
292 MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB); 293 MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB);
293 294
294 if (cal_sram[i].valid) { 295 if (sram.valid) {
295 dir_path_gain_idx = cal_sram[i].rot_dir_att_db + 296 dir_path_gain_idx = sram.rot_dir_att_db +
296 com_att_db_table[cal_sram[i].com_att_6db]; 297 com_att_db_table[sram.com_att_6db];
297 quad_path_gain_idx = cal_sram[i].rot_quad_att_db + 298 quad_path_gain_idx = sram.rot_quad_att_db +
298 com_att_db_table[cal_sram[i].com_att_6db]; 299 com_att_db_table[sram.com_att_6db];
299 300
300 dir_path_sign = (cal_sram[i].vga_dir_sign) ? 1 : -1; 301 dir_path_sign = (sram.vga_dir_sign) ? 1 : -1;
301 quad_path_sign = (cal_sram[i].vga_quad_sign) ? 1 : -1; 302 quad_path_sign = (sram.vga_quad_sign) ? 1 : -1;
302 303
303 aic_sram[i].dir_path_gain_lin = dir_path_sign * 304 aic_sram[i].dir_path_gain_lin = dir_path_sign *
304 aic_lin_table[dir_path_gain_idx]; 305 aic_lin_table[dir_path_gain_idx];
@@ -310,16 +311,16 @@ static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
310 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 311 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
311 int16_t start_idx, end_idx; 312 int16_t start_idx, end_idx;
312 313
313 if (cal_sram[i].valid) 314 if (cal_sram_valid[i])
314 continue; 315 continue;
315 316
316 start_idx = ar9003_aic_find_valid(cal_sram, 0, i); 317 start_idx = ar9003_aic_find_valid(cal_sram_valid, 0, i);
317 end_idx = ar9003_aic_find_valid(cal_sram, 1, i); 318 end_idx = ar9003_aic_find_valid(cal_sram_valid, 1, i);
318 319
319 if (start_idx < 0) { 320 if (start_idx < 0) {
320 /* extrapolation */ 321 /* extrapolation */
321 start_idx = end_idx; 322 start_idx = end_idx;
322 end_idx = ar9003_aic_find_valid(cal_sram, 1, start_idx); 323 end_idx = ar9003_aic_find_valid(cal_sram_valid, 1, start_idx);
323 324
324 if (end_idx < 0) { 325 if (end_idx < 0) {
325 ret = false; 326 ret = false;
@@ -342,7 +343,7 @@ static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
342 343
343 if (end_idx < 0) { 344 if (end_idx < 0) {
344 /* extrapolation */ 345 /* extrapolation */
345 end_idx = ar9003_aic_find_valid(cal_sram, 0, start_idx); 346 end_idx = ar9003_aic_find_valid(cal_sram_valid, 0, start_idx);
346 347
347 if (end_idx < 0) { 348 if (end_idx < 0) {
348 ret = false; 349 ret = false;
@@ -378,19 +379,21 @@ static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
378 } 379 }
379 380
380 /* From dir/quad_path_gain_lin to sram. */ 381 /* From dir/quad_path_gain_lin to sram. */
381 i = ar9003_aic_find_valid(cal_sram, 1, 0); 382 i = ar9003_aic_find_valid(cal_sram_valid, 1, 0);
382 if (i < 0) { 383 if (i < 0) {
383 i = 0; 384 i = 0;
384 ret = false; 385 ret = false;
385 } 386 }
386 fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db]; 387 fixed_com_att_db = com_att_db_table[MS(aic->aic_sram[i],
388 AR_PHY_AIC_SRAM_COM_ATT_6DB)];
387 389
388 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 390 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
389 int16_t rot_dir_path_att_db, rot_quad_path_att_db; 391 int16_t rot_dir_path_att_db, rot_quad_path_att_db;
392 struct ath_aic_sram_info sram;
390 393
391 aic_sram[i].sram.vga_dir_sign = 394 sram.vga_dir_sign =
392 (aic_sram[i].dir_path_gain_lin >= 0) ? 1 : 0; 395 (aic_sram[i].dir_path_gain_lin >= 0) ? 1 : 0;
393 aic_sram[i].sram.vga_quad_sign= 396 sram.vga_quad_sign =
394 (aic_sram[i].quad_path_gain_lin >= 0) ? 1 : 0; 397 (aic_sram[i].quad_path_gain_lin >= 0) ? 1 : 0;
395 398
396 rot_dir_path_att_db = 399 rot_dir_path_att_db =
@@ -400,33 +403,31 @@ static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
400 ar9003_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) - 403 ar9003_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) -
401 fixed_com_att_db; 404 fixed_com_att_db;
402 405
403 aic_sram[i].sram.com_att_6db = 406 sram.com_att_6db =
404 ar9003_aic_find_index(1, fixed_com_att_db); 407 ar9003_aic_find_index(1, fixed_com_att_db);
405 408
406 aic_sram[i].sram.valid = 1; 409 sram.valid = 1;
407 410
408 aic_sram[i].sram.rot_dir_att_db = 411 sram.rot_dir_att_db =
409 min(max(rot_dir_path_att_db, 412 min(max(rot_dir_path_att_db,
410 (int16_t)ATH_AIC_MIN_ROT_DIR_ATT_DB), 413 (int16_t)ATH_AIC_MIN_ROT_DIR_ATT_DB),
411 ATH_AIC_MAX_ROT_DIR_ATT_DB); 414 ATH_AIC_MAX_ROT_DIR_ATT_DB);
412 aic_sram[i].sram.rot_quad_att_db = 415 sram.rot_quad_att_db =
413 min(max(rot_quad_path_att_db, 416 min(max(rot_quad_path_att_db,
414 (int16_t)ATH_AIC_MIN_ROT_QUAD_ATT_DB), 417 (int16_t)ATH_AIC_MIN_ROT_QUAD_ATT_DB),
415 ATH_AIC_MAX_ROT_QUAD_ATT_DB); 418 ATH_AIC_MAX_ROT_QUAD_ATT_DB);
416 }
417 419
418 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) { 420 aic->aic_sram[i] = (SM(sram.vga_dir_sign,
419 aic->aic_sram[i] = (SM(aic_sram[i].sram.vga_dir_sign,
420 AR_PHY_AIC_SRAM_VGA_DIR_SIGN) | 421 AR_PHY_AIC_SRAM_VGA_DIR_SIGN) |
421 SM(aic_sram[i].sram.vga_quad_sign, 422 SM(sram.vga_quad_sign,
422 AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) | 423 AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) |
423 SM(aic_sram[i].sram.com_att_6db, 424 SM(sram.com_att_6db,
424 AR_PHY_AIC_SRAM_COM_ATT_6DB) | 425 AR_PHY_AIC_SRAM_COM_ATT_6DB) |
425 SM(aic_sram[i].sram.valid, 426 SM(sram.valid,
426 AR_PHY_AIC_SRAM_VALID) | 427 AR_PHY_AIC_SRAM_VALID) |
427 SM(aic_sram[i].sram.rot_dir_att_db, 428 SM(sram.rot_dir_att_db,
428 AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) | 429 AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) |
429 SM(aic_sram[i].sram.rot_quad_att_db, 430 SM(sram.rot_quad_att_db,
430 AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB)); 431 AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB));
431 } 432 }
432 433
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_aic.h b/drivers/net/wireless/ath/ath9k/ar9003_aic.h
index 86f40644be43..9512c63799f2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_aic.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_aic.h
@@ -50,7 +50,6 @@ struct ath_aic_sram_info {
50struct ath_aic_out_info { 50struct ath_aic_out_info {
51 int16_t dir_path_gain_lin; 51 int16_t dir_path_gain_lin;
52 int16_t quad_path_gain_lin; 52 int16_t quad_path_gain_lin;
53 struct ath_aic_sram_info sram;
54}; 53};
55 54
56u8 ar9003_aic_calibration(struct ath_hw *ah); 55u8 ar9003_aic_calibration(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 8b4561e8ce1a..54ed2f72d35e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -5485,11 +5485,11 @@ unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
5485 AR9300_PAPRD_SCALE_1); 5485 AR9300_PAPRD_SCALE_1);
5486 else { 5486 else {
5487 if (chan->channel >= 5700) 5487 if (chan->channel >= 5700)
5488 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), 5488 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20),
5489 AR9300_PAPRD_SCALE_1); 5489 AR9300_PAPRD_SCALE_1);
5490 else if (chan->channel >= 5400) 5490 else if (chan->channel >= 5400)
5491 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), 5491 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5492 AR9300_PAPRD_SCALE_2); 5492 AR9300_PAPRD_SCALE_2);
5493 else 5493 else
5494 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), 5494 return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40),
5495 AR9300_PAPRD_SCALE_1); 5495 AR9300_PAPRD_SCALE_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 8b238c15916d..2fe12b0de5b4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -698,6 +698,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
698 else if (AR_SREV_9340(ah)) 698 else if (AR_SREV_9340(ah))
699 INIT_INI_ARRAY(&ah->iniModesTxGain, 699 INIT_INI_ARRAY(&ah->iniModesTxGain,
700 ar9340Modes_low_ob_db_tx_gain_table_1p0); 700 ar9340Modes_low_ob_db_tx_gain_table_1p0);
701 else if (AR_SREV_9531_11(ah))
702 INIT_INI_ARRAY(&ah->iniModesTxGain,
703 qca953x_1p1_modes_no_xpa_low_power_tx_gain_table);
701 else if (AR_SREV_9485_11_OR_LATER(ah)) 704 else if (AR_SREV_9485_11_OR_LATER(ah))
702 INIT_INI_ARRAY(&ah->iniModesTxGain, 705 INIT_INI_ARRAY(&ah->iniModesTxGain,
703 ar9485Modes_low_ob_db_tx_gain_1_1); 706 ar9485Modes_low_ob_db_tx_gain_1_1);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 201425e7f9cb..06c1ca6e8290 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -976,9 +976,14 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
976 /* 976 /*
977 * JAPAN regulatory. 977 * JAPAN regulatory.
978 */ 978 */
979 if (chan->channel == 2484) 979 if (chan->channel == 2484) {
980 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1); 980 ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1);
981 981
982 if (AR_SREV_9531(ah))
983 REG_RMW_FIELD(ah, AR_PHY_FCAL_2_0,
984 AR_PHY_FLC_PWR_THRESH, 0);
985 }
986
982 ah->modes_index = modesIndex; 987 ah->modes_index = modesIndex;
983 ar9003_hw_override_ini(ah); 988 ar9003_hw_override_ini(ah);
984 ar9003_hw_set_channel_regs(ah, chan); 989 ar9003_hw_set_channel_regs(ah, chan);
@@ -2071,7 +2076,8 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
2071 * to be disabled. 2076 * to be disabled.
2072 * 2077 *
2073 * 0x04000409: Packet stuck on receive. 2078 * 0x04000409: Packet stuck on receive.
2074 * Full chip reset is required for all chips except AR9340. 2079 * Full chip reset is required for all chips except
2080 * AR9340, AR9531 and AR9561.
2075 */ 2081 */
2076 2082
2077/* 2083/*
@@ -2100,7 +2106,7 @@ bool ar9003_hw_bb_watchdog_check(struct ath_hw *ah)
2100 case 0x04000b09: 2106 case 0x04000b09:
2101 return true; 2107 return true;
2102 case 0x04000409: 2108 case 0x04000409:
2103 if (AR_SREV_9340(ah) || AR_SREV_9531(ah)) 2109 if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah))
2104 return false; 2110 return false;
2105 else 2111 else
2106 return true; 2112 return true;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index c5f8bc4b5595..566da789f97e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -487,6 +487,9 @@
487#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150) 487#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150)
488#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158) 488#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158)
489 489
490#define AR_PHY_FLC_PWR_THRESH 7
491#define AR_PHY_FLC_PWR_THRESH_S 0
492
490#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW 3 493#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW 3
491#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW_S 0 494#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW_S 0
492 495
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
index 6fc0d07e5ec6..c0b90daa3e3d 100644
--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -757,6 +757,71 @@ static const u32 qca953x_1p1_modes_xpa_tx_gain_table[][2] = {
757 {0x00016448, 0x6c927a70}, 757 {0x00016448, 0x6c927a70},
758}; 758};
759 759
760static const u32 qca953x_1p1_modes_no_xpa_low_power_tx_gain_table[][2] = {
761 /* Addr allmodes */
762 {0x0000a2dc, 0xfff55592},
763 {0x0000a2e0, 0xfff99924},
764 {0x0000a2e4, 0xfffe1e00},
765 {0x0000a2e8, 0xffffe000},
766 {0x0000a410, 0x000050d6},
767 {0x0000a500, 0x00000069},
768 {0x0000a504, 0x0400006b},
769 {0x0000a508, 0x0800006d},
770 {0x0000a50c, 0x0c000269},
771 {0x0000a510, 0x1000026b},
772 {0x0000a514, 0x1400026d},
773 {0x0000a518, 0x18000669},
774 {0x0000a51c, 0x1c00066b},
775 {0x0000a520, 0x1d000a68},
776 {0x0000a524, 0x21000a6a},
777 {0x0000a528, 0x25000a6c},
778 {0x0000a52c, 0x29000a6e},
779 {0x0000a530, 0x2d0012a9},
780 {0x0000a534, 0x310012ab},
781 {0x0000a538, 0x350012ad},
782 {0x0000a53c, 0x39001b0a},
783 {0x0000a540, 0x3d001b0c},
784 {0x0000a544, 0x41001b0e},
785 {0x0000a548, 0x43001bae},
786 {0x0000a54c, 0x45001914},
787 {0x0000a550, 0x47001916},
788 {0x0000a554, 0x49001b96},
789 {0x0000a558, 0x49001b96},
790 {0x0000a55c, 0x49001b96},
791 {0x0000a560, 0x49001b96},
792 {0x0000a564, 0x49001b96},
793 {0x0000a568, 0x49001b96},
794 {0x0000a56c, 0x49001b96},
795 {0x0000a570, 0x49001b96},
796 {0x0000a574, 0x49001b96},
797 {0x0000a578, 0x49001b96},
798 {0x0000a57c, 0x49001b96},
799 {0x0000a600, 0x00000000},
800 {0x0000a604, 0x00000000},
801 {0x0000a608, 0x00000000},
802 {0x0000a60c, 0x00000000},
803 {0x0000a610, 0x00000000},
804 {0x0000a614, 0x00000000},
805 {0x0000a618, 0x00804201},
806 {0x0000a61c, 0x01408201},
807 {0x0000a620, 0x01408502},
808 {0x0000a624, 0x01408502},
809 {0x0000a628, 0x01408502},
810 {0x0000a62c, 0x01408502},
811 {0x0000a630, 0x01408502},
812 {0x0000a634, 0x01408502},
813 {0x0000a638, 0x01408502},
814 {0x0000a63c, 0x01408502},
815 {0x0000b2dc, 0xfff55592},
816 {0x0000b2e0, 0xfff99924},
817 {0x0000b2e4, 0xfffe1e00},
818 {0x0000b2e8, 0xffffe000},
819 {0x00016044, 0x044922db},
820 {0x00016048, 0x6c927a70},
821 {0x00016444, 0x044922db},
822 {0x00016448, 0x6c927a70},
823};
824
760static const u32 qca953x_2p0_baseband_core[][2] = { 825static const u32 qca953x_2p0_baseband_core[][2] = {
761 /* Addr allmodes */ 826 /* Addr allmodes */
762 {0x00009800, 0xafe68e30}, 827 {0x00009800, 0xafe68e30},
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 3e2e24e4843f..37f6d66d1671 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -241,6 +241,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
241 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; 241 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
242 struct ath_common *common = ath9k_hw_common(ah); 242 struct ath_common *common = ath9k_hw_common(ah);
243 s16 default_nf = ath9k_hw_get_default_nf(ah, chan); 243 s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
244 u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL);
244 245
245 if (ah->caldata) 246 if (ah->caldata)
246 h = ah->caldata->nfCalHist; 247 h = ah->caldata->nfCalHist;
@@ -264,6 +265,16 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
264 } 265 }
265 266
266 /* 267 /*
268 * stop NF cal if ongoing to ensure NF load completes immediately
269 * (or after end rx/tx frame if ongoing)
270 */
271 if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
272 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
273 REG_RMW_BUFFER_FLUSH(ah);
274 ENABLE_REG_RMW_BUFFER(ah);
275 }
276
277 /*
267 * Load software filtered NF value into baseband internal minCCApwr 278 * Load software filtered NF value into baseband internal minCCApwr
268 * variable. 279 * variable.
269 */ 280 */
@@ -276,18 +287,33 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
276 287
277 /* 288 /*
278 * Wait for load to complete, should be fast, a few 10s of us. 289 * Wait for load to complete, should be fast, a few 10s of us.
279 * The max delay was changed from an original 250us to 10000us 290 * The max delay was changed from an original 250us to 22.2 msec.
280 * since 250us often results in NF load timeout and causes deaf 291 * This would increase timeout to the longest possible frame
281 * condition during stress testing 12/12/2009 292 * (11n max length 22.1 msec)
282 */ 293 */
283 for (j = 0; j < 10000; j++) { 294 for (j = 0; j < 22200; j++) {
284 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & 295 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
285 AR_PHY_AGC_CONTROL_NF) == 0) 296 AR_PHY_AGC_CONTROL_NF) == 0)
286 break; 297 break;
287 udelay(10); 298 udelay(10);
288 } 299 }
289 300
290 /* 301 /*
302 * Restart NF so it can continue.
303 */
304 if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
305 ENABLE_REG_RMW_BUFFER(ah);
306 if (bb_agc_ctl & AR_PHY_AGC_CONTROL_ENABLE_NF)
307 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
308 AR_PHY_AGC_CONTROL_ENABLE_NF);
309 if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NO_UPDATE_NF)
310 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
311 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
312 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
313 REG_RMW_BUFFER_FLUSH(ah);
314 }
315
316 /*
291 * We timed out waiting for the noisefloor to load, probably due to an 317 * We timed out waiting for the noisefloor to load, probably due to an
292 * in-progress rx. Simply return here and allow the load plenty of time 318 * in-progress rx. Simply return here and allow the load plenty of time
293 * to complete before the next calibration interval. We need to avoid 319 * to complete before the next calibration interval. We need to avoid
@@ -296,7 +322,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
296 * here, the baseband nf cal will just be capped by our present 322 * here, the baseband nf cal will just be capped by our present
297 * noisefloor until the next calibration timer. 323 * noisefloor until the next calibration timer.
298 */ 324 */
299 if (j == 10000) { 325 if (j == 22200) {
300 ath_dbg(common, ANY, 326 ath_dbg(common, ANY,
301 "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", 327 "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
302 REG_READ(ah, AR_PHY_AGC_CONTROL)); 328 REG_READ(ah, AR_PHY_AGC_CONTROL));
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 50e614b915f1..319cb5f25f58 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -226,7 +226,7 @@ static const char *chanctx_state_string(enum ath_chanctx_state state)
226 } 226 }
227} 227}
228 228
229static const u32 chanctx_event_delta(struct ath_softc *sc) 229static u32 chanctx_event_delta(struct ath_softc *sc)
230{ 230{
231 u64 ms; 231 u64 ms;
232 struct timespec ts, *old; 232 struct timespec ts, *old;
@@ -1454,7 +1454,7 @@ static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
1454 if (!sc->p2p_ps_timer) 1454 if (!sc->p2p_ps_timer)
1455 return; 1455 return;
1456 1456
1457 if (vif->type != NL80211_IFTYPE_STATION || !vif->p2p) 1457 if (vif->type != NL80211_IFTYPE_STATION)
1458 return; 1458 return;
1459 1459
1460 sc->p2p_ps_vif = avp; 1460 sc->p2p_ps_vif = avp;
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 165dd202c365..8cbf4904db7b 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -55,6 +55,8 @@ static struct usb_device_id ath9k_hif_usb_ids[] = {
55 .driver_info = AR9280_USB }, /* Buffalo WLI-UV-AG300P */ 55 .driver_info = AR9280_USB }, /* Buffalo WLI-UV-AG300P */
56 { USB_DEVICE(0x04da, 0x3904), 56 { USB_DEVICE(0x04da, 0x3904),
57 .driver_info = AR9280_USB }, 57 .driver_info = AR9280_USB },
58 { USB_DEVICE(0x0930, 0x0a08),
59 .driver_info = AR9280_USB }, /* Toshiba WLM-20U2 and GN-1080 */
58 60
59 { USB_DEVICE(0x0cf3, 0x20ff), 61 { USB_DEVICE(0x0cf3, 0x20ff),
60 .driver_info = STORAGE_DEVICE }, 62 .driver_info = STORAGE_DEVICE },
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 257f46ed4a04..e7a31016f370 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1368,6 +1368,16 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
1368 if (ath9k_hw_mci_is_enabled(ah)) 1368 if (ath9k_hw_mci_is_enabled(ah))
1369 ar9003_mci_check_gpm_offset(ah); 1369 ar9003_mci_check_gpm_offset(ah);
1370 1370
1371 /* DMA HALT added to resolve ar9300 and ar9580 bus error during
1372 * RTC_RC reg read
1373 */
1374 if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
1375 REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
1376 ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
1377 20 * AH_WAIT_TIMEOUT);
1378 REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
1379 }
1380
1371 REG_WRITE(ah, AR_RTC_RC, rst_flags); 1381 REG_WRITE(ah, AR_RTC_RC, rst_flags);
1372 1382
1373 REGWRITE_BUFFER_FLUSH(ah); 1383 REGWRITE_BUFFER_FLUSH(ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index ab7a1ac37849..d4e0ac946c3a 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -751,14 +751,6 @@ static const struct ieee80211_iface_combination if_comb_multi[] = {
751 751
752#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ 752#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
753 753
754static const struct ieee80211_iface_limit if_dfs_limits[] = {
755 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
756#ifdef CONFIG_MAC80211_MESH
757 BIT(NL80211_IFTYPE_MESH_POINT) |
758#endif
759 BIT(NL80211_IFTYPE_ADHOC) },
760};
761
762static const struct ieee80211_iface_combination if_comb[] = { 754static const struct ieee80211_iface_combination if_comb[] = {
763 { 755 {
764 .limits = if_limits, 756 .limits = if_limits,
@@ -766,6 +758,11 @@ static const struct ieee80211_iface_combination if_comb[] = {
766 .max_interfaces = 2048, 758 .max_interfaces = 2048,
767 .num_different_channels = 1, 759 .num_different_channels = 1,
768 .beacon_int_infra_match = true, 760 .beacon_int_infra_match = true,
761#ifdef CONFIG_ATH9K_DFS_CERTIFIED
762 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
763 BIT(NL80211_CHAN_WIDTH_20) |
764 BIT(NL80211_CHAN_WIDTH_40),
765#endif
769 }, 766 },
770 { 767 {
771 .limits = wds_limits, 768 .limits = wds_limits,
@@ -774,18 +771,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
774 .num_different_channels = 1, 771 .num_different_channels = 1,
775 .beacon_int_infra_match = true, 772 .beacon_int_infra_match = true,
776 }, 773 },
777#ifdef CONFIG_ATH9K_DFS_CERTIFIED
778 {
779 .limits = if_dfs_limits,
780 .n_limits = ARRAY_SIZE(if_dfs_limits),
781 .max_interfaces = 1,
782 .num_different_channels = 1,
783 .beacon_int_infra_match = true,
784 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
785 BIT(NL80211_CHAN_WIDTH_20) |
786 BIT(NL80211_CHAN_WIDTH_40),
787 }
788#endif
789}; 774};
790 775
791#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT 776#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index cf58a304e9f0..3aed43a63f94 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -978,7 +978,7 @@ static void ath9k_update_bssid_mask(struct ath_softc *sc,
978 if (ctx->nvifs_assigned != 1) 978 if (ctx->nvifs_assigned != 1)
979 continue; 979 continue;
980 980
981 if (!avp->vif->p2p || !iter_data->has_hw_macaddr) 981 if (!iter_data->has_hw_macaddr)
982 continue; 982 continue;
983 983
984 ether_addr_copy(common->curbssid, avp->bssid); 984 ether_addr_copy(common->curbssid, avp->bssid);
@@ -1255,6 +1255,9 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1255 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); 1255 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1256 sc->cur_chan->nvifs++; 1256 sc->cur_chan->nvifs++;
1257 1257
1258 if (vif->type == NL80211_IFTYPE_STATION && ath9k_is_chanctx_enabled())
1259 vif->driver_flags |= IEEE80211_VIF_GET_NOA_UPDATE;
1260
1258 if (ath9k_uses_beacons(vif->type)) 1261 if (ath9k_uses_beacons(vif->type))
1259 ath9k_beacon_assign_slot(sc, vif); 1262 ath9k_beacon_assign_slot(sc, vif);
1260 1263
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index caba54ddad25..c8d35febaf0f 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -34,8 +34,10 @@
34#define AR_CFG_SWRG 0x00000010 34#define AR_CFG_SWRG 0x00000010
35#define AR_CFG_AP_ADHOC_INDICATION 0x00000020 35#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
36#define AR_CFG_PHOK 0x00000100 36#define AR_CFG_PHOK 0x00000100
37#define AR_CFG_CLK_GATE_DIS 0x00000400
38#define AR_CFG_EEBS 0x00000200 37#define AR_CFG_EEBS 0x00000200
38#define AR_CFG_CLK_GATE_DIS 0x00000400
39#define AR_CFG_HALT_REQ 0x00000800
40#define AR_CFG_HALT_ACK 0x00001000
39#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 41#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000
40#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 42#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
41 43
diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index 9111d4ffc1b3..ea1d80f9a50e 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -56,6 +56,7 @@ enum carl9170_cmd_oids {
56 CARL9170_CMD_RX_FILTER = 0x07, 56 CARL9170_CMD_RX_FILTER = 0x07,
57 CARL9170_CMD_WOL = 0x08, 57 CARL9170_CMD_WOL = 0x08,
58 CARL9170_CMD_TALLY = 0x09, 58 CARL9170_CMD_TALLY = 0x09,
59 CARL9170_CMD_WREGB = 0x0a,
59 60
60 /* CAM */ 61 /* CAM */
61 CARL9170_CMD_EKEY = 0x10, 62 CARL9170_CMD_EKEY = 0x10,
@@ -123,6 +124,12 @@ struct carl9170_write_reg {
123 } regs[0] __packed; 124 } regs[0] __packed;
124} __packed; 125} __packed;
125 126
127struct carl9170_write_reg_byte {
128 __le32 addr;
129 __le32 count;
130 u8 val[0];
131} __packed;
132
126#define CARL9170FW_PHY_HT_ENABLE 0x4 133#define CARL9170FW_PHY_HT_ENABLE 0x4
127#define CARL9170FW_PHY_HT_DYN2040 0x8 134#define CARL9170FW_PHY_HT_DYN2040 0x8
128#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3 135#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3
@@ -226,6 +233,7 @@ struct carl9170_cmd {
226 struct carl9170_u32_list echo; 233 struct carl9170_u32_list echo;
227 struct carl9170_reg_list rreg; 234 struct carl9170_reg_list rreg;
228 struct carl9170_write_reg wreg; 235 struct carl9170_write_reg wreg;
236 struct carl9170_write_reg_byte wregb;
229 struct carl9170_rf_init rf_init; 237 struct carl9170_rf_init rf_init;
230 struct carl9170_psm psm; 238 struct carl9170_psm psm;
231 struct carl9170_wol_cmd wol; 239 struct carl9170_wol_cmd wol;
diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h
index 66848d47c88e..0533f79cb998 100644
--- a/drivers/net/wireless/ath/carl9170/fwdesc.h
+++ b/drivers/net/wireless/ath/carl9170/fwdesc.h
@@ -81,6 +81,12 @@ enum carl9170fw_feature_list {
81 /* Firmware will pass BA when BARs are queued */ 81 /* Firmware will pass BA when BARs are queued */
82 CARL9170FW_RX_BA_FILTER, 82 CARL9170FW_RX_BA_FILTER,
83 83
84 /* Firmware has support to write a byte at a time */
85 CARL9170FW_HAS_WREGB_CMD,
86
87 /* Pattern generator */
88 CARL9170FW_PATTERN_GENERATOR,
89
84 /* KEEP LAST */ 90 /* KEEP LAST */
85 __CARL9170FW_FEATURE_NUM 91 __CARL9170FW_FEATURE_NUM
86}; 92};
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 0db874abde50..08e0ae9c5836 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -453,9 +453,74 @@
453#define AR9170_MC_REG_BASE 0x1d1000 453#define AR9170_MC_REG_BASE 0x1d1000
454 454
455#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) 455#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000)
456#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) 456
457#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) 457#define AR9170_SPI_REG_BASE (AR9170_MC_REG_BASE + 0x200)
458#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) 458#define AR9170_SPI_REG_CONTROL0 (AR9170_SPI_REG_BASE + 0x000)
459#define AR9170_SPI_CONTROL0_BUSY BIT(0)
460#define AR9170_SPI_CONTROL0_CMD_GO BIT(1)
461#define AR9170_SPI_CONTROL0_PAGE_WR BIT(2)
462#define AR9170_SPI_CONTROL0_SEQ_RD BIT(3)
463#define AR9170_SPI_CONTROL0_CMD_ABORT BIT(4)
464#define AR9170_SPI_CONTROL0_CMD_LEN_S 8
465#define AR9170_SPI_CONTROL0_CMD_LEN 0x00000f00
466#define AR9170_SPI_CONTROL0_RD_LEN_S 12
467#define AR9170_SPI_CONTROL0_RD_LEN 0x00007000
468
469#define AR9170_SPI_REG_CONTROL1 (AR9170_SPI_REG_BASE + 0x004)
470#define AR9170_SPI_CONTROL1_SCK_RATE BIT(0)
471#define AR9170_SPI_CONTROL1_DRIVE_SDO BIT(1)
472#define AR9170_SPI_CONTROL1_MODE_SEL_S 2
473#define AR9170_SPI_CONTROL1_MODE_SEL 0x000000c0
474#define AR9170_SPI_CONTROL1_WRITE_PROTECT BIT(4)
475
476#define AR9170_SPI_REG_COMMAND_PORT0 (AR9170_SPI_REG_BASE + 0x008)
477#define AR9170_SPI_COMMAND_PORT0_CMD0_S 0
478#define AR9170_SPI_COMMAND_PORT0_CMD0 0x000000ff
479#define AR9170_SPI_COMMAND_PORT0_CMD1_S 8
480#define AR9170_SPI_COMMAND_PORT0_CMD1 0x0000ff00
481#define AR9170_SPI_COMMAND_PORT0_CMD2_S 16
482#define AR9170_SPI_COMMAND_PORT0_CMD2 0x00ff0000
483#define AR9170_SPI_COMMAND_PORT0_CMD3_S 24
484#define AR9170_SPI_COMMAND_PORT0_CMD3 0xff000000
485
486#define AR9170_SPI_REG_COMMAND_PORT1 (AR9170_SPI_REG_BASE + 0x00C)
487#define AR9170_SPI_COMMAND_PORT1_CMD4_S 0
488#define AR9170_SPI_COMMAND_PORT1_CMD4 0x000000ff
489#define AR9170_SPI_COMMAND_PORT1_CMD5_S 8
490#define AR9170_SPI_COMMAND_PORT1_CMD5 0x0000ff00
491#define AR9170_SPI_COMMAND_PORT1_CMD6_S 16
492#define AR9170_SPI_COMMAND_PORT1_CMD6 0x00ff0000
493#define AR9170_SPI_COMMAND_PORT1_CMD7_S 24
494#define AR9170_SPI_COMMAND_PORT1_CMD7 0xff000000
495
496#define AR9170_SPI_REG_DATA_PORT (AR9170_SPI_REG_BASE + 0x010)
497#define AR9170_SPI_REG_PAGE_WRITE_LEN (AR9170_SPI_REG_BASE + 0x014)
498
499#define AR9170_EEPROM_REG_BASE (AR9170_MC_REG_BASE + 0x400)
500#define AR9170_EEPROM_REG_WP_MAGIC1 (AR9170_EEPROM_REG_BASE + 0x000)
501#define AR9170_EEPROM_WP_MAGIC1 0x12345678
502
503#define AR9170_EEPROM_REG_WP_MAGIC2 (AR9170_EEPROM_REG_BASE + 0x004)
504#define AR9170_EEPROM_WP_MAGIC2 0x55aa00ff
505
506#define AR9170_EEPROM_REG_WP_MAGIC3 (AR9170_EEPROM_REG_BASE + 0x008)
507#define AR9170_EEPROM_WP_MAGIC3 0x13579ace
508
509#define AR9170_EEPROM_REG_CLOCK_DIV (AR9170_EEPROM_REG_BASE + 0x00C)
510#define AR9170_EEPROM_CLOCK_DIV_FAC_S 0
511#define AR9170_EEPROM_CLOCK_DIV_FAC 0x000001ff
512#define AR9170_EEPROM_CLOCK_DIV_FAC_39KHZ 0xff
513#define AR9170_EEPROM_CLOCK_DIV_FAC_78KHZ 0x7f
514#define AR9170_EEPROM_CLOCK_DIV_FAC_312KHZ 0x1f
515#define AR9170_EEPROM_CLOCK_DIV_FAC_10MHZ 0x0
516#define AR9170_EEPROM_CLOCK_DIV_SOFT_RST BIT(9)
517
518#define AR9170_EEPROM_REG_MODE (AR9170_EEPROM_REG_BASE + 0x010)
519#define AR9170_EEPROM_MODE_EEPROM_SIZE_16K_PLUS BIT(31)
520
521#define AR9170_EEPROM_REG_WRITE_PROTECT (AR9170_EEPROM_REG_BASE + 0x014)
522#define AR9170_EEPROM_WRITE_PROTECT_WP_STATUS BIT(0)
523#define AR9170_EEPROM_WRITE_PROTECT_WP_SET BIT(8)
459 524
460/* Interrupt Controller */ 525/* Interrupt Controller */
461#define AR9170_MAX_INT_SRC 9 526#define AR9170_MAX_INT_SRC 9
@@ -589,11 +654,13 @@
589#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) 654#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039)
590 655
591#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) 656#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f)
657#define AR9170_USB_EP_IN_STALL 0x8
592#define AR9170_USB_EP_IN_TOGGLE 0x10 658#define AR9170_USB_EP_IN_TOGGLE 0x10
593 659
594#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) 660#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e)
595 661
596#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) 662#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f)
663#define AR9170_USB_EP_OUT_STALL 0x8
597#define AR9170_USB_EP_OUT_TOGGLE 0x10 664#define AR9170_USB_EP_OUT_TOGGLE 0x10
598 665
599#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) 666#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e)
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index 2282847d4bb8..a0410fe8c03a 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
1#ifndef __CARL9170_SHARED_VERSION_H 1#ifndef __CARL9170_SHARED_VERSION_H
2#define __CARL9170_SHARED_VERSION_H 2#define __CARL9170_SHARED_VERSION_H
3#define CARL9170FW_VERSION_YEAR 12 3#define CARL9170FW_VERSION_YEAR 16
4#define CARL9170FW_VERSION_MONTH 12 4#define CARL9170FW_VERSION_MONTH 2
5#define CARL9170FW_VERSION_DAY 15 5#define CARL9170FW_VERSION_DAY 15
6#define CARL9170FW_VERSION_GIT "1.9.7" 6#define CARL9170FW_VERSION_GIT "1.9.9"
7#endif /* __CARL9170_SHARED_VERSION_H */ 7#endif /* __CARL9170_SHARED_VERSION_H */
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 1f231cd08138..11f1bb8dfebe 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -540,7 +540,18 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
540 540
541 wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code); 541 wil_dbg_misc(wil, "%s(reason=%d)\n", __func__, reason_code);
542 542
543 rc = wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); 543 if (!(test_bit(wil_status_fwconnecting, wil->status) ||
544 test_bit(wil_status_fwconnected, wil->status))) {
545 wil_err(wil, "%s: Disconnect was called while disconnected\n",
546 __func__);
547 return 0;
548 }
549
550 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
551 WMI_DISCONNECT_EVENTID, NULL, 0,
552 WIL6210_DISCONNECT_TO_MS);
553 if (rc)
554 wil_err(wil, "%s: disconnect error %d\n", __func__, rc);
544 555
545 return rc; 556 return rc;
546} 557}
@@ -701,6 +712,79 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
701 return rc; 712 return rc;
702} 713}
703 714
715/**
716 * find a specific IE in a list of IEs
717 * return a pointer to the beginning of IE in the list
718 * or NULL if not found
719 */
720static const u8 *_wil_cfg80211_find_ie(const u8 *ies, u16 ies_len, const u8 *ie,
721 u16 ie_len)
722{
723 struct ieee80211_vendor_ie *vie;
724 u32 oui;
725
726 /* IE tag at offset 0, length at offset 1 */
727 if (ie_len < 2 || 2 + ie[1] > ie_len)
728 return NULL;
729
730 if (ie[0] != WLAN_EID_VENDOR_SPECIFIC)
731 return cfg80211_find_ie(ie[0], ies, ies_len);
732
733 /* make sure there is room for 3 bytes OUI + 1 byte OUI type */
734 if (ie[1] < 4)
735 return NULL;
736 vie = (struct ieee80211_vendor_ie *)ie;
737 oui = vie->oui[0] << 16 | vie->oui[1] << 8 | vie->oui[2];
738 return cfg80211_find_vendor_ie(oui, vie->oui_type, ies,
739 ies_len);
740}
741
742/**
743 * merge the IEs in two lists into a single list.
744 * do not include IEs from the second list which exist in the first list.
745 * add only vendor specific IEs from second list to keep
746 * the merged list sorted (since vendor-specific IE has the
747 * highest tag number)
748 * caller must free the allocated memory for merged IEs
749 */
750static int _wil_cfg80211_merge_extra_ies(const u8 *ies1, u16 ies1_len,
751 const u8 *ies2, u16 ies2_len,
752 u8 **merged_ies, u16 *merged_len)
753{
754 u8 *buf, *dpos;
755 const u8 *spos;
756
757 if (ies1_len == 0 && ies2_len == 0) {
758 *merged_ies = NULL;
759 *merged_len = 0;
760 return 0;
761 }
762
763 buf = kmalloc(ies1_len + ies2_len, GFP_KERNEL);
764 if (!buf)
765 return -ENOMEM;
766 memcpy(buf, ies1, ies1_len);
767 dpos = buf + ies1_len;
768 spos = ies2;
769 while (spos + 1 < ies2 + ies2_len) {
770 /* IE tag at offset 0, length at offset 1 */
771 u16 ielen = 2 + spos[1];
772
773 if (spos + ielen > ies2 + ies2_len)
774 break;
775 if (spos[0] == WLAN_EID_VENDOR_SPECIFIC &&
776 !_wil_cfg80211_find_ie(ies1, ies1_len, spos, ielen)) {
777 memcpy(dpos, spos, ielen);
778 dpos += ielen;
779 }
780 spos += ielen;
781 }
782
783 *merged_ies = buf;
784 *merged_len = dpos - buf;
785 return 0;
786}
787
704static void wil_print_bcon_data(struct cfg80211_beacon_data *b) 788static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
705{ 789{
706 print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET, 790 print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
@@ -717,49 +801,49 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
717 b->assocresp_ies, b->assocresp_ies_len); 801 b->assocresp_ies, b->assocresp_ies_len);
718} 802}
719 803
720static int wil_fix_bcon(struct wil6210_priv *wil,
721 struct cfg80211_beacon_data *bcon)
722{
723 struct ieee80211_mgmt *f = (struct ieee80211_mgmt *)bcon->probe_resp;
724 size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
725
726 if (bcon->probe_resp_len <= hlen)
727 return 0;
728
729/* always use IE's from full probe frame, they has more info
730 * notable RSN
731 */
732 bcon->proberesp_ies = f->u.probe_resp.variable;
733 bcon->proberesp_ies_len = bcon->probe_resp_len - hlen;
734 if (!bcon->assocresp_ies) {
735 bcon->assocresp_ies = bcon->proberesp_ies;
736 bcon->assocresp_ies_len = bcon->proberesp_ies_len;
737 }
738
739 return 1;
740}
741
742/* internal functions for device reset and starting AP */ 804/* internal functions for device reset and starting AP */
743static int _wil_cfg80211_set_ies(struct wiphy *wiphy, 805static int _wil_cfg80211_set_ies(struct wiphy *wiphy,
744 struct cfg80211_beacon_data *bcon) 806 struct cfg80211_beacon_data *bcon)
745{ 807{
746 int rc; 808 int rc;
747 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 809 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
810 u16 len = 0, proberesp_len = 0;
811 u8 *ies = NULL, *proberesp = NULL;
812
813 if (bcon->probe_resp) {
814 struct ieee80211_mgmt *f =
815 (struct ieee80211_mgmt *)bcon->probe_resp;
816 size_t hlen = offsetof(struct ieee80211_mgmt,
817 u.probe_resp.variable);
818 proberesp = f->u.probe_resp.variable;
819 proberesp_len = bcon->probe_resp_len - hlen;
820 }
821 rc = _wil_cfg80211_merge_extra_ies(proberesp,
822 proberesp_len,
823 bcon->proberesp_ies,
824 bcon->proberesp_ies_len,
825 &ies, &len);
748 826
749 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, bcon->proberesp_ies_len,
750 bcon->proberesp_ies);
751 if (rc) 827 if (rc)
752 return rc; 828 goto out;
753 829
754 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, bcon->assocresp_ies_len, 830 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, len, ies);
755 bcon->assocresp_ies); 831 if (rc)
832 goto out;
833
834 if (bcon->assocresp_ies)
835 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
836 bcon->assocresp_ies_len, bcon->assocresp_ies);
837 else
838 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, len, ies);
756#if 0 /* to use beacon IE's, remove this #if 0 */ 839#if 0 /* to use beacon IE's, remove this #if 0 */
757 if (rc) 840 if (rc)
758 return rc; 841 goto out;
759 842
760 rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail); 843 rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail);
761#endif 844#endif
762 845out:
846 kfree(ies);
763 return rc; 847 return rc;
764} 848}
765 849
@@ -828,14 +912,9 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
828 wil_dbg_misc(wil, "%s()\n", __func__); 912 wil_dbg_misc(wil, "%s()\n", __func__);
829 wil_print_bcon_data(bcon); 913 wil_print_bcon_data(bcon);
830 914
831 if (wil_fix_bcon(wil, bcon)) { 915 if (bcon->tail &&
832 wil_dbg_misc(wil, "Fixed bcon\n"); 916 cfg80211_find_ie(WLAN_EID_RSN, bcon->tail,
833 wil_print_bcon_data(bcon); 917 bcon->tail_len))
834 }
835
836 if (bcon->proberesp_ies &&
837 cfg80211_find_ie(WLAN_EID_RSN, bcon->proberesp_ies,
838 bcon->proberesp_ies_len))
839 privacy = 1; 918 privacy = 1;
840 919
841 /* in case privacy has changed, need to restart the AP */ 920 /* in case privacy has changed, need to restart the AP */
@@ -910,11 +989,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
910 wil_print_bcon_data(bcon); 989 wil_print_bcon_data(bcon);
911 wil_print_crypto(wil, crypto); 990 wil_print_crypto(wil, crypto);
912 991
913 if (wil_fix_bcon(wil, bcon)) {
914 wil_dbg_misc(wil, "Fixed bcon\n");
915 wil_print_bcon_data(bcon);
916 }
917
918 rc = _wil_cfg80211_start_ap(wiphy, ndev, 992 rc = _wil_cfg80211_start_ap(wiphy, ndev,
919 info->ssid, info->ssid_len, info->privacy, 993 info->ssid, info->ssid_len, info->privacy,
920 info->beacon_interval, channel->hw_value, 994 info->beacon_interval, channel->hw_value,
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index a1d10b85989f..3bbe73b6d05a 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -68,13 +68,13 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
68 seq_puts(s, "???\n"); 68 seq_puts(s, "???\n");
69 } 69 }
70 70
71 if (vring->va && (vring->size < 1025)) { 71 if (vring->va && (vring->size <= (1 << WIL_RING_SIZE_ORDER_MAX))) {
72 uint i; 72 uint i;
73 73
74 for (i = 0; i < vring->size; i++) { 74 for (i = 0; i < vring->size; i++) {
75 volatile struct vring_tx_desc *d = &vring->va[i].tx; 75 volatile struct vring_tx_desc *d = &vring->va[i].tx;
76 76
77 if ((i % 64) == 0 && (i != 0)) 77 if ((i % 128) == 0 && (i != 0))
78 seq_puts(s, "\n"); 78 seq_puts(s, "\n");
79 seq_printf(s, "%c", (d->dma.status & BIT(0)) ? 79 seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
80 _s : (vring->ctx[i].skb ? _h : 'h')); 80 _s : (vring->ctx[i].skb ? _h : 'h'));
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index b39f0bfc591e..78ba6e04c944 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -23,9 +23,6 @@
23#include "wmi.h" 23#include "wmi.h"
24#include "boot_loader.h" 24#include "boot_loader.h"
25 25
26#define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000
27#define WAIT_FOR_DISCONNECT_INTERVAL_MS 10
28
29bool debug_fw; /* = false; */ 26bool debug_fw; /* = false; */
30module_param(debug_fw, bool, S_IRUGO); 27module_param(debug_fw, bool, S_IRUGO);
31MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug"); 28MODULE_PARM_DESC(debug_fw, " do not perform card reset. For FW debug");
@@ -155,7 +152,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
155 152
156 if (sta->status != wil_sta_unused) { 153 if (sta->status != wil_sta_unused) {
157 if (!from_event) 154 if (!from_event)
158 wmi_disconnect_sta(wil, sta->addr, reason_code); 155 wmi_disconnect_sta(wil, sta->addr, reason_code, true);
159 156
160 switch (wdev->iftype) { 157 switch (wdev->iftype) {
161 case NL80211_IFTYPE_AP: 158 case NL80211_IFTYPE_AP:
@@ -195,8 +192,8 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
195 struct wireless_dev *wdev = wil->wdev; 192 struct wireless_dev *wdev = wil->wdev;
196 193
197 might_sleep(); 194 might_sleep();
198 wil_dbg_misc(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid, 195 wil_info(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
199 reason_code, from_event ? "+" : "-"); 196 reason_code, from_event ? "+" : "-");
200 197
201 /* Cases are: 198 /* Cases are:
202 * - disconnect single STA, still connected 199 * - disconnect single STA, still connected
@@ -258,13 +255,16 @@ static void wil_disconnect_worker(struct work_struct *work)
258static void wil_connect_timer_fn(ulong x) 255static void wil_connect_timer_fn(ulong x)
259{ 256{
260 struct wil6210_priv *wil = (void *)x; 257 struct wil6210_priv *wil = (void *)x;
258 bool q;
261 259
262 wil_dbg_misc(wil, "Connect timeout\n"); 260 wil_err(wil, "Connect timeout detected, disconnect station\n");
263 261
264 /* reschedule to thread context - disconnect won't 262 /* reschedule to thread context - disconnect won't
265 * run from atomic context 263 * run from atomic context.
264 * queue on wmi_wq to prevent race with connect event.
266 */ 265 */
267 schedule_work(&wil->disconnect_worker); 266 q = queue_work(wil->wmi_wq, &wil->disconnect_worker);
267 wil_dbg_wmi(wil, "queue_work of disconnect_worker -> %d\n", q);
268} 268}
269 269
270static void wil_scan_timer_fn(ulong x) 270static void wil_scan_timer_fn(ulong x)
@@ -369,6 +369,32 @@ static int wil_find_free_vring(struct wil6210_priv *wil)
369 return -EINVAL; 369 return -EINVAL;
370} 370}
371 371
372int wil_tx_init(struct wil6210_priv *wil, int cid)
373{
374 int rc = -EINVAL, ringid;
375
376 if (cid < 0) {
377 wil_err(wil, "No connection pending\n");
378 goto out;
379 }
380 ringid = wil_find_free_vring(wil);
381 if (ringid < 0) {
382 wil_err(wil, "No free vring found\n");
383 goto out;
384 }
385
386 wil_dbg_wmi(wil, "Configure for connection CID %d vring %d\n",
387 cid, ringid);
388
389 rc = wil_vring_init_tx(wil, ringid, 1 << tx_ring_order, cid, 0);
390 if (rc)
391 wil_err(wil, "wil_vring_init_tx for CID %d vring %d failed\n",
392 cid, ringid);
393
394out:
395 return rc;
396}
397
372int wil_bcast_init(struct wil6210_priv *wil) 398int wil_bcast_init(struct wil6210_priv *wil)
373{ 399{
374 int ri = wil->bcast_vring, rc; 400 int ri = wil->bcast_vring, rc;
@@ -399,41 +425,6 @@ void wil_bcast_fini(struct wil6210_priv *wil)
399 wil_vring_fini_tx(wil, ri); 425 wil_vring_fini_tx(wil, ri);
400} 426}
401 427
402static void wil_connect_worker(struct work_struct *work)
403{
404 int rc, cid, ringid;
405 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
406 connect_worker);
407 struct net_device *ndev = wil_to_ndev(wil);
408
409 mutex_lock(&wil->mutex);
410
411 cid = wil->pending_connect_cid;
412 if (cid < 0) {
413 wil_err(wil, "No connection pending\n");
414 goto out;
415 }
416 ringid = wil_find_free_vring(wil);
417 if (ringid < 0) {
418 wil_err(wil, "No free vring found\n");
419 goto out;
420 }
421
422 wil_dbg_wmi(wil, "Configure for connection CID %d vring %d\n",
423 cid, ringid);
424
425 rc = wil_vring_init_tx(wil, ringid, 1 << tx_ring_order, cid, 0);
426 wil->pending_connect_cid = -1;
427 if (rc == 0) {
428 wil->sta[cid].status = wil_sta_connected;
429 netif_tx_wake_all_queues(ndev);
430 } else {
431 wil_disconnect_cid(wil, cid, WLAN_REASON_UNSPECIFIED, true);
432 }
433out:
434 mutex_unlock(&wil->mutex);
435}
436
437int wil_priv_init(struct wil6210_priv *wil) 428int wil_priv_init(struct wil6210_priv *wil)
438{ 429{
439 uint i; 430 uint i;
@@ -444,6 +435,9 @@ int wil_priv_init(struct wil6210_priv *wil)
444 for (i = 0; i < WIL6210_MAX_CID; i++) 435 for (i = 0; i < WIL6210_MAX_CID; i++)
445 spin_lock_init(&wil->sta[i].tid_rx_lock); 436 spin_lock_init(&wil->sta[i].tid_rx_lock);
446 437
438 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
439 spin_lock_init(&wil->vring_tx_data[i].lock);
440
447 mutex_init(&wil->mutex); 441 mutex_init(&wil->mutex);
448 mutex_init(&wil->wmi_mutex); 442 mutex_init(&wil->wmi_mutex);
449 mutex_init(&wil->back_rx_mutex); 443 mutex_init(&wil->back_rx_mutex);
@@ -453,12 +447,10 @@ int wil_priv_init(struct wil6210_priv *wil)
453 init_completion(&wil->wmi_ready); 447 init_completion(&wil->wmi_ready);
454 init_completion(&wil->wmi_call); 448 init_completion(&wil->wmi_call);
455 449
456 wil->pending_connect_cid = -1;
457 wil->bcast_vring = -1; 450 wil->bcast_vring = -1;
458 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 451 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
459 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil); 452 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil);
460 453
461 INIT_WORK(&wil->connect_worker, wil_connect_worker);
462 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 454 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
463 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 455 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
464 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 456 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
@@ -844,7 +836,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
844 } 836 }
845 837
846 /* init after reset */ 838 /* init after reset */
847 wil->pending_connect_cid = -1;
848 wil->ap_isolate = 0; 839 wil->ap_isolate = 0;
849 reinit_completion(&wil->wmi_ready); 840 reinit_completion(&wil->wmi_ready);
850 reinit_completion(&wil->wmi_call); 841 reinit_completion(&wil->wmi_call);
@@ -948,8 +939,7 @@ int wil_up(struct wil6210_priv *wil)
948 939
949int __wil_down(struct wil6210_priv *wil) 940int __wil_down(struct wil6210_priv *wil)
950{ 941{
951 int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS / 942 int rc;
952 WAIT_FOR_DISCONNECT_INTERVAL_MS;
953 943
954 WARN_ON(!mutex_is_locked(&wil->mutex)); 944 WARN_ON(!mutex_is_locked(&wil->mutex));
955 945
@@ -973,22 +963,16 @@ int __wil_down(struct wil6210_priv *wil)
973 } 963 }
974 964
975 if (test_bit(wil_status_fwconnected, wil->status) || 965 if (test_bit(wil_status_fwconnected, wil->status) ||
976 test_bit(wil_status_fwconnecting, wil->status)) 966 test_bit(wil_status_fwconnecting, wil->status)) {
977 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
978 967
979 /* make sure wil is idle (not connected) */ 968 mutex_unlock(&wil->mutex);
980 mutex_unlock(&wil->mutex); 969 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0,
981 while (iter--) { 970 WMI_DISCONNECT_EVENTID, NULL, 0,
982 int idle = !test_bit(wil_status_fwconnected, wil->status) && 971 WIL6210_DISCONNECT_TO_MS);
983 !test_bit(wil_status_fwconnecting, wil->status); 972 mutex_lock(&wil->mutex);
984 if (idle) 973 if (rc)
985 break; 974 wil_err(wil, "timeout waiting for disconnect\n");
986 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
987 } 975 }
988 mutex_lock(&wil->mutex);
989
990 if (iter < 0)
991 wil_err(wil, "timeout waiting for idle FW/HW\n");
992 976
993 wil_reset(wil, false); 977 wil_reset(wil, false);
994 978
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 56aaa2d4fb0e..ecc3c1bdae4b 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -108,8 +108,9 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
108 /* always process ALL Tx complete, regardless budget - it is fast */ 108 /* always process ALL Tx complete, regardless budget - it is fast */
109 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 109 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
110 struct vring *vring = &wil->vring_tx[i]; 110 struct vring *vring = &wil->vring_tx[i];
111 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
111 112
112 if (!vring->va) 113 if (!vring->va || !txdata->enabled)
113 continue; 114 continue;
114 115
115 tx_done += wil_tx_complete(wil, i); 116 tx_done += wil_tx_complete(wil, i);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 7887e6cfd817..6af20903cf89 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -717,6 +717,21 @@ void wil_rx_fini(struct wil6210_priv *wil)
717 wil_vring_free(wil, vring, 0); 717 wil_vring_free(wil, vring, 0);
718} 718}
719 719
720static inline void wil_tx_data_init(struct vring_tx_data *txdata)
721{
722 spin_lock_bh(&txdata->lock);
723 txdata->dot1x_open = 0;
724 txdata->enabled = 0;
725 txdata->idle = 0;
726 txdata->last_idle = 0;
727 txdata->begin = 0;
728 txdata->agg_wsize = 0;
729 txdata->agg_timeout = 0;
730 txdata->agg_amsdu = 0;
731 txdata->addba_in_progress = false;
732 spin_unlock_bh(&txdata->lock);
733}
734
720int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 735int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
721 int cid, int tid) 736 int cid, int tid)
722{ 737{
@@ -758,8 +773,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
758 goto out; 773 goto out;
759 } 774 }
760 775
761 memset(txdata, 0, sizeof(*txdata)); 776 wil_tx_data_init(txdata);
762 spin_lock_init(&txdata->lock);
763 vring->size = size; 777 vring->size = size;
764 rc = wil_vring_alloc(wil, vring); 778 rc = wil_vring_alloc(wil, vring);
765 if (rc) 779 if (rc)
@@ -791,9 +805,14 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
791 805
792 return 0; 806 return 0;
793 out_free: 807 out_free:
808 spin_lock_bh(&txdata->lock);
794 txdata->dot1x_open = false; 809 txdata->dot1x_open = false;
795 txdata->enabled = 0; 810 txdata->enabled = 0;
811 spin_unlock_bh(&txdata->lock);
796 wil_vring_free(wil, vring, 1); 812 wil_vring_free(wil, vring, 1);
813 wil->vring2cid_tid[id][0] = WIL6210_MAX_CID;
814 wil->vring2cid_tid[id][1] = 0;
815
797 out: 816 out:
798 817
799 return rc; 818 return rc;
@@ -831,8 +850,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
831 goto out; 850 goto out;
832 } 851 }
833 852
834 memset(txdata, 0, sizeof(*txdata)); 853 wil_tx_data_init(txdata);
835 spin_lock_init(&txdata->lock);
836 vring->size = size; 854 vring->size = size;
837 rc = wil_vring_alloc(wil, vring); 855 rc = wil_vring_alloc(wil, vring);
838 if (rc) 856 if (rc)
@@ -862,8 +880,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
862 880
863 return 0; 881 return 0;
864 out_free: 882 out_free:
883 spin_lock_bh(&txdata->lock);
865 txdata->enabled = 0; 884 txdata->enabled = 0;
866 txdata->dot1x_open = false; 885 txdata->dot1x_open = false;
886 spin_unlock_bh(&txdata->lock);
867 wil_vring_free(wil, vring, 1); 887 wil_vring_free(wil, vring, 1);
868 out: 888 out:
869 889
@@ -891,7 +911,6 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
891 napi_synchronize(&wil->napi_tx); 911 napi_synchronize(&wil->napi_tx);
892 912
893 wil_vring_free(wil, vring, 1); 913 wil_vring_free(wil, vring, 1);
894 memset(txdata, 0, sizeof(*txdata));
895} 914}
896 915
897static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, 916static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
@@ -911,10 +930,11 @@ static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
911 continue; 930 continue;
912 if (wil->vring2cid_tid[i][0] == cid) { 931 if (wil->vring2cid_tid[i][0] == cid) {
913 struct vring *v = &wil->vring_tx[i]; 932 struct vring *v = &wil->vring_tx[i];
933 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
914 934
915 wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n", 935 wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n",
916 __func__, eth->h_dest, i); 936 __func__, eth->h_dest, i);
917 if (v->va) { 937 if (v->va && txdata->enabled) {
918 return v; 938 return v;
919 } else { 939 } else {
920 wil_dbg_txrx(wil, "vring[%d] not valid\n", i); 940 wil_dbg_txrx(wil, "vring[%d] not valid\n", i);
@@ -935,6 +955,7 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
935 struct vring *v; 955 struct vring *v;
936 int i; 956 int i;
937 u8 cid; 957 u8 cid;
958 struct vring_tx_data *txdata;
938 959
939 /* In the STA mode, it is expected to have only 1 VRING 960 /* In the STA mode, it is expected to have only 1 VRING
940 * for the AP we connected to. 961 * for the AP we connected to.
@@ -942,7 +963,8 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
942 */ 963 */
943 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 964 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
944 v = &wil->vring_tx[i]; 965 v = &wil->vring_tx[i];
945 if (!v->va) 966 txdata = &wil->vring_tx_data[i];
967 if (!v->va || !txdata->enabled)
946 continue; 968 continue;
947 969
948 cid = wil->vring2cid_tid[i][0]; 970 cid = wil->vring2cid_tid[i][0];
@@ -978,12 +1000,14 @@ static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
978 struct sk_buff *skb) 1000 struct sk_buff *skb)
979{ 1001{
980 struct vring *v; 1002 struct vring *v;
1003 struct vring_tx_data *txdata;
981 int i = wil->bcast_vring; 1004 int i = wil->bcast_vring;
982 1005
983 if (i < 0) 1006 if (i < 0)
984 return NULL; 1007 return NULL;
985 v = &wil->vring_tx[i]; 1008 v = &wil->vring_tx[i];
986 if (!v->va) 1009 txdata = &wil->vring_tx_data[i];
1010 if (!v->va || !txdata->enabled)
987 return NULL; 1011 return NULL;
988 if (!wil->vring_tx_data[i].dot1x_open && 1012 if (!wil->vring_tx_data[i].dot1x_open &&
989 (skb->protocol != cpu_to_be16(ETH_P_PAE))) 1013 (skb->protocol != cpu_to_be16(ETH_P_PAE)))
@@ -1010,11 +1034,13 @@ static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
1010 u8 cid; 1034 u8 cid;
1011 struct ethhdr *eth = (void *)skb->data; 1035 struct ethhdr *eth = (void *)skb->data;
1012 char *src = eth->h_source; 1036 char *src = eth->h_source;
1037 struct vring_tx_data *txdata;
1013 1038
1014 /* find 1-st vring eligible for data */ 1039 /* find 1-st vring eligible for data */
1015 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 1040 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
1016 v = &wil->vring_tx[i]; 1041 v = &wil->vring_tx[i];
1017 if (!v->va) 1042 txdata = &wil->vring_tx_data[i];
1043 if (!v->va || !txdata->enabled)
1018 continue; 1044 continue;
1019 1045
1020 cid = wil->vring2cid_tid[i][0]; 1046 cid = wil->vring2cid_tid[i][0];
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 235e205ce2bc..8427d68b6fa8 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -51,7 +51,7 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
51 51
52#define WIL_TX_Q_LEN_DEFAULT (4000) 52#define WIL_TX_Q_LEN_DEFAULT (4000)
53#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10) 53#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10)
54#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10) 54#define WIL_TX_RING_SIZE_ORDER_DEFAULT (12)
55#define WIL_BCAST_RING_SIZE_ORDER_DEFAULT (7) 55#define WIL_BCAST_RING_SIZE_ORDER_DEFAULT (7)
56#define WIL_BCAST_MCS0_LIMIT (1024) /* limit for MCS0 frame size */ 56#define WIL_BCAST_MCS0_LIMIT (1024) /* limit for MCS0 frame size */
57/* limit ring size in range [32..32k] */ 57/* limit ring size in range [32..32k] */
@@ -92,6 +92,7 @@ static inline u32 wil_mtu2macbuf(u32 mtu)
92#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ 92#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */
93#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) 93#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
94#define WIL6210_SCAN_TO msecs_to_jiffies(10000) 94#define WIL6210_SCAN_TO msecs_to_jiffies(10000)
95#define WIL6210_DISCONNECT_TO_MS (2000)
95#define WIL6210_RX_HIGH_TRSH_INIT (0) 96#define WIL6210_RX_HIGH_TRSH_INIT (0)
96#define WIL6210_RX_HIGH_TRSH_DEFAULT \ 97#define WIL6210_RX_HIGH_TRSH_DEFAULT \
97 (1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3)) 98 (1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
@@ -581,12 +582,10 @@ struct wil6210_priv {
581 struct workqueue_struct *wmi_wq; /* for deferred calls */ 582 struct workqueue_struct *wmi_wq; /* for deferred calls */
582 struct work_struct wmi_event_worker; 583 struct work_struct wmi_event_worker;
583 struct workqueue_struct *wq_service; 584 struct workqueue_struct *wq_service;
584 struct work_struct connect_worker;
585 struct work_struct disconnect_worker; 585 struct work_struct disconnect_worker;
586 struct work_struct fw_error_worker; /* for FW error recovery */ 586 struct work_struct fw_error_worker; /* for FW error recovery */
587 struct timer_list connect_timer; 587 struct timer_list connect_timer;
588 struct timer_list scan_timer; /* detect scan timeout */ 588 struct timer_list scan_timer; /* detect scan timeout */
589 int pending_connect_cid;
590 struct list_head pending_wmi_ev; 589 struct list_head pending_wmi_ev;
591 /* 590 /*
592 * protect pending_wmi_ev 591 * protect pending_wmi_ev
@@ -756,7 +755,8 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
756int wmi_p2p_cfg(struct wil6210_priv *wil, int channel); 755int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
757int wmi_rxon(struct wil6210_priv *wil, bool on); 756int wmi_rxon(struct wil6210_priv *wil, bool on);
758int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 757int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
759int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason); 758int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
759 bool full_disconnect);
760int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout); 760int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
761int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); 761int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
762int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); 762int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
@@ -807,6 +807,7 @@ void wil_rx_fini(struct wil6210_priv *wil);
807int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 807int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
808 int cid, int tid); 808 int cid, int tid);
809void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 809void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
810int wil_tx_init(struct wil6210_priv *wil, int cid);
810int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size); 811int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size);
811int wil_bcast_init(struct wil6210_priv *wil); 812int wil_bcast_init(struct wil6210_priv *wil);
812void wil_bcast_fini(struct wil6210_priv *wil); 813void wil_bcast_fini(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index e3ea74cdd4aa..493e721c4fa7 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 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
@@ -426,6 +426,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
426 const size_t assoc_req_ie_offset = sizeof(u16) * 2; 426 const size_t assoc_req_ie_offset = sizeof(u16) * 2;
427 /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */ 427 /* capinfo(u16) + status_code(u16) + associd(u16) + IEs */
428 const size_t assoc_resp_ie_offset = sizeof(u16) * 3; 428 const size_t assoc_resp_ie_offset = sizeof(u16) * 3;
429 int rc;
429 430
430 if (len < sizeof(*evt)) { 431 if (len < sizeof(*evt)) {
431 wil_err(wil, "Connect event too short : %d bytes\n", len); 432 wil_err(wil, "Connect event too short : %d bytes\n", len);
@@ -445,8 +446,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
445 } 446 }
446 447
447 ch = evt->channel + 1; 448 ch = evt->channel + 1;
448 wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n", 449 wil_info(wil, "Connect %pM channel [%d] cid %d\n",
449 evt->bssid, ch, evt->cid); 450 evt->bssid, ch, evt->cid);
450 wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1, 451 wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
451 evt->assoc_info, len - sizeof(*evt), true); 452 evt->assoc_info, len - sizeof(*evt), true);
452 453
@@ -468,20 +469,67 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
468 assoc_resp_ielen = 0; 469 assoc_resp_ielen = 0;
469 } 470 }
470 471
472 mutex_lock(&wil->mutex);
473 if (test_bit(wil_status_resetting, wil->status) ||
474 !test_bit(wil_status_fwready, wil->status)) {
475 wil_err(wil, "status_resetting, cancel connect event, CID %d\n",
476 evt->cid);
477 mutex_unlock(&wil->mutex);
478 /* no need for cleanup, wil_reset will do that */
479 return;
480 }
481
471 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 482 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
472 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 483 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
473 if (!test_bit(wil_status_fwconnecting, wil->status)) { 484 if (!test_bit(wil_status_fwconnecting, wil->status)) {
474 wil_err(wil, "Not in connecting state\n"); 485 wil_err(wil, "Not in connecting state\n");
486 mutex_unlock(&wil->mutex);
475 return; 487 return;
476 } 488 }
477 del_timer_sync(&wil->connect_timer); 489 del_timer_sync(&wil->connect_timer);
478 cfg80211_connect_result(ndev, evt->bssid, 490 }
479 assoc_req_ie, assoc_req_ielen, 491
480 assoc_resp_ie, assoc_resp_ielen, 492 /* FIXME FW can transmit only ucast frames to peer */
481 WLAN_STATUS_SUCCESS, GFP_KERNEL); 493 /* FIXME real ring_id instead of hard coded 0 */
494 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid);
495 wil->sta[evt->cid].status = wil_sta_conn_pending;
482 496
497 rc = wil_tx_init(wil, evt->cid);
498 if (rc) {
499 wil_err(wil, "%s: config tx vring failed for CID %d, rc (%d)\n",
500 __func__, evt->cid, rc);
501 wmi_disconnect_sta(wil, wil->sta[evt->cid].addr,
502 WLAN_REASON_UNSPECIFIED, false);
503 } else {
504 wil_info(wil, "%s: successful connection to CID %d\n",
505 __func__, evt->cid);
506 }
507
508 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
509 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
510 if (rc) {
511 netif_tx_stop_all_queues(ndev);
512 netif_carrier_off(ndev);
513 wil_err(wil,
514 "%s: cfg80211_connect_result with failure\n",
515 __func__);
516 cfg80211_connect_result(ndev, evt->bssid, NULL, 0,
517 NULL, 0,
518 WLAN_STATUS_UNSPECIFIED_FAILURE,
519 GFP_KERNEL);
520 goto out;
521 } else {
522 cfg80211_connect_result(ndev, evt->bssid,
523 assoc_req_ie, assoc_req_ielen,
524 assoc_resp_ie, assoc_resp_ielen,
525 WLAN_STATUS_SUCCESS,
526 GFP_KERNEL);
527 }
483 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 528 } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
484 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 529 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
530 if (rc)
531 goto out;
532
485 memset(&sinfo, 0, sizeof(sinfo)); 533 memset(&sinfo, 0, sizeof(sinfo));
486 534
487 sinfo.generation = wil->sinfo_gen++; 535 sinfo.generation = wil->sinfo_gen++;
@@ -492,17 +540,21 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
492 } 540 }
493 541
494 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 542 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
543 } else {
544 wil_err(wil, "%s: unhandled iftype %d for CID %d\n",
545 __func__, wdev->iftype, evt->cid);
546 goto out;
495 } 547 }
496 clear_bit(wil_status_fwconnecting, wil->status);
497 set_bit(wil_status_fwconnected, wil->status);
498 548
499 /* FIXME FW can transmit only ucast frames to peer */ 549 wil->sta[evt->cid].status = wil_sta_connected;
500 /* FIXME real ring_id instead of hard coded 0 */ 550 set_bit(wil_status_fwconnected, wil->status);
501 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); 551 netif_tx_wake_all_queues(ndev);
502 wil->sta[evt->cid].status = wil_sta_conn_pending;
503 552
504 wil->pending_connect_cid = evt->cid; 553out:
505 queue_work(wil->wq_service, &wil->connect_worker); 554 if (rc)
555 wil->sta[evt->cid].status = wil_sta_unused;
556 clear_bit(wil_status_fwconnecting, wil->status);
557 mutex_unlock(&wil->mutex);
506} 558}
507 559
508static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 560static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
@@ -511,8 +563,8 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
511 struct wmi_disconnect_event *evt = d; 563 struct wmi_disconnect_event *evt = d;
512 u16 reason_code = le16_to_cpu(evt->protocol_reason_status); 564 u16 reason_code = le16_to_cpu(evt->protocol_reason_status);
513 565
514 wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n", 566 wil_info(wil, "Disconnect %pM reason [proto %d wmi %d]\n",
515 evt->bssid, reason_code, evt->disconnect_reason); 567 evt->bssid, reason_code, evt->disconnect_reason);
516 568
517 wil->sinfo_gen++; 569 wil->sinfo_gen++;
518 570
@@ -727,6 +779,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
727 void __iomem *src; 779 void __iomem *src;
728 ulong flags; 780 ulong flags;
729 unsigned n; 781 unsigned n;
782 unsigned int num_immed_reply = 0;
730 783
731 if (!test_bit(wil_status_mbox_ready, wil->status)) { 784 if (!test_bit(wil_status_mbox_ready, wil->status)) {
732 wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); 785 wil_err(wil, "Reset in progress. Cannot handle WMI event\n");
@@ -736,6 +789,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
736 for (n = 0;; n++) { 789 for (n = 0;; n++) {
737 u16 len; 790 u16 len;
738 bool q; 791 bool q;
792 bool immed_reply = false;
739 793
740 r->head = wil_r(wil, RGF_MBOX + 794 r->head = wil_r(wil, RGF_MBOX +
741 offsetof(struct wil6210_mbox_ctl, rx.head)); 795 offsetof(struct wil6210_mbox_ctl, rx.head));
@@ -784,6 +838,15 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
784 struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi; 838 struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi;
785 u16 id = le16_to_cpu(wmi->id); 839 u16 id = le16_to_cpu(wmi->id);
786 u32 tstamp = le32_to_cpu(wmi->timestamp); 840 u32 tstamp = le32_to_cpu(wmi->timestamp);
841 spin_lock_irqsave(&wil->wmi_ev_lock, flags);
842 if (wil->reply_id && wil->reply_id == id) {
843 if (wil->reply_buf) {
844 memcpy(wil->reply_buf, wmi,
845 min(len, wil->reply_size));
846 immed_reply = true;
847 }
848 }
849 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
787 850
788 wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n", 851 wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n",
789 id, wmi->mid, tstamp); 852 id, wmi->mid, tstamp);
@@ -799,15 +862,24 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
799 wil_w(wil, RGF_MBOX + 862 wil_w(wil, RGF_MBOX +
800 offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail); 863 offsetof(struct wil6210_mbox_ctl, rx.tail), r->tail);
801 864
802 /* add to the pending list */ 865 if (immed_reply) {
803 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 866 wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
804 list_add_tail(&evt->list, &wil->pending_wmi_ev); 867 __func__, wil->reply_id);
805 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 868 kfree(evt);
806 q = queue_work(wil->wmi_wq, &wil->wmi_event_worker); 869 num_immed_reply++;
807 wil_dbg_wmi(wil, "queue_work -> %d\n", q); 870 complete(&wil->wmi_call);
871 } else {
872 /* add to the pending list */
873 spin_lock_irqsave(&wil->wmi_ev_lock, flags);
874 list_add_tail(&evt->list, &wil->pending_wmi_ev);
875 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
876 q = queue_work(wil->wmi_wq, &wil->wmi_event_worker);
877 wil_dbg_wmi(wil, "queue_work -> %d\n", q);
878 }
808 } 879 }
809 /* normally, 1 event per IRQ should be processed */ 880 /* normally, 1 event per IRQ should be processed */
810 wil_dbg_wmi(wil, "%s -> %d events queued\n", __func__, n); 881 wil_dbg_wmi(wil, "%s -> %d events queued, %d completed\n", __func__,
882 n - num_immed_reply, num_immed_reply);
811} 883}
812 884
813int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 885int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
@@ -818,13 +890,16 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
818 890
819 mutex_lock(&wil->wmi_mutex); 891 mutex_lock(&wil->wmi_mutex);
820 892
893 spin_lock(&wil->wmi_ev_lock);
894 wil->reply_id = reply_id;
895 wil->reply_buf = reply;
896 wil->reply_size = reply_size;
897 spin_unlock(&wil->wmi_ev_lock);
898
821 rc = __wmi_send(wil, cmdid, buf, len); 899 rc = __wmi_send(wil, cmdid, buf, len);
822 if (rc) 900 if (rc)
823 goto out; 901 goto out;
824 902
825 wil->reply_id = reply_id;
826 wil->reply_buf = reply;
827 wil->reply_size = reply_size;
828 remain = wait_for_completion_timeout(&wil->wmi_call, 903 remain = wait_for_completion_timeout(&wil->wmi_call,
829 msecs_to_jiffies(to_msec)); 904 msecs_to_jiffies(to_msec));
830 if (0 == remain) { 905 if (0 == remain) {
@@ -837,10 +912,14 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
837 cmdid, reply_id, 912 cmdid, reply_id,
838 to_msec - jiffies_to_msecs(remain)); 913 to_msec - jiffies_to_msecs(remain));
839 } 914 }
915
916out:
917 spin_lock(&wil->wmi_ev_lock);
840 wil->reply_id = 0; 918 wil->reply_id = 0;
841 wil->reply_buf = NULL; 919 wil->reply_buf = NULL;
842 wil->reply_size = 0; 920 wil->reply_size = 0;
843 out: 921 spin_unlock(&wil->wmi_ev_lock);
922
844 mutex_unlock(&wil->wmi_mutex); 923 mutex_unlock(&wil->wmi_mutex);
845 924
846 return rc; 925 return rc;
@@ -1184,7 +1263,8 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
1184 return 0; 1263 return 0;
1185} 1264}
1186 1265
1187int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason) 1266int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
1267 bool full_disconnect)
1188{ 1268{
1189 int rc; 1269 int rc;
1190 u16 reason_code; 1270 u16 reason_code;
@@ -1208,19 +1288,20 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1208 return rc; 1288 return rc;
1209 } 1289 }
1210 1290
1211 /* call event handler manually after processing wmi_call, 1291 if (full_disconnect) {
1212 * to avoid deadlock - disconnect event handler acquires wil->mutex 1292 /* call event handler manually after processing wmi_call,
1213 * while it is already held here 1293 * to avoid deadlock - disconnect event handler acquires
1214 */ 1294 * wil->mutex while it is already held here
1215 reason_code = le16_to_cpu(reply.evt.protocol_reason_status); 1295 */
1216 1296 reason_code = le16_to_cpu(reply.evt.protocol_reason_status);
1217 wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n",
1218 reply.evt.bssid, reason_code,
1219 reply.evt.disconnect_reason);
1220 1297
1221 wil->sinfo_gen++; 1298 wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n",
1222 wil6210_disconnect(wil, reply.evt.bssid, reason_code, true); 1299 reply.evt.bssid, reason_code,
1300 reply.evt.disconnect_reason);
1223 1301
1302 wil->sinfo_gen++;
1303 wil6210_disconnect(wil, reply.evt.bssid, reason_code, true);
1304 }
1224 return 0; 1305 return 0;
1225} 1306}
1226 1307
@@ -1348,14 +1429,11 @@ static void wmi_event_handle(struct wil6210_priv *wil,
1348 id, wil->reply_id); 1429 id, wil->reply_id);
1349 /* check if someone waits for this event */ 1430 /* check if someone waits for this event */
1350 if (wil->reply_id && wil->reply_id == id) { 1431 if (wil->reply_id && wil->reply_id == id) {
1351 if (wil->reply_buf) { 1432 WARN_ON(wil->reply_buf);
1352 memcpy(wil->reply_buf, wmi, 1433 wmi_evt_call_handler(wil, id, evt_data,
1353 min(len, wil->reply_size)); 1434 len - sizeof(*wmi));
1354 } else { 1435 wil_dbg_wmi(wil, "%s: Complete WMI 0x%04x\n",
1355 wmi_evt_call_handler(wil, id, evt_data, 1436 __func__, id);
1356 len - sizeof(*wmi));
1357 }
1358 wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id);
1359 complete(&wil->wmi_call); 1437 complete(&wil->wmi_call);
1360 return; 1438 return;
1361 } 1439 }
diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c
index dab25136214a..1efb1d66e0b7 100644
--- a/drivers/net/wireless/atmel/at76c50x-usb.c
+++ b/drivers/net/wireless/atmel/at76c50x-usb.c
@@ -2481,9 +2481,7 @@ static int at76_probe(struct usb_interface *interface,
2481 dev_err(&interface->dev, 2481 dev_err(&interface->dev,
2482 "error %d downloading internal firmware\n", 2482 "error %d downloading internal firmware\n",
2483 ret); 2483 ret);
2484 goto exit;
2485 } 2484 }
2486 usb_put_dev(udev);
2487 goto exit; 2485 goto exit;
2488 } 2486 }
2489 2487
diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
index c279211e49f9..72380af9dc52 100644
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -4375,12 +4375,10 @@ redo:
4375 /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ 4375 /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
4376 orig_dev = dev; 4376 orig_dev = dev;
4377 mutex_unlock(&wl->mutex); 4377 mutex_unlock(&wl->mutex);
4378 if (b43_bus_host_is_sdio(dev->dev)) { 4378 if (b43_bus_host_is_sdio(dev->dev))
4379 b43_sdio_free_irq(dev); 4379 b43_sdio_free_irq(dev);
4380 } else { 4380 else
4381 synchronize_irq(dev->dev->irq);
4382 free_irq(dev->dev->irq, dev); 4381 free_irq(dev->dev->irq, dev);
4383 }
4384 mutex_lock(&wl->mutex); 4382 mutex_lock(&wl->mutex);
4385 dev = wl->current_dev; 4383 dev = wl->current_dev;
4386 if (!dev) 4384 if (!dev)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index b98db8a0a069..da0cdd313880 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -27,8 +27,6 @@
27#include <linux/mmc/sdio_func.h> 27#include <linux/mmc/sdio_func.h>
28#include <linux/mmc/card.h> 28#include <linux/mmc/card.h>
29#include <linux/mmc/host.h> 29#include <linux/mmc/host.h>
30#include <linux/platform_device.h>
31#include <linux/platform_data/brcmfmac-sdio.h>
32#include <linux/pm_runtime.h> 30#include <linux/pm_runtime.h>
33#include <linux/suspend.h> 31#include <linux/suspend.h>
34#include <linux/errno.h> 32#include <linux/errno.h>
@@ -46,7 +44,6 @@
46#include "bus.h" 44#include "bus.h"
47#include "debug.h" 45#include "debug.h"
48#include "sdio.h" 46#include "sdio.h"
49#include "of.h"
50#include "core.h" 47#include "core.h"
51#include "common.h" 48#include "common.h"
52 49
@@ -106,18 +103,18 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)
106 103
107int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) 104int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
108{ 105{
106 struct brcmfmac_sdio_pd *pdata;
109 int ret = 0; 107 int ret = 0;
110 u8 data; 108 u8 data;
111 u32 addr, gpiocontrol; 109 u32 addr, gpiocontrol;
112 unsigned long flags; 110 unsigned long flags;
113 111
114 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { 112 pdata = &sdiodev->settings->bus.sdio;
113 if (pdata->oob_irq_supported) {
115 brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", 114 brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
116 sdiodev->pdata->oob_irq_nr); 115 pdata->oob_irq_nr);
117 ret = request_irq(sdiodev->pdata->oob_irq_nr, 116 ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
118 brcmf_sdiod_oob_irqhandler, 117 pdata->oob_irq_flags, "brcmf_oob_intr",
119 sdiodev->pdata->oob_irq_flags,
120 "brcmf_oob_intr",
121 &sdiodev->func[1]->dev); 118 &sdiodev->func[1]->dev);
122 if (ret != 0) { 119 if (ret != 0) {
123 brcmf_err("request_irq failed %d\n", ret); 120 brcmf_err("request_irq failed %d\n", ret);
@@ -129,7 +126,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
129 sdiodev->irq_en = true; 126 sdiodev->irq_en = true;
130 spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); 127 spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
131 128
132 ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr); 129 ret = enable_irq_wake(pdata->oob_irq_nr);
133 if (ret != 0) { 130 if (ret != 0) {
134 brcmf_err("enable_irq_wake failed %d\n", ret); 131 brcmf_err("enable_irq_wake failed %d\n", ret);
135 return ret; 132 return ret;
@@ -158,7 +155,7 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
158 155
159 /* redirect, configure and enable io for interrupt signal */ 156 /* redirect, configure and enable io for interrupt signal */
160 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; 157 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
161 if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) 158 if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
162 data |= SDIO_SEPINT_ACT_HI; 159 data |= SDIO_SEPINT_ACT_HI;
163 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); 160 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
164 161
@@ -176,9 +173,12 @@ int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
176 173
177int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) 174int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
178{ 175{
176 struct brcmfmac_sdio_pd *pdata;
177
179 brcmf_dbg(SDIO, "Entering\n"); 178 brcmf_dbg(SDIO, "Entering\n");
180 179
181 if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { 180 pdata = &sdiodev->settings->bus.sdio;
181 if (pdata->oob_irq_supported) {
182 sdio_claim_host(sdiodev->func[1]); 182 sdio_claim_host(sdiodev->func[1]);
183 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); 183 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
184 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); 184 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
@@ -187,11 +187,10 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev)
187 if (sdiodev->oob_irq_requested) { 187 if (sdiodev->oob_irq_requested) {
188 sdiodev->oob_irq_requested = false; 188 sdiodev->oob_irq_requested = false;
189 if (sdiodev->irq_wake) { 189 if (sdiodev->irq_wake) {
190 disable_irq_wake(sdiodev->pdata->oob_irq_nr); 190 disable_irq_wake(pdata->oob_irq_nr);
191 sdiodev->irq_wake = false; 191 sdiodev->irq_wake = false;
192 } 192 }
193 free_irq(sdiodev->pdata->oob_irq_nr, 193 free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev);
194 &sdiodev->func[1]->dev);
195 sdiodev->irq_en = false; 194 sdiodev->irq_en = false;
196 } 195 }
197 } else { 196 } else {
@@ -523,7 +522,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
523 target_list = pktlist; 522 target_list = pktlist;
524 /* for host with broken sg support, prepare a page aligned list */ 523 /* for host with broken sg support, prepare a page aligned list */
525 __skb_queue_head_init(&local_list); 524 __skb_queue_head_init(&local_list);
526 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { 525 if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {
527 req_sz = 0; 526 req_sz = 0;
528 skb_queue_walk(pktlist, pkt_next) 527 skb_queue_walk(pktlist, pkt_next)
529 req_sz += pkt_next->len; 528 req_sz += pkt_next->len;
@@ -630,7 +629,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
630 } 629 }
631 } 630 }
632 631
633 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { 632 if (!write && sdiodev->settings->bus.sdio.broken_sg_support) {
634 local_pkt_next = local_list.next; 633 local_pkt_next = local_list.next;
635 orig_offset = 0; 634 orig_offset = 0;
636 skb_queue_walk(pktlist, pkt_next) { 635 skb_queue_walk(pktlist, pkt_next) {
@@ -901,7 +900,7 @@ void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
901 return; 900 return;
902 901
903 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, 902 nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,
904 sdiodev->bus_if->drvr->settings->sdiod_txglomsz); 903 sdiodev->settings->bus.sdio.txglomsz);
905 nents += (nents >> 4) + 1; 904 nents += (nents >> 4) + 1;
906 905
907 WARN_ON(nents > sdiodev->max_segment_count); 906 WARN_ON(nents > sdiodev->max_segment_count);
@@ -913,7 +912,7 @@ void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
913 sdiodev->sg_support = false; 912 sdiodev->sg_support = false;
914 } 913 }
915 914
916 sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz; 915 sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz;
917} 916}
918 917
919#ifdef CONFIG_PM_SLEEP 918#ifdef CONFIG_PM_SLEEP
@@ -1103,8 +1102,6 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
1103}; 1102};
1104MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 1103MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
1105 1104
1106static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata;
1107
1108 1105
1109static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev, 1106static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev,
1110 int val) 1107 int val)
@@ -1167,20 +1164,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1167 dev_set_drvdata(&func->dev, bus_if); 1164 dev_set_drvdata(&func->dev, bus_if);
1168 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); 1165 dev_set_drvdata(&sdiodev->func[1]->dev, bus_if);
1169 sdiodev->dev = &sdiodev->func[1]->dev; 1166 sdiodev->dev = &sdiodev->func[1]->dev;
1170 sdiodev->pdata = brcmfmac_sdio_pdata;
1171
1172 if (!sdiodev->pdata)
1173 brcmf_of_probe(sdiodev);
1174
1175#ifdef CONFIG_PM_SLEEP
1176 /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
1177 * is true or when platform data OOB irq is true).
1178 */
1179 if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
1180 ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
1181 (sdiodev->pdata && sdiodev->pdata->oob_irq_supported)))
1182 bus_if->wowl_supported = true;
1183#endif
1184 1167
1185 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); 1168 brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN);
1186 1169
@@ -1263,8 +1246,8 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1263 1246
1264 sdio_flags = MMC_PM_KEEP_POWER; 1247 sdio_flags = MMC_PM_KEEP_POWER;
1265 if (sdiodev->wowl_enabled) { 1248 if (sdiodev->wowl_enabled) {
1266 if (sdiodev->pdata->oob_irq_supported) 1249 if (sdiodev->settings->bus.sdio.oob_irq_supported)
1267 enable_irq_wake(sdiodev->pdata->oob_irq_nr); 1250 enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
1268 else 1251 else
1269 sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; 1252 sdio_flags |= MMC_PM_WAKE_SDIO_IRQ;
1270 } 1253 }
@@ -1296,7 +1279,7 @@ static const struct dev_pm_ops brcmf_sdio_pm_ops = {
1296static struct sdio_driver brcmf_sdmmc_driver = { 1279static struct sdio_driver brcmf_sdmmc_driver = {
1297 .probe = brcmf_ops_sdio_probe, 1280 .probe = brcmf_ops_sdio_probe,
1298 .remove = brcmf_ops_sdio_remove, 1281 .remove = brcmf_ops_sdio_remove,
1299 .name = BRCMFMAC_SDIO_PDATA_NAME, 1282 .name = KBUILD_MODNAME,
1300 .id_table = brcmf_sdmmc_ids, 1283 .id_table = brcmf_sdmmc_ids,
1301 .drv = { 1284 .drv = {
1302 .owner = THIS_MODULE, 1285 .owner = THIS_MODULE,
@@ -1306,37 +1289,6 @@ static struct sdio_driver brcmf_sdmmc_driver = {
1306 }, 1289 },
1307}; 1290};
1308 1291
1309static int __init brcmf_sdio_pd_probe(struct platform_device *pdev)
1310{
1311 brcmf_dbg(SDIO, "Enter\n");
1312
1313 brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev);
1314
1315 if (brcmfmac_sdio_pdata->power_on)
1316 brcmfmac_sdio_pdata->power_on();
1317
1318 return 0;
1319}
1320
1321static int brcmf_sdio_pd_remove(struct platform_device *pdev)
1322{
1323 brcmf_dbg(SDIO, "Enter\n");
1324
1325 if (brcmfmac_sdio_pdata->power_off)
1326 brcmfmac_sdio_pdata->power_off();
1327
1328 sdio_unregister_driver(&brcmf_sdmmc_driver);
1329
1330 return 0;
1331}
1332
1333static struct platform_driver brcmf_sdio_pd = {
1334 .remove = brcmf_sdio_pd_remove,
1335 .driver = {
1336 .name = BRCMFMAC_SDIO_PDATA_NAME,
1337 }
1338};
1339
1340void brcmf_sdio_register(void) 1292void brcmf_sdio_register(void)
1341{ 1293{
1342 int ret; 1294 int ret;
@@ -1350,19 +1302,6 @@ void brcmf_sdio_exit(void)
1350{ 1302{
1351 brcmf_dbg(SDIO, "Enter\n"); 1303 brcmf_dbg(SDIO, "Enter\n");
1352 1304
1353 if (brcmfmac_sdio_pdata) 1305 sdio_unregister_driver(&brcmf_sdmmc_driver);
1354 platform_driver_unregister(&brcmf_sdio_pd);
1355 else
1356 sdio_unregister_driver(&brcmf_sdmmc_driver);
1357} 1306}
1358 1307
1359void __init brcmf_sdio_init(void)
1360{
1361 int ret;
1362
1363 brcmf_dbg(SDIO, "Enter\n");
1364
1365 ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
1366 if (ret == -ENODEV)
1367 brcmf_dbg(SDIO, "No platform data available.\n");
1368}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
index 36093f93bfbe..8e02a478e889 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -43,6 +43,8 @@ enum brcmf_bus_protocol_type {
43 BRCMF_PROTO_MSGBUF 43 BRCMF_PROTO_MSGBUF
44}; 44};
45 45
46struct brcmf_mp_device;
47
46struct brcmf_bus_dcmd { 48struct brcmf_bus_dcmd {
47 char *name; 49 char *name;
48 char *param; 50 char *param;
@@ -217,7 +219,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
217void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); 219void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
218 220
219/* Indication from bus module regarding presence/insertion of dongle. */ 221/* Indication from bus module regarding presence/insertion of dongle. */
220int brcmf_attach(struct device *dev); 222int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings);
221/* Indication from bus module regarding removal/absence of dongle */ 223/* Indication from bus module regarding removal/absence of dongle */
222void brcmf_detach(struct device *dev); 224void brcmf_detach(struct device *dev);
223/* Indication from bus module that dongle should be reset */ 225/* Indication from bus module that dongle should be reset */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index d00c5c1d58bf..d5c2a27573b4 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -72,8 +72,13 @@
72#define RSN_AKM_NONE 0 /* None (IBSS) */ 72#define RSN_AKM_NONE 0 /* None (IBSS) */
73#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ 73#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74#define RSN_AKM_PSK 2 /* Pre-shared Key */ 74#define RSN_AKM_PSK 2 /* Pre-shared Key */
75#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
76#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
75#define RSN_CAP_LEN 2 /* Length of RSN capabilities */ 77#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
76#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C 78#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
79#define RSN_CAP_MFPR_MASK BIT(6)
80#define RSN_CAP_MFPC_MASK BIT(7)
81#define RSN_PMKID_COUNT_LEN 2
77 82
78#define VNDR_IE_CMD_LEN 4 /* length of the set command 83#define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL) 84 * string :"add", "del" (+ NUL)
@@ -211,12 +216,19 @@ static const struct ieee80211_regdomain brcmf_regdom = {
211 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } 216 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
212}; 217};
213 218
214static const u32 __wl_cipher_suites[] = { 219/* Note: brcmf_cipher_suites is an array of int defining which cipher suites
220 * are supported. A pointer to this array and the number of entries is passed
221 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
222 * So the cipher suite AES_CMAC has to be the last one in the array, and when
223 * device does not support MFP then the number of suites will be decreased by 1
224 */
225static const u32 brcmf_cipher_suites[] = {
215 WLAN_CIPHER_SUITE_WEP40, 226 WLAN_CIPHER_SUITE_WEP40,
216 WLAN_CIPHER_SUITE_WEP104, 227 WLAN_CIPHER_SUITE_WEP104,
217 WLAN_CIPHER_SUITE_TKIP, 228 WLAN_CIPHER_SUITE_TKIP,
218 WLAN_CIPHER_SUITE_CCMP, 229 WLAN_CIPHER_SUITE_CCMP,
219 WLAN_CIPHER_SUITE_AES_CMAC, 230 /* Keep as last entry: */
231 WLAN_CIPHER_SUITE_AES_CMAC
220}; 232};
221 233
222/* Vendor specific ie. id = 221, oui and type defines exact ie */ 234/* Vendor specific ie. id = 221, oui and type defines exact ie */
@@ -456,7 +468,7 @@ send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
456} 468}
457 469
458static s32 470static s32
459brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) 471brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
460{ 472{
461 s32 err; 473 s32 err;
462 u32 mode; 474 u32 mode;
@@ -484,6 +496,15 @@ brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
484 enable, mode); 496 enable, mode);
485 } 497 }
486 498
499 err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
500 if (err) {
501 brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
502 enable, err);
503 err = 0;
504 } else
505 brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
506 enable, mode);
507
487 return err; 508 return err;
488} 509}
489 510
@@ -564,8 +585,8 @@ struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
564 } 585 }
565 586
566 /* wait for firmware event */ 587 /* wait for firmware event */
567 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, 588 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
568 BRCMF_VIF_EVENT_TIMEOUT); 589 BRCMF_VIF_EVENT_TIMEOUT);
569 brcmf_cfg80211_arm_vif_event(cfg, NULL); 590 brcmf_cfg80211_arm_vif_event(cfg, NULL);
570 if (!err) { 591 if (!err) {
571 brcmf_err("timeout occurred\n"); 592 brcmf_err("timeout occurred\n");
@@ -1125,7 +1146,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1125 1146
1126 /* Arm scan timeout timer */ 1147 /* Arm scan timeout timer */
1127 mod_timer(&cfg->escan_timeout, jiffies + 1148 mod_timer(&cfg->escan_timeout, jiffies +
1128 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); 1149 BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1129 1150
1130 return 0; 1151 return 0;
1131 1152
@@ -1524,7 +1545,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1524 1545
1525static s32 1546static s32
1526brcmf_set_wsec_mode(struct net_device *ndev, 1547brcmf_set_wsec_mode(struct net_device *ndev,
1527 struct cfg80211_connect_params *sme, bool mfp) 1548 struct cfg80211_connect_params *sme)
1528{ 1549{
1529 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); 1550 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1530 struct brcmf_cfg80211_security *sec; 1551 struct brcmf_cfg80211_security *sec;
@@ -1583,10 +1604,7 @@ brcmf_set_wsec_mode(struct net_device *ndev,
1583 sme->privacy) 1604 sme->privacy)
1584 pval = AES_ENABLED; 1605 pval = AES_ENABLED;
1585 1606
1586 if (mfp) 1607 wsec = pval | gval;
1587 wsec = pval | gval | MFP_CAPABLE;
1588 else
1589 wsec = pval | gval;
1590 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec); 1608 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1591 if (err) { 1609 if (err) {
1592 brcmf_err("error (%d)\n", err); 1610 brcmf_err("error (%d)\n", err);
@@ -1603,56 +1621,100 @@ brcmf_set_wsec_mode(struct net_device *ndev,
1603static s32 1621static s32
1604brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) 1622brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1605{ 1623{
1606 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); 1624 struct brcmf_if *ifp = netdev_priv(ndev);
1607 struct brcmf_cfg80211_security *sec; 1625 s32 val;
1608 s32 val = 0; 1626 s32 err;
1609 s32 err = 0; 1627 const struct brcmf_tlv *rsn_ie;
1628 const u8 *ie;
1629 u32 ie_len;
1630 u32 offset;
1631 u16 rsn_cap;
1632 u32 mfp;
1633 u16 count;
1610 1634
1611 if (sme->crypto.n_akm_suites) { 1635 if (!sme->crypto.n_akm_suites)
1612 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), 1636 return 0;
1613 "wpa_auth", &val); 1637
1614 if (err) { 1638 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1615 brcmf_err("could not get wpa_auth (%d)\n", err); 1639 if (err) {
1616 return err; 1640 brcmf_err("could not get wpa_auth (%d)\n", err);
1641 return err;
1642 }
1643 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1644 switch (sme->crypto.akm_suites[0]) {
1645 case WLAN_AKM_SUITE_8021X:
1646 val = WPA_AUTH_UNSPECIFIED;
1647 break;
1648 case WLAN_AKM_SUITE_PSK:
1649 val = WPA_AUTH_PSK;
1650 break;
1651 default:
1652 brcmf_err("invalid cipher group (%d)\n",
1653 sme->crypto.cipher_group);
1654 return -EINVAL;
1617 } 1655 }
1618 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { 1656 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1619 switch (sme->crypto.akm_suites[0]) { 1657 switch (sme->crypto.akm_suites[0]) {
1620 case WLAN_AKM_SUITE_8021X: 1658 case WLAN_AKM_SUITE_8021X:
1621 val = WPA_AUTH_UNSPECIFIED; 1659 val = WPA2_AUTH_UNSPECIFIED;
1622 break; 1660 break;
1623 case WLAN_AKM_SUITE_PSK: 1661 case WLAN_AKM_SUITE_8021X_SHA256:
1624 val = WPA_AUTH_PSK; 1662 val = WPA2_AUTH_1X_SHA256;
1625 break; 1663 break;
1626 default: 1664 case WLAN_AKM_SUITE_PSK_SHA256:
1627 brcmf_err("invalid cipher group (%d)\n", 1665 val = WPA2_AUTH_PSK_SHA256;
1628 sme->crypto.cipher_group); 1666 break;
1629 return -EINVAL; 1667 case WLAN_AKM_SUITE_PSK:
1630 } 1668 val = WPA2_AUTH_PSK;
1631 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { 1669 break;
1632 switch (sme->crypto.akm_suites[0]) { 1670 default:
1633 case WLAN_AKM_SUITE_8021X: 1671 brcmf_err("invalid cipher group (%d)\n",
1634 val = WPA2_AUTH_UNSPECIFIED; 1672 sme->crypto.cipher_group);
1635 break; 1673 return -EINVAL;
1636 case WLAN_AKM_SUITE_PSK:
1637 val = WPA2_AUTH_PSK;
1638 break;
1639 default:
1640 brcmf_err("invalid cipher group (%d)\n",
1641 sme->crypto.cipher_group);
1642 return -EINVAL;
1643 }
1644 } 1674 }
1675 }
1645 1676
1646 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); 1677 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1647 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), 1678 goto skip_mfp_config;
1648 "wpa_auth", val); 1679 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
1649 if (err) { 1680 * IE will not be verified, just a quick search for MFP config
1650 brcmf_err("could not set wpa_auth (%d)\n", err); 1681 */
1651 return err; 1682 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1652 } 1683 WLAN_EID_RSN);
1684 if (!rsn_ie)
1685 goto skip_mfp_config;
1686 ie = (const u8 *)rsn_ie;
1687 ie_len = rsn_ie->len + TLV_HDR_LEN;
1688 /* Skip unicast suite */
1689 offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1690 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1691 goto skip_mfp_config;
1692 /* Skip multicast suite */
1693 count = ie[offset] + (ie[offset + 1] << 8);
1694 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1695 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1696 goto skip_mfp_config;
1697 /* Skip auth key management suite(s) */
1698 count = ie[offset] + (ie[offset + 1] << 8);
1699 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1700 if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1701 goto skip_mfp_config;
1702 /* Ready to read capabilities */
1703 mfp = BRCMF_MFP_NONE;
1704 rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1705 if (rsn_cap & RSN_CAP_MFPR_MASK)
1706 mfp = BRCMF_MFP_REQUIRED;
1707 else if (rsn_cap & RSN_CAP_MFPC_MASK)
1708 mfp = BRCMF_MFP_CAPABLE;
1709 brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1710
1711skip_mfp_config:
1712 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1713 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1714 if (err) {
1715 brcmf_err("could not set wpa_auth (%d)\n", err);
1716 return err;
1653 } 1717 }
1654 sec = &profile->sec;
1655 sec->wpa_auth = sme->crypto.akm_suites[0];
1656 1718
1657 return err; 1719 return err;
1658} 1720}
@@ -1818,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1818 goto done; 1880 goto done;
1819 } 1881 }
1820 1882
1821 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED); 1883 err = brcmf_set_wsec_mode(ndev, sme);
1822 if (err) { 1884 if (err) {
1823 brcmf_err("wl_set_set_cipher failed (%d)\n", err); 1885 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1824 goto done; 1886 goto done;
@@ -2064,98 +2126,54 @@ done:
2064} 2126}
2065 2127
2066static s32 2128static s32
2067brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, 2129brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2068 u8 key_idx, const u8 *mac_addr, struct key_params *params) 2130 u8 key_idx, bool pairwise, const u8 *mac_addr)
2069{ 2131{
2070 struct brcmf_if *ifp = netdev_priv(ndev); 2132 struct brcmf_if *ifp = netdev_priv(ndev);
2071 struct brcmf_wsec_key key; 2133 struct brcmf_wsec_key *key;
2072 s32 err = 0; 2134 s32 err;
2073 u8 keybuf[8];
2074 2135
2075 memset(&key, 0, sizeof(key)); 2136 brcmf_dbg(TRACE, "Enter\n");
2076 key.index = (u32) key_idx; 2137 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2077 /* Instead of bcast for ea address for default wep keys,
2078 driver needs it to be Null */
2079 if (!is_multicast_ether_addr(mac_addr))
2080 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2081 key.len = (u32) params->key_len;
2082 /* check for key index change */
2083 if (key.len == 0) {
2084 /* key delete */
2085 err = send_key_to_dongle(ifp, &key);
2086 if (err)
2087 brcmf_err("key delete error (%d)\n", err);
2088 } else {
2089 if (key.len > sizeof(key.data)) {
2090 brcmf_err("Invalid key length (%d)\n", key.len);
2091 return -EINVAL;
2092 }
2093 2138
2094 brcmf_dbg(CONN, "Setting the key index %d\n", key.index); 2139 if (!check_vif_up(ifp->vif))
2095 memcpy(key.data, params->key, key.len); 2140 return -EIO;
2096 2141
2097 if (!brcmf_is_apmode(ifp->vif) && 2142 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2098 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { 2143 /* we ignore this key index in this case */
2099 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); 2144 return -EINVAL;
2100 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2145 }
2101 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2102 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2103 }
2104 2146
2105 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ 2147 key = &ifp->vif->profile.key[key_idx];
2106 if (params->seq && params->seq_len == 6) {
2107 /* rx iv */
2108 u8 *ivptr;
2109 ivptr = (u8 *) params->seq;
2110 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2111 (ivptr[3] << 8) | ivptr[2];
2112 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2113 key.iv_initialized = true;
2114 }
2115 2148
2116 switch (params->cipher) { 2149 if (key->algo == CRYPTO_ALGO_OFF) {
2117 case WLAN_CIPHER_SUITE_WEP40: 2150 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2118 key.algo = CRYPTO_ALGO_WEP1; 2151 return -EINVAL;
2119 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2120 break;
2121 case WLAN_CIPHER_SUITE_WEP104:
2122 key.algo = CRYPTO_ALGO_WEP128;
2123 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2124 break;
2125 case WLAN_CIPHER_SUITE_TKIP:
2126 key.algo = CRYPTO_ALGO_TKIP;
2127 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2128 break;
2129 case WLAN_CIPHER_SUITE_AES_CMAC:
2130 key.algo = CRYPTO_ALGO_AES_CCM;
2131 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2132 break;
2133 case WLAN_CIPHER_SUITE_CCMP:
2134 key.algo = CRYPTO_ALGO_AES_CCM;
2135 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2136 break;
2137 default:
2138 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2139 return -EINVAL;
2140 }
2141 err = send_key_to_dongle(ifp, &key);
2142 if (err)
2143 brcmf_err("wsec_key error (%d)\n", err);
2144 } 2152 }
2153
2154 memset(key, 0, sizeof(*key));
2155 key->index = (u32)key_idx;
2156 key->flags = BRCMF_PRIMARY_KEY;
2157
2158 /* Clear the key/index */
2159 err = send_key_to_dongle(ifp, key);
2160
2161 brcmf_dbg(TRACE, "Exit\n");
2145 return err; 2162 return err;
2146} 2163}
2147 2164
2148static s32 2165static s32
2149brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 2166brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2150 u8 key_idx, bool pairwise, const u8 *mac_addr, 2167 u8 key_idx, bool pairwise, const u8 *mac_addr,
2151 struct key_params *params) 2168 struct key_params *params)
2152{ 2169{
2153 struct brcmf_if *ifp = netdev_priv(ndev); 2170 struct brcmf_if *ifp = netdev_priv(ndev);
2154 struct brcmf_wsec_key *key; 2171 struct brcmf_wsec_key *key;
2155 s32 val; 2172 s32 val;
2156 s32 wsec; 2173 s32 wsec;
2157 s32 err = 0; 2174 s32 err;
2158 u8 keybuf[8]; 2175 u8 keybuf[8];
2176 bool ext_key;
2159 2177
2160 brcmf_dbg(TRACE, "Enter\n"); 2178 brcmf_dbg(TRACE, "Enter\n");
2161 brcmf_dbg(CONN, "key index (%d)\n", key_idx); 2179 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
@@ -2168,27 +2186,32 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2168 return -EINVAL; 2186 return -EINVAL;
2169 } 2187 }
2170 2188
2171 if (mac_addr && 2189 if (params->key_len == 0)
2172 (params->cipher != WLAN_CIPHER_SUITE_WEP40) && 2190 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2173 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { 2191 mac_addr);
2174 brcmf_dbg(TRACE, "Exit");
2175 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2176 }
2177
2178 key = &ifp->vif->profile.key[key_idx];
2179 memset(key, 0, sizeof(*key));
2180 2192
2181 if (params->key_len > sizeof(key->data)) { 2193 if (params->key_len > sizeof(key->data)) {
2182 brcmf_err("Too long key length (%u)\n", params->key_len); 2194 brcmf_err("Too long key length (%u)\n", params->key_len);
2183 err = -EINVAL; 2195 return -EINVAL;
2184 goto done; 2196 }
2197
2198 ext_key = false;
2199 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2200 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2201 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2202 ext_key = true;
2185 } 2203 }
2204
2205 key = &ifp->vif->profile.key[key_idx];
2206 memset(key, 0, sizeof(*key));
2207 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2208 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2186 key->len = params->key_len; 2209 key->len = params->key_len;
2187 key->index = key_idx; 2210 key->index = key_idx;
2188
2189 memcpy(key->data, params->key, key->len); 2211 memcpy(key->data, params->key, key->len);
2212 if (!ext_key)
2213 key->flags = BRCMF_PRIMARY_KEY;
2190 2214
2191 key->flags = BRCMF_PRIMARY_KEY;
2192 switch (params->cipher) { 2215 switch (params->cipher) {
2193 case WLAN_CIPHER_SUITE_WEP40: 2216 case WLAN_CIPHER_SUITE_WEP40:
2194 key->algo = CRYPTO_ALGO_WEP1; 2217 key->algo = CRYPTO_ALGO_WEP1;
@@ -2228,7 +2251,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2228 } 2251 }
2229 2252
2230 err = send_key_to_dongle(ifp, key); 2253 err = send_key_to_dongle(ifp, key);
2231 if (err) 2254 if (ext_key || err)
2232 goto done; 2255 goto done;
2233 2256
2234 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); 2257 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
@@ -2249,41 +2272,10 @@ done:
2249} 2272}
2250 2273
2251static s32 2274static s32
2252brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, 2275brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2253 u8 key_idx, bool pairwise, const u8 *mac_addr) 2276 bool pairwise, const u8 *mac_addr, void *cookie,
2254{ 2277 void (*callback)(void *cookie,
2255 struct brcmf_if *ifp = netdev_priv(ndev); 2278 struct key_params *params))
2256 struct brcmf_wsec_key key;
2257 s32 err = 0;
2258
2259 brcmf_dbg(TRACE, "Enter\n");
2260 if (!check_vif_up(ifp->vif))
2261 return -EIO;
2262
2263 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2264 /* we ignore this key index in this case */
2265 return -EINVAL;
2266 }
2267
2268 memset(&key, 0, sizeof(key));
2269
2270 key.index = (u32) key_idx;
2271 key.flags = BRCMF_PRIMARY_KEY;
2272 key.algo = CRYPTO_ALGO_OFF;
2273
2274 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2275
2276 /* Set the new key/index */
2277 err = send_key_to_dongle(ifp, &key);
2278
2279 brcmf_dbg(TRACE, "Exit\n");
2280 return err;
2281}
2282
2283static s32
2284brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2285 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2286 void (*callback) (void *cookie, struct key_params * params))
2287{ 2279{
2288 struct key_params params; 2280 struct key_params params;
2289 struct brcmf_if *ifp = netdev_priv(ndev); 2281 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -2335,8 +2327,15 @@ done:
2335 2327
2336static s32 2328static s32
2337brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, 2329brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2338 struct net_device *ndev, u8 key_idx) 2330 struct net_device *ndev, u8 key_idx)
2339{ 2331{
2332 struct brcmf_if *ifp = netdev_priv(ndev);
2333
2334 brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2335
2336 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2337 return 0;
2338
2340 brcmf_dbg(INFO, "Not supported\n"); 2339 brcmf_dbg(INFO, "Not supported\n");
2341 2340
2342 return -EOPNOTSUPP; 2341 return -EOPNOTSUPP;
@@ -3020,7 +3019,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3020 3019
3021 list = (struct brcmf_scan_results *) 3020 list = (struct brcmf_scan_results *)
3022 cfg->escan_info.escan_buf; 3021 cfg->escan_info.escan_buf;
3023 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) { 3022 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3024 brcmf_err("Buffer is too small: ignoring\n"); 3023 brcmf_err("Buffer is too small: ignoring\n");
3025 goto exit; 3024 goto exit;
3026 } 3025 }
@@ -3033,8 +3032,8 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3033 bss_info_le)) 3032 bss_info_le))
3034 goto exit; 3033 goto exit;
3035 } 3034 }
3036 memcpy(&(cfg->escan_info.escan_buf[list->buflen]), 3035 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3037 bss_info_le, bi_length); 3036 bi_length);
3038 list->version = le32_to_cpu(bss_info_le->version); 3037 list->version = le32_to_cpu(bss_info_le->version);
3039 list->buflen += bi_length; 3038 list->buflen += bi_length;
3040 list->count++; 3039 list->count++;
@@ -3092,6 +3091,11 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3092 3091
3093 brcmf_dbg(SCAN, "Enter\n"); 3092 brcmf_dbg(SCAN, "Enter\n");
3094 3093
3094 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3095 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3096 return 0;
3097 }
3098
3095 if (e->event_code == BRCMF_E_PFN_NET_LOST) { 3099 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3096 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n"); 3100 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3097 return 0; 3101 return 0;
@@ -3415,6 +3419,11 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3415 3419
3416 brcmf_dbg(SCAN, "Enter\n"); 3420 brcmf_dbg(SCAN, "Enter\n");
3417 3421
3422 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3423 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3424 return 0;
3425 }
3426
3418 pfn_result = (struct brcmf_pno_scanresults_le *)data; 3427 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3419 3428
3420 if (e->event_code == BRCMF_E_PFN_NET_LOST) { 3429 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
@@ -3507,6 +3516,10 @@ static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3507 else 3516 else
3508 wakeup_data.net_detect = cfg->wowl.nd_info; 3517 wakeup_data.net_detect = cfg->wowl.nd_info;
3509 } 3518 }
3519 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3520 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3521 wakeup_data.gtk_rekey_failure = true;
3522 }
3510 } else { 3523 } else {
3511 wakeup = NULL; 3524 wakeup = NULL;
3512 } 3525 }
@@ -3533,7 +3546,8 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3533 brcmf_report_wowl_wakeind(wiphy, ifp); 3546 brcmf_report_wowl_wakeind(wiphy, ifp);
3534 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); 3547 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3535 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); 3548 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3536 brcmf_configure_arp_offload(ifp, true); 3549 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3550 brcmf_configure_arp_nd_offload(ifp, true);
3537 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, 3551 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3538 cfg->wowl.pre_pmmode); 3552 cfg->wowl.pre_pmmode);
3539 cfg->wowl.active = false; 3553 cfg->wowl.active = false;
@@ -3557,7 +3571,8 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3557 3571
3558 brcmf_dbg(TRACE, "Suspend, wowl config.\n"); 3572 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3559 3573
3560 brcmf_configure_arp_offload(ifp, false); 3574 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3575 brcmf_configure_arp_nd_offload(ifp, false);
3561 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); 3576 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3562 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); 3577 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3563 3578
@@ -3588,6 +3603,8 @@ static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3588 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, 3603 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3589 brcmf_wowl_nd_results); 3604 brcmf_wowl_nd_results);
3590 } 3605 }
3606 if (wowl->gtk_rekey_failure)
3607 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3591 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) 3608 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3592 wowl_config |= BRCMF_WOWL_UNASSOC; 3609 wowl_config |= BRCMF_WOWL_UNASSOC;
3593 3610
@@ -3818,7 +3835,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
3818 u32 auth = 0; /* d11 open authentication */ 3835 u32 auth = 0; /* d11 open authentication */
3819 u16 count; 3836 u16 count;
3820 s32 err = 0; 3837 s32 err = 0;
3821 s32 len = 0; 3838 s32 len;
3822 u32 i; 3839 u32 i;
3823 u32 wsec; 3840 u32 wsec;
3824 u32 pval = 0; 3841 u32 pval = 0;
@@ -3828,6 +3845,7 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
3828 u8 *data; 3845 u8 *data;
3829 u16 rsn_cap; 3846 u16 rsn_cap;
3830 u32 wme_bss_disable; 3847 u32 wme_bss_disable;
3848 u32 mfp;
3831 3849
3832 brcmf_dbg(TRACE, "Enter\n"); 3850 brcmf_dbg(TRACE, "Enter\n");
3833 if (wpa_ie == NULL) 3851 if (wpa_ie == NULL)
@@ -3942,19 +3960,53 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
3942 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) : 3960 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3943 (wpa_auth |= WPA_AUTH_PSK); 3961 (wpa_auth |= WPA_AUTH_PSK);
3944 break; 3962 break;
3963 case RSN_AKM_SHA256_PSK:
3964 brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
3965 wpa_auth |= WPA2_AUTH_PSK_SHA256;
3966 break;
3967 case RSN_AKM_SHA256_1X:
3968 brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
3969 wpa_auth |= WPA2_AUTH_1X_SHA256;
3970 break;
3945 default: 3971 default:
3946 brcmf_err("Ivalid key mgmt info\n"); 3972 brcmf_err("Ivalid key mgmt info\n");
3947 } 3973 }
3948 offset++; 3974 offset++;
3949 } 3975 }
3950 3976
3977 mfp = BRCMF_MFP_NONE;
3951 if (is_rsn_ie) { 3978 if (is_rsn_ie) {
3952 wme_bss_disable = 1; 3979 wme_bss_disable = 1;
3953 if ((offset + RSN_CAP_LEN) <= len) { 3980 if ((offset + RSN_CAP_LEN) <= len) {
3954 rsn_cap = data[offset] + (data[offset + 1] << 8); 3981 rsn_cap = data[offset] + (data[offset + 1] << 8);
3955 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK) 3982 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3956 wme_bss_disable = 0; 3983 wme_bss_disable = 0;
3984 if (rsn_cap & RSN_CAP_MFPR_MASK) {
3985 brcmf_dbg(TRACE, "MFP Required\n");
3986 mfp = BRCMF_MFP_REQUIRED;
3987 /* Firmware only supports mfp required in
3988 * combination with WPA2_AUTH_PSK_SHA256 or
3989 * WPA2_AUTH_1X_SHA256.
3990 */
3991 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
3992 WPA2_AUTH_1X_SHA256))) {
3993 err = -EINVAL;
3994 goto exit;
3995 }
3996 /* Firmware has requirement that WPA2_AUTH_PSK/
3997 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
3998 * is to be included in the rsn ie.
3999 */
4000 if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4001 wpa_auth |= WPA2_AUTH_PSK;
4002 else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4003 wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4004 } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4005 brcmf_dbg(TRACE, "MFP Capable\n");
4006 mfp = BRCMF_MFP_CAPABLE;
4007 }
3957 } 4008 }
4009 offset += RSN_CAP_LEN;
3958 /* set wme_bss_disable to sync RSN Capabilities */ 4010 /* set wme_bss_disable to sync RSN Capabilities */
3959 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", 4011 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3960 wme_bss_disable); 4012 wme_bss_disable);
@@ -3962,6 +4014,21 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
3962 brcmf_err("wme_bss_disable error %d\n", err); 4014 brcmf_err("wme_bss_disable error %d\n", err);
3963 goto exit; 4015 goto exit;
3964 } 4016 }
4017
4018 /* Skip PMKID cnt as it is know to be 0 for AP. */
4019 offset += RSN_PMKID_COUNT_LEN;
4020
4021 /* See if there is BIP wpa suite left for MFP */
4022 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4023 ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4024 err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4025 &data[offset],
4026 WPA_IE_MIN_OUI_LEN);
4027 if (err < 0) {
4028 brcmf_err("bip error %d\n", err);
4029 goto exit;
4030 }
4031 }
3965 } 4032 }
3966 /* FOR WPS , set SES_OW_ENABLED */ 4033 /* FOR WPS , set SES_OW_ENABLED */
3967 wsec = (pval | gval | SES_OW_ENABLED); 4034 wsec = (pval | gval | SES_OW_ENABLED);
@@ -3978,6 +4045,16 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
3978 brcmf_err("wsec error %d\n", err); 4045 brcmf_err("wsec error %d\n", err);
3979 goto exit; 4046 goto exit;
3980 } 4047 }
4048 /* Configure MFP, this needs to go after wsec otherwise the wsec command
4049 * will overwrite the values set by MFP
4050 */
4051 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4052 err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4053 if (err < 0) {
4054 brcmf_err("mfp error %d\n", err);
4055 goto exit;
4056 }
4057 }
3981 /* set upper-layer auth */ 4058 /* set upper-layer auth */
3982 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); 4059 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3983 if (err < 0) { 4060 if (err < 0) {
@@ -4326,7 +4403,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4326 4403
4327 if (!mbss) { 4404 if (!mbss) {
4328 brcmf_set_mpc(ifp, 0); 4405 brcmf_set_mpc(ifp, 0);
4329 brcmf_configure_arp_offload(ifp, false); 4406 brcmf_configure_arp_nd_offload(ifp, false);
4330 } 4407 }
4331 4408
4332 /* find the RSN_IE */ 4409 /* find the RSN_IE */
@@ -4472,7 +4549,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4472exit: 4549exit:
4473 if ((err) && (!mbss)) { 4550 if ((err) && (!mbss)) {
4474 brcmf_set_mpc(ifp, 1); 4551 brcmf_set_mpc(ifp, 1);
4475 brcmf_configure_arp_offload(ifp, true); 4552 brcmf_configure_arp_nd_offload(ifp, true);
4476 } 4553 }
4477 return err; 4554 return err;
4478} 4555}
@@ -4530,7 +4607,7 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4530 brcmf_err("bss_enable config failed %d\n", err); 4607 brcmf_err("bss_enable config failed %d\n", err);
4531 } 4608 }
4532 brcmf_set_mpc(ifp, 1); 4609 brcmf_set_mpc(ifp, 1);
4533 brcmf_configure_arp_offload(ifp, true); 4610 brcmf_configure_arp_nd_offload(ifp, true);
4534 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); 4611 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4535 brcmf_net_setcarrier(ifp, false); 4612 brcmf_net_setcarrier(ifp, false);
4536 4613
@@ -4855,7 +4932,32 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4855 return ret; 4932 return ret;
4856} 4933}
4857 4934
4858static struct cfg80211_ops wl_cfg80211_ops = { 4935#ifdef CONFIG_PM
4936static int
4937brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
4938 struct cfg80211_gtk_rekey_data *gtk)
4939{
4940 struct brcmf_if *ifp = netdev_priv(ndev);
4941 struct brcmf_gtk_keyinfo_le gtk_le;
4942 int ret;
4943
4944 brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
4945
4946 memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
4947 memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
4948 memcpy(gtk_le.replay_counter, gtk->replay_ctr,
4949 sizeof(gtk_le.replay_counter));
4950
4951 ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
4952 sizeof(gtk_le));
4953 if (ret < 0)
4954 brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
4955
4956 return ret;
4957}
4958#endif
4959
4960static struct cfg80211_ops brcmf_cfg80211_ops = {
4859 .add_virtual_intf = brcmf_cfg80211_add_iface, 4961 .add_virtual_intf = brcmf_cfg80211_add_iface,
4860 .del_virtual_intf = brcmf_cfg80211_del_iface, 4962 .del_virtual_intf = brcmf_cfg80211_del_iface,
4861 .change_virtual_intf = brcmf_cfg80211_change_iface, 4963 .change_virtual_intf = brcmf_cfg80211_change_iface,
@@ -5402,14 +5504,14 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5402{ 5504{
5403 kfree(cfg->conf); 5505 kfree(cfg->conf);
5404 cfg->conf = NULL; 5506 cfg->conf = NULL;
5405 kfree(cfg->escan_ioctl_buf);
5406 cfg->escan_ioctl_buf = NULL;
5407 kfree(cfg->extra_buf); 5507 kfree(cfg->extra_buf);
5408 cfg->extra_buf = NULL; 5508 cfg->extra_buf = NULL;
5409 kfree(cfg->wowl.nd); 5509 kfree(cfg->wowl.nd);
5410 cfg->wowl.nd = NULL; 5510 cfg->wowl.nd = NULL;
5411 kfree(cfg->wowl.nd_info); 5511 kfree(cfg->wowl.nd_info);
5412 cfg->wowl.nd_info = NULL; 5512 cfg->wowl.nd_info = NULL;
5513 kfree(cfg->escan_info.escan_buf);
5514 cfg->escan_info.escan_buf = NULL;
5413} 5515}
5414 5516
5415static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) 5517static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
@@ -5417,9 +5519,6 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5417 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); 5519 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5418 if (!cfg->conf) 5520 if (!cfg->conf)
5419 goto init_priv_mem_out; 5521 goto init_priv_mem_out;
5420 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5421 if (!cfg->escan_ioctl_buf)
5422 goto init_priv_mem_out;
5423 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 5522 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5424 if (!cfg->extra_buf) 5523 if (!cfg->extra_buf)
5425 goto init_priv_mem_out; 5524 goto init_priv_mem_out;
@@ -5431,6 +5530,9 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5431 GFP_KERNEL); 5530 GFP_KERNEL);
5432 if (!cfg->wowl.nd_info) 5531 if (!cfg->wowl.nd_info)
5433 goto init_priv_mem_out; 5532 goto init_priv_mem_out;
5533 cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
5534 if (!cfg->escan_info.escan_buf)
5535 goto init_priv_mem_out;
5434 5536
5435 return 0; 5537 return 0;
5436 5538
@@ -6120,19 +6222,18 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6120{ 6222{
6121#ifdef CONFIG_PM 6223#ifdef CONFIG_PM
6122 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 6224 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6123 s32 err;
6124 u32 wowl_cap;
6125 6225
6126 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { 6226 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6127 err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); 6227 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
6128 if (!err) { 6228 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
6129 if (wowl_cap & BRCMF_WOWL_PFN_FOUND) { 6229 init_waitqueue_head(&cfg->wowl.nd_data_wait);
6130 brcmf_wowlan_support.flags |=
6131 WIPHY_WOWLAN_NET_DETECT;
6132 init_waitqueue_head(&cfg->wowl.nd_data_wait);
6133 }
6134 } 6230 }
6135 } 6231 }
6232 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
6233 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
6234 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
6235 }
6236
6136 wiphy->wowlan = &brcmf_wowlan_support; 6237 wiphy->wowlan = &brcmf_wowlan_support;
6137#endif 6238#endif
6138} 6239}
@@ -6174,8 +6275,10 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6174 wiphy->n_addresses = i; 6275 wiphy->n_addresses = i;
6175 6276
6176 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 6277 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6177 wiphy->cipher_suites = __wl_cipher_suites; 6278 wiphy->cipher_suites = brcmf_cipher_suites;
6178 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); 6279 wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
6280 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
6281 wiphy->n_cipher_suites--;
6179 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | 6282 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
6180 WIPHY_FLAG_OFFCHAN_TX | 6283 WIPHY_FLAG_OFFCHAN_TX |
6181 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 6284 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
@@ -6277,7 +6380,7 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6277 if (err) 6380 if (err)
6278 goto default_conf_out; 6381 goto default_conf_out;
6279 6382
6280 brcmf_configure_arp_offload(ifp, true); 6383 brcmf_configure_arp_nd_offload(ifp, true);
6281 6384
6282 cfg->dongle_up = true; 6385 cfg->dongle_up = true;
6283default_conf_out: 6386default_conf_out:
@@ -6395,8 +6498,9 @@ bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6395 6498
6396 return armed; 6499 return armed;
6397} 6500}
6398int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, 6501
6399 u8 action, ulong timeout) 6502int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
6503 u8 action, ulong timeout)
6400{ 6504{
6401 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; 6505 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6402 6506
@@ -6404,28 +6508,85 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6404 vif_event_equals(event, action), timeout); 6508 vif_event_equals(event, action), timeout);
6405} 6509}
6406 6510
6511static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6512 struct brcmf_fil_country_le *ccreq)
6513{
6514 struct brcmfmac_pd_cc *country_codes;
6515 struct brcmfmac_pd_cc_entry *cc;
6516 s32 found_index;
6517 int i;
6518
6519 country_codes = drvr->settings->country_codes;
6520 if (!country_codes) {
6521 brcmf_dbg(TRACE, "No country codes configured for device\n");
6522 return -EINVAL;
6523 }
6524
6525 if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6526 (alpha2[1] == ccreq->country_abbrev[1])) {
6527 brcmf_dbg(TRACE, "Country code already set\n");
6528 return -EAGAIN;
6529 }
6530
6531 found_index = -1;
6532 for (i = 0; i < country_codes->table_size; i++) {
6533 cc = &country_codes->table[i];
6534 if ((cc->iso3166[0] == '\0') && (found_index == -1))
6535 found_index = i;
6536 if ((cc->iso3166[0] == alpha2[0]) &&
6537 (cc->iso3166[1] == alpha2[1])) {
6538 found_index = i;
6539 break;
6540 }
6541 }
6542 if (found_index == -1) {
6543 brcmf_dbg(TRACE, "No country code match found\n");
6544 return -EINVAL;
6545 }
6546 memset(ccreq, 0, sizeof(*ccreq));
6547 ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6548 memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6549 BRCMF_COUNTRY_BUF_SZ);
6550 ccreq->country_abbrev[0] = alpha2[0];
6551 ccreq->country_abbrev[1] = alpha2[1];
6552 ccreq->country_abbrev[2] = 0;
6553
6554 return 0;
6555}
6556
6407static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, 6557static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6408 struct regulatory_request *req) 6558 struct regulatory_request *req)
6409{ 6559{
6410 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); 6560 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6411 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 6561 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6412 struct brcmf_fil_country_le ccreq; 6562 struct brcmf_fil_country_le ccreq;
6563 s32 err;
6413 int i; 6564 int i;
6414 6565
6415 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6416 req->alpha2[0], req->alpha2[1]);
6417
6418 /* ignore non-ISO3166 country codes */ 6566 /* ignore non-ISO3166 country codes */
6419 for (i = 0; i < sizeof(req->alpha2); i++) 6567 for (i = 0; i < sizeof(req->alpha2); i++)
6420 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { 6568 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6421 brcmf_err("not a ISO3166 code\n"); 6569 brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
6570 req->alpha2[0], req->alpha2[1]);
6422 return; 6571 return;
6423 } 6572 }
6424 memset(&ccreq, 0, sizeof(ccreq)); 6573
6425 ccreq.rev = cpu_to_le32(-1); 6574 brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6426 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2)); 6575 req->alpha2[0], req->alpha2[1]);
6427 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) { 6576
6428 brcmf_err("firmware rejected country setting\n"); 6577 err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6578 if (err) {
6579 brcmf_err("Country code iovar returned err = %d\n", err);
6580 return;
6581 }
6582
6583 err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6584 if (err)
6585 return;
6586
6587 err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6588 if (err) {
6589 brcmf_err("Firmware rejected country setting\n");
6429 return; 6590 return;
6430 } 6591 }
6431 brcmf_setup_wiphybands(wiphy); 6592 brcmf_setup_wiphybands(wiphy);
@@ -6461,6 +6622,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6461 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; 6622 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6462 struct brcmf_cfg80211_info *cfg; 6623 struct brcmf_cfg80211_info *cfg;
6463 struct wiphy *wiphy; 6624 struct wiphy *wiphy;
6625 struct cfg80211_ops *ops;
6464 struct brcmf_cfg80211_vif *vif; 6626 struct brcmf_cfg80211_vif *vif;
6465 struct brcmf_if *ifp; 6627 struct brcmf_if *ifp;
6466 s32 err = 0; 6628 s32 err = 0;
@@ -6472,8 +6634,17 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6472 return NULL; 6634 return NULL;
6473 } 6635 }
6474 6636
6637 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
6638 if (!ops)
6639 return NULL;
6640
6641 memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
6475 ifp = netdev_priv(ndev); 6642 ifp = netdev_priv(ndev);
6476 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); 6643#ifdef CONFIG_PM
6644 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
6645 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
6646#endif
6647 wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
6477 if (!wiphy) { 6648 if (!wiphy) {
6478 brcmf_err("Could not allocate wiphy device\n"); 6649 brcmf_err("Could not allocate wiphy device\n");
6479 return NULL; 6650 return NULL;
@@ -6483,6 +6654,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6483 6654
6484 cfg = wiphy_priv(wiphy); 6655 cfg = wiphy_priv(wiphy);
6485 cfg->wiphy = wiphy; 6656 cfg->wiphy = wiphy;
6657 cfg->ops = ops;
6486 cfg->pub = drvr; 6658 cfg->pub = drvr;
6487 init_vif_event(&cfg->vif_event); 6659 init_vif_event(&cfg->vif_event);
6488 INIT_LIST_HEAD(&cfg->vif_list); 6660 INIT_LIST_HEAD(&cfg->vif_list);
@@ -6593,7 +6765,8 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6593 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) { 6765 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
6594 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; 6766 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
6595#ifdef CONFIG_PM 6767#ifdef CONFIG_PM
6596 if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT) 6768 if (wiphy->wowlan &&
6769 wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
6597 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR; 6770 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6598#endif 6771#endif
6599 } 6772 }
@@ -6608,6 +6781,7 @@ priv_out:
6608 ifp->vif = NULL; 6781 ifp->vif = NULL;
6609wiphy_out: 6782wiphy_out:
6610 brcmf_free_wiphy(wiphy); 6783 brcmf_free_wiphy(wiphy);
6784 kfree(ops);
6611 return NULL; 6785 return NULL;
6612} 6786}
6613 6787
@@ -6618,6 +6792,7 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6618 6792
6619 brcmf_btcoex_detach(cfg); 6793 brcmf_btcoex_detach(cfg);
6620 wiphy_unregister(cfg->wiphy); 6794 wiphy_unregister(cfg->wiphy);
6795 kfree(cfg->ops);
6621 wl_deinit_priv(cfg); 6796 wl_deinit_priv(cfg);
6622 brcmf_free_wiphy(cfg->wiphy); 6797 brcmf_free_wiphy(cfg->wiphy);
6623} 6798}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
index 40efb539ac26..95e35bcc16ce 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
@@ -28,8 +28,11 @@
28#define WL_ROAM_TRIGGER_LEVEL -75 28#define WL_ROAM_TRIGGER_LEVEL -75
29#define WL_ROAM_DELTA 20 29#define WL_ROAM_DELTA 20
30 30
31#define WL_ESCAN_BUF_SIZE (1024 * 64) 31/* Keep BRCMF_ESCAN_BUF_SIZE below 64K (65536). Allocing over 64K can be
32#define WL_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */ 32 * problematic on some systems and should be avoided.
33 */
34#define BRCMF_ESCAN_BUF_SIZE 65000
35#define BRCMF_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */
33 36
34#define WL_ESCAN_ACTION_START 1 37#define WL_ESCAN_ACTION_START 1
35#define WL_ESCAN_ACTION_CONTINUE 2 38#define WL_ESCAN_ACTION_CONTINUE 2
@@ -69,7 +72,7 @@
69 72
70#define BRCMF_VNDR_IE_P2PAF_SHIFT 12 73#define BRCMF_VNDR_IE_P2PAF_SHIFT 12
71 74
72#define BRCMF_MAX_DEFAULT_KEYS 4 75#define BRCMF_MAX_DEFAULT_KEYS 6
73 76
74/* beacon loss timeout defaults */ 77/* beacon loss timeout defaults */
75#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2 78#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2
@@ -104,7 +107,6 @@ struct brcmf_cfg80211_security {
104 u32 auth_type; 107 u32 auth_type;
105 u32 cipher_pairwise; 108 u32 cipher_pairwise;
106 u32 cipher_group; 109 u32 cipher_group;
107 u32 wpa_auth;
108}; 110};
109 111
110/** 112/**
@@ -205,7 +207,7 @@ enum wl_escan_state {
205 207
206struct escan_info { 208struct escan_info {
207 u32 escan_state; 209 u32 escan_state;
208 u8 escan_buf[WL_ESCAN_BUF_SIZE]; 210 u8 *escan_buf;
209 struct wiphy *wiphy; 211 struct wiphy *wiphy;
210 struct brcmf_if *ifp; 212 struct brcmf_if *ifp;
211 s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, 213 s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
@@ -253,6 +255,7 @@ struct brcmf_cfg80211_wowl {
253 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface 255 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
254 * 256 *
255 * @wiphy: wiphy object for cfg80211 interface. 257 * @wiphy: wiphy object for cfg80211 interface.
258 * @ops: pointer to copy of ops as registered with wiphy object.
256 * @conf: dongle configuration. 259 * @conf: dongle configuration.
257 * @p2p: peer-to-peer specific information. 260 * @p2p: peer-to-peer specific information.
258 * @btcoex: Bluetooth coexistence information. 261 * @btcoex: Bluetooth coexistence information.
@@ -278,7 +281,6 @@ struct brcmf_cfg80211_wowl {
278 * @escan_info: escan information. 281 * @escan_info: escan information.
279 * @escan_timeout: Timer for catch scan timeout. 282 * @escan_timeout: Timer for catch scan timeout.
280 * @escan_timeout_work: scan timeout worker. 283 * @escan_timeout_work: scan timeout worker.
281 * @escan_ioctl_buf: dongle command buffer for escan commands.
282 * @vif_list: linked list of vif instances. 284 * @vif_list: linked list of vif instances.
283 * @vif_cnt: number of vif instances. 285 * @vif_cnt: number of vif instances.
284 * @vif_event: vif event signalling. 286 * @vif_event: vif event signalling.
@@ -286,6 +288,7 @@ struct brcmf_cfg80211_wowl {
286 */ 288 */
287struct brcmf_cfg80211_info { 289struct brcmf_cfg80211_info {
288 struct wiphy *wiphy; 290 struct wiphy *wiphy;
291 struct cfg80211_ops *ops;
289 struct brcmf_cfg80211_conf *conf; 292 struct brcmf_cfg80211_conf *conf;
290 struct brcmf_p2p_info p2p; 293 struct brcmf_p2p_info p2p;
291 struct brcmf_btcoex_info *btcoex; 294 struct brcmf_btcoex_info *btcoex;
@@ -309,7 +312,6 @@ struct brcmf_cfg80211_info {
309 struct escan_info escan_info; 312 struct escan_info escan_info;
310 struct timer_list escan_timeout; 313 struct timer_list escan_timeout;
311 struct work_struct escan_timeout_work; 314 struct work_struct escan_timeout_work;
312 u8 *escan_ioctl_buf;
313 struct list_head vif_list; 315 struct list_head vif_list;
314 struct brcmf_cfg80211_vif_event vif_event; 316 struct brcmf_cfg80211_vif_event vif_event;
315 struct completion vif_disabled; 317 struct completion vif_disabled;
@@ -402,8 +404,8 @@ bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
402void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, 404void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
403 struct brcmf_cfg80211_vif *vif); 405 struct brcmf_cfg80211_vif *vif);
404bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); 406bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
405int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, 407int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
406 u8 action, ulong timeout); 408 u8 action, ulong timeout);
407s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, 409s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
408 struct brcmf_if *ifp, bool aborted, 410 struct brcmf_if *ifp, bool aborted,
409 bool fw_abort); 411 bool fw_abort);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
index cfee477a6eb1..9e909e3c2f0c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -27,6 +27,11 @@
27#include "fwil_types.h" 27#include "fwil_types.h"
28#include "tracepoint.h" 28#include "tracepoint.h"
29#include "common.h" 29#include "common.h"
30#include "of.h"
31
32MODULE_AUTHOR("Broadcom Corporation");
33MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
34MODULE_LICENSE("Dual BSD/GPL");
30 35
31const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 36const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
32 37
@@ -75,6 +80,7 @@ module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
75MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); 80MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
76#endif 81#endif
77 82
83static struct brcmfmac_platform_data *brcmfmac_pdata;
78struct brcmf_mp_global_t brcmf_mp_global; 84struct brcmf_mp_global_t brcmf_mp_global;
79 85
80int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) 86int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
@@ -221,33 +227,147 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
221} 227}
222#endif 228#endif
223 229
224void brcmf_mp_attach(void) 230static void brcmf_mp_attach(void)
225{ 231{
232 /* If module param firmware path is set then this will always be used,
233 * if not set then if available use the platform data version. To make
234 * sure it gets initialized at all, always copy the module param version
235 */
226 strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, 236 strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
227 BRCMF_FW_ALTPATH_LEN); 237 BRCMF_FW_ALTPATH_LEN);
238 if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) &&
239 (brcmf_mp_global.firmware_path[0] == '\0')) {
240 strlcpy(brcmf_mp_global.firmware_path,
241 brcmfmac_pdata->fw_alternative_path,
242 BRCMF_FW_ALTPATH_LEN);
243 }
228} 244}
229 245
230int brcmf_mp_device_attach(struct brcmf_pub *drvr) 246struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
247 enum brcmf_bus_type bus_type,
248 u32 chip, u32 chiprev)
231{ 249{
232 drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); 250 struct brcmf_mp_device *settings;
233 if (!drvr->settings) { 251 struct brcmfmac_pd_device *device_pd;
234 brcmf_err("Failed to alloca storage space for settings\n"); 252 bool found;
235 return -ENOMEM; 253 int i;
236 } 254
237 255 brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip,
238 drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; 256 chiprev);
239 drvr->settings->p2p_enable = !!brcmf_p2p_enable; 257 settings = kzalloc(sizeof(*settings), GFP_ATOMIC);
240 drvr->settings->feature_disable = brcmf_feature_disable; 258 if (!settings)
241 drvr->settings->fcmode = brcmf_fcmode; 259 return NULL;
242 drvr->settings->roamoff = !!brcmf_roamoff; 260
261 /* start by using the module paramaters */
262 settings->p2p_enable = !!brcmf_p2p_enable;
263 settings->feature_disable = brcmf_feature_disable;
264 settings->fcmode = brcmf_fcmode;
265 settings->roamoff = !!brcmf_roamoff;
243#ifdef DEBUG 266#ifdef DEBUG
244 drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; 267 settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
245#endif 268#endif
269
270 if (bus_type == BRCMF_BUSTYPE_SDIO)
271 settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz;
272
273 /* See if there is any device specific platform data configured */
274 found = false;
275 if (brcmfmac_pdata) {
276 for (i = 0; i < brcmfmac_pdata->device_count; i++) {
277 device_pd = &brcmfmac_pdata->devices[i];
278 if ((device_pd->bus_type == bus_type) &&
279 (device_pd->id == chip) &&
280 ((device_pd->rev == chiprev) ||
281 (device_pd->rev == -1))) {
282 brcmf_dbg(INFO, "Platform data for device found\n");
283 settings->country_codes =
284 device_pd->country_codes;
285 if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO)
286 memcpy(&settings->bus.sdio,
287 &device_pd->bus.sdio,
288 sizeof(settings->bus.sdio));
289 found = true;
290 break;
291 }
292 }
293 }
294 if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) {
295 /* No platform data for this device. In case of SDIO try OF
296 * (Open Firwmare) Device Tree.
297 */
298 brcmf_of_probe(dev, &settings->bus.sdio);
299 }
300 return settings;
301}
302
303void brcmf_release_module_param(struct brcmf_mp_device *module_param)
304{
305 kfree(module_param);
306}
307
308static int __init brcmf_common_pd_probe(struct platform_device *pdev)
309{
310 brcmf_dbg(INFO, "Enter\n");
311
312 brcmfmac_pdata = dev_get_platdata(&pdev->dev);
313
314 if (brcmfmac_pdata->power_on)
315 brcmfmac_pdata->power_on();
316
317 return 0;
318}
319
320static int brcmf_common_pd_remove(struct platform_device *pdev)
321{
322 brcmf_dbg(INFO, "Enter\n");
323
324 if (brcmfmac_pdata->power_off)
325 brcmfmac_pdata->power_off();
326
246 return 0; 327 return 0;
247} 328}
248 329
249void brcmf_mp_device_detach(struct brcmf_pub *drvr) 330static struct platform_driver brcmf_pd = {
331 .remove = brcmf_common_pd_remove,
332 .driver = {
333 .name = BRCMFMAC_PDATA_NAME,
334 }
335};
336
337static int __init brcmfmac_module_init(void)
338{
339 int err;
340
341 /* Initialize debug system first */
342 brcmf_debugfs_init();
343
344 /* Get the platform data (if available) for our devices */
345 err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe);
346 if (err == -ENODEV)
347 brcmf_dbg(INFO, "No platform data available.\n");
348
349 /* Initialize global module paramaters */
350 brcmf_mp_attach();
351
352 /* Continue the initialization by registering the different busses */
353 err = brcmf_core_init();
354 if (err) {
355 brcmf_debugfs_exit();
356 if (brcmfmac_pdata)
357 platform_driver_unregister(&brcmf_pd);
358 }
359
360 return err;
361}
362
363static void __exit brcmfmac_module_exit(void)
250{ 364{
251 kfree(drvr->settings); 365 brcmf_core_exit();
366 if (brcmfmac_pdata)
367 platform_driver_unregister(&brcmf_pd);
368 brcmf_debugfs_exit();
252} 369}
253 370
371module_init(brcmfmac_module_init);
372module_exit(brcmfmac_module_exit);
373
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
index 3b0a63b98e99..bd095abca393 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -15,6 +15,10 @@
15#ifndef BRCMFMAC_COMMON_H 15#ifndef BRCMFMAC_COMMON_H
16#define BRCMFMAC_COMMON_H 16#define BRCMFMAC_COMMON_H
17 17
18#include <linux/platform_device.h>
19#include <linux/platform_data/brcmfmac.h>
20#include "fwil_types.h"
21
18extern const u8 ALLFFMAC[ETH_ALEN]; 22extern const u8 ALLFFMAC[ETH_ALEN];
19 23
20#define BRCMF_FW_ALTPATH_LEN 256 24#define BRCMF_FW_ALTPATH_LEN 256
@@ -41,37 +45,30 @@ extern struct brcmf_mp_global_t brcmf_mp_global;
41/** 45/**
42 * struct brcmf_mp_device - Device module paramaters. 46 * struct brcmf_mp_device - Device module paramaters.
43 * 47 *
44 * @sdiod_txglomsz: SDIO txglom size.
45 * @joinboost_5g_rssi: 5g rssi booost for preferred join selection.
46 * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). 48 * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant).
47 * @feature_disable: Feature_disable bitmask. 49 * @feature_disable: Feature_disable bitmask.
48 * @fcmode: FWS flow control. 50 * @fcmode: FWS flow control.
49 * @roamoff: Firmware roaming off? 51 * @roamoff: Firmware roaming off?
52 * @ignore_probe_fail: Ignore probe failure.
53 * @country_codes: If available, pointer to struct for translating country codes
54 * @bus: Bus specific platform data. Only SDIO at the mmoment.
50 */ 55 */
51struct brcmf_mp_device { 56struct brcmf_mp_device {
52 int sdiod_txglomsz; 57 bool p2p_enable;
53 int joinboost_5g_rssi; 58 unsigned int feature_disable;
54 bool p2p_enable; 59 int fcmode;
55 int feature_disable; 60 bool roamoff;
56 int fcmode; 61 bool ignore_probe_fail;
57 bool roamoff; 62 struct brcmfmac_pd_cc *country_codes;
58 bool ignore_probe_fail; 63 union {
64 struct brcmfmac_sdio_pd sdio;
65 } bus;
59}; 66};
60 67
61void brcmf_mp_attach(void); 68struct brcmf_mp_device *brcmf_get_module_param(struct device *dev,
62int brcmf_mp_device_attach(struct brcmf_pub *drvr); 69 enum brcmf_bus_type bus_type,
63void brcmf_mp_device_detach(struct brcmf_pub *drvr); 70 u32 chip, u32 chiprev);
64#ifdef DEBUG 71void brcmf_release_module_param(struct brcmf_mp_device *module_param);
65static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr)
66{
67 return drvr->settings->ignore_probe_fail;
68}
69#else
70static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr)
71{
72 return false;
73}
74#endif
75 72
76/* Sets dongle media info (drv_version, mac address). */ 73/* Sets dongle media info (drv_version, mac address). */
77int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 74int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index ed9998b69709..ff825cd7739e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -20,6 +20,8 @@
20#include <linux/inetdevice.h> 20#include <linux/inetdevice.h>
21#include <net/cfg80211.h> 21#include <net/cfg80211.h>
22#include <net/rtnetlink.h> 22#include <net/rtnetlink.h>
23#include <net/addrconf.h>
24#include <net/ipv6.h>
23#include <brcmu_utils.h> 25#include <brcmu_utils.h>
24#include <brcmu_wifi.h> 26#include <brcmu_wifi.h>
25 27
@@ -36,11 +38,7 @@
36#include "pcie.h" 38#include "pcie.h"
37#include "common.h" 39#include "common.h"
38 40
39MODULE_AUTHOR("Broadcom Corporation"); 41#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950)
40MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
41MODULE_LICENSE("Dual BSD/GPL");
42
43#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(50)
44 42
45/* AMPDU rx reordering definitions */ 43/* AMPDU rx reordering definitions */
46#define BRCMF_RXREORDER_FLOWID_OFFSET 0 44#define BRCMF_RXREORDER_FLOWID_OFFSET 0
@@ -172,6 +170,35 @@ _brcmf_set_mac_address(struct work_struct *work)
172 } 170 }
173} 171}
174 172
173#if IS_ENABLED(CONFIG_IPV6)
174static void _brcmf_update_ndtable(struct work_struct *work)
175{
176 struct brcmf_if *ifp;
177 int i, ret;
178
179 ifp = container_of(work, struct brcmf_if, ndoffload_work);
180
181 /* clear the table in firmware */
182 ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0);
183 if (ret) {
184 brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret);
185 return;
186 }
187
188 for (i = 0; i < ifp->ipv6addr_idx; i++) {
189 ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip",
190 &ifp->ipv6_addr_tbl[i],
191 sizeof(struct in6_addr));
192 if (ret)
193 brcmf_err("add nd ip err %d\n", ret);
194 }
195}
196#else
197static void _brcmf_update_ndtable(struct work_struct *work)
198{
199}
200#endif
201
175static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 202static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
176{ 203{
177 struct brcmf_if *ifp = netdev_priv(ndev); 204 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -685,6 +712,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked)
685 712
686 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); 713 INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
687 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); 714 INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
715 INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
688 716
689 if (rtnl_locked) 717 if (rtnl_locked)
690 err = register_netdevice(ndev); 718 err = register_netdevice(ndev);
@@ -884,6 +912,7 @@ static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx)
884 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { 912 if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
885 cancel_work_sync(&ifp->setmacaddr_work); 913 cancel_work_sync(&ifp->setmacaddr_work);
886 cancel_work_sync(&ifp->multicast_work); 914 cancel_work_sync(&ifp->multicast_work);
915 cancel_work_sync(&ifp->ndoffload_work);
887 } 916 }
888 brcmf_net_detach(ifp->ndev); 917 brcmf_net_detach(ifp->ndev);
889 } else { 918 } else {
@@ -1006,14 +1035,14 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
1006 return NOTIFY_OK; 1035 return NOTIFY_OK;
1007 } 1036 }
1008 for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { 1037 for (i = 0; i < ARPOL_MAX_ENTRIES; i++) {
1009 if (addr_table[i] != 0) { 1038 if (addr_table[i] == 0)
1010 brcmf_fil_iovar_data_set(ifp, 1039 continue;
1011 "arp_hostip", &addr_table[i], 1040 ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip",
1012 sizeof(addr_table[i])); 1041 &addr_table[i],
1013 if (ret) 1042 sizeof(addr_table[i]));
1014 brcmf_err("add arp ip err %d\n", 1043 if (ret)
1015 ret); 1044 brcmf_err("add arp ip err %d\n",
1016 } 1045 ret);
1017 } 1046 }
1018 } 1047 }
1019 break; 1048 break;
@@ -1025,7 +1054,57 @@ static int brcmf_inetaddr_changed(struct notifier_block *nb,
1025} 1054}
1026#endif 1055#endif
1027 1056
1028int brcmf_attach(struct device *dev) 1057#if IS_ENABLED(CONFIG_IPV6)
1058static int brcmf_inet6addr_changed(struct notifier_block *nb,
1059 unsigned long action, void *data)
1060{
1061 struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub,
1062 inet6addr_notifier);
1063 struct inet6_ifaddr *ifa = data;
1064 struct brcmf_if *ifp;
1065 int i;
1066 struct in6_addr *table;
1067
1068 /* Only handle primary interface */
1069 ifp = drvr->iflist[0];
1070 if (!ifp)
1071 return NOTIFY_DONE;
1072 if (ifp->ndev != ifa->idev->dev)
1073 return NOTIFY_DONE;
1074
1075 table = ifp->ipv6_addr_tbl;
1076 for (i = 0; i < NDOL_MAX_ENTRIES; i++)
1077 if (ipv6_addr_equal(&ifa->addr, &table[i]))
1078 break;
1079
1080 switch (action) {
1081 case NETDEV_UP:
1082 if (i == NDOL_MAX_ENTRIES) {
1083 if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) {
1084 table[ifp->ipv6addr_idx++] = ifa->addr;
1085 } else {
1086 for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++)
1087 table[i] = table[i + 1];
1088 table[NDOL_MAX_ENTRIES - 1] = ifa->addr;
1089 }
1090 }
1091 break;
1092 case NETDEV_DOWN:
1093 if (i < NDOL_MAX_ENTRIES)
1094 for (; i < ifp->ipv6addr_idx; i++)
1095 table[i] = table[i + 1];
1096 break;
1097 default:
1098 break;
1099 }
1100
1101 schedule_work(&ifp->ndoffload_work);
1102
1103 return NOTIFY_OK;
1104}
1105#endif
1106
1107int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings)
1029{ 1108{
1030 struct brcmf_pub *drvr = NULL; 1109 struct brcmf_pub *drvr = NULL;
1031 int ret = 0; 1110 int ret = 0;
@@ -1047,10 +1126,7 @@ int brcmf_attach(struct device *dev)
1047 drvr->hdrlen = 0; 1126 drvr->hdrlen = 0;
1048 drvr->bus_if = dev_get_drvdata(dev); 1127 drvr->bus_if = dev_get_drvdata(dev);
1049 drvr->bus_if->drvr = drvr; 1128 drvr->bus_if->drvr = drvr;
1050 1129 drvr->settings = settings;
1051 /* Initialize device specific settings */
1052 if (brcmf_mp_device_attach(drvr))
1053 goto fail;
1054 1130
1055 /* attach debug facilities */ 1131 /* attach debug facilities */
1056 brcmf_debug_attach(drvr); 1132 brcmf_debug_attach(drvr);
@@ -1164,30 +1240,41 @@ int brcmf_bus_start(struct device *dev)
1164#ifdef CONFIG_INET 1240#ifdef CONFIG_INET
1165 drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; 1241 drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed;
1166 ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); 1242 ret = register_inetaddr_notifier(&drvr->inetaddr_notifier);
1243 if (ret)
1244 goto fail;
1245
1246#if IS_ENABLED(CONFIG_IPV6)
1247 drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed;
1248 ret = register_inet6addr_notifier(&drvr->inet6addr_notifier);
1249 if (ret) {
1250 unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
1251 goto fail;
1252 }
1167#endif 1253#endif
1254#endif /* CONFIG_INET */
1255
1256 return 0;
1168 1257
1169fail: 1258fail:
1170 if (ret < 0) { 1259 brcmf_err("failed: %d\n", ret);
1171 brcmf_err("failed: %d\n", ret); 1260 if (drvr->config) {
1172 if (drvr->config) { 1261 brcmf_cfg80211_detach(drvr->config);
1173 brcmf_cfg80211_detach(drvr->config); 1262 drvr->config = NULL;
1174 drvr->config = NULL;
1175 }
1176 if (drvr->fws) {
1177 brcmf_fws_del_interface(ifp);
1178 brcmf_fws_deinit(drvr);
1179 }
1180 if (ifp)
1181 brcmf_net_detach(ifp->ndev);
1182 if (p2p_ifp)
1183 brcmf_net_detach(p2p_ifp->ndev);
1184 drvr->iflist[0] = NULL;
1185 drvr->iflist[1] = NULL;
1186 if (brcmf_ignoring_probe_fail(drvr))
1187 ret = 0;
1188 return ret;
1189 } 1263 }
1190 return 0; 1264 if (drvr->fws) {
1265 brcmf_fws_del_interface(ifp);
1266 brcmf_fws_deinit(drvr);
1267 }
1268 if (ifp)
1269 brcmf_net_detach(ifp->ndev);
1270 if (p2p_ifp)
1271 brcmf_net_detach(p2p_ifp->ndev);
1272 drvr->iflist[0] = NULL;
1273 drvr->iflist[1] = NULL;
1274 if (drvr->settings->ignore_probe_fail)
1275 ret = 0;
1276
1277 return ret;
1191} 1278}
1192 1279
1193void brcmf_bus_add_txhdrlen(struct device *dev, uint len) 1280void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
@@ -1237,6 +1324,10 @@ void brcmf_detach(struct device *dev)
1237 unregister_inetaddr_notifier(&drvr->inetaddr_notifier); 1324 unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
1238#endif 1325#endif
1239 1326
1327#if IS_ENABLED(CONFIG_IPV6)
1328 unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
1329#endif
1330
1240 /* stop firmware event handling */ 1331 /* stop firmware event handling */
1241 brcmf_fweh_detach(drvr); 1332 brcmf_fweh_detach(drvr);
1242 if (drvr->config) 1333 if (drvr->config)
@@ -1256,8 +1347,6 @@ void brcmf_detach(struct device *dev)
1256 1347
1257 brcmf_proto_detach(drvr); 1348 brcmf_proto_detach(drvr);
1258 1349
1259 brcmf_mp_device_detach(drvr);
1260
1261 brcmf_debug_detach(drvr); 1350 brcmf_debug_detach(drvr);
1262 bus_if->drvr = NULL; 1351 bus_if->drvr = NULL;
1263 kfree(drvr); 1352 kfree(drvr);
@@ -1324,19 +1413,15 @@ static void brcmf_driver_register(struct work_struct *work)
1324} 1413}
1325static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); 1414static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
1326 1415
1327static int __init brcmfmac_module_init(void) 1416int __init brcmf_core_init(void)
1328{ 1417{
1329 brcmf_debugfs_init();
1330#ifdef CONFIG_BRCMFMAC_SDIO
1331 brcmf_sdio_init();
1332#endif
1333 if (!schedule_work(&brcmf_driver_work)) 1418 if (!schedule_work(&brcmf_driver_work))
1334 return -EBUSY; 1419 return -EBUSY;
1335 1420
1336 return 0; 1421 return 0;
1337} 1422}
1338 1423
1339static void __exit brcmfmac_module_exit(void) 1424void __exit brcmf_core_exit(void)
1340{ 1425{
1341 cancel_work_sync(&brcmf_driver_work); 1426 cancel_work_sync(&brcmf_driver_work);
1342 1427
@@ -1349,8 +1434,5 @@ static void __exit brcmfmac_module_exit(void)
1349#ifdef CONFIG_BRCMFMAC_PCIE 1434#ifdef CONFIG_BRCMFMAC_PCIE
1350 brcmf_pcie_exit(); 1435 brcmf_pcie_exit();
1351#endif 1436#endif
1352 brcmf_debugfs_exit();
1353} 1437}
1354 1438
1355module_init(brcmfmac_module_init);
1356module_exit(brcmfmac_module_exit);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
index 8f39435f976f..7bdb6fef99c3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -48,6 +48,8 @@
48 */ 48 */
49#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 49#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
50 50
51#define NDOL_MAX_ENTRIES 8
52
51/** 53/**
52 * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info 54 * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info
53 * 55 *
@@ -143,6 +145,7 @@ struct brcmf_pub {
143#endif 145#endif
144 146
145 struct notifier_block inetaddr_notifier; 147 struct notifier_block inetaddr_notifier;
148 struct notifier_block inet6addr_notifier;
146 struct brcmf_mp_device *settings; 149 struct brcmf_mp_device *settings;
147}; 150};
148 151
@@ -175,6 +178,7 @@ enum brcmf_netif_stop_reason {
175 * @stats: interface specific network statistics. 178 * @stats: interface specific network statistics.
176 * @setmacaddr_work: worker object for setting mac address. 179 * @setmacaddr_work: worker object for setting mac address.
177 * @multicast_work: worker object for multicast provisioning. 180 * @multicast_work: worker object for multicast provisioning.
181 * @ndoffload_work: worker object for neighbor discovery offload configuration.
178 * @fws_desc: interface specific firmware-signalling descriptor. 182 * @fws_desc: interface specific firmware-signalling descriptor.
179 * @ifidx: interface index in device firmware. 183 * @ifidx: interface index in device firmware.
180 * @bsscfgidx: index of bss associated with this interface. 184 * @bsscfgidx: index of bss associated with this interface.
@@ -191,6 +195,7 @@ struct brcmf_if {
191 struct net_device_stats stats; 195 struct net_device_stats stats;
192 struct work_struct setmacaddr_work; 196 struct work_struct setmacaddr_work;
193 struct work_struct multicast_work; 197 struct work_struct multicast_work;
198 struct work_struct ndoffload_work;
194 struct brcmf_fws_mac_descriptor *fws_desc; 199 struct brcmf_fws_mac_descriptor *fws_desc;
195 int ifidx; 200 int ifidx;
196 s32 bsscfgidx; 201 s32 bsscfgidx;
@@ -199,6 +204,8 @@ struct brcmf_if {
199 spinlock_t netif_stop_lock; 204 spinlock_t netif_stop_lock;
200 atomic_t pend_8021x_cnt; 205 atomic_t pend_8021x_cnt;
201 wait_queue_head_t pend_8021x_wait; 206 wait_queue_head_t pend_8021x_wait;
207 struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES];
208 u8 ipv6addr_idx;
202}; 209};
203 210
204struct brcmf_skb_reorder_data { 211struct brcmf_skb_reorder_data {
@@ -220,5 +227,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp,
220void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); 227void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
221void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); 228void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
222void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); 229void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
230int __init brcmf_core_init(void);
231void __exit brcmf_core_exit(void);
223 232
224#endif /* BRCMFMAC_CORE_H */ 233#endif /* BRCMFMAC_CORE_H */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
index 1ffa95f1b8d2..62985f2c0853 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
@@ -136,6 +136,7 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
136{ 136{
137 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); 137 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
138 struct brcmf_pno_macaddr_le pfn_mac; 138 struct brcmf_pno_macaddr_le pfn_mac;
139 u32 wowl_cap;
139 s32 err; 140 s32 err;
140 141
141 brcmf_feat_firmware_capabilities(ifp); 142 brcmf_feat_firmware_capabilities(ifp);
@@ -143,11 +144,24 @@ void brcmf_feat_attach(struct brcmf_pub *drvr)
143 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); 144 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
144 if (drvr->bus_if->wowl_supported) 145 if (drvr->bus_if->wowl_supported)
145 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); 146 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
147 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) {
148 err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
149 if (!err) {
150 ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_WOWL_ARP_ND);
151 if (wowl_cap & BRCMF_WOWL_PFN_FOUND)
152 ifp->drvr->feat_flags |=
153 BIT(BRCMF_FEAT_WOWL_ND);
154 if (wowl_cap & BRCMF_WOWL_GTK_FAILURE)
155 ifp->drvr->feat_flags |=
156 BIT(BRCMF_FEAT_WOWL_GTK);
157 }
158 }
146 /* MBSS does not work for 43362 */ 159 /* MBSS does not work for 43362 */
147 if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID) 160 if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID)
148 ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); 161 ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS);
149 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode"); 162 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode");
150 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable"); 163 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable");
164 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp");
151 165
152 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; 166 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
153 err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac, 167 err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
index 2e2479d41337..db4733a95e28 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
@@ -27,6 +27,10 @@
27 * RSDB: Real Simultaneous Dual Band 27 * RSDB: Real Simultaneous Dual Band
28 * TDLS: Tunneled Direct Link Setup 28 * TDLS: Tunneled Direct Link Setup
29 * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan. 29 * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan.
30 * WOWL_ND: WOWL net detect (PNO)
31 * WOWL_GTK: (WOWL) GTK rekeying offload
32 * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL.
33 * MFP: 802.11w Management Frame Protection.
30 */ 34 */
31#define BRCMF_FEAT_LIST \ 35#define BRCMF_FEAT_LIST \
32 BRCMF_FEAT_DEF(MBSS) \ 36 BRCMF_FEAT_DEF(MBSS) \
@@ -36,7 +40,11 @@
36 BRCMF_FEAT_DEF(P2P) \ 40 BRCMF_FEAT_DEF(P2P) \
37 BRCMF_FEAT_DEF(RSDB) \ 41 BRCMF_FEAT_DEF(RSDB) \
38 BRCMF_FEAT_DEF(TDLS) \ 42 BRCMF_FEAT_DEF(TDLS) \
39 BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) 43 BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \
44 BRCMF_FEAT_DEF(WOWL_ND) \
45 BRCMF_FEAT_DEF(WOWL_GTK) \
46 BRCMF_FEAT_DEF(WOWL_ARP_ND) \
47 BRCMF_FEAT_DEF(MFP)
40 48
41/* 49/*
42 * Quirks: 50 * Quirks:
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
index 2ca783fa50cf..7e269f9aa607 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
@@ -32,7 +32,7 @@
32#define BRCMF_FLOWRING_LOW (BRCMF_FLOWRING_HIGH - 256) 32#define BRCMF_FLOWRING_LOW (BRCMF_FLOWRING_HIGH - 256)
33#define BRCMF_FLOWRING_INVALID_IFIDX 0xff 33#define BRCMF_FLOWRING_INVALID_IFIDX 0xff
34 34
35#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] + fifo + ifidx * 16) 35#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] * 2 + fifo + ifidx * 16)
36#define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16) 36#define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16)
37 37
38static const u8 brcmf_flowring_prio2fifo[] = { 38static const u8 brcmf_flowring_prio2fifo[] = {
@@ -68,7 +68,7 @@ u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
68 u8 prio, u8 ifidx) 68 u8 prio, u8 ifidx)
69{ 69{
70 struct brcmf_flowring_hash *hash; 70 struct brcmf_flowring_hash *hash;
71 u8 hash_idx; 71 u16 hash_idx;
72 u32 i; 72 u32 i;
73 bool found; 73 bool found;
74 bool sta; 74 bool sta;
@@ -88,6 +88,7 @@ u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
88 } 88 }
89 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : 89 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
90 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); 90 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
91 hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1);
91 found = false; 92 found = false;
92 hash = flow->hash; 93 hash = flow->hash;
93 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { 94 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
@@ -98,6 +99,7 @@ u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
98 break; 99 break;
99 } 100 }
100 hash_idx++; 101 hash_idx++;
102 hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1);
101 } 103 }
102 if (found) 104 if (found)
103 return hash[hash_idx].flowid; 105 return hash[hash_idx].flowid;
@@ -111,7 +113,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
111{ 113{
112 struct brcmf_flowring_ring *ring; 114 struct brcmf_flowring_ring *ring;
113 struct brcmf_flowring_hash *hash; 115 struct brcmf_flowring_hash *hash;
114 u8 hash_idx; 116 u16 hash_idx;
115 u32 i; 117 u32 i;
116 bool found; 118 bool found;
117 u8 fifo; 119 u8 fifo;
@@ -131,6 +133,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
131 } 133 }
132 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : 134 hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) :
133 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); 135 BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx);
136 hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1);
134 found = false; 137 found = false;
135 hash = flow->hash; 138 hash = flow->hash;
136 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { 139 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
@@ -140,6 +143,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
140 break; 143 break;
141 } 144 }
142 hash_idx++; 145 hash_idx++;
146 hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1);
143 } 147 }
144 if (found) { 148 if (found) {
145 for (i = 0; i < flow->nrofrings; i++) { 149 for (i = 0; i < flow->nrofrings; i++) {
@@ -169,7 +173,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
169} 173}
170 174
171 175
172u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid) 176u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u16 flowid)
173{ 177{
174 struct brcmf_flowring_ring *ring; 178 struct brcmf_flowring_ring *ring;
175 179
@@ -179,7 +183,7 @@ u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid)
179} 183}
180 184
181 185
182static void brcmf_flowring_block(struct brcmf_flowring *flow, u8 flowid, 186static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,
183 bool blocked) 187 bool blocked)
184{ 188{
185 struct brcmf_flowring_ring *ring; 189 struct brcmf_flowring_ring *ring;
@@ -228,10 +232,10 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u8 flowid,
228} 232}
229 233
230 234
231void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid) 235void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid)
232{ 236{
233 struct brcmf_flowring_ring *ring; 237 struct brcmf_flowring_ring *ring;
234 u8 hash_idx; 238 u16 hash_idx;
235 struct sk_buff *skb; 239 struct sk_buff *skb;
236 240
237 ring = flow->rings[flowid]; 241 ring = flow->rings[flowid];
@@ -253,7 +257,7 @@ void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid)
253} 257}
254 258
255 259
256u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, 260u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u16 flowid,
257 struct sk_buff *skb) 261 struct sk_buff *skb)
258{ 262{
259 struct brcmf_flowring_ring *ring; 263 struct brcmf_flowring_ring *ring;
@@ -279,7 +283,7 @@ u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid,
279} 283}
280 284
281 285
282struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid) 286struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u16 flowid)
283{ 287{
284 struct brcmf_flowring_ring *ring; 288 struct brcmf_flowring_ring *ring;
285 struct sk_buff *skb; 289 struct sk_buff *skb;
@@ -300,7 +304,7 @@ struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid)
300} 304}
301 305
302 306
303void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, 307void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u16 flowid,
304 struct sk_buff *skb) 308 struct sk_buff *skb)
305{ 309{
306 struct brcmf_flowring_ring *ring; 310 struct brcmf_flowring_ring *ring;
@@ -311,7 +315,7 @@ void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid,
311} 315}
312 316
313 317
314u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid) 318u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u16 flowid)
315{ 319{
316 struct brcmf_flowring_ring *ring; 320 struct brcmf_flowring_ring *ring;
317 321
@@ -326,7 +330,7 @@ u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid)
326} 330}
327 331
328 332
329void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid) 333void brcmf_flowring_open(struct brcmf_flowring *flow, u16 flowid)
330{ 334{
331 struct brcmf_flowring_ring *ring; 335 struct brcmf_flowring_ring *ring;
332 336
@@ -340,10 +344,10 @@ void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid)
340} 344}
341 345
342 346
343u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid) 347u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u16 flowid)
344{ 348{
345 struct brcmf_flowring_ring *ring; 349 struct brcmf_flowring_ring *ring;
346 u8 hash_idx; 350 u16 hash_idx;
347 351
348 ring = flow->rings[flowid]; 352 ring = flow->rings[flowid];
349 hash_idx = ring->hash_id; 353 hash_idx = ring->hash_id;
@@ -384,7 +388,7 @@ void brcmf_flowring_detach(struct brcmf_flowring *flow)
384 struct brcmf_pub *drvr = bus_if->drvr; 388 struct brcmf_pub *drvr = bus_if->drvr;
385 struct brcmf_flowring_tdls_entry *search; 389 struct brcmf_flowring_tdls_entry *search;
386 struct brcmf_flowring_tdls_entry *remove; 390 struct brcmf_flowring_tdls_entry *remove;
387 u8 flowid; 391 u16 flowid;
388 392
389 for (flowid = 0; flowid < flow->nrofrings; flowid++) { 393 for (flowid = 0; flowid < flow->nrofrings; flowid++) {
390 if (flow->rings[flowid]) 394 if (flow->rings[flowid])
@@ -408,7 +412,7 @@ void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
408 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); 412 struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
409 struct brcmf_pub *drvr = bus_if->drvr; 413 struct brcmf_pub *drvr = bus_if->drvr;
410 u32 i; 414 u32 i;
411 u8 flowid; 415 u16 flowid;
412 416
413 if (flow->addr_mode[ifidx] != addr_mode) { 417 if (flow->addr_mode[ifidx] != addr_mode) {
414 for (i = 0; i < ARRAY_SIZE(flow->hash); i++) { 418 for (i = 0; i < ARRAY_SIZE(flow->hash); i++) {
@@ -434,7 +438,7 @@ void brcmf_flowring_delete_peer(struct brcmf_flowring *flow, int ifidx,
434 struct brcmf_flowring_tdls_entry *prev; 438 struct brcmf_flowring_tdls_entry *prev;
435 struct brcmf_flowring_tdls_entry *search; 439 struct brcmf_flowring_tdls_entry *search;
436 u32 i; 440 u32 i;
437 u8 flowid; 441 u16 flowid;
438 bool sta; 442 bool sta;
439 443
440 sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT); 444 sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
index 95fd1c9675d1..068e68d94999 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h
@@ -16,7 +16,7 @@
16#define BRCMFMAC_FLOWRING_H 16#define BRCMFMAC_FLOWRING_H
17 17
18 18
19#define BRCMF_FLOWRING_HASHSIZE 256 19#define BRCMF_FLOWRING_HASHSIZE 512 /* has to be 2^x */
20#define BRCMF_FLOWRING_INVALID_ID 0xFFFFFFFF 20#define BRCMF_FLOWRING_INVALID_ID 0xFFFFFFFF
21 21
22 22
@@ -24,7 +24,7 @@ struct brcmf_flowring_hash {
24 u8 mac[ETH_ALEN]; 24 u8 mac[ETH_ALEN];
25 u8 fifo; 25 u8 fifo;
26 u8 ifidx; 26 u8 ifidx;
27 u8 flowid; 27 u16 flowid;
28}; 28};
29 29
30enum ring_status { 30enum ring_status {
@@ -61,16 +61,16 @@ u32 brcmf_flowring_lookup(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
61 u8 prio, u8 ifidx); 61 u8 prio, u8 ifidx);
62u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN], 62u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
63 u8 prio, u8 ifidx); 63 u8 prio, u8 ifidx);
64void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid); 64void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid);
65void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid); 65void brcmf_flowring_open(struct brcmf_flowring *flow, u16 flowid);
66u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid); 66u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u16 flowid);
67u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, 67u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u16 flowid,
68 struct sk_buff *skb); 68 struct sk_buff *skb);
69struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid); 69struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u16 flowid);
70void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, 70void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u16 flowid,
71 struct sk_buff *skb); 71 struct sk_buff *skb);
72u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid); 72u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u16 flowid);
73u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid); 73u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u16 flowid);
74struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings); 74struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings);
75void brcmf_flowring_detach(struct brcmf_flowring *flow); 75void brcmf_flowring_detach(struct brcmf_flowring *flow);
76void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx, 76void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx,
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
index 7b26fb1b437c..d414fbbcc814 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
@@ -26,50 +26,6 @@
26#include "fwil.h" 26#include "fwil.h"
27 27
28/** 28/**
29 * struct brcm_ethhdr - broadcom specific ether header.
30 *
31 * @subtype: subtype for this packet.
32 * @length: TODO: length of appended data.
33 * @version: version indication.
34 * @oui: OUI of this packet.
35 * @usr_subtype: subtype for this OUI.
36 */
37struct brcm_ethhdr {
38 __be16 subtype;
39 __be16 length;
40 u8 version;
41 u8 oui[3];
42 __be16 usr_subtype;
43} __packed;
44
45struct brcmf_event_msg_be {
46 __be16 version;
47 __be16 flags;
48 __be32 event_type;
49 __be32 status;
50 __be32 reason;
51 __be32 auth_type;
52 __be32 datalen;
53 u8 addr[ETH_ALEN];
54 char ifname[IFNAMSIZ];
55 u8 ifidx;
56 u8 bsscfgidx;
57} __packed;
58
59/**
60 * struct brcmf_event - contents of broadcom event packet.
61 *
62 * @eth: standard ether header.
63 * @hdr: broadcom specific ether header.
64 * @msg: common part of the actual event message.
65 */
66struct brcmf_event {
67 struct ethhdr eth;
68 struct brcm_ethhdr hdr;
69 struct brcmf_event_msg_be msg;
70} __packed;
71
72/**
73 * struct brcmf_fweh_queue_item - event item on event queue. 29 * struct brcmf_fweh_queue_item - event item on event queue.
74 * 30 *
75 * @q: list element for queuing. 31 * @q: list element for queuing.
@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item {
85 u8 ifidx; 41 u8 ifidx;
86 u8 ifaddr[ETH_ALEN]; 42 u8 ifaddr[ETH_ALEN];
87 struct brcmf_event_msg_be emsg; 43 struct brcmf_event_msg_be emsg;
44 u32 datalen;
88 u8 data[0]; 45 u8 data[0];
89}; 46};
90 47
@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
294 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, 251 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
295 min_t(u32, emsg.datalen, 64), 252 min_t(u32, emsg.datalen, 64),
296 "event payload, len=%d\n", emsg.datalen); 253 "event payload, len=%d\n", emsg.datalen);
254 if (emsg.datalen > event->datalen) {
255 brcmf_err("event invalid length header=%d, msg=%d\n",
256 event->datalen, emsg.datalen);
257 goto event_free;
258 }
297 259
298 /* special handling of interface event */ 260 /* special handling of interface event */
299 if (event->code == BRCMF_E_IF) { 261 if (event->code == BRCMF_E_IF) {
@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
439 * dispatch the event to a registered handler (using worker). 401 * dispatch the event to a registered handler (using worker).
440 */ 402 */
441void brcmf_fweh_process_event(struct brcmf_pub *drvr, 403void brcmf_fweh_process_event(struct brcmf_pub *drvr,
442 struct brcmf_event *event_packet) 404 struct brcmf_event *event_packet,
405 u32 packet_len)
443{ 406{
444 enum brcmf_fweh_event_code code; 407 enum brcmf_fweh_event_code code;
445 struct brcmf_fweh_info *fweh = &drvr->fweh; 408 struct brcmf_fweh_info *fweh = &drvr->fweh;
@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
459 if (code != BRCMF_E_IF && !fweh->evt_handler[code]) 422 if (code != BRCMF_E_IF && !fweh->evt_handler[code])
460 return; 423 return;
461 424
425 if (datalen > BRCMF_DCMD_MAXLEN)
426 return;
427
462 if (in_interrupt()) 428 if (in_interrupt())
463 alloc_flag = GFP_ATOMIC; 429 alloc_flag = GFP_ATOMIC;
464 430
@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
472 /* use memcpy to get aligned event message */ 438 /* use memcpy to get aligned event message */
473 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); 439 memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg));
474 memcpy(event->data, data, datalen); 440 memcpy(event->data, data, datalen);
441 event->datalen = datalen;
475 memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); 442 memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN);
476 443
477 brcmf_fweh_queue_event(fweh, event); 444 brcmf_fweh_queue_event(fweh, event);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
index 5e39e2a9e388..26ff5a9648f3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
@@ -27,7 +27,6 @@
27struct brcmf_pub; 27struct brcmf_pub;
28struct brcmf_if; 28struct brcmf_if;
29struct brcmf_cfg80211_info; 29struct brcmf_cfg80211_info;
30struct brcmf_event;
31 30
32/* list of firmware events */ 31/* list of firmware events */
33#define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ 32#define BRCMF_FWEH_EVENT_ENUM_DEFLIST \
@@ -180,13 +179,55 @@ enum brcmf_fweh_event_code {
180/** 179/**
181 * definitions for event packet validation. 180 * definitions for event packet validation.
182 */ 181 */
183#define BRCMF_EVENT_OUI_OFFSET 19 182#define BRCM_OUI "\x00\x10\x18"
184#define BRCM_OUI "\x00\x10\x18" 183#define BCMILCP_BCM_SUBTYPE_EVENT 1
185#define DOT11_OUI_LEN 3
186#define BCMILCP_BCM_SUBTYPE_EVENT 1
187 184
188 185
189/** 186/**
187 * struct brcm_ethhdr - broadcom specific ether header.
188 *
189 * @subtype: subtype for this packet.
190 * @length: TODO: length of appended data.
191 * @version: version indication.
192 * @oui: OUI of this packet.
193 * @usr_subtype: subtype for this OUI.
194 */
195struct brcm_ethhdr {
196 __be16 subtype;
197 __be16 length;
198 u8 version;
199 u8 oui[3];
200 __be16 usr_subtype;
201} __packed;
202
203struct brcmf_event_msg_be {
204 __be16 version;
205 __be16 flags;
206 __be32 event_type;
207 __be32 status;
208 __be32 reason;
209 __be32 auth_type;
210 __be32 datalen;
211 u8 addr[ETH_ALEN];
212 char ifname[IFNAMSIZ];
213 u8 ifidx;
214 u8 bsscfgidx;
215} __packed;
216
217/**
218 * struct brcmf_event - contents of broadcom event packet.
219 *
220 * @eth: standard ether header.
221 * @hdr: broadcom specific ether header.
222 * @msg: common part of the actual event message.
223 */
224struct brcmf_event {
225 struct ethhdr eth;
226 struct brcm_ethhdr hdr;
227 struct brcmf_event_msg_be msg;
228} __packed;
229
230/**
190 * struct brcmf_event_msg - firmware event message. 231 * struct brcmf_event_msg - firmware event message.
191 * 232 *
192 * @version: version information. 233 * @version: version information.
@@ -256,34 +297,35 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr,
256 enum brcmf_fweh_event_code code); 297 enum brcmf_fweh_event_code code);
257int brcmf_fweh_activate_events(struct brcmf_if *ifp); 298int brcmf_fweh_activate_events(struct brcmf_if *ifp);
258void brcmf_fweh_process_event(struct brcmf_pub *drvr, 299void brcmf_fweh_process_event(struct brcmf_pub *drvr,
259 struct brcmf_event *event_packet); 300 struct brcmf_event *event_packet,
301 u32 packet_len);
260void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); 302void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
261 303
262static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, 304static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
263 struct sk_buff *skb) 305 struct sk_buff *skb)
264{ 306{
265 struct brcmf_event *event_packet; 307 struct brcmf_event *event_packet;
266 u8 *data;
267 u16 usr_stype; 308 u16 usr_stype;
268 309
269 /* only process events when protocol matches */ 310 /* only process events when protocol matches */
270 if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) 311 if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
271 return; 312 return;
272 313
314 if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
315 return;
316
273 /* check for BRCM oui match */ 317 /* check for BRCM oui match */
274 event_packet = (struct brcmf_event *)skb_mac_header(skb); 318 event_packet = (struct brcmf_event *)skb_mac_header(skb);
275 data = (u8 *)event_packet; 319 if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
276 data += BRCMF_EVENT_OUI_OFFSET; 320 sizeof(event_packet->hdr.oui)))
277 if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN))
278 return; 321 return;
279 322
280 /* final match on usr_subtype */ 323 /* final match on usr_subtype */
281 data += DOT11_OUI_LEN; 324 usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype);
282 usr_stype = get_unaligned_be16(data);
283 if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) 325 if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
284 return; 326 return;
285 327
286 brcmf_fweh_process_event(drvr, event_packet); 328 brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
287} 329}
288 330
289#endif /* FWEH_H_ */ 331#endif /* FWEH_H_ */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
index 1afc2ad83b6c..a4118c0ef6ca 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -111,7 +111,9 @@
111/* Wakeup if received matched secured pattern: */ 111/* Wakeup if received matched secured pattern: */
112#define BRCMF_WOWL_SECURE (1 << 25) 112#define BRCMF_WOWL_SECURE (1 << 25)
113/* Wakeup on finding preferred network */ 113/* Wakeup on finding preferred network */
114#define BRCMF_WOWL_PFN_FOUND (1 << 26) 114#define BRCMF_WOWL_PFN_FOUND (1 << 27)
115/* Wakeup on receiving pairwise key EAP packets: */
116#define WIPHY_WOWL_EAP_PK (1 << 28)
115/* Link Down indication in WoWL mode: */ 117/* Link Down indication in WoWL mode: */
116#define BRCMF_WOWL_LINKDOWN (1 << 31) 118#define BRCMF_WOWL_LINKDOWN (1 << 31)
117 119
@@ -134,6 +136,16 @@
134#define BRCMF_PFN_MAC_OUI_ONLY BIT(0) 136#define BRCMF_PFN_MAC_OUI_ONLY BIT(0)
135#define BRCMF_PFN_SET_MAC_UNASSOC BIT(1) 137#define BRCMF_PFN_SET_MAC_UNASSOC BIT(1)
136 138
139#define BRCMF_MCSSET_LEN 16
140
141#define BRCMF_RSN_KCK_LENGTH 16
142#define BRCMF_RSN_KEK_LENGTH 16
143#define BRCMF_RSN_REPLAY_LEN 8
144
145#define BRCMF_MFP_NONE 0
146#define BRCMF_MFP_CAPABLE 1
147#define BRCMF_MFP_REQUIRED 2
148
137/* join preference types for join_pref iovar */ 149/* join preference types for join_pref iovar */
138enum brcmf_join_pref_types { 150enum brcmf_join_pref_types {
139 BRCMF_JOIN_PREF_RSSI = 1, 151 BRCMF_JOIN_PREF_RSSI = 1,
@@ -279,7 +291,7 @@ struct brcmf_bss_info_le {
279 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ 291 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
280 u8 flags; /* flags */ 292 u8 flags; /* flags */
281 u8 reserved[3]; /* Reserved for expansion of BSS properties */ 293 u8 reserved[3]; /* Reserved for expansion of BSS properties */
282 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ 294 u8 basic_mcs[BRCMF_MCSSET_LEN]; /* 802.11N BSS required MCS set */
283 295
284 __le16 ie_offset; /* offset at which IEs start, from beginning */ 296 __le16 ie_offset; /* offset at which IEs start, from beginning */
285 __le32 ie_length; /* byte length of Information Elements */ 297 __le32 ie_length; /* byte length of Information Elements */
@@ -787,4 +799,17 @@ struct brcmf_pktcnt_le {
787 __le32 rx_ocast_good_pkt; 799 __le32 rx_ocast_good_pkt;
788}; 800};
789 801
802/**
803 * struct brcmf_gtk_keyinfo_le - GTP rekey data
804 *
805 * @kck: key confirmation key.
806 * @kek: key encryption key.
807 * @replay_counter: replay counter.
808 */
809struct brcmf_gtk_keyinfo_le {
810 u8 kck[BRCMF_RSN_KCK_LENGTH];
811 u8 kek[BRCMF_RSN_KEK_LENGTH];
812 u8 replay_counter[BRCMF_RSN_REPLAY_LEN];
813};
814
790#endif /* FWIL_TYPES_H_ */ 815#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index c2bdb91746cf..922966734a7f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -677,7 +677,7 @@ static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx,
677} 677}
678 678
679 679
680static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid) 680static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid)
681{ 681{
682 struct brcmf_flowring *flow = msgbuf->flow; 682 struct brcmf_flowring *flow = msgbuf->flow;
683 struct brcmf_commonring *commonring; 683 struct brcmf_commonring *commonring;
@@ -1310,7 +1310,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
1310} 1310}
1311 1311
1312 1312
1313void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid) 1313void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid)
1314{ 1314{
1315 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; 1315 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1316 struct msgbuf_tx_flowring_delete_req *delete; 1316 struct msgbuf_tx_flowring_delete_req *delete;
@@ -1415,6 +1415,13 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1415 u32 count; 1415 u32 count;
1416 1416
1417 if_msgbuf = drvr->bus_if->msgbuf; 1417 if_msgbuf = drvr->bus_if->msgbuf;
1418
1419 if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
1420 brcmf_err("driver not configured for this many flowrings %d\n",
1421 if_msgbuf->nrof_flowrings);
1422 if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
1423 }
1424
1418 msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL); 1425 msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL);
1419 if (!msgbuf) 1426 if (!msgbuf)
1420 goto fail; 1427 goto fail;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
index 3d513e407e3d..ee6906a3c3f6 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
@@ -33,7 +33,7 @@
33 33
34 34
35int brcmf_proto_msgbuf_rx_trigger(struct device *dev); 35int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
36void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid); 36void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid);
37int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr); 37int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr);
38void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr); 38void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr);
39#else 39#else
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
index 03f35e0c52ca..425c41dc0a59 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -16,17 +16,15 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/of_irq.h> 18#include <linux/of_irq.h>
19#include <linux/mmc/card.h>
20#include <linux/platform_data/brcmfmac-sdio.h>
21#include <linux/mmc/sdio_func.h>
22 19
23#include <defs.h> 20#include <defs.h>
24#include "debug.h" 21#include "debug.h"
25#include "sdio.h" 22#include "core.h"
23#include "common.h"
24#include "of.h"
26 25
27void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) 26void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
28{ 27{
29 struct device *dev = sdiodev->dev;
30 struct device_node *np = dev->of_node; 28 struct device_node *np = dev->of_node;
31 int irq; 29 int irq;
32 u32 irqf; 30 u32 irqf;
@@ -35,12 +33,8 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
35 if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) 33 if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
36 return; 34 return;
37 35
38 sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL);
39 if (!sdiodev->pdata)
40 return;
41
42 if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) 36 if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
43 sdiodev->pdata->drive_strength = val; 37 sdio->drive_strength = val;
44 38
45 /* make sure there are interrupts defined in the node */ 39 /* make sure there are interrupts defined in the node */
46 if (!of_find_property(np, "interrupts", NULL)) 40 if (!of_find_property(np, "interrupts", NULL))
@@ -53,7 +47,7 @@ void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev)
53 } 47 }
54 irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); 48 irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
55 49
56 sdiodev->pdata->oob_irq_supported = true; 50 sdio->oob_irq_supported = true;
57 sdiodev->pdata->oob_irq_nr = irq; 51 sdio->oob_irq_nr = irq;
58 sdiodev->pdata->oob_irq_flags = irqf; 52 sdio->oob_irq_flags = irqf;
59} 53}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
index 5f7c3550deda..a9d94c15d0f5 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
@@ -14,9 +14,9 @@
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16#ifdef CONFIG_OF 16#ifdef CONFIG_OF
17void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev); 17void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio);
18#else 18#else
19static void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) 19static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio)
20{ 20{
21} 21}
22#endif /* CONFIG_OF */ 22#endif /* CONFIG_OF */
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index 821b6494f9d1..b5a49e564f25 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -1361,6 +1361,11 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp,
1361 u16 mgmt_type; 1361 u16 mgmt_type;
1362 u8 action; 1362 u8 action;
1363 1363
1364 if (e->datalen < sizeof(*rxframe)) {
1365 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
1366 return 0;
1367 }
1368
1364 ch.chspec = be16_to_cpu(rxframe->chanspec); 1369 ch.chspec = be16_to_cpu(rxframe->chanspec);
1365 cfg->d11inf.decchspec(&ch); 1370 cfg->d11inf.decchspec(&ch);
1366 /* Check if wpa_supplicant has registered for this frame */ 1371 /* Check if wpa_supplicant has registered for this frame */
@@ -1858,6 +1863,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
1858 brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, 1863 brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code,
1859 e->reason); 1864 e->reason);
1860 1865
1866 if (e->datalen < sizeof(*rxframe)) {
1867 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
1868 return 0;
1869 }
1870
1861 ch.chspec = be16_to_cpu(rxframe->chanspec); 1871 ch.chspec = be16_to_cpu(rxframe->chanspec);
1862 cfg->d11inf.decchspec(&ch); 1872 cfg->d11inf.decchspec(&ch);
1863 1873
@@ -1988,8 +1998,8 @@ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
1988 brcmf_cfg80211_arm_vif_event(cfg, NULL); 1998 brcmf_cfg80211_arm_vif_event(cfg, NULL);
1989 return err; 1999 return err;
1990 } 2000 }
1991 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE, 2001 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_CHANGE,
1992 BRCMF_VIF_EVENT_TIMEOUT); 2002 BRCMF_VIF_EVENT_TIMEOUT);
1993 brcmf_cfg80211_arm_vif_event(cfg, NULL); 2003 brcmf_cfg80211_arm_vif_event(cfg, NULL);
1994 if (!err) { 2004 if (!err) {
1995 brcmf_err("No BRCMF_E_IF_CHANGE event received\n"); 2005 brcmf_err("No BRCMF_E_IF_CHANGE event received\n");
@@ -2090,8 +2100,8 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p,
2090 } 2100 }
2091 2101
2092 /* wait for firmware event */ 2102 /* wait for firmware event */
2093 err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD, 2103 err = brcmf_cfg80211_wait_vif_event(p2p->cfg, BRCMF_E_IF_ADD,
2094 BRCMF_VIF_EVENT_TIMEOUT); 2104 BRCMF_VIF_EVENT_TIMEOUT);
2095 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); 2105 brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
2096 brcmf_fweh_p2pdev_setup(pri_ifp, false); 2106 brcmf_fweh_p2pdev_setup(pri_ifp, false);
2097 if (!err) { 2107 if (!err) {
@@ -2180,8 +2190,8 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
2180 } 2190 }
2181 2191
2182 /* wait for firmware event */ 2192 /* wait for firmware event */
2183 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, 2193 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
2184 BRCMF_VIF_EVENT_TIMEOUT); 2194 BRCMF_VIF_EVENT_TIMEOUT);
2185 brcmf_cfg80211_arm_vif_event(cfg, NULL); 2195 brcmf_cfg80211_arm_vif_event(cfg, NULL);
2186 if (!err) { 2196 if (!err) {
2187 brcmf_err("timeout occurred\n"); 2197 brcmf_err("timeout occurred\n");
@@ -2272,8 +2282,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
2272 } 2282 }
2273 if (!err) { 2283 if (!err) {
2274 /* wait for firmware event */ 2284 /* wait for firmware event */
2275 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL, 2285 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
2276 BRCMF_VIF_EVENT_TIMEOUT); 2286 BRCMF_VIF_EVENT_TIMEOUT);
2277 if (!err) 2287 if (!err)
2278 err = -EIO; 2288 err = -EIO;
2279 else 2289 else
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
index d5f9ef470447..52fef5e1d615 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -37,6 +37,8 @@
37#include "pcie.h" 37#include "pcie.h"
38#include "firmware.h" 38#include "firmware.h"
39#include "chip.h" 39#include "chip.h"
40#include "core.h"
41#include "common.h"
40 42
41 43
42enum brcmf_pcie_state { 44enum brcmf_pcie_state {
@@ -53,6 +55,7 @@ BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-pcie.bin", "brcmfmac4358-pcie.txt");
53BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); 55BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt");
54BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); 56BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt");
55BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); 57BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt");
58BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt");
56BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); 59BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt");
57 60
58static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { 61static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
@@ -66,13 +69,13 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
66 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), 69 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358),
67 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), 70 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359),
68 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B), 71 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B),
69 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFFF, 4366B), 72 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B),
73 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C),
70 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), 74 BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371),
71}; 75};
72 76
73#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ 77#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
74 78
75#define BRCMF_PCIE_TCM_MAP_SIZE (4096 * 1024)
76#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) 79#define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024)
77 80
78/* backplane addres space accessed by BAR0 */ 81/* backplane addres space accessed by BAR0 */
@@ -99,9 +102,6 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
99#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 102#define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124
100#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140 103#define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140
101 104
102#define BRCMF_PCIE_GENREV1 1
103#define BRCMF_PCIE_GENREV2 2
104
105#define BRCMF_PCIE2_INTA 0x01 105#define BRCMF_PCIE2_INTA 0x01
106#define BRCMF_PCIE2_INTB 0x02 106#define BRCMF_PCIE2_INTB 0x02
107 107
@@ -207,6 +207,10 @@ static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = {
207#define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 0x4F4 207#define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 0x4F4
208#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3 208#define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3
209 209
210/* Magic number at a magic location to find RAM size */
211#define BRCMF_RAMSIZE_MAGIC 0x534d4152 /* SMAR */
212#define BRCMF_RAMSIZE_OFFSET 0x6c
213
210 214
211struct brcmf_pcie_console { 215struct brcmf_pcie_console {
212 u32 base_addr; 216 u32 base_addr;
@@ -248,14 +252,11 @@ struct brcmf_pciedev_info {
248 char nvram_name[BRCMF_FW_NAME_LEN]; 252 char nvram_name[BRCMF_FW_NAME_LEN];
249 void __iomem *regs; 253 void __iomem *regs;
250 void __iomem *tcm; 254 void __iomem *tcm;
251 u32 tcm_size;
252 u32 ram_base; 255 u32 ram_base;
253 u32 ram_size; 256 u32 ram_size;
254 struct brcmf_chip *ci; 257 struct brcmf_chip *ci;
255 u32 coreid; 258 u32 coreid;
256 u32 generic_corerev;
257 struct brcmf_pcie_shared_info shared; 259 struct brcmf_pcie_shared_info shared;
258 void (*ringbell)(struct brcmf_pciedev_info *devinfo);
259 wait_queue_head_t mbdata_resp_wait; 260 wait_queue_head_t mbdata_resp_wait;
260 bool mbdata_completed; 261 bool mbdata_completed;
261 bool irq_allocated; 262 bool irq_allocated;
@@ -267,6 +268,7 @@ struct brcmf_pciedev_info {
267 u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset); 268 u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset);
268 void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset, 269 void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
269 u16 value); 270 u16 value);
271 struct brcmf_mp_device *settings;
270}; 272};
271 273
272struct brcmf_pcie_ringbuf { 274struct brcmf_pcie_ringbuf {
@@ -742,68 +744,22 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo)
742} 744}
743 745
744 746
745static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo)
746{
747 u32 reg_value;
748
749 brcmf_dbg(PCIE, "RING !\n");
750 reg_value = brcmf_pcie_read_reg32(devinfo,
751 BRCMF_PCIE_PCIE2REG_MAILBOXINT);
752 reg_value |= BRCMF_PCIE2_INTB;
753 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
754 reg_value);
755}
756
757
758static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo)
759{
760 brcmf_dbg(PCIE, "RING !\n");
761 /* Any arbitrary value will do, lets use 1 */
762 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1);
763}
764
765
766static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo) 747static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo)
767{ 748{
768 if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) 749 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0);
769 pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK,
770 0);
771 else
772 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
773 0);
774} 750}
775 751
776 752
777static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo) 753static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo)
778{ 754{
779 if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) 755 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
780 pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, 756 BRCMF_PCIE_MB_INT_D2H_DB |
781 BRCMF_PCIE_INT_DEF); 757 BRCMF_PCIE_MB_INT_FN0_0 |
782 else 758 BRCMF_PCIE_MB_INT_FN0_1);
783 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK,
784 BRCMF_PCIE_MB_INT_D2H_DB |
785 BRCMF_PCIE_MB_INT_FN0_0 |
786 BRCMF_PCIE_MB_INT_FN0_1);
787}
788
789
790static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg)
791{
792 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
793 u32 status;
794
795 status = 0;
796 pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
797 if (status) {
798 brcmf_pcie_intr_disable(devinfo);
799 brcmf_dbg(PCIE, "Enter\n");
800 return IRQ_WAKE_THREAD;
801 }
802 return IRQ_NONE;
803} 759}
804 760
805 761
806static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg) 762static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg)
807{ 763{
808 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; 764 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
809 765
@@ -816,29 +772,7 @@ static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg)
816} 772}
817 773
818 774
819static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg) 775static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg)
820{
821 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
822 const struct pci_dev *pdev = devinfo->pdev;
823 u32 status;
824
825 devinfo->in_irq = true;
826 status = 0;
827 pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status);
828 brcmf_dbg(PCIE, "Enter %x\n", status);
829 if (status) {
830 pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
831 if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
832 brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev);
833 }
834 if (devinfo->state == BRCMFMAC_PCIE_STATE_UP)
835 brcmf_pcie_intr_enable(devinfo);
836 devinfo->in_irq = false;
837 return IRQ_HANDLED;
838}
839
840
841static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg)
842{ 776{
843 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; 777 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg;
844 u32 status; 778 u32 status;
@@ -875,28 +809,14 @@ static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
875 brcmf_pcie_intr_disable(devinfo); 809 brcmf_pcie_intr_disable(devinfo);
876 810
877 brcmf_dbg(PCIE, "Enter\n"); 811 brcmf_dbg(PCIE, "Enter\n");
878 /* is it a v1 or v2 implementation */ 812
879 pci_enable_msi(pdev); 813 pci_enable_msi(pdev);
880 if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { 814 if (request_threaded_irq(pdev->irq, brcmf_pcie_quick_check_isr,
881 if (request_threaded_irq(pdev->irq, 815 brcmf_pcie_isr_thread, IRQF_SHARED,
882 brcmf_pcie_quick_check_isr_v1, 816 "brcmf_pcie_intr", devinfo)) {
883 brcmf_pcie_isr_thread_v1, 817 pci_disable_msi(pdev);
884 IRQF_SHARED, "brcmf_pcie_intr", 818 brcmf_err("Failed to request IRQ %d\n", pdev->irq);
885 devinfo)) { 819 return -EIO;
886 pci_disable_msi(pdev);
887 brcmf_err("Failed to request IRQ %d\n", pdev->irq);
888 return -EIO;
889 }
890 } else {
891 if (request_threaded_irq(pdev->irq,
892 brcmf_pcie_quick_check_isr_v2,
893 brcmf_pcie_isr_thread_v2,
894 IRQF_SHARED, "brcmf_pcie_intr",
895 devinfo)) {
896 pci_disable_msi(pdev);
897 brcmf_err("Failed to request IRQ %d\n", pdev->irq);
898 return -EIO;
899 }
900 } 820 }
901 devinfo->irq_allocated = true; 821 devinfo->irq_allocated = true;
902 return 0; 822 return 0;
@@ -927,16 +847,9 @@ static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
927 if (devinfo->in_irq) 847 if (devinfo->in_irq)
928 brcmf_err("Still in IRQ (processing) !!!\n"); 848 brcmf_err("Still in IRQ (processing) !!!\n");
929 849
930 if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { 850 status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
931 status = 0; 851 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
932 pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); 852
933 pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status);
934 } else {
935 status = brcmf_pcie_read_reg32(devinfo,
936 BRCMF_PCIE_PCIE2REG_MAILBOXINT);
937 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
938 status);
939 }
940 devinfo->irq_allocated = false; 853 devinfo->irq_allocated = false;
941} 854}
942 855
@@ -985,7 +898,9 @@ static int brcmf_pcie_ring_mb_ring_bell(void *ctx)
985 if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) 898 if (devinfo->state != BRCMFMAC_PCIE_STATE_UP)
986 return -EIO; 899 return -EIO;
987 900
988 devinfo->ringbell(devinfo); 901 brcmf_dbg(PCIE, "RING !\n");
902 /* Any arbitrary value will do, lets use 1 */
903 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1);
989 904
990 return 0; 905 return 0;
991} 906}
@@ -1412,6 +1327,28 @@ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
1412}; 1327};
1413 1328
1414 1329
1330static void
1331brcmf_pcie_adjust_ramsize(struct brcmf_pciedev_info *devinfo, u8 *data,
1332 u32 data_len)
1333{
1334 __le32 *field;
1335 u32 newsize;
1336
1337 if (data_len < BRCMF_RAMSIZE_OFFSET + 8)
1338 return;
1339
1340 field = (__le32 *)&data[BRCMF_RAMSIZE_OFFSET];
1341 if (le32_to_cpup(field) != BRCMF_RAMSIZE_MAGIC)
1342 return;
1343 field++;
1344 newsize = le32_to_cpup(field);
1345
1346 brcmf_dbg(PCIE, "Found ramsize info in FW, adjusting to 0x%x\n",
1347 newsize);
1348 devinfo->ci->ramsize = newsize;
1349}
1350
1351
1415static int 1352static int
1416brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, 1353brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
1417 u32 sharedram_addr) 1354 u32 sharedram_addr)
@@ -1477,9 +1414,6 @@ static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo,
1477 u32 address; 1414 u32 address;
1478 u32 resetintr; 1415 u32 resetintr;
1479 1416
1480 devinfo->ringbell = brcmf_pcie_ringbell_v2;
1481 devinfo->generic_corerev = BRCMF_PCIE_GENREV2;
1482
1483 brcmf_dbg(PCIE, "Halt ARM.\n"); 1417 brcmf_dbg(PCIE, "Halt ARM.\n");
1484 err = brcmf_pcie_enter_download_state(devinfo); 1418 err = brcmf_pcie_enter_download_state(devinfo);
1485 if (err) 1419 if (err)
@@ -1566,8 +1500,7 @@ static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
1566 } 1500 }
1567 1501
1568 devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE); 1502 devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE);
1569 devinfo->tcm = ioremap_nocache(bar1_addr, BRCMF_PCIE_TCM_MAP_SIZE); 1503 devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size);
1570 devinfo->tcm_size = BRCMF_PCIE_TCM_MAP_SIZE;
1571 1504
1572 if (!devinfo->regs || !devinfo->tcm) { 1505 if (!devinfo->regs || !devinfo->tcm) {
1573 brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, 1506 brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs,
@@ -1576,8 +1509,9 @@ static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
1576 } 1509 }
1577 brcmf_dbg(PCIE, "Phys addr : reg space = %p base addr %#016llx\n", 1510 brcmf_dbg(PCIE, "Phys addr : reg space = %p base addr %#016llx\n",
1578 devinfo->regs, (unsigned long long)bar0_addr); 1511 devinfo->regs, (unsigned long long)bar0_addr);
1579 brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx\n", 1512 brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx size 0x%x\n",
1580 devinfo->tcm, (unsigned long long)bar1_addr); 1513 devinfo->tcm, (unsigned long long)bar1_addr,
1514 (unsigned int)bar1_size);
1581 1515
1582 return 0; 1516 return 0;
1583} 1517}
@@ -1594,16 +1528,16 @@ static void brcmf_pcie_release_resource(struct brcmf_pciedev_info *devinfo)
1594} 1528}
1595 1529
1596 1530
1597static int brcmf_pcie_attach_bus(struct device *dev) 1531static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo)
1598{ 1532{
1599 int ret; 1533 int ret;
1600 1534
1601 /* Attach to the common driver interface */ 1535 /* Attach to the common driver interface */
1602 ret = brcmf_attach(dev); 1536 ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings);
1603 if (ret) { 1537 if (ret) {
1604 brcmf_err("brcmf_attach failed\n"); 1538 brcmf_err("brcmf_attach failed\n");
1605 } else { 1539 } else {
1606 ret = brcmf_bus_start(dev); 1540 ret = brcmf_bus_start(&devinfo->pdev->dev);
1607 if (ret) 1541 if (ret)
1608 brcmf_err("dongle is not responding\n"); 1542 brcmf_err("dongle is not responding\n");
1609 } 1543 }
@@ -1694,6 +1628,13 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
1694 1628
1695 brcmf_pcie_attach(devinfo); 1629 brcmf_pcie_attach(devinfo);
1696 1630
1631 /* Some of the firmwares have the size of the memory of the device
1632 * defined inside the firmware. This is because part of the memory in
1633 * the device is shared and the devision is determined by FW. Parse
1634 * the firmware and adjust the chip memory size now.
1635 */
1636 brcmf_pcie_adjust_ramsize(devinfo, (u8 *)fw->data, fw->size);
1637
1697 ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len); 1638 ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len);
1698 if (ret) 1639 if (ret)
1699 goto fail; 1640 goto fail;
@@ -1734,7 +1675,7 @@ static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
1734 init_waitqueue_head(&devinfo->mbdata_resp_wait); 1675 init_waitqueue_head(&devinfo->mbdata_resp_wait);
1735 1676
1736 brcmf_pcie_intr_enable(devinfo); 1677 brcmf_pcie_intr_enable(devinfo);
1737 if (brcmf_pcie_attach_bus(bus->dev) == 0) 1678 if (brcmf_pcie_attach_bus(devinfo) == 0)
1738 return; 1679 return;
1739 1680
1740 brcmf_pcie_bus_console_read(devinfo); 1681 brcmf_pcie_bus_console_read(devinfo);
@@ -1778,6 +1719,15 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1778 goto fail; 1719 goto fail;
1779 } 1720 }
1780 1721
1722 devinfo->settings = brcmf_get_module_param(&devinfo->pdev->dev,
1723 BRCMF_BUSTYPE_PCIE,
1724 devinfo->ci->chip,
1725 devinfo->ci->chiprev);
1726 if (!devinfo->settings) {
1727 ret = -ENOMEM;
1728 goto fail;
1729 }
1730
1781 bus = kzalloc(sizeof(*bus), GFP_KERNEL); 1731 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
1782 if (!bus) { 1732 if (!bus) {
1783 ret = -ENOMEM; 1733 ret = -ENOMEM;
@@ -1822,6 +1772,8 @@ fail:
1822 brcmf_pcie_release_resource(devinfo); 1772 brcmf_pcie_release_resource(devinfo);
1823 if (devinfo->ci) 1773 if (devinfo->ci)
1824 brcmf_chip_detach(devinfo->ci); 1774 brcmf_chip_detach(devinfo->ci);
1775 if (devinfo->settings)
1776 brcmf_release_module_param(devinfo->settings);
1825 kfree(pcie_bus_dev); 1777 kfree(pcie_bus_dev);
1826 kfree(devinfo); 1778 kfree(devinfo);
1827 return ret; 1779 return ret;
@@ -1861,6 +1813,8 @@ brcmf_pcie_remove(struct pci_dev *pdev)
1861 1813
1862 if (devinfo->ci) 1814 if (devinfo->ci)
1863 brcmf_chip_detach(devinfo->ci); 1815 brcmf_chip_detach(devinfo->ci);
1816 if (devinfo->settings)
1817 brcmf_release_module_param(devinfo->settings);
1864 1818
1865 kfree(devinfo); 1819 kfree(devinfo);
1866 dev_set_drvdata(&pdev->dev, NULL); 1820 dev_set_drvdata(&pdev->dev, NULL);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index c790fa89db05..43fd3f402eba 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -33,8 +33,6 @@
33#include <linux/bcma/bcma.h> 33#include <linux/bcma/bcma.h>
34#include <linux/debugfs.h> 34#include <linux/debugfs.h>
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/platform_data/brcmfmac-sdio.h>
37#include <linux/moduleparam.h>
38#include <asm/unaligned.h> 36#include <asm/unaligned.h>
39#include <defs.h> 37#include <defs.h>
40#include <brcmu_wifi.h> 38#include <brcmu_wifi.h>
@@ -44,6 +42,8 @@
44#include "sdio.h" 42#include "sdio.h"
45#include "chip.h" 43#include "chip.h"
46#include "firmware.h" 44#include "firmware.h"
45#include "core.h"
46#include "common.h"
47 47
48#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) 48#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
49#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) 49#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
@@ -2442,15 +2442,17 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2442 2442
2443static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) 2443static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus)
2444{ 2444{
2445 struct brcmf_sdio_dev *sdiodev;
2445 unsigned long flags; 2446 unsigned long flags;
2446 2447
2447 if (bus->sdiodev->oob_irq_requested) { 2448 sdiodev = bus->sdiodev;
2448 spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); 2449 if (sdiodev->oob_irq_requested) {
2449 if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { 2450 spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
2450 enable_irq(bus->sdiodev->pdata->oob_irq_nr); 2451 if (!sdiodev->irq_en && !atomic_read(&bus->ipend)) {
2451 bus->sdiodev->irq_en = true; 2452 enable_irq(sdiodev->settings->bus.sdio.oob_irq_nr);
2453 sdiodev->irq_en = true;
2452 } 2454 }
2453 spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); 2455 spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
2454 } 2456 }
2455} 2457}
2456 2458
@@ -3394,9 +3396,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
3394 sizeof(u32)); 3396 sizeof(u32));
3395 } else { 3397 } else {
3396 /* otherwise, set txglomalign */ 3398 /* otherwise, set txglomalign */
3397 value = 4; 3399 value = sdiodev->settings->bus.sdio.sd_sgentry_align;
3398 if (sdiodev->pdata)
3399 value = sdiodev->pdata->sd_sgentry_align;
3400 /* SDIO ADMA requires at least 32 bit alignment */ 3400 /* SDIO ADMA requires at least 32 bit alignment */
3401 value = max_t(u32, value, 4); 3401 value = max_t(u32, value, 4);
3402 err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, 3402 err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
@@ -3775,26 +3775,28 @@ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
3775static bool 3775static bool
3776brcmf_sdio_probe_attach(struct brcmf_sdio *bus) 3776brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3777{ 3777{
3778 struct brcmf_sdio_dev *sdiodev;
3778 u8 clkctl = 0; 3779 u8 clkctl = 0;
3779 int err = 0; 3780 int err = 0;
3780 int reg_addr; 3781 int reg_addr;
3781 u32 reg_val; 3782 u32 reg_val;
3782 u32 drivestrength; 3783 u32 drivestrength;
3783 3784
3784 sdio_claim_host(bus->sdiodev->func[1]); 3785 sdiodev = bus->sdiodev;
3786 sdio_claim_host(sdiodev->func[1]);
3785 3787
3786 pr_debug("F1 signature read @0x18000000=0x%4x\n", 3788 pr_debug("F1 signature read @0x18000000=0x%4x\n",
3787 brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); 3789 brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL));
3788 3790
3789 /* 3791 /*
3790 * Force PLL off until brcmf_chip_attach() 3792 * Force PLL off until brcmf_chip_attach()
3791 * programs PLL control regs 3793 * programs PLL control regs
3792 */ 3794 */
3793 3795
3794 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 3796 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
3795 BRCMF_INIT_CLKCTL1, &err); 3797 BRCMF_INIT_CLKCTL1, &err);
3796 if (!err) 3798 if (!err)
3797 clkctl = brcmf_sdiod_regrb(bus->sdiodev, 3799 clkctl = brcmf_sdiod_regrb(sdiodev,
3798 SBSDIO_FUNC1_CHIPCLKCSR, &err); 3800 SBSDIO_FUNC1_CHIPCLKCSR, &err);
3799 3801
3800 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { 3802 if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) {
@@ -3803,50 +3805,81 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3803 goto fail; 3805 goto fail;
3804 } 3806 }
3805 3807
3806 bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); 3808 bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops);
3807 if (IS_ERR(bus->ci)) { 3809 if (IS_ERR(bus->ci)) {
3808 brcmf_err("brcmf_chip_attach failed!\n"); 3810 brcmf_err("brcmf_chip_attach failed!\n");
3809 bus->ci = NULL; 3811 bus->ci = NULL;
3810 goto fail; 3812 goto fail;
3811 } 3813 }
3814 sdiodev->settings = brcmf_get_module_param(sdiodev->dev,
3815 BRCMF_BUSTYPE_SDIO,
3816 bus->ci->chip,
3817 bus->ci->chiprev);
3818 if (!sdiodev->settings) {
3819 brcmf_err("Failed to get device parameters\n");
3820 goto fail;
3821 }
3822 /* platform specific configuration:
3823 * alignments must be at least 4 bytes for ADMA
3824 */
3825 bus->head_align = ALIGNMENT;
3826 bus->sgentry_align = ALIGNMENT;
3827 if (sdiodev->settings->bus.sdio.sd_head_align > ALIGNMENT)
3828 bus->head_align = sdiodev->settings->bus.sdio.sd_head_align;
3829 if (sdiodev->settings->bus.sdio.sd_sgentry_align > ALIGNMENT)
3830 bus->sgentry_align =
3831 sdiodev->settings->bus.sdio.sd_sgentry_align;
3832
3833 /* allocate scatter-gather table. sg support
3834 * will be disabled upon allocation failure.
3835 */
3836 brcmf_sdiod_sgtable_alloc(sdiodev);
3837
3838#ifdef CONFIG_PM_SLEEP
3839 /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ
3840 * is true or when platform data OOB irq is true).
3841 */
3842 if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) &&
3843 ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) ||
3844 (sdiodev->settings->bus.sdio.oob_irq_supported)))
3845 sdiodev->bus_if->wowl_supported = true;
3846#endif
3812 3847
3813 if (brcmf_sdio_kso_init(bus)) { 3848 if (brcmf_sdio_kso_init(bus)) {
3814 brcmf_err("error enabling KSO\n"); 3849 brcmf_err("error enabling KSO\n");
3815 goto fail; 3850 goto fail;
3816 } 3851 }
3817 3852
3818 if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) 3853 if (sdiodev->settings->bus.sdio.drive_strength)
3819 drivestrength = bus->sdiodev->pdata->drive_strength; 3854 drivestrength = sdiodev->settings->bus.sdio.drive_strength;
3820 else 3855 else
3821 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; 3856 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
3822 brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); 3857 brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength);
3823 3858
3824 /* Set card control so an SDIO card reset does a WLAN backplane reset */ 3859 /* Set card control so an SDIO card reset does a WLAN backplane reset */
3825 reg_val = brcmf_sdiod_regrb(bus->sdiodev, 3860 reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err);
3826 SDIO_CCCR_BRCM_CARDCTRL, &err);
3827 if (err) 3861 if (err)
3828 goto fail; 3862 goto fail;
3829 3863
3830 reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; 3864 reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET;
3831 3865
3832 brcmf_sdiod_regwb(bus->sdiodev, 3866 brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
3833 SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err);
3834 if (err) 3867 if (err)
3835 goto fail; 3868 goto fail;
3836 3869
3837 /* set PMUControl so a backplane reset does PMU state reload */ 3870 /* set PMUControl so a backplane reset does PMU state reload */
3838 reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); 3871 reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
3839 reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); 3872 reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err);
3840 if (err) 3873 if (err)
3841 goto fail; 3874 goto fail;
3842 3875
3843 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); 3876 reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT);
3844 3877
3845 brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err); 3878 brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err);
3846 if (err) 3879 if (err)
3847 goto fail; 3880 goto fail;
3848 3881
3849 sdio_release_host(bus->sdiodev->func[1]); 3882 sdio_release_host(sdiodev->func[1]);
3850 3883
3851 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3884 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3852 3885
@@ -3867,7 +3900,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3867 return true; 3900 return true;
3868 3901
3869fail: 3902fail:
3870 sdio_release_host(bus->sdiodev->func[1]); 3903 sdio_release_host(sdiodev->func[1]);
3871 return false; 3904 return false;
3872} 3905}
3873 3906
@@ -4045,18 +4078,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4045 bus->txminmax = BRCMF_TXMINMAX; 4078 bus->txminmax = BRCMF_TXMINMAX;
4046 bus->tx_seq = SDPCM_SEQ_WRAP - 1; 4079 bus->tx_seq = SDPCM_SEQ_WRAP - 1;
4047 4080
4048 /* platform specific configuration:
4049 * alignments must be at least 4 bytes for ADMA
4050 */
4051 bus->head_align = ALIGNMENT;
4052 bus->sgentry_align = ALIGNMENT;
4053 if (sdiodev->pdata) {
4054 if (sdiodev->pdata->sd_head_align > ALIGNMENT)
4055 bus->head_align = sdiodev->pdata->sd_head_align;
4056 if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
4057 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
4058 }
4059
4060 /* single-threaded workqueue */ 4081 /* single-threaded workqueue */
4061 wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM, 4082 wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM,
4062 dev_name(&sdiodev->func[1]->dev)); 4083 dev_name(&sdiodev->func[1]->dev));
@@ -4107,7 +4128,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4107 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; 4128 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
4108 4129
4109 /* Attach to the common layer, reserve hdr space */ 4130 /* Attach to the common layer, reserve hdr space */
4110 ret = brcmf_attach(bus->sdiodev->dev); 4131 ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings);
4111 if (ret != 0) { 4132 if (ret != 0) {
4112 brcmf_err("brcmf_attach failed\n"); 4133 brcmf_err("brcmf_attach failed\n");
4113 goto fail; 4134 goto fail;
@@ -4211,6 +4232,8 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4211 } 4232 }
4212 brcmf_chip_detach(bus->ci); 4233 brcmf_chip_detach(bus->ci);
4213 } 4234 }
4235 if (bus->sdiodev->settings)
4236 brcmf_release_module_param(bus->sdiodev->settings);
4214 4237
4215 kfree(bus->rxbuf); 4238 kfree(bus->rxbuf);
4216 kfree(bus->hdrbuf); 4239 kfree(bus->hdrbuf);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
index 23f223150cef..dcf0ce8cd2c1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
@@ -184,7 +184,7 @@ struct brcmf_sdio_dev {
184 struct brcmf_sdio *bus; 184 struct brcmf_sdio *bus;
185 struct device *dev; 185 struct device *dev;
186 struct brcmf_bus *bus_if; 186 struct brcmf_bus *bus_if;
187 struct brcmfmac_sdio_platform_data *pdata; 187 struct brcmf_mp_device *settings;
188 bool oob_irq_requested; 188 bool oob_irq_requested;
189 bool irq_en; /* irq enable flags */ 189 bool irq_en; /* irq enable flags */
190 spinlock_t irq_en_lock; 190 spinlock_t irq_en_lock;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
index c72b7b352a77..869eb82db8b1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -27,6 +27,8 @@
27#include "debug.h" 27#include "debug.h"
28#include "firmware.h" 28#include "firmware.h"
29#include "usb.h" 29#include "usb.h"
30#include "core.h"
31#include "common.h"
30 32
31 33
32#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000) 34#define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000)
@@ -171,6 +173,7 @@ struct brcmf_usbdev_info {
171 struct urb *bulk_urb; /* used for FW download */ 173 struct urb *bulk_urb; /* used for FW download */
172 174
173 bool wowl_enabled; 175 bool wowl_enabled;
176 struct brcmf_mp_device *settings;
174}; 177};
175 178
176static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, 179static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -1027,6 +1030,9 @@ static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
1027 1030
1028 kfree(devinfo->tx_reqs); 1031 kfree(devinfo->tx_reqs);
1029 kfree(devinfo->rx_reqs); 1032 kfree(devinfo->rx_reqs);
1033
1034 if (devinfo->settings)
1035 brcmf_release_module_param(devinfo->settings);
1030} 1036}
1031 1037
1032 1038
@@ -1136,7 +1142,7 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
1136 int ret; 1142 int ret;
1137 1143
1138 /* Attach to the common driver interface */ 1144 /* Attach to the common driver interface */
1139 ret = brcmf_attach(devinfo->dev); 1145 ret = brcmf_attach(devinfo->dev, devinfo->settings);
1140 if (ret) { 1146 if (ret) {
1141 brcmf_err("brcmf_attach failed\n"); 1147 brcmf_err("brcmf_attach failed\n");
1142 return ret; 1148 return ret;
@@ -1223,6 +1229,14 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1223 bus->wowl_supported = true; 1229 bus->wowl_supported = true;
1224#endif 1230#endif
1225 1231
1232 devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB,
1233 bus_pub->devid,
1234 bus_pub->chiprev);
1235 if (!devinfo->settings) {
1236 ret = -ENOMEM;
1237 goto fail;
1238 }
1239
1226 if (!brcmf_usb_dlneeded(devinfo)) { 1240 if (!brcmf_usb_dlneeded(devinfo)) {
1227 ret = brcmf_usb_bus_setup(devinfo); 1241 ret = brcmf_usb_bus_setup(devinfo);
1228 if (ret) 1242 if (ret)
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
index 3f68dd5ecd11..7b9a77981df1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
@@ -236,6 +236,8 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
236#define WPA2_AUTH_RESERVED3 0x0200 236#define WPA2_AUTH_RESERVED3 0x0200
237#define WPA2_AUTH_RESERVED4 0x0400 237#define WPA2_AUTH_RESERVED4 0x0400
238#define WPA2_AUTH_RESERVED5 0x0800 238#define WPA2_AUTH_RESERVED5 0x0800
239#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */
240#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */
239 241
240#define DOT11_DEFAULT_RTS_LEN 2347 242#define DOT11_DEFAULT_RTS_LEN 2347
241#define DOT11_DEFAULT_FRAG_LEN 2346 243#define DOT11_DEFAULT_FRAG_LEN 2346
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
index fa41a5e1c890..fc475ce59b47 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c
@@ -73,8 +73,8 @@
73/* Highest firmware API version supported */ 73/* Highest firmware API version supported */
74#define IWL7260_UCODE_API_MAX 17 74#define IWL7260_UCODE_API_MAX 17
75#define IWL7265_UCODE_API_MAX 17 75#define IWL7265_UCODE_API_MAX 17
76#define IWL7265D_UCODE_API_MAX 20 76#define IWL7265D_UCODE_API_MAX 21
77#define IWL3168_UCODE_API_MAX 20 77#define IWL3168_UCODE_API_MAX 21
78 78
79/* Oldest version we won't warn about */ 79/* Oldest version we won't warn about */
80#define IWL7260_UCODE_API_OK 13 80#define IWL7260_UCODE_API_OK 13
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
index bce9b3420a13..97be104d1203 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c
@@ -70,8 +70,8 @@
70#include "iwl-agn-hw.h" 70#include "iwl-agn-hw.h"
71 71
72/* Highest firmware API version supported */ 72/* Highest firmware API version supported */
73#define IWL8000_UCODE_API_MAX 20 73#define IWL8000_UCODE_API_MAX 21
74#define IWL8265_UCODE_API_MAX 20 74#define IWL8265_UCODE_API_MAX 21
75 75
76/* Oldest version we won't warn about */ 76/* Oldest version we won't warn about */
77#define IWL8000_UCODE_API_OK 13 77#define IWL8000_UCODE_API_OK 13
@@ -217,6 +217,7 @@ const struct iwl_cfg iwl8265_2ac_cfg = {
217 .nvm_ver = IWL8000_NVM_VERSION, 217 .nvm_ver = IWL8000_NVM_VERSION,
218 .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 218 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
219 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, 219 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
220 .vht_mu_mimo_supported = true,
220}; 221};
221 222
222const struct iwl_cfg iwl4165_2ac_cfg = { 223const struct iwl_cfg iwl4165_2ac_cfg = {
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
index 4b93404f46a7..8e32a57dda0f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c
@@ -55,7 +55,7 @@
55#include "iwl-agn-hw.h" 55#include "iwl-agn-hw.h"
56 56
57/* Highest firmware API version supported */ 57/* Highest firmware API version supported */
58#define IWL9000_UCODE_API_MAX 20 58#define IWL9000_UCODE_API_MAX 21
59 59
60/* Oldest version we won't warn about */ 60/* Oldest version we won't warn about */
61#define IWL9000_UCODE_API_OK 13 61#define IWL9000_UCODE_API_OK 13
@@ -139,7 +139,8 @@ static const struct iwl_tt_params iwl9000_tt_params = {
139 .smem_len = IWL9000_SMEM_LEN, \ 139 .smem_len = IWL9000_SMEM_LEN, \
140 .thermal_params = &iwl9000_tt_params, \ 140 .thermal_params = &iwl9000_tt_params, \
141 .apmg_not_supported = true, \ 141 .apmg_not_supported = true, \
142 .mq_rx_supported = true 142 .mq_rx_supported = true, \
143 .vht_mu_mimo_supported = true
143 144
144const struct iwl_cfg iwl9260_2ac_cfg = { 145const struct iwl_cfg iwl9260_2ac_cfg = {
145 .name = "Intel(R) Dual Band Wireless AC 9260", 146 .name = "Intel(R) Dual Band Wireless AC 9260",
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index dad5570d6cc8..4f2b57e8bbc7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -312,6 +312,7 @@ struct iwl_pwr_tx_backoff {
312 * @smem_offset: offset from which the SMEM begins 312 * @smem_offset: offset from which the SMEM begins
313 * @smem_len: the length of SMEM 313 * @smem_len: the length of SMEM
314 * @mq_rx_supported: multi-queue rx support 314 * @mq_rx_supported: multi-queue rx support
315 * @vht_mu_mimo_supported: VHT MU-MIMO support
315 * 316 *
316 * We enable the driver to be backward compatible wrt. hardware features. 317 * We enable the driver to be backward compatible wrt. hardware features.
317 * API differences in uCode shouldn't be handled here but through TLVs 318 * API differences in uCode shouldn't be handled here but through TLVs
@@ -364,6 +365,7 @@ struct iwl_cfg {
364 const struct iwl_tt_params *thermal_params; 365 const struct iwl_tt_params *thermal_params;
365 bool apmg_not_supported; 366 bool apmg_not_supported;
366 bool mq_rx_supported; 367 bool mq_rx_supported;
368 bool vht_mu_mimo_supported;
367}; 369};
368 370
369/* 371/*
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
index 163b21bc20cb..a79c4f61a851 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -549,4 +550,52 @@ enum dtd_diode_reg {
549 DTS_DIODE_REG_FLAGS_PASS_ONCE = 0x00000080, /* bits [7:7] */ 550 DTS_DIODE_REG_FLAGS_PASS_ONCE = 0x00000080, /* bits [7:7] */
550}; 551};
551 552
553/*****************************************************************************
554 * MSIX related registers *
555 *****************************************************************************/
556
557#define CSR_MSIX_BASE (0x2000)
558#define CSR_MSIX_FH_INT_CAUSES_AD (CSR_MSIX_BASE + 0x800)
559#define CSR_MSIX_FH_INT_MASK_AD (CSR_MSIX_BASE + 0x804)
560#define CSR_MSIX_HW_INT_CAUSES_AD (CSR_MSIX_BASE + 0x808)
561#define CSR_MSIX_HW_INT_MASK_AD (CSR_MSIX_BASE + 0x80C)
562#define CSR_MSIX_AUTOMASK_ST_AD (CSR_MSIX_BASE + 0x810)
563#define CSR_MSIX_RX_IVAR_AD_REG (CSR_MSIX_BASE + 0x880)
564#define CSR_MSIX_IVAR_AD_REG (CSR_MSIX_BASE + 0x890)
565#define CSR_MSIX_PENDING_PBA_AD (CSR_MSIX_BASE + 0x1000)
566#define CSR_MSIX_RX_IVAR(cause) (CSR_MSIX_RX_IVAR_AD_REG + (cause))
567#define CSR_MSIX_IVAR(cause) (CSR_MSIX_IVAR_AD_REG + (cause))
568
569#define MSIX_FH_INT_CAUSES_Q(q) (q)
570
571/*
572 * Causes for the FH register interrupts
573 */
574enum msix_fh_int_causes {
575 MSIX_FH_INT_CAUSES_D2S_CH0_NUM = BIT(16),
576 MSIX_FH_INT_CAUSES_D2S_CH1_NUM = BIT(17),
577 MSIX_FH_INT_CAUSES_S2D = BIT(19),
578 MSIX_FH_INT_CAUSES_FH_ERR = BIT(21),
579};
580
581/*
582 * Causes for the HW register interrupts
583 */
584enum msix_hw_int_causes {
585 MSIX_HW_INT_CAUSES_REG_ALIVE = BIT(0),
586 MSIX_HW_INT_CAUSES_REG_WAKEUP = BIT(1),
587 MSIX_HW_INT_CAUSES_REG_CT_KILL = BIT(6),
588 MSIX_HW_INT_CAUSES_REG_RF_KILL = BIT(7),
589 MSIX_HW_INT_CAUSES_REG_PERIODIC = BIT(8),
590 MSIX_HW_INT_CAUSES_REG_SW_ERR = BIT(25),
591 MSIX_HW_INT_CAUSES_REG_SCD = BIT(26),
592 MSIX_HW_INT_CAUSES_REG_FH_TX = BIT(27),
593 MSIX_HW_INT_CAUSES_REG_HW_ERR = BIT(29),
594 MSIX_HW_INT_CAUSES_REG_HAP = BIT(30),
595};
596
597#define MSIX_MIN_INTERRUPT_VECTORS 2
598#define MSIX_AUTO_CLEAR_CAUSE 0
599#define MSIX_NON_AUTO_CLEAR_CAUSE BIT(7)
600
552#endif /* !__iwl_csr_h__ */ 601#endif /* !__iwl_csr_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
index 22786d7dc00a..2a0703fcec56 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-iwlwifi.h
@@ -73,12 +73,12 @@ TRACE_EVENT(iwlwifi_dev_rx,
73 TP_ARGS(dev, trans, pkt, len), 73 TP_ARGS(dev, trans, pkt, len),
74 TP_STRUCT__entry( 74 TP_STRUCT__entry(
75 DEV_ENTRY 75 DEV_ENTRY
76 __field(u8, cmd) 76 __field(u16, cmd)
77 __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, pkt, len)) 77 __dynamic_array(u8, rxbuf, iwl_rx_trace_len(trans, pkt, len))
78 ), 78 ),
79 TP_fast_assign( 79 TP_fast_assign(
80 DEV_ASSIGN; 80 DEV_ASSIGN;
81 __entry->cmd = pkt->hdr.cmd; 81 __entry->cmd = WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd);
82 memcpy(__get_dynamic_array(rxbuf), pkt, 82 memcpy(__get_dynamic_array(rxbuf), pkt,
83 iwl_rx_trace_len(trans, pkt, len)); 83 iwl_rx_trace_len(trans, pkt, len));
84 ), 84 ),
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
index ab4c2a0470b2..184c0fef37c0 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
@@ -1033,7 +1033,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
1033 } 1033 }
1034 } 1034 }
1035 1035
1036 if (usniffer_req && !*usniffer_images) { 1036 if (!fw_has_capa(capa, IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED) &&
1037 usniffer_req && !*usniffer_images) {
1037 IWL_ERR(drv, 1038 IWL_ERR(drv,
1038 "user selected to work with usniffer but usniffer image isn't available in ucode package\n"); 1039 "user selected to work with usniffer but usniffer image isn't available in ucode package\n");
1039 return -EINVAL; 1040 return -EINVAL;
@@ -1718,3 +1719,7 @@ MODULE_PARM_DESC(fw_monitor,
1718module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_entry_delay, 1719module_param_named(d0i3_timeout, iwlwifi_mod_params.d0i3_entry_delay,
1719 uint, S_IRUGO); 1720 uint, S_IRUGO);
1720MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)"); 1721MODULE_PARM_DESC(d0i3_timeout, "Timeout to D0i3 entry when idle (ms)");
1722
1723module_param_named(disable_11ac, iwlwifi_mod_params.disable_11ac, bool,
1724 S_IRUGO);
1725MODULE_PARM_DESC(disable_11ac, "Disable VHT capabilities");
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
index 4ab6682ea53e..8af818b10e71 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fh.h
@@ -6,7 +6,7 @@
6 * GPL LICENSE SUMMARY 6 * GPL LICENSE SUMMARY
7 * 7 *
8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2015 Intel Deutschland GmbH 9 * Copyright(c) 2015 - 2016 Intel Deutschland 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) 2005 - 2014 Intel Corporation. All rights reserved. 34 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2015 Intel Deutschland GmbH 35 * Copyright(c) 2015 - 2016 Intel Deutschland 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
@@ -368,20 +368,24 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
368#define RFH_RXF_DMA_RBDCB_SIZE_512 (0x9 << RFH_RXF_DMA_RBDCB_SIZE_POS) 368#define RFH_RXF_DMA_RBDCB_SIZE_512 (0x9 << RFH_RXF_DMA_RBDCB_SIZE_POS)
369#define RFH_RXF_DMA_RBDCB_SIZE_1024 (0xA << RFH_RXF_DMA_RBDCB_SIZE_POS) 369#define RFH_RXF_DMA_RBDCB_SIZE_1024 (0xA << RFH_RXF_DMA_RBDCB_SIZE_POS)
370#define RFH_RXF_DMA_RBDCB_SIZE_2048 (0xB << RFH_RXF_DMA_RBDCB_SIZE_POS) 370#define RFH_RXF_DMA_RBDCB_SIZE_2048 (0xB << RFH_RXF_DMA_RBDCB_SIZE_POS)
371#define RFH_RXF_DMA_MIN_RB_SIZE_MASK (0x03000000) /* bit 24-25 */ 371#define RFH_RXF_DMA_MIN_RB_SIZE_MASK (0x03000000) /* bit 24-25 */
372#define RFH_RXF_DMA_MIN_RB_SIZE_POS 24 372#define RFH_RXF_DMA_MIN_RB_SIZE_POS 24
373#define RFH_RXF_DMA_MIN_RB_4_8 (3 << RFH_RXF_DMA_MIN_RB_SIZE_POS) 373#define RFH_RXF_DMA_MIN_RB_4_8 (3 << RFH_RXF_DMA_MIN_RB_SIZE_POS)
374#define RFH_RXF_DMA_SINGLE_FRAME_MASK (0x20000000) /* bit 29 */ 374#define RFH_RXF_DMA_DROP_TOO_LARGE_MASK (0x04000000) /* bit 26 */
375#define RFH_DMA_EN_MASK (0xC0000000) /* bits 30-31*/ 375#define RFH_RXF_DMA_SINGLE_FRAME_MASK (0x20000000) /* bit 29 */
376#define RFH_DMA_EN_ENABLE_VAL BIT(31) 376#define RFH_DMA_EN_MASK (0xC0000000) /* bits 30-31*/
377#define RFH_DMA_EN_ENABLE_VAL BIT(31)
377 378
378#define RFH_RXF_RXQ_ACTIVE 0xA0980C 379#define RFH_RXF_RXQ_ACTIVE 0xA0980C
379 380
380#define RFH_GEN_CFG 0xA09800 381#define RFH_GEN_CFG 0xA09800
382#define RFH_GEN_CFG_SERVICE_DMA_SNOOP BIT(0)
383#define RFH_GEN_CFG_RFH_DMA_SNOOP BIT(1)
384#define RFH_GEN_CFG_RB_CHUNK_SIZE BIT(4) /* 0 - 64B, 1- 128B */
381#define RFH_GEN_CFG_DEFAULT_RXQ_NUM_MASK 0xF00 385#define RFH_GEN_CFG_DEFAULT_RXQ_NUM_MASK 0xF00
382#define RFH_GEN_CFG_SERVICE_DMA_SNOOP BIT(0) 386#define RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS 8
383#define RFH_GEN_CFG_RFH_DMA_SNOOP BIT(1) 387
384#define DEFAULT_RXQ_NUM 8 388#define DEFAULT_RXQ_NUM 0
385 389
386/* end of 9000 rx series registers */ 390/* end of 9000 rx series registers */
387 391
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
index e2dbc67a367b..5f69bf5e04c7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h
@@ -318,6 +318,12 @@ typedef unsigned int __bitwise__ iwl_ucode_tlv_capa_t;
318 * @IWL_UCODE_TLV_CAPA_BEACON_STORING: firmware will store the latest beacon 318 * @IWL_UCODE_TLV_CAPA_BEACON_STORING: firmware will store the latest beacon
319 * from AP and will send it upon d0i3 exit. 319 * from AP and will send it upon d0i3 exit.
320 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2: support LAR API V2 320 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2: support LAR API V2
321 * @IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW: firmware responsible for CT-kill
322 * @IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT: supports temperature
323 * thresholds reporting
324 * @IWL_UCODE_TLV_CAPA_CTDP_SUPPORT: supports cTDP command
325 * @IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED: supports usniffer enabled in
326 * regular image.
321 * 327 *
322 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used 328 * @NUM_IWL_UCODE_TLV_CAPA: number of bits used
323 */ 329 */
@@ -351,6 +357,10 @@ enum iwl_ucode_tlv_capa {
351 IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION = (__force iwl_ucode_tlv_capa_t)71, 357 IWL_UCODE_TLV_CAPA_BEACON_ANT_SELECTION = (__force iwl_ucode_tlv_capa_t)71,
352 IWL_UCODE_TLV_CAPA_BEACON_STORING = (__force iwl_ucode_tlv_capa_t)72, 358 IWL_UCODE_TLV_CAPA_BEACON_STORING = (__force iwl_ucode_tlv_capa_t)72,
353 IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2 = (__force iwl_ucode_tlv_capa_t)73, 359 IWL_UCODE_TLV_CAPA_LAR_SUPPORT_V2 = (__force iwl_ucode_tlv_capa_t)73,
360 IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW = (__force iwl_ucode_tlv_capa_t)74,
361 IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT = (__force iwl_ucode_tlv_capa_t)75,
362 IWL_UCODE_TLV_CAPA_CTDP_SUPPORT = (__force iwl_ucode_tlv_capa_t)76,
363 IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED = (__force iwl_ucode_tlv_capa_t)77,
354 364
355 NUM_IWL_UCODE_TLV_CAPA 365 NUM_IWL_UCODE_TLV_CAPA
356#ifdef __CHECKER__ 366#ifdef __CHECKER__
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
index b88ecc7892a9..d1a5dd1602f5 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-modparams.h
@@ -115,6 +115,7 @@ enum iwl_amsdu_size {
115 * entering D0i3 (in msecs) 115 * entering D0i3 (in msecs)
116 * @lar_disable: disable LAR (regulatory), default = 0 116 * @lar_disable: disable LAR (regulatory), default = 0
117 * @fw_monitor: allow to use firmware monitor 117 * @fw_monitor: allow to use firmware monitor
118 * @disable_11ac: disable VHT capabilities, default = false.
118 */ 119 */
119struct iwl_mod_params { 120struct iwl_mod_params {
120 int sw_crypto; 121 int sw_crypto;
@@ -135,6 +136,7 @@ struct iwl_mod_params {
135 unsigned int d0i3_entry_delay; 136 unsigned int d0i3_entry_delay;
136 bool lar_disable; 137 bool lar_disable;
137 bool fw_monitor; 138 bool fw_monitor;
139 bool disable_11ac;
138}; 140};
139 141
140#endif /* #__iwl_modparams_h__ */ 142#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 50f4cc60cf3e..348135792f3e 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -366,6 +366,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
366 max_ampdu_exponent << 366 max_ampdu_exponent <<
367 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; 367 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
368 368
369 if (cfg->vht_mu_mimo_supported)
370 vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
371
369 if (cfg->ht_params->ldpc) 372 if (cfg->ht_params->ldpc)
370 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; 373 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
371 374
@@ -449,7 +452,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
449 IEEE80211_BAND_5GHZ); 452 IEEE80211_BAND_5GHZ);
450 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ, 453 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
451 tx_chains, rx_chains); 454 tx_chains, rx_chains);
452 if (data->sku_cap_11ac_enable) 455 if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
453 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap, 456 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
454 tx_chains, rx_chains); 457 tx_chains, rx_chains);
455 458
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
index 5bde23a472b4..c46e596e12b1 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-prph.h
@@ -404,4 +404,6 @@ enum {
404 LMPM_PAGE_PASS_NOTIF_POS = BIT(20), 404 LMPM_PAGE_PASS_NOTIF_POS = BIT(20),
405}; 405};
406 406
407#define UREG_CHICK (0xA05C00)
408#define UREG_CHICK_MSIX_ENABLE BIT(25)
407#endif /* __iwl_prph_h__ */ 409#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 0ca0f13b69b0..91d74b3f666b 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -836,6 +836,7 @@ struct iwl_trans {
836 836
837 enum iwl_plat_pm_mode system_pm_mode; 837 enum iwl_plat_pm_mode system_pm_mode;
838 enum iwl_plat_pm_mode runtime_pm_mode; 838 enum iwl_plat_pm_mode runtime_pm_mode;
839 bool suspending;
839 840
840 /* pointer to trans specific struct */ 841 /* pointer to trans specific struct */
841 /*Ensure that this pointer will always be aligned to sizeof pointer */ 842 /*Ensure that this pointer will always be aligned to sizeof pointer */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
index 5214482a0403..c1a313149eed 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
@@ -816,8 +816,7 @@ static int iwl_mvm_switch_to_d3(struct iwl_mvm *mvm)
816{ 816{
817 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true); 817 iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
818 818
819 iwl_trans_stop_device(mvm->trans); 819 iwl_mvm_stop_device(mvm);
820
821 /* 820 /*
822 * Set the HW restart bit -- this is mostly true as we're 821 * Set the HW restart bit -- this is mostly true as we're
823 * going to load new firmware and reprogram that, though 822 * going to load new firmware and reprogram that, though
@@ -856,8 +855,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
856 wowlan_config_cmd->is_11n_connection = 855 wowlan_config_cmd->is_11n_connection =
857 ap_sta->ht_cap.ht_supported; 856 ap_sta->ht_cap.ht_supported;
858 wowlan_config_cmd->flags = ENABLE_L3_FILTERING | 857 wowlan_config_cmd->flags = ENABLE_L3_FILTERING |
859 ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING | 858 ENABLE_NBNS_FILTERING | ENABLE_DHCP_FILTERING;
860 ENABLE_STORE_BEACON;
861 859
862 /* Query the last used seqno and set it */ 860 /* Query the last used seqno and set it */
863 ret = iwl_mvm_get_last_nonqos_seq(mvm, vif); 861 ret = iwl_mvm_get_last_nonqos_seq(mvm, vif);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
index c529e5355803..56e6b0b8b9cc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c
@@ -64,6 +64,7 @@
64 * 64 *
65 *****************************************************************************/ 65 *****************************************************************************/
66#include <linux/vmalloc.h> 66#include <linux/vmalloc.h>
67#include <linux/ieee80211.h>
67 68
68#include "mvm.h" 69#include "mvm.h"
69#include "fw-dbg.h" 70#include "fw-dbg.h"
@@ -976,7 +977,7 @@ static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm,
976 memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table, 977 memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table,
977 ARRAY_SIZE(cmd.indirection_table) % nbytes); 978 ARRAY_SIZE(cmd.indirection_table) % nbytes);
978 979
979 memcpy(cmd.secret_key, mvm->secret_key, ARRAY_SIZE(cmd.secret_key)); 980 memcpy(cmd.secret_key, mvm->secret_key, sizeof(cmd.secret_key));
980 981
981 mutex_lock(&mvm->mutex); 982 mutex_lock(&mvm->mutex);
982 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd); 983 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
@@ -1080,6 +1081,22 @@ static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
1080 return count; 1081 return count;
1081} 1082}
1082 1083
1084static ssize_t iwl_dbgfs_max_amsdu_len_write(struct iwl_mvm *mvm,
1085 char *buf, size_t count,
1086 loff_t *ppos)
1087{
1088 unsigned int max_amsdu_len;
1089 int ret;
1090
1091 ret = kstrtouint(buf, 0, &max_amsdu_len);
1092
1093 if (max_amsdu_len > IEEE80211_MAX_MPDU_LEN_VHT_11454)
1094 return -EINVAL;
1095 mvm->max_amsdu_len = max_amsdu_len;
1096
1097 return count;
1098}
1099
1083#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__) 1100#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
1084#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1101#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1085static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file, 1102static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
@@ -1497,7 +1514,9 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1497MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); 1514MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1498MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); 1515MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64);
1499MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8); 1516MVM_DEBUGFS_WRITE_FILE_OPS(cont_recording, 8);
1500MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 16); 1517MVM_DEBUGFS_WRITE_FILE_OPS(max_amsdu_len, 8);
1518MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl,
1519 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2));
1501 1520
1502#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1521#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1503MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); 1522MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
@@ -1540,6 +1559,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1540 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1559 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
1541 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1560 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
1542 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR); 1561 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
1562 MVM_DEBUGFS_ADD_FILE(max_amsdu_len, mvm->debugfs_dir, S_IWUSR);
1543 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR); 1563 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, S_IWUSR);
1544 MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR); 1564 MVM_DEBUGFS_ADD_FILE(cont_recording, mvm->debugfs_dir, S_IWUSR);
1545 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, S_IWUSR); 1565 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, S_IWUSR);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
index df939f51d9b9..eb9b87038e1f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rx.h
@@ -391,4 +391,56 @@ struct iwl_rss_config_cmd {
391 u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE]; 391 u8 indirection_table[IWL_RSS_INDIRECTION_TABLE_SIZE];
392} __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */ 392} __packed; /* RSS_CONFIG_CMD_API_S_VER_1 */
393 393
394#define IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE 128
395#define IWL_MULTI_QUEUE_SYNC_SENDER_POS 0
396#define IWL_MULTI_QUEUE_SYNC_SENDER_MSK 0xf
397
398/**
399 * struct iwl_rxq_sync_cmd - RXQ notification trigger
400 *
401 * @flags: flags of the notification. bit 0:3 are the sender queue
402 * @rxq_mask: rx queues to send the notification on
403 * @count: number of bytes in payload, should be DWORD aligned
404 * @payload: data to send to rx queues
405 */
406struct iwl_rxq_sync_cmd {
407 __le32 flags;
408 __le32 rxq_mask;
409 __le32 count;
410 u8 payload[];
411} __packed; /* MULTI_QUEUE_DRV_SYNC_HDR_CMD_API_S_VER_1 */
412
413/**
414 * struct iwl_rxq_sync_notification - Notification triggered by RXQ
415 * sync command
416 *
417 * @count: number of bytes in payload
418 * @payload: data to send to rx queues
419 */
420struct iwl_rxq_sync_notification {
421 __le32 count;
422 u8 payload[];
423} __packed; /* MULTI_QUEUE_DRV_SYNC_HDR_CMD_API_S_VER_1 */
424
425/**
426* Internal message identifier
427*
428* @IWL_MVM_RXQ_NOTIF_DEL_BA: notify RSS queues of delBA
429*/
430enum iwl_mvm_rxq_notif_type {
431 IWL_MVM_RXQ_NOTIF_DEL_BA,
432};
433
434/**
435* struct iwl_mvm_internal_rxq_notif - Internal representation of the data sent
436* in &iwl_rxq_sync_cmd. Should be DWORD aligned.
437*
438* @type: value from &iwl_mvm_rxq_notif_type
439* @data: payload
440*/
441struct iwl_mvm_internal_rxq_notif {
442 u32 type;
443 u8 data[];
444} __packed;
445
394#endif /* __fw_api_rx_h__ */ 446#endif /* __fw_api_rx_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
index f332497e29d1..4a0fc47c81f2 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
@@ -119,6 +119,8 @@ enum {
119 SCAN_ABORT_UMAC = 0xe, 119 SCAN_ABORT_UMAC = 0xe,
120 SCAN_COMPLETE_UMAC = 0xf, 120 SCAN_COMPLETE_UMAC = 0xf,
121 121
122 BA_WINDOW_STATUS_NOTIFICATION_ID = 0x13,
123
122 /* station table */ 124 /* station table */
123 ADD_STA_KEY = 0x17, 125 ADD_STA_KEY = 0x17,
124 ADD_STA = 0x18, 126 ADD_STA = 0x18,
@@ -279,9 +281,19 @@ enum {
279 */ 281 */
280enum iwl_phy_ops_subcmd_ids { 282enum iwl_phy_ops_subcmd_ids {
281 CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0, 283 CMD_DTS_MEASUREMENT_TRIGGER_WIDE = 0x0,
284 CTDP_CONFIG_CMD = 0x03,
285 TEMP_REPORTING_THRESHOLDS_CMD = 0x04,
286 CT_KILL_NOTIFICATION = 0xFE,
282 DTS_MEASUREMENT_NOTIF_WIDE = 0xFF, 287 DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
283}; 288};
284 289
290enum iwl_data_path_subcmd_ids {
291 UPDATE_MU_GROUPS_CMD = 0x1,
292 TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
293 MU_GROUP_MGMT_NOTIF = 0xFE,
294 RX_QUEUES_NOTIFICATION = 0xFF,
295};
296
285enum iwl_prot_offload_subcmd_ids { 297enum iwl_prot_offload_subcmd_ids {
286 STORED_BEACON_NTF = 0xFF, 298 STORED_BEACON_NTF = 0xFF,
287}; 299};
@@ -291,6 +303,7 @@ enum {
291 LEGACY_GROUP = 0x0, 303 LEGACY_GROUP = 0x0,
292 LONG_GROUP = 0x1, 304 LONG_GROUP = 0x1,
293 PHY_OPS_GROUP = 0x4, 305 PHY_OPS_GROUP = 0x4,
306 DATA_PATH_GROUP = 0x5,
294 PROT_OFFLOAD_GROUP = 0xb, 307 PROT_OFFLOAD_GROUP = 0xb,
295}; 308};
296 309
@@ -1278,6 +1291,26 @@ struct iwl_fw_bcast_filter {
1278 struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS]; 1291 struct iwl_fw_bcast_filter_attr attrs[MAX_BCAST_FILTER_ATTRS];
1279} __packed; /* BCAST_FILTER_S_VER_1 */ 1292} __packed; /* BCAST_FILTER_S_VER_1 */
1280 1293
1294#define BA_WINDOW_STREAMS_MAX 16
1295#define BA_WINDOW_STATUS_TID_MSK 0x000F
1296#define BA_WINDOW_STATUS_STA_ID_POS 4
1297#define BA_WINDOW_STATUS_STA_ID_MSK 0x01F0
1298#define BA_WINDOW_STATUS_VALID_MSK BIT(9)
1299
1300/**
1301 * struct iwl_ba_window_status_notif - reordering window's status notification
1302 * @bitmap: bitmap of received frames [start_seq_num + 0]..[start_seq_num + 63]
1303 * @ra_tid: bit 3:0 - TID, bit 8:4 - STA_ID, bit 9 - valid
1304 * @start_seq_num: the start sequence number of the bitmap
1305 * @mpdu_rx_count: the number of received MPDUs since entering D0i3
1306 */
1307struct iwl_ba_window_status_notif {
1308 __le64 bitmap[BA_WINDOW_STREAMS_MAX];
1309 __le16 ra_tid[BA_WINDOW_STREAMS_MAX];
1310 __le32 start_seq_num[BA_WINDOW_STREAMS_MAX];
1311 __le16 mpdu_rx_count[BA_WINDOW_STREAMS_MAX];
1312} __packed; /* BA_WINDOW_STATUS_NTFY_API_S_VER_1 */
1313
1281/** 1314/**
1282 * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration. 1315 * struct iwl_fw_bcast_mac - per-mac broadcast filtering configuration.
1283 * @default_discard: default action for this mac (discard (1) / pass (0)). 1316 * @default_discard: default action for this mac (discard (1) / pass (0)).
@@ -1675,15 +1708,77 @@ struct iwl_ext_dts_measurement_cmd {
1675} __packed; /* XVT_FW_DTS_CONTROL_MEASUREMENT_REQUEST_API_S */ 1708} __packed; /* XVT_FW_DTS_CONTROL_MEASUREMENT_REQUEST_API_S */
1676 1709
1677/** 1710/**
1678 * iwl_dts_measurement_notif - notification received with the measurements 1711 * struct iwl_dts_measurement_notif_v1 - measurements notification
1679 * 1712 *
1680 * @temp: the measured temperature 1713 * @temp: the measured temperature
1681 * @voltage: the measured voltage 1714 * @voltage: the measured voltage
1682 */ 1715 */
1683struct iwl_dts_measurement_notif { 1716struct iwl_dts_measurement_notif_v1 {
1684 __le32 temp; 1717 __le32 temp;
1685 __le32 voltage; 1718 __le32 voltage;
1686} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ 1719} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_1*/
1720
1721/**
1722 * struct iwl_dts_measurement_notif_v2 - measurements notification
1723 *
1724 * @temp: the measured temperature
1725 * @voltage: the measured voltage
1726 * @threshold_idx: the trip index that was crossed
1727 */
1728struct iwl_dts_measurement_notif_v2 {
1729 __le32 temp;
1730 __le32 voltage;
1731 __le32 threshold_idx;
1732} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S_VER_2 */
1733
1734/**
1735 * struct ct_kill_notif - CT-kill entry notification
1736 *
1737 * @temperature: the current temperature in celsius
1738 * @reserved: reserved
1739 */
1740struct ct_kill_notif {
1741 __le16 temperature;
1742 __le16 reserved;
1743} __packed; /* GRP_PHY_CT_KILL_NTF */
1744
1745/**
1746* enum ctdp_cmd_operation - CTDP command operations
1747* @CTDP_CMD_OPERATION_START: update the current budget
1748* @CTDP_CMD_OPERATION_STOP: stop ctdp
1749* @CTDP_CMD_OPERATION_REPORT: get the avgerage budget
1750*/
1751enum iwl_mvm_ctdp_cmd_operation {
1752 CTDP_CMD_OPERATION_START = 0x1,
1753 CTDP_CMD_OPERATION_STOP = 0x2,
1754 CTDP_CMD_OPERATION_REPORT = 0x4,
1755};/* CTDP_CMD_OPERATION_TYPE_E */
1756
1757/**
1758 * struct iwl_mvm_ctdp_cmd - track and manage the FW power consumption budget
1759 *
1760 * @operation: see &enum iwl_mvm_ctdp_cmd_operation
1761 * @budget: the budget in milliwatt
1762 * @window_size: defined in API but not used
1763 */
1764struct iwl_mvm_ctdp_cmd {
1765 __le32 operation;
1766 __le32 budget;
1767 __le32 window_size;
1768} __packed;
1769
1770#define IWL_MAX_DTS_TRIPS 8
1771
1772/**
1773 * struct iwl_temp_report_ths_cmd - set temperature thresholds
1774 *
1775 * @num_temps: number of temperature thresholds passed
1776 * @thresholds: array with the thresholds to be configured
1777 */
1778struct temp_report_ths_cmd {
1779 __le32 num_temps;
1780 __le16 thresholds[IWL_MAX_DTS_TRIPS];
1781} __packed; /* GRP_PHY_TEMP_REPORTING_THRESHOLDS_CMD */
1687 1782
1688/*********************************** 1783/***********************************
1689 * TDLS API 1784 * TDLS API
@@ -1858,6 +1953,31 @@ struct iwl_shared_mem_cfg {
1858 __le32 page_buff_size; 1953 __le32 page_buff_size;
1859} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */ 1954} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
1860 1955
1956/**
1957 * VHT MU-MIMO group configuration
1958 *
1959 * @membership_status: a bitmap of MU groups
1960 * @user_position:the position of station in a group. If the station is in the
1961 * group then bits (group * 2) is the position -1
1962 */
1963struct iwl_mu_group_mgmt_cmd {
1964 __le32 reserved;
1965 __le32 membership_status[2];
1966 __le32 user_position[4];
1967} __packed; /* MU_GROUP_ID_MNG_TABLE_API_S_VER_1 */
1968
1969/**
1970 * struct iwl_mu_group_mgmt_notif - VHT MU-MIMO group id notification
1971 *
1972 * @membership_status: a bitmap of MU groups
1973 * @user_position: the position of station in a group. If the station is in the
1974 * group then bits (group * 2) is the position -1
1975 */
1976struct iwl_mu_group_mgmt_notif {
1977 __le32 membership_status[2];
1978 __le32 user_position[4];
1979} __packed; /* MU_GROUP_MNG_NTFY_API_S_VER_1 */
1980
1861#define MAX_STORED_BEACON_SIZE 600 1981#define MAX_STORED_BEACON_SIZE 600
1862 1982
1863/** 1983/**
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 62ae43d2ab7b..594cd0dc7df9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -121,7 +121,7 @@ static int iwl_send_rss_cfg_cmd(struct iwl_mvm *mvm)
121 121
122 for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++) 122 for (i = 0; i < ARRAY_SIZE(cmd.indirection_table); i++)
123 cmd.indirection_table[i] = i % mvm->trans->num_rx_queues; 123 cmd.indirection_table[i] = i % mvm->trans->num_rx_queues;
124 memcpy(cmd.secret_key, mvm->secret_key, ARRAY_SIZE(cmd.secret_key)); 124 memcpy(cmd.secret_key, mvm->secret_key, sizeof(cmd.secret_key));
125 125
126 return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd); 126 return iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, sizeof(cmd), &cmd);
127} 127}
@@ -539,7 +539,9 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
539 struct iwl_sf_region st_fwrd_space; 539 struct iwl_sf_region st_fwrd_space;
540 540
541 if (ucode_type == IWL_UCODE_REGULAR && 541 if (ucode_type == IWL_UCODE_REGULAR &&
542 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE)) 542 iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
543 !(fw_has_capa(&mvm->fw->ucode_capa,
544 IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED)))
543 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER); 545 fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
544 else 546 else
545 fw = iwl_get_ucode_image(mvm, ucode_type); 547 fw = iwl_get_ucode_image(mvm, ucode_type);
@@ -954,8 +956,26 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
954 goto error; 956 goto error;
955 } 957 }
956 958
959#ifdef CONFIG_THERMAL
960 if (iwl_mvm_is_tt_in_fw(mvm)) {
961 /* in order to give the responsibility of ct-kill and
962 * TX backoff to FW we need to send empty temperature reporting
963 * cmd during init time
964 */
965 iwl_mvm_send_temp_report_ths_cmd(mvm);
966 } else {
967 /* Initialize tx backoffs to the minimal possible */
968 iwl_mvm_tt_tx_backoff(mvm, 0);
969 }
970
971 /* TODO: read the budget from BIOS / Platform NVM */
972 if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0)
973 ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
974 mvm->cooling_dev.cur_state);
975#else
957 /* Initialize tx backoffs to the minimal possible */ 976 /* Initialize tx backoffs to the minimal possible */
958 iwl_mvm_tt_tx_backoff(mvm, 0); 977 iwl_mvm_tt_tx_backoff(mvm, 0);
978#endif
959 979
960 WARN_ON(iwl_mvm_config_ltr(mvm)); 980 WARN_ON(iwl_mvm_config_ltr(mvm));
961 981
@@ -991,7 +1011,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
991 IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); 1011 IWL_DEBUG_INFO(mvm, "RT uCode started.\n");
992 return 0; 1012 return 0;
993 error: 1013 error:
994 iwl_trans_stop_device(mvm->trans); 1014 iwl_mvm_stop_device(mvm);
995 return ret; 1015 return ret;
996} 1016}
997 1017
@@ -1035,7 +1055,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
1035 1055
1036 return 0; 1056 return 0;
1037 error: 1057 error:
1038 iwl_trans_stop_device(mvm->trans); 1058 iwl_mvm_stop_device(mvm);
1039 return ret; 1059 return ret;
1040} 1060}
1041 1061
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
index 535134d639e0..e885db3464b0 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
@@ -1484,6 +1484,8 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
1484 /* update rx_status according to the notification's metadata */ 1484 /* update rx_status according to the notification's metadata */
1485 memset(&rx_status, 0, sizeof(rx_status)); 1485 memset(&rx_status, 0, sizeof(rx_status));
1486 rx_status.mactime = le64_to_cpu(sb->tsf); 1486 rx_status.mactime = le64_to_cpu(sb->tsf);
1487 /* TSF as indicated by the firmware is at INA time */
1488 rx_status.flag |= RX_FLAG_MACTIME_PLCP_START;
1487 rx_status.device_timestamp = le32_to_cpu(sb->system_time); 1489 rx_status.device_timestamp = le32_to_cpu(sb->system_time);
1488 rx_status.band = 1490 rx_status.band =
1489 (sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? 1491 (sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ?
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 53156810185d..ec6b07282e7d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -7,6 +7,7 @@
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 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -69,7 +70,6 @@
69#include <linux/etherdevice.h> 70#include <linux/etherdevice.h>
70#include <linux/ip.h> 71#include <linux/ip.h>
71#include <linux/if_arp.h> 72#include <linux/if_arp.h>
72#include <linux/devcoredump.h>
73#include <linux/time.h> 73#include <linux/time.h>
74#include <net/mac80211.h> 74#include <net/mac80211.h>
75#include <net/ieee80211_radiotap.h> 75#include <net/ieee80211_radiotap.h>
@@ -85,7 +85,6 @@
85#include "testmode.h" 85#include "testmode.h"
86#include "iwl-fw-error-dump.h" 86#include "iwl-fw-error-dump.h"
87#include "iwl-prph.h" 87#include "iwl-prph.h"
88#include "iwl-csr.h"
89#include "iwl-nvm-parse.h" 88#include "iwl-nvm-parse.h"
90#include "fw-dbg.h" 89#include "fw-dbg.h"
91 90
@@ -611,6 +610,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
611 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) 610 IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
612 hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES; 611 hw->wiphy->features |= NL80211_FEATURE_WFA_TPC_IE_IN_PROBES;
613 612
613 wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_RRM);
614
614 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 615 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
615 616
616#ifdef CONFIG_PM_SLEEP 617#ifdef CONFIG_PM_SLEEP
@@ -847,6 +848,7 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
847 u16 tid = params->tid; 848 u16 tid = params->tid;
848 u16 *ssn = &params->ssn; 849 u16 *ssn = &params->ssn;
849 u8 buf_size = params->buf_size; 850 u8 buf_size = params->buf_size;
851 bool amsdu = params->amsdu;
850 852
851 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n", 853 IWL_DEBUG_HT(mvm, "A-MPDU action on addr %pM tid %d: action %d\n",
852 sta->addr, tid, action); 854 sta->addr, tid, action);
@@ -907,7 +909,8 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
907 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid); 909 ret = iwl_mvm_sta_tx_agg_flush(mvm, vif, sta, tid);
908 break; 910 break;
909 case IEEE80211_AMPDU_TX_OPERATIONAL: 911 case IEEE80211_AMPDU_TX_OPERATIONAL:
910 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid, buf_size); 912 ret = iwl_mvm_sta_tx_agg_oper(mvm, vif, sta, tid,
913 buf_size, amsdu);
911 break; 914 break;
912 default: 915 default:
913 WARN_ON_ONCE(1); 916 WARN_ON_ONCE(1);
@@ -969,7 +972,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
969 */ 972 */
970 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN); 973 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
971 974
972 iwl_trans_stop_device(mvm->trans); 975 iwl_mvm_stop_device(mvm);
973 976
974 mvm->scan_status = 0; 977 mvm->scan_status = 0;
975 mvm->ps_disabled = false; 978 mvm->ps_disabled = false;
@@ -1138,7 +1141,7 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
1138 */ 1141 */
1139 flush_work(&mvm->roc_done_wk); 1142 flush_work(&mvm->roc_done_wk);
1140 1143
1141 iwl_trans_stop_device(mvm->trans); 1144 iwl_mvm_stop_device(mvm);
1142 1145
1143 iwl_mvm_async_handlers_purge(mvm); 1146 iwl_mvm_async_handlers_purge(mvm);
1144 /* async_handlers_list is empty and will stay empty: HW is stopped */ 1147 /* async_handlers_list is empty and will stay empty: HW is stopped */
@@ -1169,8 +1172,6 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
1169 mvm->scan_uid_status[i] = 0; 1172 mvm->scan_uid_status[i] = 0;
1170 } 1173 }
1171 } 1174 }
1172
1173 mvm->ucode_loaded = false;
1174} 1175}
1175 1176
1176static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) 1177static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
@@ -1762,6 +1763,50 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
1762} 1763}
1763#endif 1764#endif
1764 1765
1766static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm,
1767 struct ieee80211_vif *vif)
1768{
1769 struct iwl_mu_group_mgmt_cmd cmd = {};
1770
1771 memcpy(cmd.membership_status, vif->bss_conf.mu_group.membership,
1772 WLAN_MEMBERSHIP_LEN);
1773 memcpy(cmd.user_position, vif->bss_conf.mu_group.position,
1774 WLAN_USER_POSITION_LEN);
1775
1776 return iwl_mvm_send_cmd_pdu(mvm,
1777 WIDE_ID(DATA_PATH_GROUP,
1778 UPDATE_MU_GROUPS_CMD),
1779 0, sizeof(cmd), &cmd);
1780}
1781
1782static void iwl_mvm_mu_mimo_iface_iterator(void *_data, u8 *mac,
1783 struct ieee80211_vif *vif)
1784{
1785 if (vif->mu_mimo_owner) {
1786 struct iwl_mu_group_mgmt_notif *notif = _data;
1787
1788 /*
1789 * MU-MIMO Group Id action frame is little endian. We treat
1790 * the data received from firmware as if it came from the
1791 * action frame, so no conversion is needed.
1792 */
1793 ieee80211_update_mu_groups(vif,
1794 (u8 *)&notif->membership_status,
1795 (u8 *)&notif->user_position);
1796 }
1797}
1798
1799void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
1800 struct iwl_rx_cmd_buffer *rxb)
1801{
1802 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1803 struct iwl_mu_group_mgmt_notif *notif = (void *)pkt->data;
1804
1805 ieee80211_iterate_active_interfaces_atomic(
1806 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1807 iwl_mvm_mu_mimo_iface_iterator, notif);
1808}
1809
1765static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 1810static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1766 struct ieee80211_vif *vif, 1811 struct ieee80211_vif *vif,
1767 struct ieee80211_bss_conf *bss_conf, 1812 struct ieee80211_bss_conf *bss_conf,
@@ -1870,6 +1915,18 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1870 vif->addr); 1915 vif->addr);
1871 } 1916 }
1872 1917
1918 /*
1919 * The firmware tracks the MU-MIMO group on its own.
1920 * However, on HW restart we should restore this data.
1921 */
1922 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
1923 (changes & BSS_CHANGED_MU_GROUPS) && vif->mu_mimo_owner) {
1924 ret = iwl_mvm_update_mu_groups(mvm, vif);
1925 if (ret)
1926 IWL_ERR(mvm,
1927 "failed to update VHT MU_MIMO groups\n");
1928 }
1929
1873 iwl_mvm_recalc_multicast(mvm); 1930 iwl_mvm_recalc_multicast(mvm);
1874 iwl_mvm_configure_bcast_filter(mvm); 1931 iwl_mvm_configure_bcast_filter(mvm);
1875 1932
@@ -1896,7 +1953,12 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1896 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); 1953 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
1897 } 1954 }
1898 1955
1899 if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS)) { 1956 if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS |
1957 /*
1958 * Send power command on every beacon change,
1959 * because we may have not enabled beacon abort yet.
1960 */
1961 BSS_CHANGED_BEACON_INFO)) {
1900 ret = iwl_mvm_power_update_mac(mvm); 1962 ret = iwl_mvm_power_update_mac(mvm);
1901 if (ret) 1963 if (ret)
1902 IWL_ERR(mvm, "failed to update power mode\n"); 1964 IWL_ERR(mvm, "failed to update power mode\n");
@@ -2083,7 +2145,6 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
2083 bss_conf->txpower); 2145 bss_conf->txpower);
2084 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower); 2146 iwl_mvm_set_tx_power(mvm, vif, bss_conf->txpower);
2085 } 2147 }
2086
2087} 2148}
2088 2149
2089static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, 2150static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
@@ -2276,6 +2337,11 @@ static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2276 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT)) 2337 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
2277 return; 2338 return;
2278 2339
2340 if (vif->p2p && !iwl_mvm_is_p2p_standalone_uapsd_supported(mvm)) {
2341 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2342 return;
2343 }
2344
2279 if (iwlwifi_mod_params.uapsd_disable) { 2345 if (iwlwifi_mod_params.uapsd_disable) {
2280 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD; 2346 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2281 return; 2347 return;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index cc279e0961fa..ab410b4659f3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -7,6 +7,7 @@
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 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
33 * 34 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
37 * Copyright(c) 2016 Intel Deutschland GmbH
36 * All rights reserved. 38 * All rights reserved.
37 * 39 *
38 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
@@ -71,6 +73,10 @@
71#include <linux/leds.h> 73#include <linux/leds.h>
72#include <linux/in6.h> 74#include <linux/in6.h>
73 75
76#ifdef CONFIG_THERMAL
77#include <linux/thermal.h>
78#endif
79
74#include "iwl-op-mode.h" 80#include "iwl-op-mode.h"
75#include "iwl-trans.h" 81#include "iwl-trans.h"
76#include "iwl-notif-wait.h" 82#include "iwl-notif-wait.h"
@@ -487,6 +493,12 @@ enum iwl_mvm_scan_type {
487 IWL_SCAN_TYPE_FRAGMENTED, 493 IWL_SCAN_TYPE_FRAGMENTED,
488}; 494};
489 495
496enum iwl_mvm_sched_scan_pass_all_states {
497 SCHED_SCAN_PASS_ALL_DISABLED,
498 SCHED_SCAN_PASS_ALL_ENABLED,
499 SCHED_SCAN_PASS_ALL_FOUND,
500};
501
490/** 502/**
491 * struct iwl_nvm_section - describes an NVM section in memory. 503 * struct iwl_nvm_section - describes an NVM section in memory.
492 * 504 *
@@ -517,6 +529,30 @@ struct iwl_mvm_tt_mgmt {
517 bool throttle; 529 bool throttle;
518}; 530};
519 531
532#ifdef CONFIG_THERMAL
533/**
534 *struct iwl_mvm_thermal_device - thermal zone related data
535 * @temp_trips: temperature thresholds for report
536 * @fw_trips_index: keep indexes to original array - temp_trips
537 * @tzone: thermal zone device data
538*/
539struct iwl_mvm_thermal_device {
540 s16 temp_trips[IWL_MAX_DTS_TRIPS];
541 u8 fw_trips_index[IWL_MAX_DTS_TRIPS];
542 struct thermal_zone_device *tzone;
543};
544
545/*
546 * iwl_mvm_cooling_device
547 * @cur_state: current state in milliwatts
548 * @cdev: struct thermal cooling device
549 */
550struct iwl_mvm_cooling_device {
551 u32 cur_state;
552 struct thermal_cooling_device *cdev;
553};
554#endif
555
520#define IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES 8 556#define IWL_MVM_NUM_LAST_FRAMES_UCODE_RATES 8
521 557
522struct iwl_mvm_frame_stats { 558struct iwl_mvm_frame_stats {
@@ -657,6 +693,7 @@ struct iwl_mvm {
657 void *scan_cmd; 693 void *scan_cmd;
658 struct iwl_mcast_filter_cmd *mcast_filter_cmd; 694 struct iwl_mcast_filter_cmd *mcast_filter_cmd;
659 enum iwl_mvm_scan_type scan_type; 695 enum iwl_mvm_scan_type scan_type;
696 enum iwl_mvm_sched_scan_pass_all_states sched_scan_pass_all;
660 697
661 /* max number of simultaneous scans the FW supports */ 698 /* max number of simultaneous scans the FW supports */
662 unsigned int max_scans; 699 unsigned int max_scans;
@@ -797,6 +834,11 @@ struct iwl_mvm {
797 834
798 /* Thermal Throttling and CTkill */ 835 /* Thermal Throttling and CTkill */
799 struct iwl_mvm_tt_mgmt thermal_throttle; 836 struct iwl_mvm_tt_mgmt thermal_throttle;
837#ifdef CONFIG_THERMAL
838 struct iwl_mvm_thermal_device tz_device;
839 struct iwl_mvm_cooling_device cooling_dev;
840#endif
841
800 s32 temperature; /* Celsius */ 842 s32 temperature; /* Celsius */
801 /* 843 /*
802 * Debug option to set the NIC temperature. This option makes the 844 * Debug option to set the NIC temperature. This option makes the
@@ -819,6 +861,7 @@ struct iwl_mvm {
819 861
820 /* Indicate if device power save is allowed */ 862 /* Indicate if device power save is allowed */
821 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */ 863 u8 ps_disabled; /* u8 instead of bool to ease debugfs_create_* usage */
864 unsigned int max_amsdu_len; /* used for debugfs only */
822 865
823 struct ieee80211_vif __rcu *csa_vif; 866 struct ieee80211_vif __rcu *csa_vif;
824 struct ieee80211_vif __rcu *csa_tx_blocked_vif; 867 struct ieee80211_vif __rcu *csa_tx_blocked_vif;
@@ -943,8 +986,9 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
943 986
944static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm) 987static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm)
945{ 988{
946 return fw_has_capa(&mvm->fw->ucode_capa, 989 /* Make sure DQA isn't allowed in driver until feature is complete */
947 IWL_UCODE_TLV_CAPA_DQA_SUPPORT); 990 return false && fw_has_capa(&mvm->fw->ucode_capa,
991 IWL_UCODE_TLV_CAPA_DQA_SUPPORT);
948} 992}
949 993
950static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm) 994static inline bool iwl_mvm_enter_d0i3_on_suspend(struct iwl_mvm *mvm)
@@ -1028,6 +1072,28 @@ static inline bool iwl_mvm_has_new_rx_api(struct iwl_mvm *mvm)
1028 IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT); 1072 IWL_UCODE_TLV_CAPA_MULTI_QUEUE_RX_SUPPORT);
1029} 1073}
1030 1074
1075static inline bool iwl_mvm_is_tt_in_fw(struct iwl_mvm *mvm)
1076{
1077#ifdef CONFIG_THERMAL
1078 /* these two TLV are redundant since the responsibility to CT-kill by
1079 * FW happens only after we send at least one command of
1080 * temperature THs report.
1081 */
1082 return fw_has_capa(&mvm->fw->ucode_capa,
1083 IWL_UCODE_TLV_CAPA_CT_KILL_BY_FW) &&
1084 fw_has_capa(&mvm->fw->ucode_capa,
1085 IWL_UCODE_TLV_CAPA_TEMP_THS_REPORT_SUPPORT);
1086#else /* CONFIG_THERMAL */
1087 return false;
1088#endif /* CONFIG_THERMAL */
1089}
1090
1091static inline bool iwl_mvm_is_ctdp_supported(struct iwl_mvm *mvm)
1092{
1093 return fw_has_capa(&mvm->fw->ucode_capa,
1094 IWL_UCODE_TLV_CAPA_CTDP_SUPPORT);
1095}
1096
1031extern const u8 iwl_mvm_ac_to_tx_fifo[]; 1097extern const u8 iwl_mvm_ac_to_tx_fifo[];
1032 1098
1033struct iwl_rate_info { 1099struct iwl_rate_info {
@@ -1160,6 +1226,10 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
1160 struct iwl_rx_cmd_buffer *rxb, int queue); 1226 struct iwl_rx_cmd_buffer *rxb, int queue);
1161void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm, 1227void iwl_mvm_rx_frame_release(struct iwl_mvm *mvm,
1162 struct iwl_rx_cmd_buffer *rxb, int queue); 1228 struct iwl_rx_cmd_buffer *rxb, int queue);
1229int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
1230 const u8 *data, u32 count);
1231void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
1232 int queue);
1163void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1233void iwl_mvm_rx_tx_cmd(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1164void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb); 1234void iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1165void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, 1235void iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
@@ -1203,6 +1273,10 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *mvm,
1203 struct iwl_rx_cmd_buffer *rxb); 1273 struct iwl_rx_cmd_buffer *rxb);
1204void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm, 1274void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
1205 struct iwl_rx_cmd_buffer *rxb); 1275 struct iwl_rx_cmd_buffer *rxb);
1276void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
1277 struct iwl_rx_cmd_buffer *rxb);
1278void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,
1279 struct iwl_rx_cmd_buffer *rxb);
1206void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm, 1280void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
1207 struct ieee80211_vif *vif); 1281 struct ieee80211_vif *vif);
1208unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm, 1282unsigned long iwl_mvm_get_used_hw_queues(struct iwl_mvm *mvm,
@@ -1479,32 +1553,30 @@ void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue,
1479 iwl_mvm_enable_txq(mvm, queue, mac80211_queue, ssn, &cfg, wdg_timeout); 1553 iwl_mvm_enable_txq(mvm, queue, mac80211_queue, ssn, &cfg, wdg_timeout);
1480} 1554}
1481 1555
1482static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue, 1556static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
1483 int mac80211_queue, int fifo,
1484 int sta_id, int tid, int frame_limit,
1485 u16 ssn, unsigned int wdg_timeout)
1486{ 1557{
1487 struct iwl_trans_txq_scd_cfg cfg = { 1558 mvm->ucode_loaded = false;
1488 .fifo = fifo, 1559 iwl_trans_stop_device(mvm->trans);
1489 .sta_id = sta_id,
1490 .tid = tid,
1491 .frame_limit = frame_limit,
1492 .aggregate = true,
1493 };
1494
1495 iwl_mvm_enable_txq(mvm, queue, mac80211_queue, ssn, &cfg, wdg_timeout);
1496} 1560}
1497 1561
1562/* Stop/start all mac queues in a given bitmap */
1563void iwl_mvm_start_mac_queues(struct iwl_mvm *mvm, unsigned long mq);
1564void iwl_mvm_stop_mac_queues(struct iwl_mvm *mvm, unsigned long mq);
1565
1498/* Thermal management and CT-kill */ 1566/* Thermal management and CT-kill */
1499void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1567void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1500void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp); 1568void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp);
1501void iwl_mvm_temp_notif(struct iwl_mvm *mvm, 1569void iwl_mvm_temp_notif(struct iwl_mvm *mvm,
1502 struct iwl_rx_cmd_buffer *rxb); 1570 struct iwl_rx_cmd_buffer *rxb);
1503void iwl_mvm_tt_handler(struct iwl_mvm *mvm); 1571void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
1504void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff); 1572void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff);
1505void iwl_mvm_tt_exit(struct iwl_mvm *mvm); 1573void iwl_mvm_thermal_exit(struct iwl_mvm *mvm);
1506void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); 1574void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
1507int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp); 1575int iwl_mvm_get_temp(struct iwl_mvm *mvm, s32 *temp);
1576void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb);
1577int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm);
1578int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm);
1579int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget);
1508 1580
1509/* Location Aware Regulatory */ 1581/* Location Aware Regulatory */
1510struct iwl_mcc_update_resp * 1582struct iwl_mcc_update_resp *
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index fd8f4a80ddfc..699a80863e86 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -236,6 +236,9 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
236 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION, 236 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
237 iwl_mvm_rx_ant_coupling_notif, true), 237 iwl_mvm_rx_ant_coupling_notif, true),
238 238
239 RX_HANDLER(BA_WINDOW_STATUS_NOTIFICATION_ID,
240 iwl_mvm_window_status_notif, false),
241
239 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 242 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
240 RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true), 243 RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true),
241 244
@@ -263,6 +266,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
263 RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true), 266 RX_HANDLER(DTS_MEASUREMENT_NOTIFICATION, iwl_mvm_temp_notif, true),
264 RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE, 267 RX_HANDLER_GRP(PHY_OPS_GROUP, DTS_MEASUREMENT_NOTIF_WIDE,
265 iwl_mvm_temp_notif, true), 268 iwl_mvm_temp_notif, true),
269 RX_HANDLER_GRP(PHY_OPS_GROUP, CT_KILL_NOTIFICATION,
270 iwl_mvm_ct_kill_notif, false),
266 271
267 RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif, 272 RX_HANDLER(TDLS_CHANNEL_SWITCH_NOTIFICATION, iwl_mvm_rx_tdls_notif,
268 true), 273 true),
@@ -270,6 +275,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
270 RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler, true), 275 RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler, true),
271 RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF, 276 RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
272 iwl_mvm_rx_stored_beacon_notif, false), 277 iwl_mvm_rx_stored_beacon_notif, false),
278 RX_HANDLER_GRP(DATA_PATH_GROUP, MU_GROUP_MGMT_NOTIF,
279 iwl_mvm_mu_mimo_grp_notif, false),
273 280
274}; 281};
275#undef RX_HANDLER 282#undef RX_HANDLER
@@ -292,6 +299,7 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
292 HCMD_NAME(SCAN_COMPLETE_UMAC), 299 HCMD_NAME(SCAN_COMPLETE_UMAC),
293 HCMD_NAME(TOF_CMD), 300 HCMD_NAME(TOF_CMD),
294 HCMD_NAME(TOF_NOTIFICATION), 301 HCMD_NAME(TOF_NOTIFICATION),
302 HCMD_NAME(BA_WINDOW_STATUS_NOTIFICATION_ID),
295 HCMD_NAME(ADD_STA_KEY), 303 HCMD_NAME(ADD_STA_KEY),
296 HCMD_NAME(ADD_STA), 304 HCMD_NAME(ADD_STA),
297 HCMD_NAME(REMOVE_STA), 305 HCMD_NAME(REMOVE_STA),
@@ -387,12 +395,25 @@ static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
387 */ 395 */
388static const struct iwl_hcmd_names iwl_mvm_phy_names[] = { 396static const struct iwl_hcmd_names iwl_mvm_phy_names[] = {
389 HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE), 397 HCMD_NAME(CMD_DTS_MEASUREMENT_TRIGGER_WIDE),
398 HCMD_NAME(CTDP_CONFIG_CMD),
399 HCMD_NAME(TEMP_REPORTING_THRESHOLDS_CMD),
400 HCMD_NAME(CT_KILL_NOTIFICATION),
390 HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE), 401 HCMD_NAME(DTS_MEASUREMENT_NOTIF_WIDE),
391}; 402};
392 403
393/* Please keep this array *SORTED* by hex value. 404/* Please keep this array *SORTED* by hex value.
394 * Access is done through binary search 405 * Access is done through binary search
395 */ 406 */
407static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
408 HCMD_NAME(UPDATE_MU_GROUPS_CMD),
409 HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
410 HCMD_NAME(MU_GROUP_MGMT_NOTIF),
411 HCMD_NAME(RX_QUEUES_NOTIFICATION),
412};
413
414/* Please keep this array *SORTED* by hex value.
415 * Access is done through binary search
416 */
396static const struct iwl_hcmd_names iwl_mvm_prot_offload_names[] = { 417static const struct iwl_hcmd_names iwl_mvm_prot_offload_names[] = {
397 HCMD_NAME(STORED_BEACON_NTF), 418 HCMD_NAME(STORED_BEACON_NTF),
398}; 419};
@@ -401,6 +422,7 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
401 [LEGACY_GROUP] = HCMD_ARR(iwl_mvm_legacy_names), 422 [LEGACY_GROUP] = HCMD_ARR(iwl_mvm_legacy_names),
402 [LONG_GROUP] = HCMD_ARR(iwl_mvm_legacy_names), 423 [LONG_GROUP] = HCMD_ARR(iwl_mvm_legacy_names),
403 [PHY_OPS_GROUP] = HCMD_ARR(iwl_mvm_phy_names), 424 [PHY_OPS_GROUP] = HCMD_ARR(iwl_mvm_phy_names),
425 [DATA_PATH_GROUP] = HCMD_ARR(iwl_mvm_data_path_names),
404 [PROT_OFFLOAD_GROUP] = HCMD_ARR(iwl_mvm_prot_offload_names), 426 [PROT_OFFLOAD_GROUP] = HCMD_ARR(iwl_mvm_prot_offload_names),
405}; 427};
406 428
@@ -474,8 +496,11 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
474 496
475 if (iwl_mvm_has_new_rx_api(mvm)) { 497 if (iwl_mvm_has_new_rx_api(mvm)) {
476 op_mode->ops = &iwl_mvm_ops_mq; 498 op_mode->ops = &iwl_mvm_ops_mq;
499 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_desc);
477 } else { 500 } else {
478 op_mode->ops = &iwl_mvm_ops; 501 op_mode->ops = &iwl_mvm_ops;
502 trans->rx_mpdu_cmd_hdr_size =
503 sizeof(struct iwl_rx_mpdu_res_start);
479 504
480 if (WARN_ON(trans->num_rx_queues > 1)) 505 if (WARN_ON(trans->num_rx_queues > 1))
481 goto out_free; 506 goto out_free;
@@ -567,7 +592,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
567 iwl_trans_configure(mvm->trans, &trans_cfg); 592 iwl_trans_configure(mvm->trans, &trans_cfg);
568 593
569 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; 594 trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD;
570 trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start);
571 trans->dbg_dest_tlv = mvm->fw->dbg_dest_tlv; 595 trans->dbg_dest_tlv = mvm->fw->dbg_dest_tlv;
572 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num; 596 trans->dbg_dest_reg_num = mvm->fw->dbg_dest_reg_num;
573 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv, 597 memcpy(trans->dbg_conf_tlv, mvm->fw->dbg_conf_tlv,
@@ -588,7 +612,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
588 mvm->cfg->name, mvm->trans->hw_rev); 612 mvm->cfg->name, mvm->trans->hw_rev);
589 613
590 min_backoff = calc_min_backoff(trans, cfg); 614 min_backoff = calc_min_backoff(trans, cfg);
591 iwl_mvm_tt_initialize(mvm, min_backoff); 615 iwl_mvm_thermal_initialize(mvm, min_backoff);
592 616
593 if (iwlwifi_mod_params.nvm_file) 617 if (iwlwifi_mod_params.nvm_file)
594 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; 618 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
@@ -619,7 +643,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
619 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); 643 iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE);
620 err = iwl_run_init_mvm_ucode(mvm, true); 644 err = iwl_run_init_mvm_ucode(mvm, true);
621 if (!err || !iwlmvm_mod_params.init_dbg) 645 if (!err || !iwlmvm_mod_params.init_dbg)
622 iwl_trans_stop_device(trans); 646 iwl_mvm_stop_device(mvm);
623 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE); 647 iwl_mvm_unref(mvm, IWL_MVM_REF_INIT_UCODE);
624 mutex_unlock(&mvm->mutex); 648 mutex_unlock(&mvm->mutex);
625 /* returns 0 if successful, 1 if success but in rfkill */ 649 /* returns 0 if successful, 1 if success but in rfkill */
@@ -648,19 +672,22 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
648 672
649 memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); 673 memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
650 674
651 /* rpm starts with a taken reference, we can release it now */ 675 /* The transport always starts with a taken reference, we can
652 iwl_trans_unref(mvm->trans); 676 * release it now if d0i3 is supported */
677 if (iwl_mvm_is_d0i3_supported(mvm))
678 iwl_trans_unref(mvm->trans);
653 679
654 iwl_mvm_tof_init(mvm); 680 iwl_mvm_tof_init(mvm);
655 681
656 /* init RSS hash key */ 682 /* init RSS hash key */
657 get_random_bytes(mvm->secret_key, ARRAY_SIZE(mvm->secret_key)); 683 get_random_bytes(mvm->secret_key, sizeof(mvm->secret_key));
658 684
659 return op_mode; 685 return op_mode;
660 686
661 out_unregister: 687 out_unregister:
662 ieee80211_unregister_hw(mvm->hw); 688 ieee80211_unregister_hw(mvm->hw);
663 iwl_mvm_leds_exit(mvm); 689 iwl_mvm_leds_exit(mvm);
690 iwl_mvm_thermal_exit(mvm);
664 out_free: 691 out_free:
665 flush_delayed_work(&mvm->fw_dump_wk); 692 flush_delayed_work(&mvm->fw_dump_wk);
666 iwl_phy_db_free(mvm->phy_db); 693 iwl_phy_db_free(mvm->phy_db);
@@ -676,9 +703,16 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
676 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 703 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
677 int i; 704 int i;
678 705
706 /* If d0i3 is supported, we have released the reference that
707 * the transport started with, so we should take it back now
708 * that we are leaving.
709 */
710 if (iwl_mvm_is_d0i3_supported(mvm))
711 iwl_trans_ref(mvm->trans);
712
679 iwl_mvm_leds_exit(mvm); 713 iwl_mvm_leds_exit(mvm);
680 714
681 iwl_mvm_tt_exit(mvm); 715 iwl_mvm_thermal_exit(mvm);
682 716
683 ieee80211_unregister_hw(mvm->hw); 717 ieee80211_unregister_hw(mvm->hw);
684 718
@@ -858,28 +892,24 @@ static void iwl_mvm_rx_mq(struct iwl_op_mode *op_mode,
858 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0); 892 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, 0);
859 else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD) 893 else if (pkt->hdr.cmd == REPLY_RX_PHY_CMD)
860 iwl_mvm_rx_phy_cmd_mq(mvm, rxb); 894 iwl_mvm_rx_phy_cmd_mq(mvm, rxb);
895 else if (unlikely(pkt->hdr.group_id == DATA_PATH_GROUP &&
896 pkt->hdr.cmd == RX_QUEUES_NOTIFICATION))
897 iwl_mvm_rx_queue_notif(mvm, rxb, 0);
861 else 898 else
862 iwl_mvm_rx_common(mvm, rxb, pkt); 899 iwl_mvm_rx_common(mvm, rxb, pkt);
863} 900}
864 901
865static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int queue) 902void iwl_mvm_stop_mac_queues(struct iwl_mvm *mvm, unsigned long mq)
866{ 903{
867 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
868 unsigned long mq;
869 int q; 904 int q;
870 905
871 spin_lock_bh(&mvm->queue_info_lock);
872 mq = mvm->queue_info[queue].hw_queue_to_mac80211;
873 spin_unlock_bh(&mvm->queue_info_lock);
874
875 if (WARN_ON_ONCE(!mq)) 906 if (WARN_ON_ONCE(!mq))
876 return; 907 return;
877 908
878 for_each_set_bit(q, &mq, IEEE80211_MAX_QUEUES) { 909 for_each_set_bit(q, &mq, IEEE80211_MAX_QUEUES) {
879 if (atomic_inc_return(&mvm->mac80211_queue_stop_count[q]) > 1) { 910 if (atomic_inc_return(&mvm->mac80211_queue_stop_count[q]) > 1) {
880 IWL_DEBUG_TX_QUEUES(mvm, 911 IWL_DEBUG_TX_QUEUES(mvm,
881 "queue %d (mac80211 %d) already stopped\n", 912 "mac80211 %d already stopped\n", q);
882 queue, q);
883 continue; 913 continue;
884 } 914 }
885 915
@@ -899,24 +929,29 @@ static void iwl_mvm_async_cb(struct iwl_op_mode *op_mode,
899 iwl_trans_block_txq_ptrs(mvm->trans, false); 929 iwl_trans_block_txq_ptrs(mvm->trans, false);
900} 930}
901 931
902static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue) 932static void iwl_mvm_stop_sw_queue(struct iwl_op_mode *op_mode, int hw_queue)
903{ 933{
904 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 934 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
905 unsigned long mq; 935 unsigned long mq;
906 int q;
907 936
908 spin_lock_bh(&mvm->queue_info_lock); 937 spin_lock_bh(&mvm->queue_info_lock);
909 mq = mvm->queue_info[queue].hw_queue_to_mac80211; 938 mq = mvm->queue_info[hw_queue].hw_queue_to_mac80211;
910 spin_unlock_bh(&mvm->queue_info_lock); 939 spin_unlock_bh(&mvm->queue_info_lock);
911 940
941 iwl_mvm_stop_mac_queues(mvm, mq);
942}
943
944void iwl_mvm_start_mac_queues(struct iwl_mvm *mvm, unsigned long mq)
945{
946 int q;
947
912 if (WARN_ON_ONCE(!mq)) 948 if (WARN_ON_ONCE(!mq))
913 return; 949 return;
914 950
915 for_each_set_bit(q, &mq, IEEE80211_MAX_QUEUES) { 951 for_each_set_bit(q, &mq, IEEE80211_MAX_QUEUES) {
916 if (atomic_dec_return(&mvm->mac80211_queue_stop_count[q]) > 0) { 952 if (atomic_dec_return(&mvm->mac80211_queue_stop_count[q]) > 0) {
917 IWL_DEBUG_TX_QUEUES(mvm, 953 IWL_DEBUG_TX_QUEUES(mvm,
918 "queue %d (mac80211 %d) still stopped\n", 954 "mac80211 %d still stopped\n", q);
919 queue, q);
920 continue; 955 continue;
921 } 956 }
922 957
@@ -924,6 +959,18 @@ static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int queue)
924 } 959 }
925} 960}
926 961
962static void iwl_mvm_wake_sw_queue(struct iwl_op_mode *op_mode, int hw_queue)
963{
964 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
965 unsigned long mq;
966
967 spin_lock_bh(&mvm->queue_info_lock);
968 mq = mvm->queue_info[hw_queue].hw_queue_to_mac80211;
969 spin_unlock_bh(&mvm->queue_info_lock);
970
971 iwl_mvm_start_mac_queues(mvm, mq);
972}
973
927void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state) 974void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
928{ 975{
929 if (state) 976 if (state)
@@ -1530,6 +1577,9 @@ static void iwl_mvm_rx_mq_rss(struct iwl_op_mode *op_mode,
1530 1577
1531 if (unlikely(pkt->hdr.cmd == FRAME_RELEASE)) 1578 if (unlikely(pkt->hdr.cmd == FRAME_RELEASE))
1532 iwl_mvm_rx_frame_release(mvm, rxb, queue); 1579 iwl_mvm_rx_frame_release(mvm, rxb, queue);
1580 else if (unlikely(pkt->hdr.cmd == RX_QUEUES_NOTIFICATION &&
1581 pkt->hdr.group_id == DATA_PATH_GROUP))
1582 iwl_mvm_rx_queue_notif(mvm, rxb, queue);
1533 else 1583 else
1534 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, queue); 1584 iwl_mvm_rx_mpdu_mq(mvm, napi, rxb, queue);
1535} 1585}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
index 6e7e78a37879..61d0a8cd13f9 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
@@ -556,6 +556,7 @@ static char *rs_pretty_rate(const struct rs_rate *rate)
556 if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX)) 556 if (is_type_legacy(rate->type) && (rate->index <= IWL_RATE_54M_INDEX))
557 rate_str = legacy_rates[rate->index]; 557 rate_str = legacy_rates[rate->index];
558 else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) && 558 else if ((is_type_ht(rate->type) || is_type_vht(rate->type)) &&
559 (rate->index >= IWL_RATE_MCS_0_INDEX) &&
559 (rate->index <= IWL_RATE_MCS_9_INDEX)) 560 (rate->index <= IWL_RATE_MCS_9_INDEX))
560 rate_str = ht_vht_rates[rate->index]; 561 rate_str = ht_vht_rates[rate->index];
561 else 562 else
@@ -1672,6 +1673,20 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1672 } 1673 }
1673} 1674}
1674 1675
1676static void rs_set_amsdu_len(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1677 struct iwl_scale_tbl_info *tbl,
1678 enum rs_action scale_action)
1679{
1680 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
1681
1682 if ((!is_vht(&tbl->rate) && !is_ht(&tbl->rate)) ||
1683 tbl->rate.index < IWL_RATE_MCS_5_INDEX ||
1684 scale_action == RS_ACTION_DOWNSCALE)
1685 sta_priv->tlc_amsdu = false;
1686 else
1687 sta_priv->tlc_amsdu = true;
1688}
1689
1675/* 1690/*
1676 * setup rate table in uCode 1691 * setup rate table in uCode
1677 */ 1692 */
@@ -2415,6 +2430,7 @@ lq_update:
2415 tbl->rate.index = index; 2430 tbl->rate.index = index;
2416 if (IWL_MVM_RS_80_20_FAR_RANGE_TWEAK) 2431 if (IWL_MVM_RS_80_20_FAR_RANGE_TWEAK)
2417 rs_tweak_rate_tbl(mvm, sta, lq_sta, tbl, scale_action); 2432 rs_tweak_rate_tbl(mvm, sta, lq_sta, tbl, scale_action);
2433 rs_set_amsdu_len(mvm, sta, tbl, scale_action);
2418 rs_update_rate_tbl(mvm, sta, lq_sta, tbl); 2434 rs_update_rate_tbl(mvm, sta, lq_sta, tbl);
2419 } 2435 }
2420 2436
@@ -3098,6 +3114,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
3098 sband = hw->wiphy->bands[band]; 3114 sband = hw->wiphy->bands[band];
3099 3115
3100 lq_sta->lq.sta_id = sta_priv->sta_id; 3116 lq_sta->lq.sta_id = sta_priv->sta_id;
3117 sta_priv->tlc_amsdu = false;
3101 3118
3102 for (j = 0; j < LQ_SIZE; j++) 3119 for (j = 0; j < LQ_SIZE; j++)
3103 rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); 3120 rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]);
@@ -3657,10 +3674,13 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3657 ssize_t ret; 3674 ssize_t ret;
3658 3675
3659 struct iwl_lq_sta *lq_sta = file->private_data; 3676 struct iwl_lq_sta *lq_sta = file->private_data;
3677 struct iwl_mvm_sta *mvmsta =
3678 container_of(lq_sta, struct iwl_mvm_sta, lq_sta);
3660 struct iwl_mvm *mvm; 3679 struct iwl_mvm *mvm;
3661 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 3680 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
3662 struct rs_rate *rate = &tbl->rate; 3681 struct rs_rate *rate = &tbl->rate;
3663 u32 ss_params; 3682 u32 ss_params;
3683
3664 mvm = lq_sta->pers.drv; 3684 mvm = lq_sta->pers.drv;
3665 buff = kmalloc(2048, GFP_KERNEL); 3685 buff = kmalloc(2048, GFP_KERNEL);
3666 if (!buff) 3686 if (!buff)
@@ -3686,10 +3706,11 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3686 (is_ht20(rate)) ? "20MHz" : 3706 (is_ht20(rate)) ? "20MHz" :
3687 (is_ht40(rate)) ? "40MHz" : 3707 (is_ht40(rate)) ? "40MHz" :
3688 (is_ht80(rate)) ? "80Mhz" : "BAD BW"); 3708 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
3689 desc += sprintf(buff + desc, " %s %s %s\n", 3709 desc += sprintf(buff + desc, " %s %s %s %s\n",
3690 (rate->sgi) ? "SGI" : "NGI", 3710 (rate->sgi) ? "SGI" : "NGI",
3691 (rate->ldpc) ? "LDPC" : "BCC", 3711 (rate->ldpc) ? "LDPC" : "BCC",
3692 (lq_sta->is_agg) ? "AGG on" : ""); 3712 (lq_sta->is_agg) ? "AGG on" : "",
3713 (mvmsta->tlc_amsdu) ? "AMSDU on" : "");
3693 } 3714 }
3694 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 3715 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
3695 lq_sta->last_rate_n_flags); 3716 lq_sta->last_rate_n_flags);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
index 145ec68ce6f9..485cfc1a4daa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c
@@ -7,6 +7,7 @@
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 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -322,11 +323,9 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
322 rx_status->freq = 323 rx_status->freq =
323 ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel), 324 ieee80211_channel_to_frequency(le16_to_cpu(phy_info->channel),
324 rx_status->band); 325 rx_status->band);
325 /* 326
326 * TSF as indicated by the fw is at INA time, but mac80211 expects the 327 /* TSF as indicated by the firmware is at INA time */
327 * TSF at the beginning of the MPDU. 328 rx_status->flag |= RX_FLAG_MACTIME_PLCP_START;
328 */
329 /*rx_status->flag |= RX_FLAG_MACTIME_MPDU;*/
330 329
331 iwl_mvm_get_signal_strength(mvm, phy_info, rx_status); 330 iwl_mvm_get_signal_strength(mvm, phy_info, rx_status);
332 331
@@ -448,6 +447,12 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
448 iwl_mvm_update_frame_stats(mvm, rate_n_flags, 447 iwl_mvm_update_frame_stats(mvm, rate_n_flags,
449 rx_status->flag & RX_FLAG_AMPDU_DETAILS); 448 rx_status->flag & RX_FLAG_AMPDU_DETAILS);
450#endif 449#endif
450
451 if (unlikely((ieee80211_is_beacon(hdr->frame_control) ||
452 ieee80211_is_probe_resp(hdr->frame_control)) &&
453 mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED))
454 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_FOUND;
455
451 iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, hdr, len, ampdu_status, 456 iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, hdr, len, ampdu_status,
452 crypt_len, rxb); 457 crypt_len, rxb);
453} 458}
@@ -622,3 +627,51 @@ void iwl_mvm_rx_statistics(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
622{ 627{
623 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb)); 628 iwl_mvm_handle_rx_statistics(mvm, rxb_addr(rxb));
624} 629}
630
631void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,
632 struct iwl_rx_cmd_buffer *rxb)
633{
634 struct iwl_rx_packet *pkt = rxb_addr(rxb);
635 struct iwl_ba_window_status_notif *notif = (void *)pkt->data;
636 int i;
637 u32 pkt_len = iwl_rx_packet_payload_len(pkt);
638
639 if (WARN_ONCE(pkt_len != sizeof(*notif),
640 "Received window status notification of wrong size (%u)\n",
641 pkt_len))
642 return;
643
644 rcu_read_lock();
645 for (i = 0; i < BA_WINDOW_STREAMS_MAX; i++) {
646 struct ieee80211_sta *sta;
647 u8 sta_id, tid;
648 u64 bitmap;
649 u32 ssn;
650 u16 ratid;
651 u16 received_mpdu;
652
653 ratid = le16_to_cpu(notif->ra_tid[i]);
654 /* check that this TID is valid */
655 if (!(ratid & BA_WINDOW_STATUS_VALID_MSK))
656 continue;
657
658 received_mpdu = le16_to_cpu(notif->mpdu_rx_count[i]);
659 if (received_mpdu == 0)
660 continue;
661
662 tid = ratid & BA_WINDOW_STATUS_TID_MSK;
663 /* get the station */
664 sta_id = (ratid & BA_WINDOW_STATUS_STA_ID_MSK)
665 >> BA_WINDOW_STATUS_STA_ID_POS;
666 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
667 if (IS_ERR_OR_NULL(sta))
668 continue;
669 bitmap = le64_to_cpu(notif->bitmap[i]);
670 ssn = le32_to_cpu(notif->start_seq_num[i]);
671
672 /* update mac80211 with the bitmap for the reordering buffer */
673 ieee80211_mark_rx_ba_filtered_frames(sta, tid, ssn, bitmap,
674 received_mpdu);
675 }
676 rcu_read_unlock();
677}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 615dea143d4e..cd6ca374e5d3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -7,7 +7,7 @@
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 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 Intel Deutschland GmbH 10 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as 13 * it under the terms of version 2 of the GNU General Public License as
@@ -29,7 +29,7 @@
29 * 29 *
30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 30 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 31 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
32 * Copyright(c) 2015 Intel Deutschland GmbH 32 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
33 * All rights reserved. 33 * All rights reserved.
34 * 34 *
35 * Redistribution and use in source and binary forms, with or without 35 * Redistribution and use in source and binary forms, with or without
@@ -156,7 +156,14 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
156 u16 len, u8 crypt_len, 156 u16 len, u8 crypt_len,
157 struct iwl_rx_cmd_buffer *rxb) 157 struct iwl_rx_cmd_buffer *rxb)
158{ 158{
159 unsigned int hdrlen, fraglen; 159 struct iwl_rx_packet *pkt = rxb_addr(rxb);
160 struct iwl_rx_mpdu_desc *desc = (void *)pkt->data;
161 unsigned int headlen, fraglen, pad_len = 0;
162 unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control);
163
164 if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD)
165 pad_len = 2;
166 len -= pad_len;
160 167
161 /* If frame is small enough to fit in skb->head, pull it completely. 168 /* If frame is small enough to fit in skb->head, pull it completely.
162 * If not, only pull ieee80211_hdr (including crypto if present, and 169 * If not, only pull ieee80211_hdr (including crypto if present, and
@@ -170,14 +177,23 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr,
170 * If the latter changes (there are efforts in the standards group 177 * If the latter changes (there are efforts in the standards group
171 * to do so) we should revisit this and ieee80211_data_to_8023(). 178 * to do so) we should revisit this and ieee80211_data_to_8023().
172 */ 179 */
173 hdrlen = (len <= skb_tailroom(skb)) ? len : 180 headlen = (len <= skb_tailroom(skb)) ? len :
174 sizeof(*hdr) + crypt_len + 8; 181 hdrlen + crypt_len + 8;
175 182
183 /* The firmware may align the packet to DWORD.
184 * The padding is inserted after the IV.
185 * After copying the header + IV skip the padding if
186 * present before copying packet data.
187 */
188 hdrlen += crypt_len;
176 memcpy(skb_put(skb, hdrlen), hdr, hdrlen); 189 memcpy(skb_put(skb, hdrlen), hdr, hdrlen);
177 fraglen = len - hdrlen; 190 memcpy(skb_put(skb, headlen - hdrlen), (u8 *)hdr + hdrlen + pad_len,
191 headlen - hdrlen);
192
193 fraglen = len - headlen;
178 194
179 if (fraglen) { 195 if (fraglen) {
180 int offset = (void *)hdr + hdrlen - 196 int offset = (void *)hdr + headlen + pad_len -
181 rxb_addr(rxb) + rxb_offset(rxb); 197 rxb_addr(rxb) + rxb_offset(rxb);
182 198
183 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, 199 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
@@ -285,6 +301,114 @@ static void iwl_mvm_rx_csum(struct ieee80211_sta *sta,
285 skb->ip_summed = CHECKSUM_UNNECESSARY; 301 skb->ip_summed = CHECKSUM_UNNECESSARY;
286} 302}
287 303
304/*
305 * returns true if a packet outside BA session is a duplicate and
306 * should be dropped
307 */
308static bool iwl_mvm_is_nonagg_dup(struct ieee80211_sta *sta, int queue,
309 struct ieee80211_rx_status *rx_status,
310 struct ieee80211_hdr *hdr,
311 struct iwl_rx_mpdu_desc *desc)
312{
313 struct iwl_mvm_sta *mvm_sta;
314 struct iwl_mvm_rxq_dup_data *dup_data;
315 u8 baid, tid, sub_frame_idx;
316
317 if (WARN_ON(IS_ERR_OR_NULL(sta)))
318 return false;
319
320 baid = (le32_to_cpu(desc->reorder_data) &
321 IWL_RX_MPDU_REORDER_BAID_MASK) >>
322 IWL_RX_MPDU_REORDER_BAID_SHIFT;
323
324 if (baid != IWL_RX_REORDER_DATA_INVALID_BAID)
325 return false;
326
327 mvm_sta = iwl_mvm_sta_from_mac80211(sta);
328 dup_data = &mvm_sta->dup_data[queue];
329
330 /*
331 * Drop duplicate 802.11 retransmissions
332 * (IEEE 802.11-2012: 9.3.2.10 "Duplicate detection and recovery")
333 */
334 if (ieee80211_is_ctl(hdr->frame_control) ||
335 ieee80211_is_qos_nullfunc(hdr->frame_control) ||
336 is_multicast_ether_addr(hdr->addr1)) {
337 rx_status->flag |= RX_FLAG_DUP_VALIDATED;
338 return false;
339 }
340
341 if (ieee80211_is_data_qos(hdr->frame_control))
342 /* frame has qos control */
343 tid = *ieee80211_get_qos_ctl(hdr) &
344 IEEE80211_QOS_CTL_TID_MASK;
345 else
346 tid = IWL_MAX_TID_COUNT;
347
348 /* If this wasn't a part of an A-MSDU the sub-frame index will be 0 */
349 sub_frame_idx = desc->amsdu_info & IWL_RX_MPDU_AMSDU_SUBFRAME_IDX_MASK;
350
351 if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
352 dup_data->last_seq[tid] == hdr->seq_ctrl &&
353 dup_data->last_sub_frame[tid] >= sub_frame_idx))
354 return true;
355
356 dup_data->last_seq[tid] = hdr->seq_ctrl;
357 dup_data->last_sub_frame[tid] = sub_frame_idx;
358
359 rx_status->flag |= RX_FLAG_DUP_VALIDATED;
360
361 return false;
362}
363
364int iwl_mvm_notify_rx_queue(struct iwl_mvm *mvm, u32 rxq_mask,
365 const u8 *data, u32 count)
366{
367 struct iwl_rxq_sync_cmd *cmd;
368 u32 data_size = sizeof(*cmd) + count;
369 int ret;
370
371 /* should be DWORD aligned */
372 if (WARN_ON(count & 3 || count > IWL_MULTI_QUEUE_SYNC_MSG_MAX_SIZE))
373 return -EINVAL;
374
375 cmd = kzalloc(data_size, GFP_KERNEL);
376 if (!cmd)
377 return -ENOMEM;
378
379 cmd->rxq_mask = cpu_to_le32(rxq_mask);
380 cmd->count = cpu_to_le32(count);
381 cmd->flags = 0;
382 memcpy(cmd->payload, data, count);
383
384 ret = iwl_mvm_send_cmd_pdu(mvm,
385 WIDE_ID(DATA_PATH_GROUP,
386 TRIGGER_RX_QUEUES_NOTIF_CMD),
387 0, data_size, cmd);
388
389 kfree(cmd);
390 return ret;
391}
392
393void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
394 int queue)
395{
396 struct iwl_rx_packet *pkt = rxb_addr(rxb);
397 struct iwl_rxq_sync_notification *notif;
398 struct iwl_mvm_internal_rxq_notif *internal_notif;
399
400 notif = (void *)pkt->data;
401 internal_notif = (void *)notif->payload;
402
403 switch (internal_notif->type) {
404 case IWL_MVM_RXQ_NOTIF_DEL_BA:
405 /* TODO */
406 break;
407 default:
408 WARN_ONCE(1, "Invalid identifier %d", internal_notif->type);
409 }
410}
411
288void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, 412void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
289 struct iwl_rx_cmd_buffer *rxb, int queue) 413 struct iwl_rx_cmd_buffer *rxb, int queue)
290{ 414{
@@ -332,6 +456,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
332 rx_status->freq = ieee80211_channel_to_frequency(desc->channel, 456 rx_status->freq = ieee80211_channel_to_frequency(desc->channel,
333 rx_status->band); 457 rx_status->band);
334 iwl_mvm_get_signal_strength(mvm, desc, rx_status); 458 iwl_mvm_get_signal_strength(mvm, desc, rx_status);
459 /* TSF as indicated by the firmware is at INA time */
460 rx_status->flag |= RX_FLAG_MACTIME_PLCP_START;
335 461
336 rcu_read_lock(); 462 rcu_read_lock();
337 463
@@ -387,6 +513,12 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
387 513
388 if (ieee80211_is_data(hdr->frame_control)) 514 if (ieee80211_is_data(hdr->frame_control))
389 iwl_mvm_rx_csum(sta, skb, desc); 515 iwl_mvm_rx_csum(sta, skb, desc);
516
517 if (iwl_mvm_is_nonagg_dup(sta, queue, rx_status, hdr, desc)) {
518 kfree_skb(skb);
519 rcu_read_unlock();
520 return;
521 }
390 } 522 }
391 523
392 /* 524 /*
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index aa6d8074f63a..09eb72c4ae43 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -7,6 +7,7 @@
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 - 2015 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 * Copyright(c) 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -33,6 +34,7 @@
33 * 34 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
37 * Copyright(c) 2016 Intel Deutschland GmbH
36 * All rights reserved. 38 * All rights reserved.
37 * 39 *
38 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
@@ -297,6 +299,12 @@ void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
297 iwl_mvm_dump_channel_list(notif->results, 299 iwl_mvm_dump_channel_list(notif->results,
298 notif->scanned_channels, buf, 300 notif->scanned_channels, buf,
299 sizeof(buf))); 301 sizeof(buf)));
302
303 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
304 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
305 ieee80211_sched_scan_results(mvm->hw);
306 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
307 }
300} 308}
301 309
302void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm, 310void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
@@ -380,6 +388,7 @@ void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
380 388
381 mvm->scan_status &= ~IWL_MVM_SCAN_SCHED; 389 mvm->scan_status &= ~IWL_MVM_SCAN_SCHED;
382 ieee80211_sched_scan_stopped(mvm->hw); 390 ieee80211_sched_scan_stopped(mvm->hw);
391 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
383 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) { 392 } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
384 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n", 393 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
385 aborted ? "aborted" : "completed", 394 aborted ? "aborted" : "completed",
@@ -533,10 +542,13 @@ static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
533 IWL_DEBUG_SCAN(mvm, 542 IWL_DEBUG_SCAN(mvm,
534 "Sending scheduled scan with filtering, n_match_sets %d\n", 543 "Sending scheduled scan with filtering, n_match_sets %d\n",
535 req->n_match_sets); 544 req->n_match_sets);
545 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
536 return false; 546 return false;
537 } 547 }
538 548
539 IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n"); 549 IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n");
550
551 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
540 return true; 552 return true;
541} 553}
542 554
@@ -788,6 +800,9 @@ static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
788 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE; 800 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
789#endif 801#endif
790 802
803 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
804 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
805
791 if (iwl_mvm_is_regular_scan(params) && 806 if (iwl_mvm_is_regular_scan(params) &&
792 vif->type != NL80211_IFTYPE_P2P_DEVICE && 807 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
793 params->type != IWL_SCAN_TYPE_FRAGMENTED) 808 params->type != IWL_SCAN_TYPE_FRAGMENTED)
@@ -1074,6 +1089,9 @@ static u32 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
1074 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE; 1089 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1075#endif 1090#endif
1076 1091
1092 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
1093 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
1094
1077 if (iwl_mvm_is_regular_scan(params) && 1095 if (iwl_mvm_is_regular_scan(params) &&
1078 vif->type != NL80211_IFTYPE_P2P_DEVICE && 1096 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
1079 params->type != IWL_SCAN_TYPE_FRAGMENTED) 1097 params->type != IWL_SCAN_TYPE_FRAGMENTED)
@@ -1301,10 +1319,6 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
1301 return -EBUSY; 1319 return -EBUSY;
1302 } 1320 }
1303 1321
1304 /* we don't support "match all" in the firmware */
1305 if (!req->n_match_sets)
1306 return -EOPNOTSUPP;
1307
1308 ret = iwl_mvm_check_running_scans(mvm, type); 1322 ret = iwl_mvm_check_running_scans(mvm, type);
1309 if (ret) 1323 if (ret)
1310 return ret; 1324 return ret;
@@ -1400,6 +1414,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
1400 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1414 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1401 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) { 1415 } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
1402 ieee80211_sched_scan_stopped(mvm->hw); 1416 ieee80211_sched_scan_stopped(mvm->hw);
1417 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1403 } 1418 }
1404 1419
1405 mvm->scan_status &= ~mvm->scan_uid_status[uid]; 1420 mvm->scan_status &= ~mvm->scan_uid_status[uid];
@@ -1434,6 +1449,12 @@ void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
1434 iwl_mvm_dump_channel_list(notif->results, 1449 iwl_mvm_dump_channel_list(notif->results,
1435 notif->scanned_channels, buf, 1450 notif->scanned_channels, buf,
1436 sizeof(buf))); 1451 sizeof(buf)));
1452
1453 if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
1454 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
1455 ieee80211_sched_scan_results(mvm->hw);
1456 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
1457 }
1437} 1458}
1438 1459
1439static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type) 1460static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
@@ -1528,6 +1549,7 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
1528 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED); 1549 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
1529 if (uid >= 0 && !mvm->restart_fw) { 1550 if (uid >= 0 && !mvm->restart_fw) {
1530 ieee80211_sched_scan_stopped(mvm->hw); 1551 ieee80211_sched_scan_stopped(mvm->hw);
1552 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1531 mvm->scan_uid_status[uid] = 0; 1553 mvm->scan_uid_status[uid] = 0;
1532 } 1554 }
1533 1555
@@ -1549,8 +1571,11 @@ void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
1549 * restart_hw, so do not report if FW is about to be 1571 * restart_hw, so do not report if FW is about to be
1550 * restarted. 1572 * restarted.
1551 */ 1573 */
1552 if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) && !mvm->restart_fw) 1574 if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) &&
1575 !mvm->restart_fw) {
1553 ieee80211_sched_scan_stopped(mvm->hw); 1576 ieee80211_sched_scan_stopped(mvm->hw);
1577 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1578 }
1554 } 1579 }
1555} 1580}
1556 1581
@@ -1586,6 +1611,7 @@ out:
1586 ieee80211_scan_completed(mvm->hw, true); 1611 ieee80211_scan_completed(mvm->hw, true);
1587 } else if (notify) { 1612 } else if (notify) {
1588 ieee80211_sched_scan_stopped(mvm->hw); 1613 ieee80211_sched_scan_stopped(mvm->hw);
1614 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
1589 } 1615 }
1590 1616
1591 return ret; 1617 return ret;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 4854e79cbda8..ef99942d7169 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -280,6 +280,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
280{ 280{
281 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 281 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
282 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta); 282 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
283 struct iwl_mvm_rxq_dup_data *dup_data;
283 int i, ret, sta_id; 284 int i, ret, sta_id;
284 285
285 lockdep_assert_held(&mvm->mutex); 286 lockdep_assert_held(&mvm->mutex);
@@ -327,6 +328,16 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
327 } 328 }
328 mvm_sta->agg_tids = 0; 329 mvm_sta->agg_tids = 0;
329 330
331 if (iwl_mvm_has_new_rx_api(mvm) &&
332 !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
333 dup_data = kcalloc(mvm->trans->num_rx_queues,
334 sizeof(*dup_data),
335 GFP_KERNEL);
336 if (!dup_data)
337 return -ENOMEM;
338 mvm_sta->dup_data = dup_data;
339 }
340
330 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); 341 ret = iwl_mvm_sta_send_to_fw(mvm, sta, false);
331 if (ret) 342 if (ret)
332 goto err; 343 goto err;
@@ -508,6 +519,9 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
508 519
509 lockdep_assert_held(&mvm->mutex); 520 lockdep_assert_held(&mvm->mutex);
510 521
522 if (iwl_mvm_has_new_rx_api(mvm))
523 kfree(mvm_sta->dup_data);
524
511 if (vif->type == NL80211_IFTYPE_STATION && 525 if (vif->type == NL80211_IFTYPE_STATION &&
512 mvmvif->ap_sta_id == mvm_sta->sta_id) { 526 mvmvif->ap_sta_id == mvm_sta->sta_id) {
513 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true); 527 ret = iwl_mvm_drain_sta(mvm, mvm_sta, true);
@@ -1031,15 +1045,23 @@ release_locks:
1031} 1045}
1032 1046
1033int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1047int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1034 struct ieee80211_sta *sta, u16 tid, u8 buf_size) 1048 struct ieee80211_sta *sta, u16 tid, u8 buf_size,
1049 bool amsdu)
1035{ 1050{
1036 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1051 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1037 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 1052 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
1038 unsigned int wdg_timeout = 1053 unsigned int wdg_timeout =
1039 iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false); 1054 iwl_mvm_get_wd_timeout(mvm, vif, sta->tdls, false);
1040 int queue, fifo, ret; 1055 int queue, ret;
1041 u16 ssn; 1056 u16 ssn;
1042 1057
1058 struct iwl_trans_txq_scd_cfg cfg = {
1059 .sta_id = mvmsta->sta_id,
1060 .tid = tid,
1061 .frame_limit = buf_size,
1062 .aggregate = true,
1063 };
1064
1043 BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE) 1065 BUILD_BUG_ON((sizeof(mvmsta->agg_tids) * BITS_PER_BYTE)
1044 != IWL_MAX_TID_COUNT); 1066 != IWL_MAX_TID_COUNT);
1045 1067
@@ -1051,13 +1073,13 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1051 tid_data->state = IWL_AGG_ON; 1073 tid_data->state = IWL_AGG_ON;
1052 mvmsta->agg_tids |= BIT(tid); 1074 mvmsta->agg_tids |= BIT(tid);
1053 tid_data->ssn = 0xffff; 1075 tid_data->ssn = 0xffff;
1076 tid_data->amsdu_in_ampdu_allowed = amsdu;
1054 spin_unlock_bh(&mvmsta->lock); 1077 spin_unlock_bh(&mvmsta->lock);
1055 1078
1056 fifo = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]]; 1079 cfg.fifo = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]];
1057 1080
1058 iwl_mvm_enable_agg_txq(mvm, queue, 1081 iwl_mvm_enable_txq(mvm, queue, vif->hw_queue[tid_to_mac80211_ac[tid]],
1059 vif->hw_queue[tid_to_mac80211_ac[tid]], fifo, 1082 ssn, &cfg, wdg_timeout);
1060 mvmsta->sta_id, tid, buf_size, ssn, wdg_timeout);
1061 1083
1062 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true); 1084 ret = iwl_mvm_sta_tx_agg(mvm, sta, tid, queue, true);
1063 if (ret) 1085 if (ret)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
index e3b9446ee995..1a8f69a41405 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.h
@@ -258,8 +258,7 @@ enum iwl_mvm_agg_state {
258 * This is basically (last acked packet++). 258 * This is basically (last acked packet++).
259 * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the 259 * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
260 * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA). 260 * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
261 * @reduced_tpc: Reduced tx power. Holds the data between the 261 * @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed.
262 * Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
263 * @state: state of the BA agreement establishment / tear down. 262 * @state: state of the BA agreement establishment / tear down.
264 * @txq_id: Tx queue used by the BA session 263 * @txq_id: Tx queue used by the BA session
265 * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or 264 * @ssn: the first packet to be sent in AGG HW queue in Tx AGG start flow, or
@@ -273,7 +272,7 @@ struct iwl_mvm_tid_data {
273 u16 next_reclaimed; 272 u16 next_reclaimed;
274 /* The rest is Tx AGG related */ 273 /* The rest is Tx AGG related */
275 u32 rate_n_flags; 274 u32 rate_n_flags;
276 u8 reduced_tpc; 275 bool amsdu_in_ampdu_allowed;
277 enum iwl_mvm_agg_state state; 276 enum iwl_mvm_agg_state state;
278 u16 txq_id; 277 u16 txq_id;
279 u16 ssn; 278 u16 ssn;
@@ -294,6 +293,16 @@ struct iwl_mvm_key_pn {
294}; 293};
295 294
296/** 295/**
296 * struct iwl_mvm_rxq_dup_data - per station per rx queue data
297 * @last_seq: last sequence per tid for duplicate packet detection
298 * @last_sub_frame: last subframe packet
299 */
300struct iwl_mvm_rxq_dup_data {
301 __le16 last_seq[IWL_MAX_TID_COUNT + 1];
302 u8 last_sub_frame[IWL_MAX_TID_COUNT + 1];
303} ____cacheline_aligned_in_smp;
304
305/**
297 * struct iwl_mvm_sta - representation of a station in the driver 306 * struct iwl_mvm_sta - representation of a station in the driver
298 * @sta_id: the index of the station in the fw (will be replaced by id_n_color) 307 * @sta_id: the index of the station in the fw (will be replaced by id_n_color)
299 * @tfd_queue_msk: the tfd queues used by the station 308 * @tfd_queue_msk: the tfd queues used by the station
@@ -311,6 +320,7 @@ struct iwl_mvm_key_pn {
311 * @tx_protection: reference counter for controlling the Tx protection. 320 * @tx_protection: reference counter for controlling the Tx protection.
312 * @tt_tx_protection: is thermal throttling enable Tx protection? 321 * @tt_tx_protection: is thermal throttling enable Tx protection?
313 * @disable_tx: is tx to this STA disabled? 322 * @disable_tx: is tx to this STA disabled?
323 * @tlc_amsdu: true if A-MSDU is allowed
314 * @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON) 324 * @agg_tids: bitmap of tids whose status is operational aggregated (IWL_AGG_ON)
315 * @sleep_tx_count: the number of frames that we told the firmware to let out 325 * @sleep_tx_count: the number of frames that we told the firmware to let out
316 * even when that station is asleep. This is useful in case the queue 326 * even when that station is asleep. This is useful in case the queue
@@ -318,6 +328,7 @@ struct iwl_mvm_key_pn {
318 * we are sending frames from an AMPDU queue and there was a hole in 328 * we are sending frames from an AMPDU queue and there was a hole in
319 * the BA window. To be used for UAPSD only. 329 * the BA window. To be used for UAPSD only.
320 * @ptk_pn: per-queue PTK PN data structures 330 * @ptk_pn: per-queue PTK PN data structures
331 * @dup_data: per queue duplicate packet detection data
321 * 332 *
322 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 333 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
323 * in the structure for use by driver. This structure is placed in that 334 * in the structure for use by driver. This structure is placed in that
@@ -337,14 +348,15 @@ struct iwl_mvm_sta {
337 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT]; 348 struct iwl_mvm_tid_data tid_data[IWL_MAX_TID_COUNT];
338 struct iwl_lq_sta lq_sta; 349 struct iwl_lq_sta lq_sta;
339 struct ieee80211_vif *vif; 350 struct ieee80211_vif *vif;
340
341 struct iwl_mvm_key_pn __rcu *ptk_pn[4]; 351 struct iwl_mvm_key_pn __rcu *ptk_pn[4];
352 struct iwl_mvm_rxq_dup_data *dup_data;
342 353
343 /* Temporary, until the new TLC will control the Tx protection */ 354 /* Temporary, until the new TLC will control the Tx protection */
344 s8 tx_protection; 355 s8 tx_protection;
345 bool tt_tx_protection; 356 bool tt_tx_protection;
346 357
347 bool disable_tx; 358 bool disable_tx;
359 bool tlc_amsdu;
348 u8 agg_tids; 360 u8 agg_tids;
349 u8 sleep_tx_count; 361 u8 sleep_tx_count;
350}; 362};
@@ -405,7 +417,8 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
405int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 417int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
406 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 418 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
407int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 419int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
408 struct ieee80211_sta *sta, u16 tid, u8 buf_size); 420 struct ieee80211_sta *sta, u16 tid, u8 buf_size,
421 bool amsdu);
409int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 422int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
410 struct ieee80211_sta *sta, u16 tid); 423 struct ieee80211_sta *sta, u16 tid);
411int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 424int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
index 758d05a8c6aa..999bcb898be8 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tt.c
@@ -7,6 +7,7 @@
7 * 7 *
8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved. 8 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 9 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
10 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
10 * 11 *
11 * This program is free software; you can redistribute it and/or modify 12 * 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 13 * it under the terms of version 2 of the GNU General Public License as
@@ -33,7 +34,7 @@
33 * 34 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 35 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH 36 * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
36 * Copyright(c) 2015 Intel Deutschland GmbH 37 * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
37 * All rights reserved. 38 * All rights reserved.
38 * 39 *
39 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
@@ -64,6 +65,8 @@
64 * 65 *
65 *****************************************************************************/ 66 *****************************************************************************/
66 67
68#include <linux/sort.h>
69
67#include "mvm.h" 70#include "mvm.h"
68 71
69#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ 72#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
@@ -79,8 +82,10 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
79 IWL_ERR(mvm, "Enter CT Kill\n"); 82 IWL_ERR(mvm, "Enter CT Kill\n");
80 iwl_mvm_set_hw_ctkill_state(mvm, true); 83 iwl_mvm_set_hw_ctkill_state(mvm, true);
81 84
82 tt->throttle = false; 85 if (!iwl_mvm_is_tt_in_fw(mvm)) {
83 tt->dynamic_smps = false; 86 tt->throttle = false;
87 tt->dynamic_smps = false;
88 }
84 89
85 /* Don't schedule an exit work if we're in test mode, since 90 /* Don't schedule an exit work if we're in test mode, since
86 * the temperature will not change unless we manually set it 91 * the temperature will not change unless we manually set it
@@ -116,18 +121,21 @@ void iwl_mvm_tt_temp_changed(struct iwl_mvm *mvm, u32 temp)
116static int iwl_mvm_temp_notif_parse(struct iwl_mvm *mvm, 121static int iwl_mvm_temp_notif_parse(struct iwl_mvm *mvm,
117 struct iwl_rx_packet *pkt) 122 struct iwl_rx_packet *pkt)
118{ 123{
119 struct iwl_dts_measurement_notif *notif; 124 struct iwl_dts_measurement_notif_v1 *notif_v1;
120 int len = iwl_rx_packet_payload_len(pkt); 125 int len = iwl_rx_packet_payload_len(pkt);
121 int temp; 126 int temp;
122 127
123 if (WARN_ON_ONCE(len < sizeof(*notif))) { 128 /* we can use notif_v1 only, because v2 only adds an additional
129 * parameter, which is not used in this function.
130 */
131 if (WARN_ON_ONCE(len < sizeof(*notif_v1))) {
124 IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n"); 132 IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n");
125 return -EINVAL; 133 return -EINVAL;
126 } 134 }
127 135
128 notif = (void *)pkt->data; 136 notif_v1 = (void *)pkt->data;
129 137
130 temp = le32_to_cpu(notif->temp); 138 temp = le32_to_cpu(notif_v1->temp);
131 139
132 /* shouldn't be negative, but since it's s32, make sure it isn't */ 140 /* shouldn't be negative, but since it's s32, make sure it isn't */
133 if (WARN_ON_ONCE(temp < 0)) 141 if (WARN_ON_ONCE(temp < 0))
@@ -158,17 +166,74 @@ static bool iwl_mvm_temp_notif_wait(struct iwl_notif_wait_data *notif_wait,
158void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb) 166void iwl_mvm_temp_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
159{ 167{
160 struct iwl_rx_packet *pkt = rxb_addr(rxb); 168 struct iwl_rx_packet *pkt = rxb_addr(rxb);
169 struct iwl_dts_measurement_notif_v2 *notif_v2;
170 int len = iwl_rx_packet_payload_len(pkt);
161 int temp; 171 int temp;
172 u32 ths_crossed;
162 173
163 /* the notification is handled synchronously in ctkill, so skip here */ 174 /* the notification is handled synchronously in ctkill, so skip here */
164 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) 175 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
165 return; 176 return;
166 177
167 temp = iwl_mvm_temp_notif_parse(mvm, pkt); 178 temp = iwl_mvm_temp_notif_parse(mvm, pkt);
168 if (temp < 0) 179
180 if (!iwl_mvm_is_tt_in_fw(mvm)) {
181 if (temp >= 0)
182 iwl_mvm_tt_temp_changed(mvm, temp);
169 return; 183 return;
184 }
185
186 if (WARN_ON_ONCE(len < sizeof(*notif_v2))) {
187 IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n");
188 return;
189 }
190
191 notif_v2 = (void *)pkt->data;
192 ths_crossed = le32_to_cpu(notif_v2->threshold_idx);
170 193
171 iwl_mvm_tt_temp_changed(mvm, temp); 194 /* 0xFF in ths_crossed means the notification is not related
195 * to a trip, so we can ignore it here.
196 */
197 if (ths_crossed == 0xFF)
198 return;
199
200 IWL_DEBUG_TEMP(mvm, "Temp = %d Threshold crossed = %d\n",
201 temp, ths_crossed);
202
203#ifdef CONFIG_THERMAL
204 if (WARN_ON(ths_crossed >= IWL_MAX_DTS_TRIPS))
205 return;
206
207 /*
208 * We are now handling a temperature notification from the firmware
209 * in ASYNC and hold the mutex. thermal_notify_framework will call
210 * us back through get_temp() which ought to send a SYNC command to
211 * the firmware and hence to take the mutex.
212 * Avoid the deadlock by unlocking the mutex here.
213 */
214 mutex_unlock(&mvm->mutex);
215 thermal_notify_framework(mvm->tz_device.tzone,
216 mvm->tz_device.fw_trips_index[ths_crossed]);
217 mutex_lock(&mvm->mutex);
218#endif /* CONFIG_THERMAL */
219}
220
221void iwl_mvm_ct_kill_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
222{
223 struct iwl_rx_packet *pkt = rxb_addr(rxb);
224 struct ct_kill_notif *notif;
225 int len = iwl_rx_packet_payload_len(pkt);
226
227 if (WARN_ON_ONCE(len != sizeof(*notif))) {
228 IWL_ERR(mvm, "Invalid CT_KILL_NOTIFICATION\n");
229 return;
230 }
231
232 notif = (struct ct_kill_notif *)pkt->data;
233 IWL_DEBUG_TEMP(mvm, "CT Kill notification temperature = %d\n",
234 notif->temperature);
235
236 iwl_mvm_enter_ctkill(mvm);
172} 237}
173 238
174static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) 239static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
@@ -236,6 +301,12 @@ static void check_exit_ctkill(struct work_struct *work)
236 tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work); 301 tt = container_of(work, struct iwl_mvm_tt_mgmt, ct_kill_exit.work);
237 mvm = container_of(tt, struct iwl_mvm, thermal_throttle); 302 mvm = container_of(tt, struct iwl_mvm, thermal_throttle);
238 303
304 if (iwl_mvm_is_tt_in_fw(mvm)) {
305 iwl_mvm_exit_ctkill(mvm);
306
307 return;
308 }
309
239 duration = tt->params.ct_kill_duration; 310 duration = tt->params.ct_kill_duration;
240 311
241 mutex_lock(&mvm->mutex); 312 mutex_lock(&mvm->mutex);
@@ -435,7 +506,365 @@ static const struct iwl_tt_params iwl_mvm_default_tt_params = {
435 .support_tx_backoff = true, 506 .support_tx_backoff = true,
436}; 507};
437 508
438void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff) 509#ifdef CONFIG_THERMAL
510static int compare_temps(const void *a, const void *b)
511{
512 return ((s16)le16_to_cpu(*(__le16 *)a) -
513 (s16)le16_to_cpu(*(__le16 *)b));
514}
515
516int iwl_mvm_send_temp_report_ths_cmd(struct iwl_mvm *mvm)
517{
518 struct temp_report_ths_cmd cmd = {0};
519 int ret, i, j, idx = 0;
520
521 lockdep_assert_held(&mvm->mutex);
522
523 /* The driver holds array of temperature trips that are unsorted
524 * and uncompressed, the FW should get it compressed and sorted
525 */
526
527 /* compress temp_trips to cmd array, remove uninitialized values*/
528 for (i = 0; i < IWL_MAX_DTS_TRIPS; i++)
529 if (mvm->tz_device.temp_trips[i] != S16_MIN) {
530 cmd.thresholds[idx++] =
531 cpu_to_le16(mvm->tz_device.temp_trips[i]);
532 }
533 cmd.num_temps = cpu_to_le32(idx);
534
535 if (!idx)
536 goto send;
537
538 /*sort cmd array*/
539 sort(cmd.thresholds, idx, sizeof(s16), compare_temps, NULL);
540
541 /* we should save the indexes of trips because we sort
542 * and compress the orginal array
543 */
544 for (i = 0; i < idx; i++) {
545 for (j = 0; j < IWL_MAX_DTS_TRIPS; j++) {
546 if (le16_to_cpu(cmd.thresholds[i]) ==
547 mvm->tz_device.temp_trips[j])
548 mvm->tz_device.fw_trips_index[i] = j;
549 }
550 }
551
552send:
553 ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(PHY_OPS_GROUP,
554 TEMP_REPORTING_THRESHOLDS_CMD),
555 0, sizeof(cmd), &cmd);
556 if (ret)
557 IWL_ERR(mvm, "TEMP_REPORT_THS_CMD command failed (err=%d)\n",
558 ret);
559
560 return ret;
561}
562
563static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
564 int *temperature)
565{
566 struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
567 int ret;
568 int temp;
569
570 mutex_lock(&mvm->mutex);
571
572 if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
573 ret = -EIO;
574 goto out;
575 }
576
577 ret = iwl_mvm_get_temp(mvm, &temp);
578 if (ret)
579 goto out;
580
581 *temperature = temp * 1000;
582
583out:
584 mutex_unlock(&mvm->mutex);
585 return ret;
586}
587
588static int iwl_mvm_tzone_get_trip_temp(struct thermal_zone_device *device,
589 int trip, int *temp)
590{
591 struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
592
593 if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
594 return -EINVAL;
595
596 *temp = mvm->tz_device.temp_trips[trip] * 1000;
597
598 return 0;
599}
600
601static int iwl_mvm_tzone_get_trip_type(struct thermal_zone_device *device,
602 int trip, enum thermal_trip_type *type)
603{
604 if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS)
605 return -EINVAL;
606
607 *type = THERMAL_TRIP_PASSIVE;
608
609 return 0;
610}
611
612static int iwl_mvm_tzone_set_trip_temp(struct thermal_zone_device *device,
613 int trip, int temp)
614{
615 struct iwl_mvm *mvm = (struct iwl_mvm *)device->devdata;
616 struct iwl_mvm_thermal_device *tzone;
617 int i, ret;
618 s16 temperature;
619
620 mutex_lock(&mvm->mutex);
621
622 if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
623 ret = -EIO;
624 goto out;
625 }
626
627 if (trip < 0 || trip >= IWL_MAX_DTS_TRIPS) {
628 ret = -EINVAL;
629 goto out;
630 }
631
632 if ((temp / 1000) > S16_MAX) {
633 ret = -EINVAL;
634 goto out;
635 }
636
637 temperature = (s16)(temp / 1000);
638 tzone = &mvm->tz_device;
639
640 if (!tzone) {
641 ret = -EIO;
642 goto out;
643 }
644
645 /* no updates*/
646 if (tzone->temp_trips[trip] == temperature) {
647 ret = 0;
648 goto out;
649 }
650
651 /* already existing temperature */
652 for (i = 0; i < IWL_MAX_DTS_TRIPS; i++) {
653 if (tzone->temp_trips[i] == temperature) {
654 ret = -EINVAL;
655 goto out;
656 }
657 }
658
659 tzone->temp_trips[trip] = temperature;
660
661 ret = iwl_mvm_send_temp_report_ths_cmd(mvm);
662out:
663 mutex_unlock(&mvm->mutex);
664 return ret;
665}
666
667static struct thermal_zone_device_ops tzone_ops = {
668 .get_temp = iwl_mvm_tzone_get_temp,
669 .get_trip_temp = iwl_mvm_tzone_get_trip_temp,
670 .get_trip_type = iwl_mvm_tzone_get_trip_type,
671 .set_trip_temp = iwl_mvm_tzone_set_trip_temp,
672};
673
674/* make all trips writable */
675#define IWL_WRITABLE_TRIPS_MSK (BIT(IWL_MAX_DTS_TRIPS) - 1)
676
677static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
678{
679 int i;
680 char name[] = "iwlwifi";
681
682 if (!iwl_mvm_is_tt_in_fw(mvm)) {
683 mvm->tz_device.tzone = NULL;
684
685 return;
686 }
687
688 BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
689
690 mvm->tz_device.tzone = thermal_zone_device_register(name,
691 IWL_MAX_DTS_TRIPS,
692 IWL_WRITABLE_TRIPS_MSK,
693 mvm, &tzone_ops,
694 NULL, 0, 0);
695 if (IS_ERR(mvm->tz_device.tzone)) {
696 IWL_DEBUG_TEMP(mvm,
697 "Failed to register to thermal zone (err = %ld)\n",
698 PTR_ERR(mvm->tz_device.tzone));
699 return;
700 }
701
702 /* 0 is a valid temperature,
703 * so initialize the array with S16_MIN which invalid temperature
704 */
705 for (i = 0 ; i < IWL_MAX_DTS_TRIPS; i++)
706 mvm->tz_device.temp_trips[i] = S16_MIN;
707}
708
709static const u32 iwl_mvm_cdev_budgets[] = {
710 2000, /* cooling state 0 */
711 1800, /* cooling state 1 */
712 1600, /* cooling state 2 */
713 1400, /* cooling state 3 */
714 1200, /* cooling state 4 */
715 1000, /* cooling state 5 */
716 900, /* cooling state 6 */
717 800, /* cooling state 7 */
718 700, /* cooling state 8 */
719 650, /* cooling state 9 */
720 600, /* cooling state 10 */
721 550, /* cooling state 11 */
722 500, /* cooling state 12 */
723 450, /* cooling state 13 */
724 400, /* cooling state 14 */
725 350, /* cooling state 15 */
726 300, /* cooling state 16 */
727 250, /* cooling state 17 */
728 200, /* cooling state 18 */
729 150, /* cooling state 19 */
730};
731
732int iwl_mvm_ctdp_command(struct iwl_mvm *mvm, u32 op, u32 budget)
733{
734 struct iwl_mvm_ctdp_cmd cmd = {
735 .operation = cpu_to_le32(op),
736 .budget = cpu_to_le32(budget),
737 .window_size = 0,
738 };
739 int ret;
740 u32 status;
741
742 lockdep_assert_held(&mvm->mutex);
743
744 ret = iwl_mvm_send_cmd_pdu_status(mvm, WIDE_ID(PHY_OPS_GROUP,
745 CTDP_CONFIG_CMD),
746 sizeof(cmd), &cmd, &status);
747
748 if (ret) {
749 IWL_ERR(mvm, "cTDP command failed (err=%d)\n", ret);
750 return ret;
751 }
752
753 if (op == CTDP_CMD_OPERATION_START)
754 mvm->cooling_dev.cur_state = budget;
755
756 else if (op == CTDP_CMD_OPERATION_REPORT)
757 IWL_DEBUG_TEMP(mvm, "cTDP avg energy in mWatt = %d\n", status);
758
759 return 0;
760}
761
762static int iwl_mvm_tcool_get_max_state(struct thermal_cooling_device *cdev,
763 unsigned long *state)
764{
765 *state = ARRAY_SIZE(iwl_mvm_cdev_budgets) - 1;
766
767 return 0;
768}
769
770static int iwl_mvm_tcool_get_cur_state(struct thermal_cooling_device *cdev,
771 unsigned long *state)
772{
773 struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
774
775 if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
776 return -EBUSY;
777
778 *state = mvm->cooling_dev.cur_state;
779 return 0;
780}
781
782static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,
783 unsigned long new_state)
784{
785 struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
786 int ret;
787
788 if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
789 return -EIO;
790
791 if (test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status))
792 return -EBUSY;
793
794 mutex_lock(&mvm->mutex);
795
796 if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
797 ret = -EINVAL;
798 goto unlock;
799 }
800
801 ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
802 iwl_mvm_cdev_budgets[new_state]);
803
804unlock:
805 mutex_unlock(&mvm->mutex);
806 return ret;
807}
808
809static struct thermal_cooling_device_ops tcooling_ops = {
810 .get_max_state = iwl_mvm_tcool_get_max_state,
811 .get_cur_state = iwl_mvm_tcool_get_cur_state,
812 .set_cur_state = iwl_mvm_tcool_set_cur_state,
813};
814
815int iwl_mvm_cooling_device_register(struct iwl_mvm *mvm)
816{
817 char name[] = "iwlwifi";
818
819 if (!iwl_mvm_is_ctdp_supported(mvm)) {
820 mvm->cooling_dev.cdev = NULL;
821
822 return 0;
823 }
824
825 BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
826
827 mvm->cooling_dev.cdev =
828 thermal_cooling_device_register(name,
829 mvm,
830 &tcooling_ops);
831
832 if (IS_ERR(mvm->cooling_dev.cdev)) {
833 IWL_DEBUG_TEMP(mvm,
834 "Failed to register to cooling device (err = %ld)\n",
835 PTR_ERR(mvm->cooling_dev.cdev));
836 return PTR_ERR(mvm->cooling_dev.cdev);
837 }
838
839 return 0;
840}
841
842static void iwl_mvm_thermal_zone_unregister(struct iwl_mvm *mvm)
843{
844 if (!iwl_mvm_is_tt_in_fw(mvm))
845 return;
846
847 if (mvm->tz_device.tzone) {
848 IWL_DEBUG_TEMP(mvm, "Thermal zone device unregister\n");
849 thermal_zone_device_unregister(mvm->tz_device.tzone);
850 mvm->tz_device.tzone = NULL;
851 }
852}
853
854static void iwl_mvm_cooling_device_unregister(struct iwl_mvm *mvm)
855{
856 if (!iwl_mvm_is_ctdp_supported(mvm))
857 return;
858
859 if (mvm->cooling_dev.cdev) {
860 IWL_DEBUG_TEMP(mvm, "Cooling device unregister\n");
861 thermal_cooling_device_unregister(mvm->cooling_dev.cdev);
862 mvm->cooling_dev.cdev = NULL;
863 }
864}
865#endif /* CONFIG_THERMAL */
866
867void iwl_mvm_thermal_initialize(struct iwl_mvm *mvm, u32 min_backoff)
439{ 868{
440 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; 869 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
441 870
@@ -450,10 +879,20 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff)
450 tt->dynamic_smps = false; 879 tt->dynamic_smps = false;
451 tt->min_backoff = min_backoff; 880 tt->min_backoff = min_backoff;
452 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); 881 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
882
883#ifdef CONFIG_THERMAL
884 iwl_mvm_cooling_device_register(mvm);
885 iwl_mvm_thermal_zone_register(mvm);
886#endif
453} 887}
454 888
455void iwl_mvm_tt_exit(struct iwl_mvm *mvm) 889void iwl_mvm_thermal_exit(struct iwl_mvm *mvm)
456{ 890{
457 cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit); 891 cancel_delayed_work_sync(&mvm->thermal_throttle.ct_kill_exit);
458 IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n"); 892 IWL_DEBUG_TEMP(mvm, "Exit Thermal Throttling\n");
893
894#ifdef CONFIG_THERMAL
895 iwl_mvm_cooling_device_unregister(mvm);
896 iwl_mvm_thermal_zone_unregister(mvm);
897#endif
459} 898}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index dae2c40d605c..271e8da6d140 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -65,6 +65,7 @@
65#include <linux/ieee80211.h> 65#include <linux/ieee80211.h>
66#include <linux/etherdevice.h> 66#include <linux/etherdevice.h>
67#include <linux/tcp.h> 67#include <linux/tcp.h>
68#include <net/ip.h>
68 69
69#include "iwl-trans.h" 70#include "iwl-trans.h"
70#include "iwl-eeprom-parse.h" 71#include "iwl-eeprom-parse.h"
@@ -182,7 +183,8 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
182 183
183 tx_cmd->tx_flags = cpu_to_le32(tx_flags); 184 tx_cmd->tx_flags = cpu_to_le32(tx_flags);
184 /* Total # bytes to be transmitted */ 185 /* Total # bytes to be transmitted */
185 tx_cmd->len = cpu_to_le16((u16)skb->len); 186 tx_cmd->len = cpu_to_le16((u16)skb->len +
187 (uintptr_t)info->driver_data[0]);
186 tx_cmd->next_frame_len = 0; 188 tx_cmd->next_frame_len = 0;
187 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); 189 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
188 tx_cmd->sta_id = sta_id; 190 tx_cmd->sta_id = sta_id;
@@ -372,6 +374,9 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
372 info->hw_queue != info->control.vif->cab_queue))) 374 info->hw_queue != info->control.vif->cab_queue)))
373 return -1; 375 return -1;
374 376
377 /* This holds the amsdu headers length */
378 info->driver_data[0] = (void *)(uintptr_t)0;
379
375 /* 380 /*
376 * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used 381 * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
377 * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel 382 * in 2 different types of vifs, P2P & STATION. P2P uses the offchannel
@@ -437,33 +442,194 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
437 return 0; 442 return 0;
438} 443}
439 444
440static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb_gso, 445#ifdef CONFIG_INET
446static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
441 struct ieee80211_sta *sta, 447 struct ieee80211_sta *sta,
442 struct sk_buff_head *mpdus_skb) 448 struct sk_buff_head *mpdus_skb)
443{ 449{
450 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
451 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
452 struct ieee80211_hdr *hdr = (void *)skb->data;
453 unsigned int mss = skb_shinfo(skb)->gso_size;
444 struct sk_buff *tmp, *next; 454 struct sk_buff *tmp, *next;
445 char cb[sizeof(skb_gso->cb)]; 455 char cb[sizeof(skb->cb)];
456 unsigned int num_subframes, tcp_payload_len, subf_len, max_amsdu_len;
457 bool ipv4 = (skb->protocol == htons(ETH_P_IP));
458 u16 ip_base_id = ipv4 ? ntohs(ip_hdr(skb)->id) : 0;
459 u16 amsdu_add, snap_ip_tcp, pad, i = 0;
460 unsigned int dbg_max_amsdu_len;
461 u8 *qc, tid, txf;
462
463 snap_ip_tcp = 8 + skb_transport_header(skb) - skb_network_header(skb) +
464 tcp_hdrlen(skb);
465
466 qc = ieee80211_get_qos_ctl(hdr);
467 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
468 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
469 return -EINVAL;
470
471 if (!sta->max_amsdu_len ||
472 !ieee80211_is_data_qos(hdr->frame_control) ||
473 !mvmsta->tlc_amsdu) {
474 num_subframes = 1;
475 pad = 0;
476 goto segment;
477 }
478
479 /*
480 * No need to lock amsdu_in_ampdu_allowed since it can't be modified
481 * during an BA session.
482 */
483 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
484 !mvmsta->tid_data[tid].amsdu_in_ampdu_allowed) {
485 num_subframes = 1;
486 pad = 0;
487 goto segment;
488 }
489
490 max_amsdu_len = sta->max_amsdu_len;
491 dbg_max_amsdu_len = ACCESS_ONCE(mvm->max_amsdu_len);
492
493 /* the Tx FIFO to which this A-MSDU will be routed */
494 txf = iwl_mvm_ac_to_tx_fifo[tid_to_mac80211_ac[tid]];
495
496 /*
497 * Don't send an AMSDU that will be longer than the TXF.
498 * Add a security margin of 256 for the TX command + headers.
499 * We also want to have the start of the next packet inside the
500 * fifo to be able to send bursts.
501 */
502 max_amsdu_len = min_t(unsigned int, max_amsdu_len,
503 mvm->shared_mem_cfg.txfifo_size[txf] - 256);
504
505 if (dbg_max_amsdu_len)
506 max_amsdu_len = min_t(unsigned int, max_amsdu_len,
507 dbg_max_amsdu_len);
508
509 /*
510 * Limit A-MSDU in A-MPDU to 4095 bytes when VHT is not
511 * supported. This is a spec requirement (IEEE 802.11-2015
512 * section 8.7.3 NOTE 3).
513 */
514 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
515 !sta->vht_cap.vht_supported)
516 max_amsdu_len = min_t(unsigned int, max_amsdu_len, 4095);
517
518 /* Sub frame header + SNAP + IP header + TCP header + MSS */
519 subf_len = sizeof(struct ethhdr) + snap_ip_tcp + mss;
520 pad = (4 - subf_len) & 0x3;
521
522 /*
523 * If we have N subframes in the A-MSDU, then the A-MSDU's size is
524 * N * subf_len + (N - 1) * pad.
525 */
526 num_subframes = (max_amsdu_len + pad) / (subf_len + pad);
527 if (num_subframes > 1)
528 *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT;
446 529
447 memcpy(cb, skb_gso->cb, sizeof(cb)); 530 tcp_payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
448 next = skb_gso_segment(skb_gso, 0); 531 tcp_hdrlen(skb) + skb->data_len;
449 if (IS_ERR(next)) 532
533 /*
534 * Make sure we have enough TBs for the A-MSDU:
535 * 2 for each subframe
536 * 1 more for each fragment
537 * 1 more for the potential data in the header
538 */
539 num_subframes =
540 min_t(unsigned int, num_subframes,
541 (mvm->trans->max_skb_frags - 1 -
542 skb_shinfo(skb)->nr_frags) / 2);
543
544 /* This skb fits in one single A-MSDU */
545 if (num_subframes * mss >= tcp_payload_len) {
546 /*
547 * Compute the length of all the data added for the A-MSDU.
548 * This will be used to compute the length to write in the TX
549 * command. We have: SNAP + IP + TCP for n -1 subframes and
550 * ETH header for n subframes. Note that the original skb
551 * already had one set of SNAP / IP / TCP headers.
552 */
553 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
554 info = IEEE80211_SKB_CB(skb);
555 amsdu_add = num_subframes * sizeof(struct ethhdr) +
556 (num_subframes - 1) * (snap_ip_tcp + pad);
557 /* This holds the amsdu headers length */
558 info->driver_data[0] = (void *)(uintptr_t)amsdu_add;
559
560 __skb_queue_tail(mpdus_skb, skb);
561 return 0;
562 }
563
564 /*
565 * Trick the segmentation function to make it
566 * create SKBs that can fit into one A-MSDU.
567 */
568segment:
569 skb_shinfo(skb)->gso_size = num_subframes * mss;
570 memcpy(cb, skb->cb, sizeof(cb));
571
572 next = skb_gso_segment(skb, NETIF_F_CSUM_MASK | NETIF_F_SG);
573 skb_shinfo(skb)->gso_size = mss;
574 if (WARN_ON_ONCE(IS_ERR(next)))
450 return -EINVAL; 575 return -EINVAL;
451 else if (next) 576 else if (next)
452 consume_skb(skb_gso); 577 consume_skb(skb);
453 578
454 while (next) { 579 while (next) {
455 tmp = next; 580 tmp = next;
456 next = tmp->next; 581 next = tmp->next;
582
457 memcpy(tmp->cb, cb, sizeof(tmp->cb)); 583 memcpy(tmp->cb, cb, sizeof(tmp->cb));
584 /*
585 * Compute the length of all the data added for the A-MSDU.
586 * This will be used to compute the length to write in the TX
587 * command. We have: SNAP + IP + TCP for n -1 subframes and
588 * ETH header for n subframes.
589 */
590 tcp_payload_len = skb_tail_pointer(tmp) -
591 skb_transport_header(tmp) -
592 tcp_hdrlen(tmp) + tmp->data_len;
593
594 if (ipv4)
595 ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
596
597 if (tcp_payload_len > mss) {
598 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
599 info = IEEE80211_SKB_CB(tmp);
600 amsdu_add = num_subframes * sizeof(struct ethhdr) +
601 (num_subframes - 1) * (snap_ip_tcp + pad);
602 info->driver_data[0] = (void *)(uintptr_t)amsdu_add;
603 skb_shinfo(tmp)->gso_size = mss;
604 } else {
605 qc = ieee80211_get_qos_ctl((void *)tmp->data);
606
607 if (ipv4)
608 ip_send_check(ip_hdr(tmp));
609 *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
610 skb_shinfo(tmp)->gso_size = 0;
611 }
458 612
459 tmp->prev = NULL; 613 tmp->prev = NULL;
460 tmp->next = NULL; 614 tmp->next = NULL;
461 615
462 __skb_queue_tail(mpdus_skb, tmp); 616 __skb_queue_tail(mpdus_skb, tmp);
617 i++;
463 } 618 }
464 619
465 return 0; 620 return 0;
466} 621}
622#else /* CONFIG_INET */
623static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
624 struct ieee80211_sta *sta,
625 struct sk_buff_head *mpdus_skb)
626{
627 /* Impossible to get TSO with CONFIG_INET */
628 WARN_ON(1);
629
630 return -1;
631}
632#endif
467 633
468/* 634/*
469 * Sets the fields in the Tx cmd that are crypto related 635 * Sets the fields in the Tx cmd that are crypto related
@@ -569,6 +735,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
569 struct ieee80211_sta *sta) 735 struct ieee80211_sta *sta)
570{ 736{
571 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 737 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
738 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
572 struct sk_buff_head mpdus_skbs; 739 struct sk_buff_head mpdus_skbs;
573 unsigned int payload_len; 740 unsigned int payload_len;
574 int ret; 741 int ret;
@@ -579,6 +746,9 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
579 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) 746 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
580 return -1; 747 return -1;
581 748
749 /* This holds the amsdu headers length */
750 info->driver_data[0] = (void *)(uintptr_t)0;
751
582 if (!skb_is_gso(skb)) 752 if (!skb_is_gso(skb))
583 return iwl_mvm_tx_mpdu(mvm, skb, sta); 753 return iwl_mvm_tx_mpdu(mvm, skb, sta);
584 754
@@ -598,7 +768,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
598 return ret; 768 return ret;
599 769
600 while (!skb_queue_empty(&mpdus_skbs)) { 770 while (!skb_queue_empty(&mpdus_skbs)) {
601 struct sk_buff *skb = __skb_dequeue(&mpdus_skbs); 771 skb = __skb_dequeue(&mpdus_skbs);
602 772
603 ret = iwl_mvm_tx_mpdu(mvm, skb, sta); 773 ret = iwl_mvm_tx_mpdu(mvm, skb, sta);
604 if (ret) { 774 if (ret) {
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 753ec6785912..d33b6baf5f98 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -811,6 +811,45 @@ static int iwl_pci_runtime_resume(struct device *device)
811 811
812 return 0; 812 return 0;
813} 813}
814
815static int iwl_pci_system_prepare(struct device *device)
816{
817 struct pci_dev *pdev = to_pci_dev(device);
818 struct iwl_trans *trans = pci_get_drvdata(pdev);
819
820 IWL_DEBUG_RPM(trans, "preparing for system suspend\n");
821
822 /* This is called before entering system suspend and before
823 * the runtime resume is called. Set the suspending flag to
824 * prevent the wakelock from being taken.
825 */
826 trans->suspending = true;
827
828 /* Wake the device up from runtime suspend before going to
829 * platform suspend. This is needed because we don't know
830 * whether wowlan any is set and, if it's not, mac80211 will
831 * disconnect (in which case, we can't be in D0i3).
832 */
833 pm_runtime_resume(device);
834
835 return 0;
836}
837
838static void iwl_pci_system_complete(struct device *device)
839{
840 struct pci_dev *pdev = to_pci_dev(device);
841 struct iwl_trans *trans = pci_get_drvdata(pdev);
842
843 IWL_DEBUG_RPM(trans, "completing system suspend\n");
844
845 /* This is called as a counterpart to the prepare op. It is
846 * called either when suspending fails or when suspend
847 * completed successfully. Now there's no risk of grabbing
848 * the wakelock anymore, so we can release the suspending
849 * flag.
850 */
851 trans->suspending = false;
852}
814#endif /* CONFIG_IWLWIFI_PCIE_RTPM */ 853#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
815 854
816static const struct dev_pm_ops iwl_dev_pm_ops = { 855static const struct dev_pm_ops iwl_dev_pm_ops = {
@@ -820,6 +859,8 @@ static const struct dev_pm_ops iwl_dev_pm_ops = {
820 SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend, 859 SET_RUNTIME_PM_OPS(iwl_pci_runtime_suspend,
821 iwl_pci_runtime_resume, 860 iwl_pci_runtime_resume,
822 NULL) 861 NULL)
862 .prepare = iwl_pci_system_prepare,
863 .complete = iwl_pci_system_complete,
823#endif /* CONFIG_IWLWIFI_PCIE_RTPM */ 864#endif /* CONFIG_IWLWIFI_PCIE_RTPM */
824}; 865};
825 866
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
index 542bbc5e2b24..6677f3122226 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/internal.h
@@ -336,6 +336,14 @@ struct iwl_tso_hdr_page {
336 * @fw_mon_phys: physical address of the buffer for the firmware monitor 336 * @fw_mon_phys: physical address of the buffer for the firmware monitor
337 * @fw_mon_page: points to the first page of the buffer for the firmware monitor 337 * @fw_mon_page: points to the first page of the buffer for the firmware monitor
338 * @fw_mon_size: size of the buffer for the firmware monitor 338 * @fw_mon_size: size of the buffer for the firmware monitor
339 * @msix_entries: array of MSI-X entries
340 * @msix_enabled: true if managed to enable MSI-X
341 * @allocated_vector: the number of interrupt vector allocated by the OS
342 * @default_irq_num: default irq for non rx interrupt
343 * @fh_init_mask: initial unmasked fh causes
344 * @hw_init_mask: initial unmasked hw causes
345 * @fh_mask: current unmasked fh causes
346 * @hw_mask: current unmasked hw causes
339 */ 347 */
340struct iwl_trans_pcie { 348struct iwl_trans_pcie {
341 struct iwl_rxq *rxq; 349 struct iwl_rxq *rxq;
@@ -402,6 +410,15 @@ struct iwl_trans_pcie {
402 dma_addr_t fw_mon_phys; 410 dma_addr_t fw_mon_phys;
403 struct page *fw_mon_page; 411 struct page *fw_mon_page;
404 u32 fw_mon_size; 412 u32 fw_mon_size;
413
414 struct msix_entry msix_entries[IWL_MAX_RX_HW_QUEUES];
415 bool msix_enabled;
416 u32 allocated_vector;
417 u32 default_irq_num;
418 u32 fh_init_mask;
419 u32 hw_init_mask;
420 u32 fh_mask;
421 u32 hw_mask;
405}; 422};
406 423
407static inline struct iwl_trans_pcie * 424static inline struct iwl_trans_pcie *
@@ -430,7 +447,10 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
430* RX 447* RX
431******************************************************/ 448******************************************************/
432int iwl_pcie_rx_init(struct iwl_trans *trans); 449int iwl_pcie_rx_init(struct iwl_trans *trans);
450irqreturn_t iwl_pcie_msix_isr(int irq, void *data);
433irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id); 451irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id);
452irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id);
453irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id);
434int iwl_pcie_rx_stop(struct iwl_trans *trans); 454int iwl_pcie_rx_stop(struct iwl_trans *trans);
435void iwl_pcie_rx_free(struct iwl_trans *trans); 455void iwl_pcie_rx_free(struct iwl_trans *trans);
436 456
@@ -485,15 +505,24 @@ void iwl_pcie_dump_csr(struct iwl_trans *trans);
485******************************************************/ 505******************************************************/
486static inline void iwl_disable_interrupts(struct iwl_trans *trans) 506static inline void iwl_disable_interrupts(struct iwl_trans *trans)
487{ 507{
488 clear_bit(STATUS_INT_ENABLED, &trans->status); 508 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
489
490 /* disable interrupts from uCode/NIC to host */
491 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
492 509
493 /* acknowledge/clear/reset any interrupts still pending 510 clear_bit(STATUS_INT_ENABLED, &trans->status);
494 * from uCode or flow handler (Rx/Tx DMA) */ 511 if (!trans_pcie->msix_enabled) {
495 iwl_write32(trans, CSR_INT, 0xffffffff); 512 /* disable interrupts from uCode/NIC to host */
496 iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff); 513 iwl_write32(trans, CSR_INT_MASK, 0x00000000);
514
515 /* acknowledge/clear/reset any interrupts still pending
516 * from uCode or flow handler (Rx/Tx DMA) */
517 iwl_write32(trans, CSR_INT, 0xffffffff);
518 iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff);
519 } else {
520 /* disable all the interrupt we might use */
521 iwl_write32(trans, CSR_MSIX_FH_INT_MASK_AD,
522 trans_pcie->fh_init_mask);
523 iwl_write32(trans, CSR_MSIX_HW_INT_MASK_AD,
524 trans_pcie->hw_init_mask);
525 }
497 IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); 526 IWL_DEBUG_ISR(trans, "Disabled interrupts\n");
498} 527}
499 528
@@ -503,8 +532,37 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans)
503 532
504 IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); 533 IWL_DEBUG_ISR(trans, "Enabling interrupts\n");
505 set_bit(STATUS_INT_ENABLED, &trans->status); 534 set_bit(STATUS_INT_ENABLED, &trans->status);
506 trans_pcie->inta_mask = CSR_INI_SET_MASK; 535 if (!trans_pcie->msix_enabled) {
507 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); 536 trans_pcie->inta_mask = CSR_INI_SET_MASK;
537 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
538 } else {
539 /*
540 * fh/hw_mask keeps all the unmasked causes.
541 * Unlike msi, in msix cause is enabled when it is unset.
542 */
543 trans_pcie->hw_mask = trans_pcie->hw_init_mask;
544 trans_pcie->fh_mask = trans_pcie->fh_init_mask;
545 iwl_write32(trans, CSR_MSIX_FH_INT_MASK_AD,
546 ~trans_pcie->fh_mask);
547 iwl_write32(trans, CSR_MSIX_HW_INT_MASK_AD,
548 ~trans_pcie->hw_mask);
549 }
550}
551
552static inline void iwl_enable_hw_int_msk_msix(struct iwl_trans *trans, u32 msk)
553{
554 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
555
556 iwl_write32(trans, CSR_MSIX_HW_INT_MASK_AD, ~msk);
557 trans_pcie->hw_mask = msk;
558}
559
560static inline void iwl_enable_fh_int_msk_msix(struct iwl_trans *trans, u32 msk)
561{
562 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
563
564 iwl_write32(trans, CSR_MSIX_FH_INT_MASK_AD, ~msk);
565 trans_pcie->fh_mask = msk;
508} 566}
509 567
510static inline void iwl_enable_fw_load_int(struct iwl_trans *trans) 568static inline void iwl_enable_fw_load_int(struct iwl_trans *trans)
@@ -512,8 +570,15 @@ static inline void iwl_enable_fw_load_int(struct iwl_trans *trans)
512 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 570 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
513 571
514 IWL_DEBUG_ISR(trans, "Enabling FW load interrupt\n"); 572 IWL_DEBUG_ISR(trans, "Enabling FW load interrupt\n");
515 trans_pcie->inta_mask = CSR_INT_BIT_FH_TX; 573 if (!trans_pcie->msix_enabled) {
516 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); 574 trans_pcie->inta_mask = CSR_INT_BIT_FH_TX;
575 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
576 } else {
577 iwl_write32(trans, CSR_MSIX_HW_INT_MASK_AD,
578 trans_pcie->hw_init_mask);
579 iwl_enable_fh_int_msk_msix(trans,
580 MSIX_FH_INT_CAUSES_D2S_CH0_NUM);
581 }
517} 582}
518 583
519static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) 584static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
@@ -521,8 +586,15 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
521 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 586 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
522 587
523 IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); 588 IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n");
524 trans_pcie->inta_mask = CSR_INT_BIT_RF_KILL; 589 if (!trans_pcie->msix_enabled) {
525 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); 590 trans_pcie->inta_mask = CSR_INT_BIT_RF_KILL;
591 iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask);
592 } else {
593 iwl_write32(trans, CSR_MSIX_FH_INT_MASK_AD,
594 trans_pcie->fh_init_mask);
595 iwl_enable_hw_int_msk_msix(trans,
596 MSIX_HW_INT_CAUSES_REG_RF_KILL);
597 }
526} 598}
527 599
528static inline void iwl_wake_queue(struct iwl_trans *trans, 600static inline void iwl_wake_queue(struct iwl_trans *trans,
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
index 07973ef826c1..489b07a9e471 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c
@@ -783,16 +783,26 @@ static void iwl_pcie_rx_mq_hw_init(struct iwl_trans *trans)
783 * Single frame mode 783 * Single frame mode
784 * Rx buffer size 4 or 8k or 12k 784 * Rx buffer size 4 or 8k or 12k
785 * Min RB size 4 or 8 785 * Min RB size 4 or 8
786 * Drop frames that exceed RB size
786 * 512 RBDs 787 * 512 RBDs
787 */ 788 */
788 iwl_write_prph(trans, RFH_RXF_DMA_CFG, 789 iwl_write_prph(trans, RFH_RXF_DMA_CFG,
789 RFH_DMA_EN_ENABLE_VAL | 790 RFH_DMA_EN_ENABLE_VAL |
790 rb_size | RFH_RXF_DMA_SINGLE_FRAME_MASK | 791 rb_size | RFH_RXF_DMA_SINGLE_FRAME_MASK |
791 RFH_RXF_DMA_MIN_RB_4_8 | 792 RFH_RXF_DMA_MIN_RB_4_8 |
793 RFH_RXF_DMA_DROP_TOO_LARGE_MASK |
792 RFH_RXF_DMA_RBDCB_SIZE_512); 794 RFH_RXF_DMA_RBDCB_SIZE_512);
793 795
796 /*
797 * Activate DMA snooping.
798 * Set RX DMA chunk size to 128 bit
799 * Default queue is 0
800 */
794 iwl_write_prph(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP | 801 iwl_write_prph(trans, RFH_GEN_CFG, RFH_GEN_CFG_RFH_DMA_SNOOP |
795 RFH_GEN_CFG_SERVICE_DMA_SNOOP); 802 RFH_GEN_CFG_RB_CHUNK_SIZE |
803 (DEFAULT_RXQ_NUM << RFH_GEN_CFG_DEFAULT_RXQ_NUM_POS) |
804 RFH_GEN_CFG_SERVICE_DMA_SNOOP);
805 /* Enable the relevant rx queues */
796 iwl_write_prph(trans, RFH_RXF_RXQ_ACTIVE, enabled); 806 iwl_write_prph(trans, RFH_RXF_RXQ_ACTIVE, enabled);
797 807
798 /* Set interrupt coalescing timer to default (2048 usecs) */ 808 /* Set interrupt coalescing timer to default (2048 usecs) */
@@ -1135,10 +1145,10 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
1135/* 1145/*
1136 * iwl_pcie_rx_handle - Main entry function for receiving responses from fw 1146 * iwl_pcie_rx_handle - Main entry function for receiving responses from fw
1137 */ 1147 */
1138static void iwl_pcie_rx_handle(struct iwl_trans *trans) 1148static void iwl_pcie_rx_handle(struct iwl_trans *trans, int queue)
1139{ 1149{
1140 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1150 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1141 struct iwl_rxq *rxq = &trans_pcie->rxq[0]; 1151 struct iwl_rxq *rxq = &trans_pcie->rxq[queue];
1142 u32 r, i, j, count = 0; 1152 u32 r, i, j, count = 0;
1143 bool emergency = false; 1153 bool emergency = false;
1144 1154
@@ -1149,9 +1159,12 @@ restart:
1149 r = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num)) & 0x0FFF; 1159 r = le16_to_cpu(ACCESS_ONCE(rxq->rb_stts->closed_rb_num)) & 0x0FFF;
1150 i = rxq->read; 1160 i = rxq->read;
1151 1161
1162 /* W/A 9000 device step A0 wrap-around bug */
1163 r &= (rxq->queue_size - 1);
1164
1152 /* Rx interrupt, but nothing sent from uCode */ 1165 /* Rx interrupt, but nothing sent from uCode */
1153 if (i == r) 1166 if (i == r)
1154 IWL_DEBUG_RX(trans, "HW = SW = %d\n", r); 1167 IWL_DEBUG_RX(trans, "Q %d: HW = SW = %d\n", rxq->id, r);
1155 1168
1156 while (i != r) { 1169 while (i != r) {
1157 struct iwl_rx_mem_buffer *rxb; 1170 struct iwl_rx_mem_buffer *rxb;
@@ -1164,15 +1177,18 @@ restart:
1164 * used_bd is a 32 bit but only 12 are used to retrieve 1177 * used_bd is a 32 bit but only 12 are used to retrieve
1165 * the vid 1178 * the vid
1166 */ 1179 */
1167 u16 vid = (u16)le32_to_cpu(rxq->used_bd[i]); 1180 u16 vid = le32_to_cpu(rxq->used_bd[i]) & 0x0FFF;
1168 1181
1182 if (WARN(vid >= ARRAY_SIZE(trans_pcie->global_table),
1183 "Invalid rxb index from HW %u\n", (u32)vid))
1184 goto out;
1169 rxb = trans_pcie->global_table[vid]; 1185 rxb = trans_pcie->global_table[vid];
1170 } else { 1186 } else {
1171 rxb = rxq->queue[i]; 1187 rxb = rxq->queue[i];
1172 rxq->queue[i] = NULL; 1188 rxq->queue[i] = NULL;
1173 } 1189 }
1174 1190
1175 IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d\n", r, i); 1191 IWL_DEBUG_RX(trans, "Q %d: HW = %d, SW = %d\n", rxq->id, r, i);
1176 iwl_pcie_rx_handle_rb(trans, rxq, rxb, emergency); 1192 iwl_pcie_rx_handle_rb(trans, rxq, rxb, emergency);
1177 1193
1178 i = (i + 1) & (rxq->queue_size - 1); 1194 i = (i + 1) & (rxq->queue_size - 1);
@@ -1235,7 +1251,7 @@ restart:
1235 goto restart; 1251 goto restart;
1236 } 1252 }
1237 } 1253 }
1238 1254out:
1239 /* Backtrack one entry */ 1255 /* Backtrack one entry */
1240 rxq->read = i; 1256 rxq->read = i;
1241 spin_unlock(&rxq->lock); 1257 spin_unlock(&rxq->lock);
@@ -1259,6 +1275,54 @@ restart:
1259 napi_gro_flush(&rxq->napi, false); 1275 napi_gro_flush(&rxq->napi, false);
1260} 1276}
1261 1277
1278static struct iwl_trans_pcie *iwl_pcie_get_trans_pcie(struct msix_entry *entry)
1279{
1280 u8 queue = entry->entry;
1281 struct msix_entry *entries = entry - queue;
1282
1283 return container_of(entries, struct iwl_trans_pcie, msix_entries[0]);
1284}
1285
1286static inline void iwl_pcie_clear_irq(struct iwl_trans *trans,
1287 struct msix_entry *entry)
1288{
1289 /*
1290 * Before sending the interrupt the HW disables it to prevent
1291 * a nested interrupt. This is done by writing 1 to the corresponding
1292 * bit in the mask register. After handling the interrupt, it should be
1293 * re-enabled by clearing this bit. This register is defined as
1294 * write 1 clear (W1C) register, meaning that it's being clear
1295 * by writing 1 to the bit.
1296 */
1297 iwl_write_direct32(trans, CSR_MSIX_AUTOMASK_ST_AD, BIT(entry->entry));
1298}
1299
1300/*
1301 * iwl_pcie_rx_msix_handle - Main entry function for receiving responses from fw
1302 * This interrupt handler should be used with RSS queue only.
1303 */
1304irqreturn_t iwl_pcie_irq_rx_msix_handler(int irq, void *dev_id)
1305{
1306 struct msix_entry *entry = dev_id;
1307 struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
1308 struct iwl_trans *trans = trans_pcie->trans;
1309
1310 if (WARN_ON(entry->entry >= trans->num_rx_queues))
1311 return IRQ_NONE;
1312
1313 lock_map_acquire(&trans->sync_cmd_lockdep_map);
1314
1315 local_bh_disable();
1316 iwl_pcie_rx_handle(trans, entry->entry);
1317 local_bh_enable();
1318
1319 iwl_pcie_clear_irq(trans, entry);
1320
1321 lock_map_release(&trans->sync_cmd_lockdep_map);
1322
1323 return IRQ_HANDLED;
1324}
1325
1262/* 1326/*
1263 * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card 1327 * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card
1264 */ 1328 */
@@ -1589,7 +1653,7 @@ irqreturn_t iwl_pcie_irq_handler(int irq, void *dev_id)
1589 isr_stats->rx++; 1653 isr_stats->rx++;
1590 1654
1591 local_bh_disable(); 1655 local_bh_disable();
1592 iwl_pcie_rx_handle(trans); 1656 iwl_pcie_rx_handle(trans, 0);
1593 local_bh_enable(); 1657 local_bh_enable();
1594 } 1658 }
1595 1659
@@ -1732,3 +1796,129 @@ irqreturn_t iwl_pcie_isr(int irq, void *data)
1732 1796
1733 return IRQ_WAKE_THREAD; 1797 return IRQ_WAKE_THREAD;
1734} 1798}
1799
1800irqreturn_t iwl_pcie_msix_isr(int irq, void *data)
1801{
1802 return IRQ_WAKE_THREAD;
1803}
1804
1805irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id)
1806{
1807 struct msix_entry *entry = dev_id;
1808 struct iwl_trans_pcie *trans_pcie = iwl_pcie_get_trans_pcie(entry);
1809 struct iwl_trans *trans = trans_pcie->trans;
1810 struct isr_statistics *isr_stats = isr_stats = &trans_pcie->isr_stats;
1811 u32 inta_fh, inta_hw;
1812
1813 lock_map_acquire(&trans->sync_cmd_lockdep_map);
1814
1815 spin_lock(&trans_pcie->irq_lock);
1816 inta_fh = iwl_read_direct32(trans, CSR_MSIX_FH_INT_CAUSES_AD);
1817 inta_hw = iwl_read_direct32(trans, CSR_MSIX_HW_INT_CAUSES_AD);
1818 /*
1819 * Clear causes registers to avoid being handling the same cause.
1820 */
1821 iwl_write_direct32(trans, CSR_MSIX_FH_INT_CAUSES_AD, inta_fh);
1822 iwl_write_direct32(trans, CSR_MSIX_HW_INT_CAUSES_AD, inta_hw);
1823 spin_unlock(&trans_pcie->irq_lock);
1824
1825 if (unlikely(!(inta_fh | inta_hw))) {
1826 IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n");
1827 lock_map_release(&trans->sync_cmd_lockdep_map);
1828 return IRQ_NONE;
1829 }
1830
1831 if (iwl_have_debug_level(IWL_DL_ISR))
1832 IWL_DEBUG_ISR(trans, "ISR inta_fh 0x%08x, enabled 0x%08x\n",
1833 inta_fh,
1834 iwl_read32(trans, CSR_MSIX_FH_INT_MASK_AD));
1835
1836 /* This "Tx" DMA channel is used only for loading uCode */
1837 if (inta_fh & MSIX_FH_INT_CAUSES_D2S_CH0_NUM) {
1838 IWL_DEBUG_ISR(trans, "uCode load interrupt\n");
1839 isr_stats->tx++;
1840 /*
1841 * Wake up uCode load routine,
1842 * now that load is complete
1843 */
1844 trans_pcie->ucode_write_complete = true;
1845 wake_up(&trans_pcie->ucode_write_waitq);
1846 }
1847
1848 /* Error detected by uCode */
1849 if ((inta_fh & MSIX_FH_INT_CAUSES_FH_ERR) ||
1850 (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR)) {
1851 IWL_ERR(trans,
1852 "Microcode SW error detected. Restarting 0x%X.\n",
1853 inta_fh);
1854 isr_stats->sw++;
1855 iwl_pcie_irq_handle_error(trans);
1856 }
1857
1858 /* After checking FH register check HW register */
1859 if (iwl_have_debug_level(IWL_DL_ISR))
1860 IWL_DEBUG_ISR(trans,
1861 "ISR inta_hw 0x%08x, enabled 0x%08x\n",
1862 inta_hw,
1863 iwl_read32(trans, CSR_MSIX_HW_INT_MASK_AD));
1864
1865 /* Alive notification via Rx interrupt will do the real work */
1866 if (inta_hw & MSIX_HW_INT_CAUSES_REG_ALIVE) {
1867 IWL_DEBUG_ISR(trans, "Alive interrupt\n");
1868 isr_stats->alive++;
1869 }
1870
1871 /* uCode wakes up after power-down sleep */
1872 if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) {
1873 IWL_DEBUG_ISR(trans, "Wakeup interrupt\n");
1874 iwl_pcie_rxq_check_wrptr(trans);
1875 iwl_pcie_txq_check_wrptrs(trans);
1876
1877 isr_stats->wakeup++;
1878 }
1879
1880 /* Chip got too hot and stopped itself */
1881 if (inta_hw & MSIX_HW_INT_CAUSES_REG_CT_KILL) {
1882 IWL_ERR(trans, "Microcode CT kill error detected.\n");
1883 isr_stats->ctkill++;
1884 }
1885
1886 /* HW RF KILL switch toggled */
1887 if (inta_hw & MSIX_HW_INT_CAUSES_REG_RF_KILL) {
1888 bool hw_rfkill;
1889
1890 hw_rfkill = iwl_is_rfkill_set(trans);
1891 IWL_WARN(trans, "RF_KILL bit toggled to %s.\n",
1892 hw_rfkill ? "disable radio" : "enable radio");
1893
1894 isr_stats->rfkill++;
1895
1896 mutex_lock(&trans_pcie->mutex);
1897 iwl_trans_pcie_rf_kill(trans, hw_rfkill);
1898 mutex_unlock(&trans_pcie->mutex);
1899 if (hw_rfkill) {
1900 set_bit(STATUS_RFKILL, &trans->status);
1901 if (test_and_clear_bit(STATUS_SYNC_HCMD_ACTIVE,
1902 &trans->status))
1903 IWL_DEBUG_RF_KILL(trans,
1904 "Rfkill while SYNC HCMD in flight\n");
1905 wake_up(&trans_pcie->wait_command_queue);
1906 } else {
1907 clear_bit(STATUS_RFKILL, &trans->status);
1908 }
1909 }
1910
1911 if (inta_hw & MSIX_HW_INT_CAUSES_REG_HW_ERR) {
1912 IWL_ERR(trans,
1913 "Hardware error detected. Restarting.\n");
1914
1915 isr_stats->hw++;
1916 iwl_pcie_irq_handle_error(trans);
1917 }
1918
1919 iwl_pcie_clear_irq(trans, entry);
1920
1921 lock_map_release(&trans->sync_cmd_lockdep_map);
1922
1923 return IRQ_HANDLED;
1924}
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 58591ca051fd..e67957d6ac79 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -616,38 +616,38 @@ static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr,
616 dma_addr_t phy_addr, u32 byte_cnt) 616 dma_addr_t phy_addr, u32 byte_cnt)
617{ 617{
618 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 618 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
619 unsigned long flags;
619 int ret; 620 int ret;
620 621
621 trans_pcie->ucode_write_complete = false; 622 trans_pcie->ucode_write_complete = false;
622 623
623 iwl_write_direct32(trans, 624 if (!iwl_trans_grab_nic_access(trans, &flags))
624 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 625 return -EIO;
625 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); 626
627 iwl_write32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
628 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
626 629
627 iwl_write_direct32(trans, 630 iwl_write32(trans, FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL),
628 FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), 631 dst_addr);
629 dst_addr);
630 632
631 iwl_write_direct32(trans, 633 iwl_write32(trans, FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
632 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), 634 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
633 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
634 635
635 iwl_write_direct32(trans, 636 iwl_write32(trans, FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
636 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), 637 (iwl_get_dma_hi_addr(phy_addr)
637 (iwl_get_dma_hi_addr(phy_addr) 638 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
638 << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
639 639
640 iwl_write_direct32(trans, 640 iwl_write32(trans, FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
641 FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), 641 BIT(FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM) |
642 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | 642 BIT(FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX) |
643 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | 643 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
644 FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID);
645 644
646 iwl_write_direct32(trans, 645 iwl_write32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
647 FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), 646 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
648 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | 647 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
649 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 648 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
650 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 649
650 iwl_trans_release_nic_access(trans, &flags);
651 651
652 ret = wait_event_timeout(trans_pcie->ucode_write_waitq, 652 ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
653 trans_pcie->ucode_write_complete, 5 * HZ); 653 trans_pcie->ucode_write_complete, 5 * HZ);
@@ -1123,6 +1123,20 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power)
1123 iwl_pcie_prepare_card_hw(trans); 1123 iwl_pcie_prepare_card_hw(trans);
1124} 1124}
1125 1125
1126static void iwl_pcie_synchronize_irqs(struct iwl_trans *trans)
1127{
1128 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1129
1130 if (trans_pcie->msix_enabled) {
1131 int i;
1132
1133 for (i = 0; i < trans_pcie->allocated_vector; i++)
1134 synchronize_irq(trans_pcie->msix_entries[i].vector);
1135 } else {
1136 synchronize_irq(trans_pcie->pci_dev->irq);
1137 }
1138}
1139
1126static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 1140static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1127 const struct fw_img *fw, bool run_in_rfkill) 1141 const struct fw_img *fw, bool run_in_rfkill)
1128{ 1142{
@@ -1149,7 +1163,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
1149 iwl_disable_interrupts(trans); 1163 iwl_disable_interrupts(trans);
1150 1164
1151 /* Make sure it finished running */ 1165 /* Make sure it finished running */
1152 synchronize_irq(trans_pcie->pci_dev->irq); 1166 iwl_pcie_synchronize_irqs(trans);
1153 1167
1154 mutex_lock(&trans_pcie->mutex); 1168 mutex_lock(&trans_pcie->mutex);
1155 1169
@@ -1252,8 +1266,6 @@ void iwl_trans_pcie_rf_kill(struct iwl_trans *trans, bool state)
1252static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test, 1266static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
1253 bool reset) 1267 bool reset)
1254{ 1268{
1255 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1256
1257 if (!reset) { 1269 if (!reset) {
1258 /* Enable persistence mode to avoid reset */ 1270 /* Enable persistence mode to avoid reset */
1259 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, 1271 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
@@ -1271,7 +1283,7 @@ static void iwl_trans_pcie_d3_suspend(struct iwl_trans *trans, bool test,
1271 1283
1272 iwl_pcie_disable_ict(trans); 1284 iwl_pcie_disable_ict(trans);
1273 1285
1274 synchronize_irq(trans_pcie->pci_dev->irq); 1286 iwl_pcie_synchronize_irqs(trans);
1275 1287
1276 iwl_clear_bit(trans, CSR_GP_CNTRL, 1288 iwl_clear_bit(trans, CSR_GP_CNTRL,
1277 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1289 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -1350,6 +1362,153 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans,
1350 return 0; 1362 return 0;
1351} 1363}
1352 1364
1365struct iwl_causes_list {
1366 u32 cause_num;
1367 u32 mask_reg;
1368 u8 addr;
1369};
1370
1371static struct iwl_causes_list causes_list[] = {
1372 {MSIX_FH_INT_CAUSES_D2S_CH0_NUM, CSR_MSIX_FH_INT_MASK_AD, 0},
1373 {MSIX_FH_INT_CAUSES_D2S_CH1_NUM, CSR_MSIX_FH_INT_MASK_AD, 0x1},
1374 {MSIX_FH_INT_CAUSES_S2D, CSR_MSIX_FH_INT_MASK_AD, 0x3},
1375 {MSIX_FH_INT_CAUSES_FH_ERR, CSR_MSIX_FH_INT_MASK_AD, 0x5},
1376 {MSIX_HW_INT_CAUSES_REG_ALIVE, CSR_MSIX_HW_INT_MASK_AD, 0x10},
1377 {MSIX_HW_INT_CAUSES_REG_WAKEUP, CSR_MSIX_HW_INT_MASK_AD, 0x11},
1378 {MSIX_HW_INT_CAUSES_REG_CT_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x16},
1379 {MSIX_HW_INT_CAUSES_REG_RF_KILL, CSR_MSIX_HW_INT_MASK_AD, 0x17},
1380 {MSIX_HW_INT_CAUSES_REG_PERIODIC, CSR_MSIX_HW_INT_MASK_AD, 0x18},
1381 {MSIX_HW_INT_CAUSES_REG_SW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x29},
1382 {MSIX_HW_INT_CAUSES_REG_SCD, CSR_MSIX_HW_INT_MASK_AD, 0x2A},
1383 {MSIX_HW_INT_CAUSES_REG_FH_TX, CSR_MSIX_HW_INT_MASK_AD, 0x2B},
1384 {MSIX_HW_INT_CAUSES_REG_HW_ERR, CSR_MSIX_HW_INT_MASK_AD, 0x2D},
1385 {MSIX_HW_INT_CAUSES_REG_HAP, CSR_MSIX_HW_INT_MASK_AD, 0x2E},
1386};
1387
1388static void iwl_pcie_init_msix(struct iwl_trans_pcie *trans_pcie)
1389{
1390 u32 val, max_rx_vector, i;
1391 struct iwl_trans *trans = trans_pcie->trans;
1392
1393 max_rx_vector = trans_pcie->allocated_vector - 1;
1394
1395 if (!trans_pcie->msix_enabled)
1396 return;
1397
1398 iwl_write_prph(trans, UREG_CHICK, UREG_CHICK_MSIX_ENABLE);
1399
1400 /*
1401 * Each cause from the list above and the RX causes is represented as
1402 * a byte in the IVAR table. We access the first (N - 1) bytes and map
1403 * them to the (N - 1) vectors so these vectors will be used as rx
1404 * vectors. Then access all non rx causes and map them to the
1405 * default queue (N'th queue).
1406 */
1407 for (i = 0; i < max_rx_vector; i++) {
1408 iwl_write8(trans, CSR_MSIX_RX_IVAR(i), MSIX_FH_INT_CAUSES_Q(i));
1409 iwl_clear_bit(trans, CSR_MSIX_FH_INT_MASK_AD,
1410 BIT(MSIX_FH_INT_CAUSES_Q(i)));
1411 }
1412
1413 for (i = 0; i < ARRAY_SIZE(causes_list); i++) {
1414 val = trans_pcie->default_irq_num |
1415 MSIX_NON_AUTO_CLEAR_CAUSE;
1416 iwl_write8(trans, CSR_MSIX_IVAR(causes_list[i].addr), val);
1417 iwl_clear_bit(trans, causes_list[i].mask_reg,
1418 causes_list[i].cause_num);
1419 }
1420 trans_pcie->fh_init_mask =
1421 ~iwl_read32(trans, CSR_MSIX_FH_INT_MASK_AD);
1422 trans_pcie->fh_mask = trans_pcie->fh_init_mask;
1423 trans_pcie->hw_init_mask =
1424 ~iwl_read32(trans, CSR_MSIX_HW_INT_MASK_AD);
1425 trans_pcie->hw_mask = trans_pcie->hw_init_mask;
1426}
1427
1428static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
1429 struct iwl_trans *trans)
1430{
1431 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1432 u16 pci_cmd;
1433 int max_vector;
1434 int ret, i;
1435
1436 if (trans->cfg->mq_rx_supported) {
1437 max_vector = min_t(u32, (num_possible_cpus() + 1),
1438 IWL_MAX_RX_HW_QUEUES);
1439 for (i = 0; i < max_vector; i++)
1440 trans_pcie->msix_entries[i].entry = i;
1441
1442 ret = pci_enable_msix_range(pdev, trans_pcie->msix_entries,
1443 MSIX_MIN_INTERRUPT_VECTORS,
1444 max_vector);
1445 if (ret > 1) {
1446 IWL_DEBUG_INFO(trans,
1447 "Enable MSI-X allocate %d interrupt vector\n",
1448 ret);
1449 trans_pcie->allocated_vector = ret;
1450 trans_pcie->default_irq_num =
1451 trans_pcie->allocated_vector - 1;
1452 trans_pcie->trans->num_rx_queues =
1453 trans_pcie->allocated_vector - 1;
1454 trans_pcie->msix_enabled = true;
1455
1456 return;
1457 }
1458 IWL_DEBUG_INFO(trans,
1459 "ret = %d %s move to msi mode\n", ret,
1460 (ret == 1) ?
1461 "can't allocate more than 1 interrupt vector" :
1462 "failed to enable msi-x mode");
1463 pci_disable_msix(pdev);
1464 }
1465
1466 ret = pci_enable_msi(pdev);
1467 if (ret) {
1468 dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", ret);
1469 /* enable rfkill interrupt: hw bug w/a */
1470 pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
1471 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
1472 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
1473 pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
1474 }
1475 }
1476}
1477
1478static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
1479 struct iwl_trans_pcie *trans_pcie)
1480{
1481 int i, last_vector;
1482
1483 last_vector = trans_pcie->trans->num_rx_queues;
1484
1485 for (i = 0; i < trans_pcie->allocated_vector; i++) {
1486 int ret;
1487
1488 ret = request_threaded_irq(trans_pcie->msix_entries[i].vector,
1489 iwl_pcie_msix_isr,
1490 (i == last_vector) ?
1491 iwl_pcie_irq_msix_handler :
1492 iwl_pcie_irq_rx_msix_handler,
1493 IRQF_SHARED,
1494 DRV_NAME,
1495 &trans_pcie->msix_entries[i]);
1496 if (ret) {
1497 int j;
1498
1499 IWL_ERR(trans_pcie->trans,
1500 "Error allocating IRQ %d\n", i);
1501 for (j = 0; j < i; j++)
1502 free_irq(trans_pcie->msix_entries[i].vector,
1503 &trans_pcie->msix_entries[i]);
1504 pci_disable_msix(pdev);
1505 return ret;
1506 }
1507 }
1508
1509 return 0;
1510}
1511
1353static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) 1512static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
1354{ 1513{
1355 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1514 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -1371,6 +1530,7 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
1371 1530
1372 iwl_pcie_apm_init(trans); 1531 iwl_pcie_apm_init(trans);
1373 1532
1533 iwl_pcie_init_msix(trans_pcie);
1374 /* From now on, the op_mode will be kept updated about RF kill state */ 1534 /* From now on, the op_mode will be kept updated about RF kill state */
1375 iwl_enable_rfkill_int(trans); 1535 iwl_enable_rfkill_int(trans);
1376 1536
@@ -1425,7 +1585,7 @@ static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans)
1425 1585
1426 mutex_unlock(&trans_pcie->mutex); 1586 mutex_unlock(&trans_pcie->mutex);
1427 1587
1428 synchronize_irq(trans_pcie->pci_dev->irq); 1588 iwl_pcie_synchronize_irqs(trans);
1429} 1589}
1430 1590
1431static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) 1591static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val)
@@ -1506,15 +1666,25 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
1506 /* TODO: check if this is really needed */ 1666 /* TODO: check if this is really needed */
1507 pm_runtime_disable(trans->dev); 1667 pm_runtime_disable(trans->dev);
1508 1668
1509 synchronize_irq(trans_pcie->pci_dev->irq); 1669 iwl_pcie_synchronize_irqs(trans);
1510 1670
1511 iwl_pcie_tx_free(trans); 1671 iwl_pcie_tx_free(trans);
1512 iwl_pcie_rx_free(trans); 1672 iwl_pcie_rx_free(trans);
1513 1673
1514 free_irq(trans_pcie->pci_dev->irq, trans); 1674 if (trans_pcie->msix_enabled) {
1515 iwl_pcie_free_ict(trans); 1675 for (i = 0; i < trans_pcie->allocated_vector; i++)
1676 free_irq(trans_pcie->msix_entries[i].vector,
1677 &trans_pcie->msix_entries[i]);
1678
1679 pci_disable_msix(trans_pcie->pci_dev);
1680 trans_pcie->msix_enabled = false;
1681 } else {
1682 free_irq(trans_pcie->pci_dev->irq, trans);
1516 1683
1517 pci_disable_msi(trans_pcie->pci_dev); 1684 iwl_pcie_free_ict(trans);
1685
1686 pci_disable_msi(trans_pcie->pci_dev);
1687 }
1518 iounmap(trans_pcie->hw_base); 1688 iounmap(trans_pcie->hw_base);
1519 pci_release_regions(trans_pcie->pci_dev); 1689 pci_release_regions(trans_pcie->pci_dev);
1520 pci_disable_device(trans_pcie->pci_dev); 1690 pci_disable_device(trans_pcie->pci_dev);
@@ -2069,7 +2239,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
2069 } else { 2239 } else {
2070 pos += scnprintf(buf + pos, bufsz - pos, 2240 pos += scnprintf(buf + pos, bufsz - pos,
2071 "\tclosed_rb_num: Not Allocated\n"); 2241 "\tclosed_rb_num: Not Allocated\n");
2072 } 2242 }
2073 } 2243 }
2074 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2244 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
2075 kfree(buf); 2245 kfree(buf);
@@ -2615,7 +2785,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2615{ 2785{
2616 struct iwl_trans_pcie *trans_pcie; 2786 struct iwl_trans_pcie *trans_pcie;
2617 struct iwl_trans *trans; 2787 struct iwl_trans *trans;
2618 u16 pci_cmd;
2619 int ret, addr_size; 2788 int ret, addr_size;
2620 2789
2621 trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), 2790 trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie),
@@ -2698,17 +2867,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2698 trans_pcie->pci_dev = pdev; 2867 trans_pcie->pci_dev = pdev;
2699 iwl_disable_interrupts(trans); 2868 iwl_disable_interrupts(trans);
2700 2869
2701 ret = pci_enable_msi(pdev);
2702 if (ret) {
2703 dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", ret);
2704 /* enable rfkill interrupt: hw bug w/a */
2705 pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
2706 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
2707 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
2708 pci_write_config_word(pdev, PCI_COMMAND, pci_cmd);
2709 }
2710 }
2711
2712 trans->hw_rev = iwl_read32(trans, CSR_HW_REV); 2870 trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
2713 /* 2871 /*
2714 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have 2872 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
@@ -2760,6 +2918,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2760 } 2918 }
2761 } 2919 }
2762 2920
2921 iwl_pcie_set_interrupt_capa(pdev, trans);
2763 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; 2922 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
2764 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 2923 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
2765 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); 2924 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
@@ -2769,19 +2928,23 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2769 2928
2770 init_waitqueue_head(&trans_pcie->d0i3_waitq); 2929 init_waitqueue_head(&trans_pcie->d0i3_waitq);
2771 2930
2772 ret = iwl_pcie_alloc_ict(trans); 2931 if (trans_pcie->msix_enabled) {
2773 if (ret) 2932 if (iwl_pcie_init_msix_handler(pdev, trans_pcie))
2774 goto out_pci_disable_msi; 2933 goto out_pci_release_regions;
2775 2934 } else {
2776 ret = request_threaded_irq(pdev->irq, iwl_pcie_isr, 2935 ret = iwl_pcie_alloc_ict(trans);
2777 iwl_pcie_irq_handler, 2936 if (ret)
2778 IRQF_SHARED, DRV_NAME, trans); 2937 goto out_pci_disable_msi;
2779 if (ret) {
2780 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
2781 goto out_free_ict;
2782 }
2783 2938
2784 trans_pcie->inta_mask = CSR_INI_SET_MASK; 2939 ret = request_threaded_irq(pdev->irq, iwl_pcie_isr,
2940 iwl_pcie_irq_handler,
2941 IRQF_SHARED, DRV_NAME, trans);
2942 if (ret) {
2943 IWL_ERR(trans, "Error allocating IRQ %d\n", pdev->irq);
2944 goto out_free_ict;
2945 }
2946 trans_pcie->inta_mask = CSR_INI_SET_MASK;
2947 }
2785 2948
2786#ifdef CONFIG_IWLWIFI_PCIE_RTPM 2949#ifdef CONFIG_IWLWIFI_PCIE_RTPM
2787 trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3; 2950 trans->runtime_pm_mode = IWL_PLAT_PM_MODE_D0I3;
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
index 837a7d536874..16ad820ca824 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
@@ -1062,10 +1062,10 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1062 1062
1063 if (iwl_queue_space(&txq->q) > txq->q.low_mark && 1063 if (iwl_queue_space(&txq->q) > txq->q.low_mark &&
1064 test_bit(txq_id, trans_pcie->queue_stopped)) { 1064 test_bit(txq_id, trans_pcie->queue_stopped)) {
1065 struct sk_buff_head skbs; 1065 struct sk_buff_head overflow_skbs;
1066 1066
1067 __skb_queue_head_init(&skbs); 1067 __skb_queue_head_init(&overflow_skbs);
1068 skb_queue_splice_init(&txq->overflow_q, &skbs); 1068 skb_queue_splice_init(&txq->overflow_q, &overflow_skbs);
1069 1069
1070 /* 1070 /*
1071 * This is tricky: we are in reclaim path which is non 1071 * This is tricky: we are in reclaim path which is non
@@ -1076,8 +1076,8 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
1076 */ 1076 */
1077 spin_unlock_bh(&txq->lock); 1077 spin_unlock_bh(&txq->lock);
1078 1078
1079 while (!skb_queue_empty(&skbs)) { 1079 while (!skb_queue_empty(&overflow_skbs)) {
1080 struct sk_buff *skb = __skb_dequeue(&skbs); 1080 struct sk_buff *skb = __skb_dequeue(&overflow_skbs);
1081 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1081 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1082 u8 dev_cmd_idx = IWL_TRANS_FIRST_DRIVER_DATA + 1; 1082 u8 dev_cmd_idx = IWL_TRANS_FIRST_DRIVER_DATA + 1;
1083 struct iwl_device_cmd *dev_cmd = 1083 struct iwl_device_cmd *dev_cmd =
diff --git a/drivers/net/wireless/marvell/mwifiex/11h.c b/drivers/net/wireless/marvell/mwifiex/11h.c
index 71a1b580796f..81c60d0a1bda 100644
--- a/drivers/net/wireless/marvell/mwifiex/11h.c
+++ b/drivers/net/wireless/marvell/mwifiex/11h.c
@@ -123,8 +123,7 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
123void mwifiex_dfs_cac_work_queue(struct work_struct *work) 123void mwifiex_dfs_cac_work_queue(struct work_struct *work)
124{ 124{
125 struct cfg80211_chan_def chandef; 125 struct cfg80211_chan_def chandef;
126 struct delayed_work *delayed_work = 126 struct delayed_work *delayed_work = to_delayed_work(work);
127 container_of(work, struct delayed_work, work);
128 struct mwifiex_private *priv = 127 struct mwifiex_private *priv =
129 container_of(delayed_work, struct mwifiex_private, 128 container_of(delayed_work, struct mwifiex_private,
130 dfs_cac_work); 129 dfs_cac_work);
@@ -289,8 +288,7 @@ int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
289void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work) 288void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
290{ 289{
291 struct mwifiex_uap_bss_param *bss_cfg; 290 struct mwifiex_uap_bss_param *bss_cfg;
292 struct delayed_work *delayed_work = 291 struct delayed_work *delayed_work = to_delayed_work(work);
293 container_of(work, struct delayed_work, work);
294 struct mwifiex_private *priv = 292 struct mwifiex_private *priv =
295 container_of(delayed_work, struct mwifiex_private, 293 container_of(delayed_work, struct mwifiex_private,
296 dfs_chan_sw_work); 294 dfs_chan_sw_work);
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index f2dce81ba36e..29b7f6eed240 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -676,7 +676,7 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
676 } 676 }
677 break; 677 break;
678 678
679 case MWIFIEX_BSS_ROLE_STA: 679 case MWIFIEX_BSS_ROLE_STA:
680 if (priv->media_connected) { 680 if (priv->media_connected) {
681 mwifiex_dbg(adapter, ERROR, 681 mwifiex_dbg(adapter, ERROR,
682 "cannot change wiphy params when connected"); 682 "cannot change wiphy params when connected");
diff --git a/drivers/net/wireless/marvell/mwifiex/ioctl.h b/drivers/net/wireless/marvell/mwifiex/ioctl.h
index 14cfa37deb00..a5a48c183d37 100644
--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h
+++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h
@@ -184,6 +184,7 @@ struct mwifiex_ds_tx_ba_stream_tbl {
184}; 184};
185 185
186#define DBG_CMD_NUM 5 186#define DBG_CMD_NUM 5
187#define MWIFIEX_DBG_SDIO_MP_NUM 10
187 188
188struct tdls_peer_info { 189struct tdls_peer_info {
189 u8 peer_addr[ETH_ALEN]; 190 u8 peer_addr[ETH_ALEN];
@@ -235,6 +236,11 @@ struct mwifiex_debug_info {
235 u8 cmd_sent; 236 u8 cmd_sent;
236 u8 cmd_resp_received; 237 u8 cmd_resp_received;
237 u8 event_received; 238 u8 event_received;
239 u32 last_mp_wr_bitmap[MWIFIEX_DBG_SDIO_MP_NUM];
240 u32 last_mp_wr_ports[MWIFIEX_DBG_SDIO_MP_NUM];
241 u32 last_mp_wr_len[MWIFIEX_DBG_SDIO_MP_NUM];
242 u32 last_mp_curr_wr_port[MWIFIEX_DBG_SDIO_MP_NUM];
243 u8 last_sdio_mp_index;
238}; 244};
239 245
240#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000 246#define MWIFIEX_KEY_INDEX_UNICAST 0x40000000
diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index aea7aee46cf7..aafc4ab4e5ae 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -223,6 +223,11 @@ struct mwifiex_dbg {
223 u16 last_cmd_resp_index; 223 u16 last_cmd_resp_index;
224 u16 last_event[DBG_CMD_NUM]; 224 u16 last_event[DBG_CMD_NUM];
225 u16 last_event_index; 225 u16 last_event_index;
226 u32 last_mp_wr_bitmap[MWIFIEX_DBG_SDIO_MP_NUM];
227 u32 last_mp_wr_ports[MWIFIEX_DBG_SDIO_MP_NUM];
228 u32 last_mp_wr_len[MWIFIEX_DBG_SDIO_MP_NUM];
229 u32 last_mp_curr_wr_port[MWIFIEX_DBG_SDIO_MP_NUM];
230 u8 last_sdio_mp_index;
226}; 231};
227 232
228enum MWIFIEX_HARDWARE_STATUS { 233enum MWIFIEX_HARDWARE_STATUS {
diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index cc072142411a..de364381fe7b 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -1401,7 +1401,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb)
1401 return -1; 1401 return -1;
1402 } 1402 }
1403 1403
1404 if (mwifiex_map_pci_memory(adapter, skb, skb->len , PCI_DMA_TODEVICE)) 1404 if (mwifiex_map_pci_memory(adapter, skb, skb->len, PCI_DMA_TODEVICE))
1405 return -1; 1405 return -1;
1406 1406
1407 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); 1407 buf_pa = MWIFIEX_SKB_DMA_ADDR(skb);
@@ -2452,7 +2452,7 @@ static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2452 for (i = 0; i < 4; i++) { 2452 for (i = 0; i < 4; i++) {
2453 mwifiex_read_reg_byte(adapter, reg, &read_reg); 2453 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2454 memory_size |= (read_reg << (i * 8)); 2454 memory_size |= (read_reg << (i * 8));
2455 reg++; 2455 reg++;
2456 } 2456 }
2457 } else { 2457 } else {
2458 memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE; 2458 memory_size = MWIFIEX_FW_DUMP_MAX_MEMSIZE;
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c
index abf15dbdfe08..b2c839ae2c3c 100644
--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
+++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
@@ -1355,6 +1355,9 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1355 card->mpa_rx.start_port; 1355 card->mpa_rx.start_port;
1356 } 1356 }
1357 1357
1358 if (card->mpa_rx.pkt_cnt == 1)
1359 mport = adapter->ioport + port;
1360
1358 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, 1361 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
1359 card->mpa_rx.buf_len, mport, 1)) 1362 card->mpa_rx.buf_len, mport, 1))
1360 goto error; 1363 goto error;
@@ -1684,6 +1687,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1684 s32 f_precopy_cur_buf = 0; 1687 s32 f_precopy_cur_buf = 0;
1685 s32 f_postcopy_cur_buf = 0; 1688 s32 f_postcopy_cur_buf = 0;
1686 u32 mport; 1689 u32 mport;
1690 int index;
1687 1691
1688 if (!card->mpa_tx.enabled || 1692 if (!card->mpa_tx.enabled ||
1689 (card->has_control_mask && (port == CTRL_PORT)) || 1693 (card->has_control_mask && (port == CTRL_PORT)) ||
@@ -1785,9 +1789,21 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1785 card->mpa_tx.start_port; 1789 card->mpa_tx.start_port;
1786 } 1790 }
1787 1791
1792 if (card->mpa_tx.pkt_cnt == 1)
1793 mport = adapter->ioport + port;
1794
1788 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, 1795 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
1789 card->mpa_tx.buf_len, mport); 1796 card->mpa_tx.buf_len, mport);
1790 1797
1798 /* Save the last multi port tx aggreagation info to debug log */
1799 index = adapter->dbg.last_sdio_mp_index;
1800 index = (index + 1) % MWIFIEX_DBG_SDIO_MP_NUM;
1801 adapter->dbg.last_sdio_mp_index = index;
1802 adapter->dbg.last_mp_wr_ports[index] = mport;
1803 adapter->dbg.last_mp_wr_bitmap[index] = card->mp_wr_bitmap;
1804 adapter->dbg.last_mp_wr_len[index] = card->mpa_tx.buf_len;
1805 adapter->dbg.last_mp_curr_wr_port[index] = card->curr_wr_port;
1806
1791 MP_TX_AGGR_BUF_RESET(card); 1807 MP_TX_AGGR_BUF_RESET(card);
1792 } 1808 }
1793 1809
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
index 5cbee58f8781..d5c56eb9e985 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
@@ -314,6 +314,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
314 mwifiex_dbg(adapter, ERROR, 314 mwifiex_dbg(adapter, ERROR,
315 "Attempt to reconnect on csa closed chan(%d)\n", 315 "Attempt to reconnect on csa closed chan(%d)\n",
316 bss_desc->channel); 316 bss_desc->channel);
317 ret = -1;
317 goto done; 318 goto done;
318 } 319 }
319 320
diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c
index 9275f9c3f869..150649602e98 100644
--- a/drivers/net/wireless/marvell/mwifiex/tdls.c
+++ b/drivers/net/wireless/marvell/mwifiex/tdls.c
@@ -680,6 +680,13 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
680 __net_timestamp(skb); 680 __net_timestamp(skb);
681 mwifiex_queue_tx_pkt(priv, skb); 681 mwifiex_queue_tx_pkt(priv, skb);
682 682
683 /* Delay 10ms to make sure tdls setup confirm/teardown frame
684 * is received by peer
685 */
686 if (action_code == WLAN_TDLS_SETUP_CONFIRM ||
687 action_code == WLAN_TDLS_TEARDOWN)
688 msleep_interruptible(10);
689
683 return 0; 690 return 0;
684} 691}
685 692
diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
index e791166d90c4..16d95b22fe5c 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
@@ -192,7 +192,7 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
192 } 192 }
193 priv->ap_11n_enabled = 1; 193 priv->ap_11n_enabled = 1;
194 } else { 194 } else {
195 memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); 195 memset(&bss_cfg->ht_cap, 0, sizeof(struct ieee80211_ht_cap));
196 bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP); 196 bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP);
197 bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU; 197 bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU;
198 } 198 }
diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c
index e43aff932360..05108618430d 100644
--- a/drivers/net/wireless/marvell/mwifiex/usb.c
+++ b/drivers/net/wireless/marvell/mwifiex/usb.c
@@ -244,9 +244,9 @@ setup_for_next:
244 if (card->rx_cmd_ep == context->ep) { 244 if (card->rx_cmd_ep == context->ep) {
245 mwifiex_usb_submit_rx_urb(context, size); 245 mwifiex_usb_submit_rx_urb(context, size);
246 } else { 246 } else {
247 if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING){ 247 if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING) {
248 mwifiex_usb_submit_rx_urb(context, size); 248 mwifiex_usb_submit_rx_urb(context, size);
249 }else{ 249 } else {
250 context->skb = NULL; 250 context->skb = NULL;
251 } 251 }
252 } 252 }
diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c
index 0cec8a64473e..6681be0511c7 100644
--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -78,6 +78,16 @@ static struct mwifiex_debug_data items[] = {
78 item_addr(last_event), DBG_CMD_NUM}, 78 item_addr(last_event), DBG_CMD_NUM},
79 {"last_event_index", item_size(last_event_index), 79 {"last_event_index", item_size(last_event_index),
80 item_addr(last_event_index), 1}, 80 item_addr(last_event_index), 1},
81 {"last_mp_wr_bitmap", item_size(last_mp_wr_bitmap),
82 item_addr(last_mp_wr_bitmap), MWIFIEX_DBG_SDIO_MP_NUM},
83 {"last_mp_wr_ports", item_size(last_mp_wr_ports),
84 item_addr(last_mp_wr_ports), MWIFIEX_DBG_SDIO_MP_NUM},
85 {"last_mp_wr_len", item_size(last_mp_wr_len),
86 item_addr(last_mp_wr_len), MWIFIEX_DBG_SDIO_MP_NUM},
87 {"last_mp_curr_wr_port", item_size(last_mp_curr_wr_port),
88 item_addr(last_mp_curr_wr_port), MWIFIEX_DBG_SDIO_MP_NUM},
89 {"last_sdio_mp_index", item_size(last_sdio_mp_index),
90 item_addr(last_sdio_mp_index), 1},
81 {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure), 91 {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
82 item_addr(num_cmd_host_to_card_failure), 1}, 92 item_addr(num_cmd_host_to_card_failure), 1},
83 {"num_cmd_sleep_cfm_fail", 93 {"num_cmd_sleep_cfm_fail",
@@ -233,6 +243,16 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
233 memcpy(info->last_event, adapter->dbg.last_event, 243 memcpy(info->last_event, adapter->dbg.last_event,
234 sizeof(adapter->dbg.last_event)); 244 sizeof(adapter->dbg.last_event));
235 info->last_event_index = adapter->dbg.last_event_index; 245 info->last_event_index = adapter->dbg.last_event_index;
246 memcpy(info->last_mp_wr_bitmap, adapter->dbg.last_mp_wr_bitmap,
247 sizeof(adapter->dbg.last_mp_wr_bitmap));
248 memcpy(info->last_mp_wr_ports, adapter->dbg.last_mp_wr_ports,
249 sizeof(adapter->dbg.last_mp_wr_ports));
250 memcpy(info->last_mp_curr_wr_port,
251 adapter->dbg.last_mp_curr_wr_port,
252 sizeof(adapter->dbg.last_mp_curr_wr_port));
253 memcpy(info->last_mp_wr_len, adapter->dbg.last_mp_wr_len,
254 sizeof(adapter->dbg.last_mp_wr_len));
255 info->last_sdio_mp_index = adapter->dbg.last_sdio_mp_index;
236 info->data_sent = adapter->data_sent; 256 info->data_sent = adapter->data_sent;
237 info->cmd_sent = adapter->cmd_sent; 257 info->cmd_sent = adapter->cmd_sent;
238 info->cmd_resp_received = adapter->cmd_resp_received; 258 info->cmd_resp_received = adapter->cmd_resp_received;
diff --git a/drivers/net/wireless/mediatek/mt7601u/mcu.c b/drivers/net/wireless/mediatek/mt7601u/mcu.c
index fbb1986eda3c..91c4b3427965 100644
--- a/drivers/net/wireless/mediatek/mt7601u/mcu.c
+++ b/drivers/net/wireless/mediatek/mt7601u/mcu.c
@@ -362,7 +362,9 @@ mt7601u_upload_firmware(struct mt7601u_dev *dev, const struct mt76_fw *fw)
362 int i, ret; 362 int i, ret;
363 363
364 ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL); 364 ivb = kmemdup(fw->ivb, sizeof(fw->ivb), GFP_KERNEL);
365 if (!ivb || mt7601u_usb_alloc_buf(dev, MCU_FW_URB_SIZE, &dma_buf)) { 365 if (!ivb)
366 return -ENOMEM;
367 if (mt7601u_usb_alloc_buf(dev, MCU_FW_URB_SIZE, &dma_buf)) {
366 ret = -ENOMEM; 368 ret = -ENOMEM;
367 goto error; 369 goto error;
368 } 370 }
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index bf9afbf46c1b..4b0bb6b4f6f1 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -1026,6 +1026,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1026 { USB_DEVICE(0x0411, 0x01a2) }, 1026 { USB_DEVICE(0x0411, 0x01a2) },
1027 { USB_DEVICE(0x0411, 0x01ee) }, 1027 { USB_DEVICE(0x0411, 0x01ee) },
1028 { USB_DEVICE(0x0411, 0x01a8) }, 1028 { USB_DEVICE(0x0411, 0x01a8) },
1029 { USB_DEVICE(0x0411, 0x01fd) },
1029 /* Corega */ 1030 /* Corega */
1030 { USB_DEVICE(0x07aa, 0x002f) }, 1031 { USB_DEVICE(0x07aa, 0x002f) },
1031 { USB_DEVICE(0x07aa, 0x003c) }, 1032 { USB_DEVICE(0x07aa, 0x003c) },
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
index 25ee3cb8e982..72ae530e4a3b 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c
@@ -478,7 +478,7 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
478{ \ 478{ \
479 struct rt2x00debug_intf *intf = file->private_data; \ 479 struct rt2x00debug_intf *intf = file->private_data; \
480 const struct rt2x00debug *debug = intf->debug; \ 480 const struct rt2x00debug *debug = intf->debug; \
481 char line[16]; \ 481 char line[17]; \
482 size_t size; \ 482 size_t size; \
483 unsigned int index = intf->offset_##__name; \ 483 unsigned int index = intf->offset_##__name; \
484 __type value; \ 484 __type value; \
@@ -494,7 +494,8 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
494 \ 494 \
495 if (copy_from_user(line, buf, length)) \ 495 if (copy_from_user(line, buf, length)) \
496 return -EFAULT; \ 496 return -EFAULT; \
497 \ 497 line[16] = 0; \
498 \
498 size = strlen(line); \ 499 size = strlen(line); \
499 value = simple_strtoul(line, NULL, 0); \ 500 value = simple_strtoul(line, NULL, 0); \
500 \ 501 \
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
index dd4d626aecbc..8f053c350227 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
+++ b/drivers/net/wireless/realtek/rtl8xxxu/Kconfig
@@ -13,7 +13,7 @@ config RTL8XXXU
13 This driver is under development and has a limited feature 13 This driver is under development and has a limited feature
14 set. In particular it does not yet support 40MHz channels 14 set. In particular it does not yet support 40MHz channels
15 and power management. However it should have a smaller 15 and power management. However it should have a smaller
16 memory footprint than the vendor drivers and benetifs 16 memory footprint than the vendor drivers and benefits
17 from the in kernel mac80211 stack. 17 from the in kernel mac80211 stack.
18 18
19 It can coexist with drivers from drivers/staging/rtl8723au, 19 It can coexist with drivers from drivers/staging/rtl8723au,
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
index 7d820c395375..e654bd33b434 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.c
@@ -1599,9 +1599,9 @@ rtl8723a_set_tx_power(struct rtl8xxxu_priv *priv, int channel, bool ht40)
1599static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv, 1599static void rtl8xxxu_set_linktype(struct rtl8xxxu_priv *priv,
1600 enum nl80211_iftype linktype) 1600 enum nl80211_iftype linktype)
1601{ 1601{
1602 u16 val8; 1602 u8 val8;
1603 1603
1604 val8 = rtl8xxxu_read16(priv, REG_MSR); 1604 val8 = rtl8xxxu_read8(priv, REG_MSR);
1605 val8 &= ~MSR_LINKTYPE_MASK; 1605 val8 &= ~MSR_LINKTYPE_MASK;
1606 1606
1607 switch (linktype) { 1607 switch (linktype) {
@@ -1704,6 +1704,7 @@ static int rtl8xxxu_identify_chip(struct rtl8xxxu_priv *priv)
1704 priv->has_bluetooth = 1; 1704 priv->has_bluetooth = 1;
1705 if (val32 & MULTI_GPS_FUNC_EN) 1705 if (val32 & MULTI_GPS_FUNC_EN)
1706 priv->has_gps = 1; 1706 priv->has_gps = 1;
1707 priv->is_multi_func = 1;
1707 } else if (val32 & SYS_CFG_TYPE_ID) { 1708 } else if (val32 & SYS_CFG_TYPE_ID) {
1708 bonding = rtl8xxxu_read32(priv, REG_HPON_FSM); 1709 bonding = rtl8xxxu_read32(priv, REG_HPON_FSM);
1709 bonding &= HPON_FSM_BONDING_MASK; 1710 bonding &= HPON_FSM_BONDING_MASK;
@@ -1938,9 +1939,11 @@ static int rtl8xxxu_read_efuse(struct rtl8xxxu_priv *priv)
1938 if (val16 & EEPROM_BOOT) 1939 if (val16 & EEPROM_BOOT)
1939 priv->boot_eeprom = 1; 1940 priv->boot_eeprom = 1;
1940 1941
1941 val32 = rtl8xxxu_read32(priv, REG_EFUSE_TEST); 1942 if (priv->is_multi_func) {
1942 val32 = (val32 & ~EFUSE_SELECT_MASK) | EFUSE_WIFI_SELECT; 1943 val32 = rtl8xxxu_read32(priv, REG_EFUSE_TEST);
1943 rtl8xxxu_write32(priv, REG_EFUSE_TEST, val32); 1944 val32 = (val32 & ~EFUSE_SELECT_MASK) | EFUSE_WIFI_SELECT;
1945 rtl8xxxu_write32(priv, REG_EFUSE_TEST, val32);
1946 }
1944 1947
1945 dev_dbg(dev, "Booting from %s\n", 1948 dev_dbg(dev, "Booting from %s\n",
1946 priv->boot_eeprom ? "EEPROM" : "EFUSE"); 1949 priv->boot_eeprom ? "EEPROM" : "EFUSE");
@@ -2043,6 +2046,24 @@ exit:
2043 return ret; 2046 return ret;
2044} 2047}
2045 2048
2049static void rtl8xxxu_reset_8051(struct rtl8xxxu_priv *priv)
2050{
2051 u8 val8;
2052 u16 sys_func;
2053
2054 val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
2055 val8 &= ~BIT(0);
2056 rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
2057 sys_func = rtl8xxxu_read16(priv, REG_SYS_FUNC);
2058 sys_func &= ~SYS_FUNC_CPU_ENABLE;
2059 rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func);
2060 val8 = rtl8xxxu_read8(priv, REG_RSV_CTRL + 1);
2061 val8 |= BIT(0);
2062 rtl8xxxu_write8(priv, REG_RSV_CTRL + 1, val8);
2063 sys_func |= SYS_FUNC_CPU_ENABLE;
2064 rtl8xxxu_write16(priv, REG_SYS_FUNC, sys_func);
2065}
2066
2046static int rtl8xxxu_start_firmware(struct rtl8xxxu_priv *priv) 2067static int rtl8xxxu_start_firmware(struct rtl8xxxu_priv *priv)
2047{ 2068{
2048 struct device *dev = &priv->udev->dev; 2069 struct device *dev = &priv->udev->dev;
@@ -2067,6 +2088,12 @@ static int rtl8xxxu_start_firmware(struct rtl8xxxu_priv *priv)
2067 val32 &= ~MCU_WINT_INIT_READY; 2088 val32 &= ~MCU_WINT_INIT_READY;
2068 rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32); 2089 rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32);
2069 2090
2091 /*
2092 * Reset the 8051 in order for the firmware to start running,
2093 * otherwise it won't come up on the 8192eu
2094 */
2095 rtl8xxxu_reset_8051(priv);
2096
2070 /* Wait for firmware to become ready */ 2097 /* Wait for firmware to become ready */
2071 for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) { 2098 for (i = 0; i < RTL8XXXU_FIRMWARE_POLL_MAX; i++) {
2072 val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL); 2099 val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
@@ -2100,19 +2127,30 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
2100 2127
2101 /* 8051 enable */ 2128 /* 8051 enable */
2102 val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC); 2129 val16 = rtl8xxxu_read16(priv, REG_SYS_FUNC);
2103 rtl8xxxu_write16(priv, REG_SYS_FUNC, val16 | SYS_FUNC_CPU_ENABLE); 2130 val16 |= SYS_FUNC_CPU_ENABLE;
2131 rtl8xxxu_write16(priv, REG_SYS_FUNC, val16);
2132
2133 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
2134 if (val8 & MCU_FW_RAM_SEL) {
2135 pr_info("do the RAM reset\n");
2136 rtl8xxxu_write8(priv, REG_MCU_FW_DL, 0x00);
2137 rtl8xxxu_reset_8051(priv);
2138 }
2104 2139
2105 /* MCU firmware download enable */ 2140 /* MCU firmware download enable */
2106 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL); 2141 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
2107 rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_ENABLE); 2142 val8 |= MCU_FW_DL_ENABLE;
2143 rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8);
2108 2144
2109 /* 8051 reset */ 2145 /* 8051 reset */
2110 val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL); 2146 val32 = rtl8xxxu_read32(priv, REG_MCU_FW_DL);
2111 rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32 & ~BIT(19)); 2147 val32 &= ~BIT(19);
2148 rtl8xxxu_write32(priv, REG_MCU_FW_DL, val32);
2112 2149
2113 /* Reset firmware download checksum */ 2150 /* Reset firmware download checksum */
2114 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL); 2151 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL);
2115 rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8 | MCU_FW_DL_CSUM_REPORT); 2152 val8 |= MCU_FW_DL_CSUM_REPORT;
2153 rtl8xxxu_write8(priv, REG_MCU_FW_DL, val8);
2116 2154
2117 pages = priv->fw_size / RTL_FW_PAGE_SIZE; 2155 pages = priv->fw_size / RTL_FW_PAGE_SIZE;
2118 remainder = priv->fw_size % RTL_FW_PAGE_SIZE; 2156 remainder = priv->fw_size % RTL_FW_PAGE_SIZE;
@@ -2121,7 +2159,8 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
2121 2159
2122 for (i = 0; i < pages; i++) { 2160 for (i = 0; i < pages; i++) {
2123 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8; 2161 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
2124 rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i); 2162 val8 |= i;
2163 rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8);
2125 2164
2126 ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS, 2165 ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
2127 fwptr, RTL_FW_PAGE_SIZE); 2166 fwptr, RTL_FW_PAGE_SIZE);
@@ -2135,7 +2174,8 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
2135 2174
2136 if (remainder) { 2175 if (remainder) {
2137 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8; 2176 val8 = rtl8xxxu_read8(priv, REG_MCU_FW_DL + 2) & 0xF8;
2138 rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8 | i); 2177 val8 |= i;
2178 rtl8xxxu_write8(priv, REG_MCU_FW_DL + 2, val8);
2139 ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS, 2179 ret = rtl8xxxu_writeN(priv, REG_FW_START_ADDRESS,
2140 fwptr, remainder); 2180 fwptr, remainder);
2141 if (ret != remainder) { 2181 if (ret != remainder) {
@@ -2148,8 +2188,8 @@ static int rtl8xxxu_download_firmware(struct rtl8xxxu_priv *priv)
2148fw_abort: 2188fw_abort:
2149 /* MCU firmware download disable */ 2189 /* MCU firmware download disable */
2150 val16 = rtl8xxxu_read16(priv, REG_MCU_FW_DL); 2190 val16 = rtl8xxxu_read16(priv, REG_MCU_FW_DL);
2151 rtl8xxxu_write16(priv, REG_MCU_FW_DL, 2191 val16 &= ~MCU_FW_DL_ENABLE;
2152 val16 & (~MCU_FW_DL_ENABLE & 0xff)); 2192 rtl8xxxu_write16(priv, REG_MCU_FW_DL, val16);
2153 2193
2154 return ret; 2194 return ret;
2155} 2195}
@@ -2174,6 +2214,10 @@ static int rtl8xxxu_load_firmware(struct rtl8xxxu_priv *priv, char *fw_name)
2174 } 2214 }
2175 2215
2176 priv->fw_data = kmemdup(fw->data, fw->size, GFP_KERNEL); 2216 priv->fw_data = kmemdup(fw->data, fw->size, GFP_KERNEL);
2217 if (!priv->fw_data) {
2218 ret = -ENOMEM;
2219 goto exit;
2220 }
2177 priv->fw_size = fw->size - sizeof(struct rtl8xxxu_firmware_header); 2221 priv->fw_size = fw->size - sizeof(struct rtl8xxxu_firmware_header);
2178 2222
2179 signature = le16_to_cpu(priv->fw_data->signature); 2223 signature = le16_to_cpu(priv->fw_data->signature);
@@ -2492,8 +2536,6 @@ static int rtl8xxxu_init_rf_regs(struct rtl8xxxu_priv *priv,
2492 continue; 2536 continue;
2493 } 2537 }
2494 2538
2495 reg &= 0x3f;
2496
2497 ret = rtl8xxxu_write_rfreg(priv, path, reg, val); 2539 ret = rtl8xxxu_write_rfreg(priv, path, reg, val);
2498 if (ret) { 2540 if (ret) {
2499 dev_warn(&priv->udev->dev, 2541 dev_warn(&priv->udev->dev,
@@ -4155,7 +4197,6 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
4155 * Configure initial WMAC settings 4197 * Configure initial WMAC settings
4156 */ 4198 */
4157 val32 = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_MCAST | RCR_ACCEPT_BCAST | 4199 val32 = RCR_ACCEPT_PHYS_MATCH | RCR_ACCEPT_MCAST | RCR_ACCEPT_BCAST |
4158 /* RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON | */
4159 RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL | 4200 RCR_ACCEPT_MGMT_FRAME | RCR_HTC_LOC_CTRL |
4160 RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC; 4201 RCR_APPEND_PHYSTAT | RCR_APPEND_ICV | RCR_APPEND_MIC;
4161 rtl8xxxu_write32(priv, REG_RCR, val32); 4202 rtl8xxxu_write32(priv, REG_RCR, val32);
@@ -4248,17 +4289,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
4248 4289
4249 rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0); 4290 rtl8xxxu_write16(priv, REG_FAST_EDCA_CTRL, 0);
4250 4291
4251 /* 4292 rtl8723a_phy_iq_calibrate(priv);
4252 * Not sure if we should get into this at all
4253 */
4254 if (priv->iqk_initialized) {
4255 rtl8xxxu_restore_regs(priv, rtl8723au_iqk_phy_iq_bb_reg,
4256 priv->bb_recovery_backup,
4257 RTL8XXXU_BB_REGS);
4258 } else {
4259 rtl8723a_phy_iq_calibrate(priv);
4260 priv->iqk_initialized = true;
4261 }
4262 4293
4263 /* 4294 /*
4264 * This should enable thermal meter 4295 * This should enable thermal meter
@@ -4312,14 +4343,17 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
4312 val8 = ((30000 + NAV_UPPER_UNIT - 1) / NAV_UPPER_UNIT); 4343 val8 = ((30000 + NAV_UPPER_UNIT - 1) / NAV_UPPER_UNIT);
4313 rtl8xxxu_write8(priv, REG_NAV_UPPER, val8); 4344 rtl8xxxu_write8(priv, REG_NAV_UPPER, val8);
4314 4345
4315 /* 4346 if (priv->rtlchip == 0x8723a) {
4316 * 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, 4347 /*
4317 * but we need to fin root cause. 4348 * 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test,
4318 */ 4349 * but we need to find root cause.
4319 val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE); 4350 * This is 8723au only.
4320 if ((val32 & 0xff000000) != 0x83000000) { 4351 */
4321 val32 |= FPGA_RF_MODE_CCK; 4352 val32 = rtl8xxxu_read32(priv, REG_FPGA0_RF_MODE);
4322 rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32); 4353 if ((val32 & 0xff000000) != 0x83000000) {
4354 val32 |= FPGA_RF_MODE_CCK;
4355 rtl8xxxu_write32(priv, REG_FPGA0_RF_MODE, val32);
4356 }
4323 } 4357 }
4324 4358
4325 val32 = rtl8xxxu_read32(priv, REG_FWHW_TXQ_CTRL); 4359 val32 = rtl8xxxu_read32(priv, REG_FWHW_TXQ_CTRL);
@@ -4381,7 +4415,7 @@ static void rtl8xxxu_cam_write(struct rtl8xxxu_priv *priv,
4381} 4415}
4382 4416
4383static void rtl8xxxu_sw_scan_start(struct ieee80211_hw *hw, 4417static void rtl8xxxu_sw_scan_start(struct ieee80211_hw *hw,
4384 struct ieee80211_vif *vif, const u8* mac) 4418 struct ieee80211_vif *vif, const u8 *mac)
4385{ 4419{
4386 struct rtl8xxxu_priv *priv = hw->priv; 4420 struct rtl8xxxu_priv *priv = hw->priv;
4387 u8 val8; 4421 u8 val8;
@@ -4488,13 +4522,6 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4488 4522
4489 rtl8xxxu_update_rate_mask(priv, ramask, sgi); 4523 rtl8xxxu_update_rate_mask(priv, ramask, sgi);
4490 4524
4491 val32 = rtl8xxxu_read32(priv, REG_RCR);
4492 val32 |= RCR_CHECK_BSSID_MATCH | RCR_CHECK_BSSID_BEACON;
4493 rtl8xxxu_write32(priv, REG_RCR, val32);
4494
4495 /* Enable RX of data frames */
4496 rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff);
4497
4498 rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff); 4525 rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
4499 4526
4500 rtl8723a_stop_tx_beacon(priv); 4527 rtl8723a_stop_tx_beacon(priv);
@@ -4505,17 +4532,10 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4505 4532
4506 h2c.joinbss.data = H2C_JOIN_BSS_CONNECT; 4533 h2c.joinbss.data = H2C_JOIN_BSS_CONNECT;
4507 } else { 4534 } else {
4508 val32 = rtl8xxxu_read32(priv, REG_RCR);
4509 val32 &= ~(RCR_CHECK_BSSID_MATCH |
4510 RCR_CHECK_BSSID_BEACON);
4511 rtl8xxxu_write32(priv, REG_RCR, val32);
4512
4513 val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL); 4535 val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
4514 val8 |= BEACON_DISABLE_TSF_UPDATE; 4536 val8 |= BEACON_DISABLE_TSF_UPDATE;
4515 rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8); 4537 rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
4516 4538
4517 /* Disable RX of data frames */
4518 rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
4519 h2c.joinbss.data = H2C_JOIN_BSS_DISCONNECT; 4539 h2c.joinbss.data = H2C_JOIN_BSS_DISCONNECT;
4520 } 4540 }
4521 h2c.joinbss.cmd = H2C_JOIN_BSS_REPORT; 4541 h2c.joinbss.cmd = H2C_JOIN_BSS_REPORT;
@@ -5012,17 +5032,14 @@ static void rtl8xxxu_rx_complete(struct urb *urb)
5012 struct rtl8xxxu_rx_desc *rx_desc = (struct rtl8xxxu_rx_desc *)skb->data; 5032 struct rtl8xxxu_rx_desc *rx_desc = (struct rtl8xxxu_rx_desc *)skb->data;
5013 struct rtl8723au_phy_stats *phy_stats; 5033 struct rtl8723au_phy_stats *phy_stats;
5014 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 5034 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
5015 struct ieee80211_mgmt *mgmt;
5016 struct device *dev = &priv->udev->dev; 5035 struct device *dev = &priv->udev->dev;
5017 __le32 *_rx_desc_le = (__le32 *)skb->data; 5036 __le32 *_rx_desc_le = (__le32 *)skb->data;
5018 u32 *_rx_desc = (u32 *)skb->data; 5037 u32 *_rx_desc = (u32 *)skb->data;
5019 int cnt, len, drvinfo_sz, desc_shift, i; 5038 int drvinfo_sz, desc_shift, i;
5020 5039
5021 for (i = 0; i < (sizeof(struct rtl8xxxu_rx_desc) / sizeof(u32)); i++) 5040 for (i = 0; i < (sizeof(struct rtl8xxxu_rx_desc) / sizeof(u32)); i++)
5022 _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]); 5041 _rx_desc[i] = le32_to_cpu(_rx_desc_le[i]);
5023 5042
5024 cnt = rx_desc->frag;
5025 len = rx_desc->pktlen;
5026 drvinfo_sz = rx_desc->drvinfo_sz * 8; 5043 drvinfo_sz = rx_desc->drvinfo_sz * 8;
5027 desc_shift = rx_desc->shift; 5044 desc_shift = rx_desc->shift;
5028 skb_put(skb, urb->actual_length); 5045 skb_put(skb, urb->actual_length);
@@ -5033,8 +5050,6 @@ static void rtl8xxxu_rx_complete(struct urb *urb)
5033 5050
5034 skb_pull(skb, drvinfo_sz + desc_shift); 5051 skb_pull(skb, drvinfo_sz + desc_shift);
5035 5052
5036 mgmt = (struct ieee80211_mgmt *)skb->data;
5037
5038 memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); 5053 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
5039 5054
5040 if (rx_desc->phy_stats) 5055 if (rx_desc->phy_stats)
@@ -5284,11 +5299,56 @@ static void rtl8xxxu_configure_filter(struct ieee80211_hw *hw,
5284 unsigned int *total_flags, u64 multicast) 5299 unsigned int *total_flags, u64 multicast)
5285{ 5300{
5286 struct rtl8xxxu_priv *priv = hw->priv; 5301 struct rtl8xxxu_priv *priv = hw->priv;
5302 u32 rcr = rtl8xxxu_read32(priv, REG_RCR);
5287 5303
5288 dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n", 5304 dev_dbg(&priv->udev->dev, "%s: changed_flags %08x, total_flags %08x\n",
5289 __func__, changed_flags, *total_flags); 5305 __func__, changed_flags, *total_flags);
5290 5306
5291 *total_flags &= (FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC); 5307 /*
5308 * FIF_ALLMULTI ignored as all multicast frames are accepted (REG_MAR)
5309 */
5310
5311 if (*total_flags & FIF_FCSFAIL)
5312 rcr |= RCR_ACCEPT_CRC32;
5313 else
5314 rcr &= ~RCR_ACCEPT_CRC32;
5315
5316 /*
5317 * FIF_PLCPFAIL not supported?
5318 */
5319
5320 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
5321 rcr &= ~RCR_CHECK_BSSID_BEACON;
5322 else
5323 rcr |= RCR_CHECK_BSSID_BEACON;
5324
5325 if (*total_flags & FIF_CONTROL)
5326 rcr |= RCR_ACCEPT_CTRL_FRAME;
5327 else
5328 rcr &= ~RCR_ACCEPT_CTRL_FRAME;
5329
5330 if (*total_flags & FIF_OTHER_BSS) {
5331 rcr |= RCR_ACCEPT_AP;
5332 rcr &= ~RCR_CHECK_BSSID_MATCH;
5333 } else {
5334 rcr &= ~RCR_ACCEPT_AP;
5335 rcr |= RCR_CHECK_BSSID_MATCH;
5336 }
5337
5338 if (*total_flags & FIF_PSPOLL)
5339 rcr |= RCR_ACCEPT_PM;
5340 else
5341 rcr &= ~RCR_ACCEPT_PM;
5342
5343 /*
5344 * FIF_PROBE_REQ ignored as probe requests always seem to be accepted
5345 */
5346
5347 rtl8xxxu_write32(priv, REG_RCR, rcr);
5348
5349 *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_BCN_PRBRESP_PROMISC |
5350 FIF_CONTROL | FIF_OTHER_BSS | FIF_PSPOLL |
5351 FIF_PROBE_REQ);
5292} 5352}
5293 5353
5294static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, u32 rts) 5354static int rtl8xxxu_set_rts_threshold(struct ieee80211_hw *hw, u32 rts)
@@ -5473,12 +5533,9 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw)
5473 } 5533 }
5474exit: 5534exit:
5475 /* 5535 /*
5476 * Disable all data frames 5536 * Accept all data and mgmt frames
5477 */
5478 rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0x0000);
5479 /*
5480 * Accept all mgmt frames
5481 */ 5537 */
5538 rtl8xxxu_write16(priv, REG_RXFLTMAP2, 0xffff);
5482 rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff); 5539 rtl8xxxu_write16(priv, REG_RXFLTMAP0, 0xffff);
5483 5540
5484 rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6954341e); 5541 rtl8xxxu_write32(priv, REG_OFDM0_XA_AGC_CORE1, 0x6954341e);
@@ -5891,8 +5948,6 @@ static struct usb_device_id dev_table[] = {
5891 .driver_info = (unsigned long)&rtl8192cu_fops}, 5948 .driver_info = (unsigned long)&rtl8192cu_fops},
5892{USB_DEVICE_AND_INTERFACE_INFO(0xcdab, 0x8010, 0xff, 0xff, 0xff), 5949{USB_DEVICE_AND_INTERFACE_INFO(0xcdab, 0x8010, 0xff, 0xff, 0xff),
5893 .driver_info = (unsigned long)&rtl8192cu_fops}, 5950 .driver_info = (unsigned long)&rtl8192cu_fops},
5894{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x317f, 0xff, 0xff, 0xff),
5895 .driver_info = (unsigned long)&rtl8192cu_fops}, /* Netcore 8188RU */
5896{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff7, 0xff, 0xff, 0xff), 5951{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff7, 0xff, 0xff, 0xff),
5897 .driver_info = (unsigned long)&rtl8192cu_fops}, 5952 .driver_info = (unsigned long)&rtl8192cu_fops},
5898{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff9, 0xff, 0xff, 0xff), 5953{USB_DEVICE_AND_INTERFACE_INFO(0x04f2, 0xaff9, 0xff, 0xff, 0xff),
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index f2a1bac6c8ec..bbd0f6b76b82 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -597,6 +597,7 @@ struct rtl8xxxu_priv {
597 struct rtl8723au_idx ht20_max_power_offset[3]; 597 struct rtl8723au_idx ht20_max_power_offset[3];
598 u32 chip_cut:4; 598 u32 chip_cut:4;
599 u32 rom_rev:4; 599 u32 rom_rev:4;
600 u32 is_multi_func:1;
600 u32 has_wifi:1; 601 u32 has_wifi:1;
601 u32 has_bluetooth:1; 602 u32 has_bluetooth:1;
602 u32 enable_bluetooth:1; 603 u32 enable_bluetooth:1;
@@ -652,7 +653,6 @@ struct rtl8xxxu_priv {
652 u32 bb_recovery_backup[RTL8XXXU_BB_REGS]; 653 u32 bb_recovery_backup[RTL8XXXU_BB_REGS];
653 u32 rtlchip; 654 u32 rtlchip;
654 u8 pi_enabled:1; 655 u8 pi_enabled:1;
655 u8 iqk_initialized:1;
656 u8 int_buf[USB_INTR_CONTENT_LENGTH]; 656 u8 int_buf[USB_INTR_CONTENT_LENGTH];
657}; 657};
658 658
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
index 23208f79b97c..8f6c9c6c7c09 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h
@@ -45,6 +45,7 @@
45#define APS_FSMCO_ENABLE_POWERDOWN BIT(4) 45#define APS_FSMCO_ENABLE_POWERDOWN BIT(4)
46#define APS_FSMCO_MAC_ENABLE BIT(8) 46#define APS_FSMCO_MAC_ENABLE BIT(8)
47#define APS_FSMCO_MAC_OFF BIT(9) 47#define APS_FSMCO_MAC_OFF BIT(9)
48#define APS_FSMCO_SW_LPS BIT(10)
48#define APS_FSMCO_HW_SUSPEND BIT(11) 49#define APS_FSMCO_HW_SUSPEND BIT(11)
49#define APS_FSMCO_PCIE BIT(12) 50#define APS_FSMCO_PCIE BIT(12)
50#define APS_FSMCO_HW_POWERDOWN BIT(15) 51#define APS_FSMCO_HW_POWERDOWN BIT(15)
@@ -213,6 +214,7 @@
213#define SYS_CFG_PCIRSTB BIT(4) 214#define SYS_CFG_PCIRSTB BIT(4)
214#define SYS_CFG_V15_VLD BIT(5) 215#define SYS_CFG_V15_VLD BIT(5)
215#define SYS_CFG_TRP_B15V_EN BIT(7) 216#define SYS_CFG_TRP_B15V_EN BIT(7)
217#define SYS_CFG_SW_OFFLOAD_EN BIT(7) /* For chips with IOL support */
216#define SYS_CFG_SIC_IDLE BIT(8) 218#define SYS_CFG_SIC_IDLE BIT(8)
217#define SYS_CFG_BD_MAC2 BIT(9) 219#define SYS_CFG_BD_MAC2 BIT(9)
218#define SYS_CFG_BD_MAC1 BIT(10) 220#define SYS_CFG_BD_MAC1 BIT(10)
@@ -340,6 +342,11 @@
340#define REG_BB_ACCEESS_CTRL 0x01e8 342#define REG_BB_ACCEESS_CTRL 0x01e8
341#define REG_BB_ACCESS_DATA 0x01ec 343#define REG_BB_ACCESS_DATA 0x01ec
342 344
345#define REG_HMBOX_EXT0_8723B 0x01f0
346#define REG_HMBOX_EXT1_8723B 0x01f4
347#define REG_HMBOX_EXT2_8723B 0x01f8
348#define REG_HMBOX_EXT3_8723B 0x01fc
349
343/* 0x0200 ~ 0x027F TXDMA Configuration */ 350/* 0x0200 ~ 0x027F TXDMA Configuration */
344#define REG_RQPN 0x0200 351#define REG_RQPN 0x0200
345#define RQPN_HI_PQ_SHIFT 0 352#define RQPN_HI_PQ_SHIFT 0
@@ -352,6 +359,8 @@
352#define REG_TXDMA_OFFSET_CHK 0x020c 359#define REG_TXDMA_OFFSET_CHK 0x020c
353#define REG_TXDMA_STATUS 0x0210 360#define REG_TXDMA_STATUS 0x0210
354#define REG_RQPN_NPQ 0x0214 361#define REG_RQPN_NPQ 0x0214
362#define RQPN_NPQ_SHIFT 0
363#define RQPN_EPQ_SHIFT 16
355 364
356/* 0x0280 ~ 0x02FF RXDMA Configuration */ 365/* 0x0280 ~ 0x02FF RXDMA Configuration */
357#define REG_RXDMA_AGG_PG_TH 0x0280 366#define REG_RXDMA_AGG_PG_TH 0x0280
@@ -453,6 +462,8 @@
453#define REG_NEED_CPU_HANDLE 0x04e0 462#define REG_NEED_CPU_HANDLE 0x04e0
454#define REG_PKT_LOSE_RPT 0x04e1 463#define REG_PKT_LOSE_RPT 0x04e1
455#define REG_PTCL_ERR_STATUS 0x04e2 464#define REG_PTCL_ERR_STATUS 0x04e2
465#define REG_TX_REPORT_CTRL 0x04ec
466#define REG_TX_REPORT_TIME 0x04f0
456#define REG_DUMMY 0x04fc 467#define REG_DUMMY 0x04fc
457 468
458/* 0x0500 ~ 0x05FF EDCA Configuration */ 469/* 0x0500 ~ 0x05FF EDCA Configuration */
@@ -559,13 +570,25 @@
559 (Rx beacon, probe rsp) */ 570 (Rx beacon, probe rsp) */
560#define RCR_ACCEPT_CRC32 BIT(8) /* Accept CRC32 error packet */ 571#define RCR_ACCEPT_CRC32 BIT(8) /* Accept CRC32 error packet */
561#define RCR_ACCEPT_ICV BIT(9) /* Accept ICV error packet */ 572#define RCR_ACCEPT_ICV BIT(9) /* Accept ICV error packet */
562#define RCR_ACCEPT_DATA_FRAME BIT(11) 573#define RCR_ACCEPT_DATA_FRAME BIT(11) /* Accept all data pkt or use
563#define RCR_ACCEPT_CTRL_FRAME BIT(12) 574 REG_RXFLTMAP2 */
564#define RCR_ACCEPT_MGMT_FRAME BIT(13) 575#define RCR_ACCEPT_CTRL_FRAME BIT(12) /* Accept all control pkt or use
576 REG_RXFLTMAP1 */
577#define RCR_ACCEPT_MGMT_FRAME BIT(13) /* Accept all mgmt pkt or use
578 REG_RXFLTMAP0 */
565#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */ 579#define RCR_HTC_LOC_CTRL BIT(14) /* MFC<--HTC=1 MFC-->HTC=0 */
580#define RCR_UC_DATA_PKT_INT_ENABLE BIT(16) /* Enable unicast data packet
581 interrupt */
582#define RCR_BM_DATA_PKT_INT_ENABLE BIT(17) /* Enable broadcast data packet
583 interrupt */
584#define RCR_TIM_PARSER_ENABLE BIT(18) /* Enable RX beacon TIM parser*/
566#define RCR_MFBEN BIT(22) 585#define RCR_MFBEN BIT(22)
567#define RCR_LSIGEN BIT(23) 586#define RCR_LSIG_ENABLE BIT(23) /* Enable LSIG TXOP Protection
587 function. Search KEYCAM for
588 each rx packet to check if
589 LSIGEN bit is set. */
568#define RCR_MULTI_BSSID_ENABLE BIT(24) /* Enable Multiple BssId */ 590#define RCR_MULTI_BSSID_ENABLE BIT(24) /* Enable Multiple BssId */
591#define RCR_FORCE_ACK BIT(26)
569#define RCR_ACCEPT_BA_SSN BIT(27) /* Accept BA SSN */ 592#define RCR_ACCEPT_BA_SSN BIT(27) /* Accept BA SSN */
570#define RCR_APPEND_PHYSTAT BIT(28) 593#define RCR_APPEND_PHYSTAT BIT(28)
571#define RCR_APPEND_ICV BIT(29) 594#define RCR_APPEND_ICV BIT(29)
@@ -632,9 +655,20 @@
632#define REG_LPNAV_CTRL 0x0694 655#define REG_LPNAV_CTRL 0x0694
633#define REG_WKFMCAM_CMD 0x0698 656#define REG_WKFMCAM_CMD 0x0698
634#define REG_WKFMCAM_RWD 0x069c 657#define REG_WKFMCAM_RWD 0x069c
635#define REG_RXFLTMAP0 0x06a0 658
636#define REG_RXFLTMAP1 0x06a2 659/*
637#define REG_RXFLTMAP2 0x06a4 660 * RX Filters: each bit corresponds to the numerical value of the subtype.
661 * If it is set the subtype frame type is passed. The filter is only used when
662 * the RCR_ACCEPT_DATA_FRAME, RCR_ACCEPT_CTRL_FRAME, RCR_ACCEPT_MGMT_FRAME bit
663 * in the RCR are low.
664 *
665 * Example: Beacon subtype is binary 1000 which is decimal 8 so we have to set
666 * bit 8 (0x100) in REG_RXFLTMAP0 to enable reception.
667 */
668#define REG_RXFLTMAP0 0x06a0 /* Management frames */
669#define REG_RXFLTMAP1 0x06a2 /* Control frames */
670#define REG_RXFLTMAP2 0x06a4 /* Data frames */
671
638#define REG_BCN_PSR_RPT 0x06a8 672#define REG_BCN_PSR_RPT 0x06a8
639#define REG_CALB32K_CTRL 0x06ac 673#define REG_CALB32K_CTRL 0x06ac
640#define REG_PKT_MON_CTRL 0x06b4 674#define REG_PKT_MON_CTRL 0x06b4
@@ -742,6 +776,10 @@
742#define REG_FPGA1_RF_MODE 0x0900 776#define REG_FPGA1_RF_MODE 0x0900
743 777
744#define REG_FPGA1_TX_INFO 0x090c 778#define REG_FPGA1_TX_INFO 0x090c
779#define REG_DPDT_CTRL 0x092c /* 8723BU */
780#define REG_RFE_CTRL_ANTA_SRC 0x0930 /* 8723BU */
781#define REG_RFE_PATH_SELECT 0x0940 /* 8723BU */
782#define REG_RFE_BUFFER 0x0944 /* 8723BU */
745 783
746#define REG_CCK0_SYSTEM 0x0a00 784#define REG_CCK0_SYSTEM 0x0a00
747#define CCK0_SIDEBAND BIT(4) 785#define CCK0_SIDEBAND BIT(4)
@@ -770,6 +808,9 @@
770 808
771#define REG_OFDM0_ENERGY_CCA_THRES 0x0c4c 809#define REG_OFDM0_ENERGY_CCA_THRES 0x0c4c
772 810
811#define REG_OFDM0_RX_D_SYNC_PATH 0x0c40
812#define OFDM0_SYNC_PATH_NOTCH_FILTER BIT(1)
813
773#define REG_OFDM0_XA_AGC_CORE1 0x0c50 814#define REG_OFDM0_XA_AGC_CORE1 0x0c50
774#define REG_OFDM0_XA_AGC_CORE2 0x0c54 815#define REG_OFDM0_XA_AGC_CORE2 0x0c54
775#define REG_OFDM0_XB_AGC_CORE1 0x0c58 816#define REG_OFDM0_XB_AGC_CORE1 0x0c58
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index f2507610314b..0f48048b8654 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -35,62 +35,58 @@
35#include <linux/export.h> 35#include <linux/export.h>
36#include <net/cfg80211.h> 36#include <net/cfg80211.h>
37 37
38u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
39 36, 38, 40, 42, 44, 46, 48, /* Band 1 */
40 52, 54, 56, 58, 60, 62, 64, /* Band 2 */
41 100, 102, 104, 106, 108, 110, 112, /* Band 3 */
42 116, 118, 120, 122, 124, 126, 128, /* Band 3 */
43 132, 134, 136, 138, 140, 142, 144, /* Band 3 */
44 149, 151, 153, 155, 157, 159, 161, /* Band 4 */
45 165, 167, 169, 171, 173, 175, 177 /* Band 4 */
46};
47EXPORT_SYMBOL(channel5g);
48
49u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
50 42, 58, 106, 122, 138, 155, 171
51};
52EXPORT_SYMBOL(channel5g_80m);
53
38void rtl_addr_delay(u32 addr) 54void rtl_addr_delay(u32 addr)
39{ 55{
40 if (addr == 0xfe) 56 if (addr == 0xfe)
41 mdelay(50); 57 msleep(50);
42 else if (addr == 0xfd) 58 else if (addr == 0xfd)
43 mdelay(5); 59 msleep(5);
44 else if (addr == 0xfc) 60 else if (addr == 0xfc)
45 mdelay(1); 61 msleep(1);
46 else if (addr == 0xfb) 62 else if (addr == 0xfb)
47 udelay(50); 63 usleep_range(50, 100);
48 else if (addr == 0xfa) 64 else if (addr == 0xfa)
49 udelay(5); 65 usleep_range(5, 10);
50 else if (addr == 0xf9) 66 else if (addr == 0xf9)
51 udelay(1); 67 usleep_range(1, 2);
52} 68}
53EXPORT_SYMBOL(rtl_addr_delay); 69EXPORT_SYMBOL(rtl_addr_delay);
54 70
55void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, 71void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
56 u32 mask, u32 data) 72 u32 mask, u32 data)
57{ 73{
58 if (addr == 0xfe) { 74 if (addr >= 0xf9 && addr <= 0xfe) {
59 mdelay(50); 75 rtl_addr_delay(addr);
60 } else if (addr == 0xfd) {
61 mdelay(5);
62 } else if (addr == 0xfc) {
63 mdelay(1);
64 } else if (addr == 0xfb) {
65 udelay(50);
66 } else if (addr == 0xfa) {
67 udelay(5);
68 } else if (addr == 0xf9) {
69 udelay(1);
70 } else { 76 } else {
71 rtl_set_rfreg(hw, rfpath, addr, mask, data); 77 rtl_set_rfreg(hw, rfpath, addr, mask, data);
72 udelay(1); 78 usleep_range(1, 2);
73 } 79 }
74} 80}
75EXPORT_SYMBOL(rtl_rfreg_delay); 81EXPORT_SYMBOL(rtl_rfreg_delay);
76 82
77void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data) 83void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
78{ 84{
79 if (addr == 0xfe) { 85 if (addr >= 0xf9 && addr <= 0xfe) {
80 mdelay(50); 86 rtl_addr_delay(addr);
81 } else if (addr == 0xfd) {
82 mdelay(5);
83 } else if (addr == 0xfc) {
84 mdelay(1);
85 } else if (addr == 0xfb) {
86 udelay(50);
87 } else if (addr == 0xfa) {
88 udelay(5);
89 } else if (addr == 0xf9) {
90 udelay(1);
91 } else { 87 } else {
92 rtl_set_bbreg(hw, addr, MASKDWORD, data); 88 rtl_set_bbreg(hw, addr, MASKDWORD, data);
93 udelay(1); 89 usleep_range(1, 2);
94 } 90 }
95} 91}
96EXPORT_SYMBOL(rtl_bb_delay); 92EXPORT_SYMBOL(rtl_bb_delay);
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 7f471bff435c..283d608b9973 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -855,7 +855,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
855 } 855 }
856 /* handle command packet here */ 856 /* handle command packet here */
857 if (rtlpriv->cfg->ops->rx_command_packet && 857 if (rtlpriv->cfg->ops->rx_command_packet &&
858 rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { 858 rtlpriv->cfg->ops->rx_command_packet(hw, &stats, skb)) {
859 dev_kfree_skb_any(skb); 859 dev_kfree_skb_any(skb);
860 goto new_trx_end; 860 goto new_trx_end;
861 } 861 }
@@ -2392,7 +2392,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
2392 rtlpriv->cfg->ops->deinit_sw_vars(hw); 2392 rtlpriv->cfg->ops->deinit_sw_vars(hw);
2393 2393
2394 if (rtlpci->irq_alloc) { 2394 if (rtlpci->irq_alloc) {
2395 synchronize_irq(rtlpci->pdev->irq);
2396 free_irq(rtlpci->pdev->irq, hw); 2395 free_irq(rtlpci->pdev->irq, hw);
2397 rtlpci->irq_alloc = 0; 2396 rtlpci->irq_alloc = 0;
2398 } 2397 }
diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c
index 28f7010e7108..1aca77719521 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rc.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rc.c
@@ -41,7 +41,7 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
41 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 41 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
42 struct rtl_phy *rtlphy = &(rtlpriv->phy); 42 struct rtl_phy *rtlphy = &(rtlpriv->phy);
43 struct rtl_sta_info *sta_entry = NULL; 43 struct rtl_sta_info *sta_entry = NULL;
44 u8 wireless_mode = 0; 44 u16 wireless_mode = 0;
45 45
46 /* 46 /*
47 *this rate is no use for true rate, firmware 47 *this rate is no use for true rate, firmware
@@ -99,7 +99,7 @@ static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
99{ 99{
100 struct rtl_mac *mac = rtl_mac(rtlpriv); 100 struct rtl_mac *mac = rtl_mac(rtlpriv);
101 struct rtl_sta_info *sta_entry = NULL; 101 struct rtl_sta_info *sta_entry = NULL;
102 u8 wireless_mode = 0; 102 u16 wireless_mode = 0;
103 u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0; 103 u8 sgi_20 = 0, sgi_40 = 0, sgi_80 = 0;
104 104
105 if (sta) { 105 if (sta) {
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
index 791efbe6b18c..11701064b0e1 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.c
@@ -851,7 +851,7 @@ void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
851} 851}
852 852
853u32 rtl88ee_rx_command_packet(struct ieee80211_hw *hw, 853u32 rtl88ee_rx_command_packet(struct ieee80211_hw *hw,
854 struct rtl_stats status, 854 const struct rtl_stats *status,
855 struct sk_buff *skb) 855 struct sk_buff *skb)
856{ 856{
857 return 0; 857 return 0;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h
index eab5ae0eb46c..5a24d194ac76 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/trx.h
@@ -790,7 +790,7 @@ void rtl88ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
790 bool firstseg, bool lastseg, 790 bool firstseg, bool lastseg,
791 struct sk_buff *skb); 791 struct sk_buff *skb);
792u32 rtl88ee_rx_command_packet(struct ieee80211_hw *hw, 792u32 rtl88ee_rx_command_packet(struct ieee80211_hw *hw,
793 struct rtl_stats status, 793 const struct rtl_stats *status,
794 struct sk_buff *skb); 794 struct sk_buff *skb);
795 795
796#endif 796#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
index bb06fe836fe7..7810fe87dca7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c
@@ -924,19 +924,11 @@ static void _rtl92d_ccxpower_index_check(struct ieee80211_hw *hw,
924 924
925static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl) 925static u8 _rtl92c_phy_get_rightchnlplace(u8 chnl)
926{ 926{
927 u8 channel_5g[59] = {
928 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
929 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
930 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
931 114, 116, 118, 120, 122, 124, 126, 128,
932 130, 132, 134, 136, 138, 140, 149, 151,
933 153, 155, 157, 159, 161, 163, 165
934 };
935 u8 place = chnl; 927 u8 place = chnl;
936 928
937 if (chnl > 14) { 929 if (chnl > 14) {
938 for (place = 14; place < sizeof(channel_5g); place++) { 930 for (place = 14; place < sizeof(channel5g); place++) {
939 if (channel_5g[place] == chnl) { 931 if (channel5g[place] == chnl) {
940 place++; 932 place++;
941 break; 933 break;
942 } 934 }
@@ -2471,16 +2463,9 @@ static bool _rtl92d_is_legal_5g_channel(struct ieee80211_hw *hw, u8 channel)
2471{ 2463{
2472 2464
2473 int i; 2465 int i;
2474 u8 channel_5g[45] = {
2475 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2476 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2477 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
2478 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
2479 161, 163, 165
2480 };
2481 2466
2482 for (i = 0; i < sizeof(channel_5g); i++) 2467 for (i = 0; i < sizeof(channel5g); i++)
2483 if (channel == channel_5g[i]) 2468 if (channel == channel5g[i])
2484 return true; 2469 return true;
2485 return false; 2470 return false;
2486} 2471}
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
index 5f14308e8eb3..9fd3f1b6e4a8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/hw.c
@@ -2018,18 +2018,6 @@ static void _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
2018 struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw)); 2018 struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw));
2019 struct txpower_info_2g pwr2g; 2019 struct txpower_info_2g pwr2g;
2020 struct txpower_info_5g pwr5g; 2020 struct txpower_info_5g pwr5g;
2021 u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
2022 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
2023 56, 58, 60, 62, 64, 100, 102, 104, 106,
2024 108, 110, 112, 114, 116, 118, 120, 122,
2025 124, 126, 128, 130, 132, 134, 136, 138,
2026 140, 142, 144, 149, 151, 153, 155, 157,
2027 159, 161, 163, 165, 167, 168, 169, 171,
2028 173, 175, 177
2029 };
2030 u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2031 42, 58, 106, 122, 138, 155, 171
2032 };
2033 u8 rf, idx; 2021 u8 rf, idx;
2034 u8 i; 2022 u8 i;
2035 2023
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c
index d39ee67f6113..24eff8ea4c2e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.c
@@ -1105,13 +1105,13 @@ void rtl92ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
1105} 1105}
1106 1106
1107u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw, 1107u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw,
1108 struct rtl_stats status, 1108 const struct rtl_stats *status,
1109 struct sk_buff *skb) 1109 struct sk_buff *skb)
1110{ 1110{
1111 u32 result = 0; 1111 u32 result = 0;
1112 struct rtl_priv *rtlpriv = rtl_priv(hw); 1112 struct rtl_priv *rtlpriv = rtl_priv(hw);
1113 1113
1114 switch (status.packet_report_type) { 1114 switch (status->packet_report_type) {
1115 case NORMAL_RX: 1115 case NORMAL_RX:
1116 result = 0; 1116 result = 0;
1117 break; 1117 break;
@@ -1121,7 +1121,7 @@ u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw,
1121 break; 1121 break;
1122 default: 1122 default:
1123 RT_TRACE(rtlpriv, COMP_RECV, DBG_TRACE, 1123 RT_TRACE(rtlpriv, COMP_RECV, DBG_TRACE,
1124 "Unknown packet type %d\n", status.packet_report_type); 1124 "Unknown packet type %d\n", status->packet_report_type);
1125 break; 1125 break;
1126 } 1126 }
1127 1127
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h
index 8f78ac9e6040..a4c38345233e 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/trx.h
@@ -857,6 +857,6 @@ void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
857 bool firstseg, bool lastseg, 857 bool firstseg, bool lastseg,
858 struct sk_buff *skb); 858 struct sk_buff *skb);
859u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw, 859u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw,
860 struct rtl_stats status, 860 const struct rtl_stats *status,
861 struct sk_buff *skb); 861 struct sk_buff *skb);
862#endif 862#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
index 2f7c144d7980..7b4a9b63583b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.c
@@ -710,7 +710,7 @@ void rtl8723e_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
710} 710}
711 711
712u32 rtl8723e_rx_command_packet(struct ieee80211_hw *hw, 712u32 rtl8723e_rx_command_packet(struct ieee80211_hw *hw,
713 struct rtl_stats status, 713 const struct rtl_stats *status,
714 struct sk_buff *skb) 714 struct sk_buff *skb)
715{ 715{
716 return 0; 716 return 0;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h
index 017da7e194d8..32970bf18856 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/trx.h
@@ -716,6 +716,6 @@ void rtl8723e_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
716 bool firstseg, bool lastseg, 716 bool firstseg, bool lastseg,
717 struct sk_buff *skb); 717 struct sk_buff *skb);
718u32 rtl8723e_rx_command_packet(struct ieee80211_hw *hw, 718u32 rtl8723e_rx_command_packet(struct ieee80211_hw *hw,
719 struct rtl_stats status, 719 const struct rtl_stats *status,
720 struct sk_buff *skb); 720 struct sk_buff *skb);
721#endif 721#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c
index 338ec9a9d09b..60345975f9fd 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.c
@@ -758,13 +758,13 @@ void rtl8723be_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
758} 758}
759 759
760u32 rtl8723be_rx_command_packet(struct ieee80211_hw *hw, 760u32 rtl8723be_rx_command_packet(struct ieee80211_hw *hw,
761 struct rtl_stats status, 761 const struct rtl_stats *status,
762 struct sk_buff *skb) 762 struct sk_buff *skb)
763{ 763{
764 u32 result = 0; 764 u32 result = 0;
765 struct rtl_priv *rtlpriv = rtl_priv(hw); 765 struct rtl_priv *rtlpriv = rtl_priv(hw);
766 766
767 switch (status.packet_report_type) { 767 switch (status->packet_report_type) {
768 case NORMAL_RX: 768 case NORMAL_RX:
769 result = 0; 769 result = 0;
770 break; 770 break;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h
index 45949ac4854c..40c36607b8b9 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/trx.h
@@ -620,6 +620,6 @@ void rtl8723be_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
620 bool firstseg, bool lastseg, 620 bool firstseg, bool lastseg,
621 struct sk_buff *skb); 621 struct sk_buff *skb);
622u32 rtl8723be_rx_command_packet(struct ieee80211_hw *hw, 622u32 rtl8723be_rx_command_packet(struct ieee80211_hw *hw,
623 struct rtl_stats status, 623 const struct rtl_stats *status,
624 struct sk_buff *skb); 624 struct sk_buff *skb);
625#endif 625#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
index 525eb234627c..a4fc70e8c9c0 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c
@@ -271,7 +271,7 @@ int rtl8821ae_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw)
271 271
272 err = _rtl8821ae_fw_free_to_go(hw); 272 err = _rtl8821ae_fw_free_to_go(hw);
273 if (err) { 273 if (err) {
274 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 274 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
275 "Firmware is not ready to run!\n"); 275 "Firmware is not ready to run!\n");
276 } else { 276 } else {
277 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, 277 RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD,
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index bbb789f8990b..fe900badd468 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -2786,14 +2786,6 @@ static void _rtl8812ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
2786 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2786 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2787 struct txpower_info_2g pwrinfo24g; 2787 struct txpower_info_2g pwrinfo24g;
2788 struct txpower_info_5g pwrinfo5g; 2788 struct txpower_info_5g pwrinfo5g;
2789 u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
2790 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
2791 56, 58, 60, 62, 64, 100, 102, 104, 106,
2792 108, 110, 112, 114, 116, 118, 120, 122,
2793 124, 126, 128, 130, 132, 134, 136, 138,
2794 140, 142, 144, 149, 151, 153, 155, 157,
2795 159, 161, 163, 165, 167, 168, 169, 171, 173, 175, 177};
2796 u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {42, 58, 106, 122, 138, 155, 171};
2797 u8 rf_path, index; 2789 u8 rf_path, index;
2798 u8 i; 2790 u8 i;
2799 2791
@@ -2872,16 +2864,6 @@ static void _rtl8821ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
2872 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2864 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2873 struct txpower_info_2g pwrinfo24g; 2865 struct txpower_info_2g pwrinfo24g;
2874 struct txpower_info_5g pwrinfo5g; 2866 struct txpower_info_5g pwrinfo5g;
2875 u8 channel5g[CHANNEL_MAX_NUMBER_5G] = {
2876 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
2877 56, 58, 60, 62, 64, 100, 102, 104, 106,
2878 108, 110, 112, 114, 116, 118, 120, 122,
2879 124, 126, 128, 130, 132, 134, 136, 138,
2880 140, 142, 144, 149, 151, 153, 155, 157,
2881 159, 161, 163, 165, 167, 168, 169, 171,
2882 173, 175, 177};
2883 u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2884 42, 58, 106, 122, 138, 155, 171};
2885 u8 rf_path, index; 2867 u8 rf_path, index;
2886 u8 i; 2868 u8 i;
2887 2869
@@ -3855,7 +3837,7 @@ void rtl8821ae_update_channel_access_setting(struct ieee80211_hw *hw)
3855{ 3837{
3856 struct rtl_priv *rtlpriv = rtl_priv(hw); 3838 struct rtl_priv *rtlpriv = rtl_priv(hw);
3857 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 3839 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3858 u8 wireless_mode = mac->mode; 3840 u16 wireless_mode = mac->mode;
3859 u8 sifs_timer, r2t_sifs; 3841 u8 sifs_timer, r2t_sifs;
3860 3842
3861 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 3843 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
index 9b4d8a637915..74165b3eb362 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
@@ -1472,18 +1472,13 @@ static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1472{ 1472{
1473 struct rtl_priv *rtlpriv = rtl_priv(hw); 1473 struct rtl_priv *rtlpriv = rtl_priv(hw);
1474 char channel_index = -1; 1474 char channel_index = -1;
1475 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1476 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1477 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1478 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1479 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1480 173, 175, 177};
1481 u8 i = 0; 1475 u8 i = 0;
1476
1482 if (band == BAND_ON_2_4G) 1477 if (band == BAND_ON_2_4G)
1483 channel_index = channel - 1; 1478 channel_index = channel - 1;
1484 else if (band == BAND_ON_5G) { 1479 else if (band == BAND_ON_5G) {
1485 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) { 1480 for (i = 0; i < sizeof(channel5g)/sizeof(u8); ++i) {
1486 if (channel_5g[i] == channel) 1481 if (channel5g[i] == channel)
1487 channel_index = i; 1482 channel_index = i;
1488 } 1483 }
1489 } else 1484 } else
@@ -2240,13 +2235,6 @@ void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2240 2235
2241static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index) 2236static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2242{ 2237{
2243 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2244 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2245 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2246 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2247 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2248 167, 168, 169, 171, 173, 175, 177
2249 };
2250 u8 i = 0; 2238 u8 i = 0;
2251 bool in_24g = true; 2239 bool in_24g = true;
2252 2240
@@ -2257,7 +2245,7 @@ static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2257 in_24g = false; 2245 in_24g = false;
2258 2246
2259 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) { 2247 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2260 if (channel_5g[i] == channel) { 2248 if (channel5g[i] == channel) {
2261 *chnl_index = i; 2249 *chnl_index = i;
2262 return in_24g; 2250 return in_24g;
2263 } 2251 }
@@ -2728,13 +2716,10 @@ static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2728 rate <= DESC_RATEVHT2SS_MCS9)) 2716 rate <= DESC_RATEVHT2SS_MCS9))
2729 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S]; 2717 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2730 } else if (bandwidth == HT_CHANNEL_WIDTH_80) { 2718 } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2731 u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2732 42, 58, 106, 122, 138, 155, 171
2733 };
2734 u8 i; 2719 u8 i;
2735 2720
2736 for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i) 2721 for (i = 0; i < sizeof(channel5g_80m) / sizeof(u8); ++i)
2737 if (channel_5g_80m[i] == channel) 2722 if (channel5g_80m[i] == channel)
2738 index = i; 2723 index = i;
2739 2724
2740 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2725 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
index 174743aef943..41efaa148d13 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.c
@@ -998,13 +998,13 @@ void rtl8821ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
998} 998}
999 999
1000u32 rtl8821ae_rx_command_packet(struct ieee80211_hw *hw, 1000u32 rtl8821ae_rx_command_packet(struct ieee80211_hw *hw,
1001 struct rtl_stats status, 1001 const struct rtl_stats *status,
1002 struct sk_buff *skb) 1002 struct sk_buff *skb)
1003{ 1003{
1004 u32 result = 0; 1004 u32 result = 0;
1005 struct rtl_priv *rtlpriv = rtl_priv(hw); 1005 struct rtl_priv *rtlpriv = rtl_priv(hw);
1006 1006
1007 switch (status.packet_report_type) { 1007 switch (status->packet_report_type) {
1008 case NORMAL_RX: 1008 case NORMAL_RX:
1009 result = 0; 1009 result = 0;
1010 break; 1010 break;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
index 31409042d8dd..ad565bebf1d5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
@@ -615,6 +615,6 @@ void rtl8821ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
615 bool firstseg, bool lastseg, 615 bool firstseg, bool lastseg,
616 struct sk_buff *skb); 616 struct sk_buff *skb);
617u32 rtl8821ae_rx_command_packet(struct ieee80211_hw *hw, 617u32 rtl8821ae_rx_command_packet(struct ieee80211_hw *hw,
618 struct rtl_stats status, 618 const struct rtl_stats *status,
619 struct sk_buff *skb); 619 struct sk_buff *skb);
620#endif 620#endif
diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
index 4544752a2ba8..554d81420f19 100644
--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
+++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
@@ -116,17 +116,12 @@
116 116
117#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ 117#define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */
118#define CHANNEL_MAX_NUMBER_2G 14 118#define CHANNEL_MAX_NUMBER_2G 14
119#define CHANNEL_MAX_NUMBER_5G 54 /* Please refer to 119#define CHANNEL_MAX_NUMBER_5G 49 /* Please refer to
120 *"phy_GetChnlGroup8812A" and 120 *"phy_GetChnlGroup8812A" and
121 * "Hal_ReadTxPowerInfo8812A" 121 * "Hal_ReadTxPowerInfo8812A"
122 */ 122 */
123#define CHANNEL_MAX_NUMBER_5G_80M 7 123#define CHANNEL_MAX_NUMBER_5G_80M 7
124#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ 124#define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */
125#define CHANNEL_MAX_NUMBER_5G 54 /* Please refer to
126 *"phy_GetChnlGroup8812A" and
127 * "Hal_ReadTxPowerInfo8812A"
128 */
129#define CHANNEL_MAX_NUMBER_5G_80M 7
130#define MAX_PG_GROUP 13 125#define MAX_PG_GROUP 13
131#define CHANNEL_GROUP_MAX_2G 3 126#define CHANNEL_GROUP_MAX_2G 3
132#define CHANNEL_GROUP_IDX_5GL 3 127#define CHANNEL_GROUP_IDX_5GL 3
@@ -1323,14 +1318,13 @@ struct rtl_tid_data {
1323 1318
1324struct rtl_sta_info { 1319struct rtl_sta_info {
1325 struct list_head list; 1320 struct list_head list;
1326 u8 ratr_index;
1327 u8 wireless_mode;
1328 u8 mimo_ps;
1329 u8 mac_addr[ETH_ALEN];
1330 struct rtl_tid_data tids[MAX_TID_COUNT]; 1321 struct rtl_tid_data tids[MAX_TID_COUNT];
1331
1332 /* just used for ap adhoc or mesh*/ 1322 /* just used for ap adhoc or mesh*/
1333 struct rssi_sta rssi_stat; 1323 struct rssi_sta rssi_stat;
1324 u16 wireless_mode;
1325 u8 ratr_index;
1326 u8 mimo_ps;
1327 u8 mac_addr[ETH_ALEN];
1334} __packed; 1328} __packed;
1335 1329
1336struct rtl_priv; 1330struct rtl_priv;
@@ -2194,7 +2188,7 @@ struct rtl_hal_ops {
2194 bool (*get_btc_status) (void); 2188 bool (*get_btc_status) (void);
2195 bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr); 2189 bool (*is_fw_header)(struct rtlwifi_firmware_header *hdr);
2196 u32 (*rx_command_packet)(struct ieee80211_hw *hw, 2190 u32 (*rx_command_packet)(struct ieee80211_hw *hw,
2197 struct rtl_stats status, struct sk_buff *skb); 2191 const struct rtl_stats *status, struct sk_buff *skb);
2198 void (*add_wowlan_pattern)(struct ieee80211_hw *hw, 2192 void (*add_wowlan_pattern)(struct ieee80211_hw *hw,
2199 struct rtl_wow_pattern *rtl_pattern, 2193 struct rtl_wow_pattern *rtl_pattern,
2200 u8 index); 2194 u8 index);
@@ -2904,6 +2898,10 @@ value to host byte ordering.*/
2904#define STBC_VHT_TEST_TX_ENABLE BIT(2) 2898#define STBC_VHT_TEST_TX_ENABLE BIT(2)
2905#define STBC_VHT_CAP_TX BIT(3) 2899#define STBC_VHT_CAP_TX BIT(3)
2906 2900
2901extern u8 channel5g[CHANNEL_MAX_NUMBER_5G];
2902
2903extern u8 channel5g_80m[CHANNEL_MAX_NUMBER_5G_80M];
2904
2907static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) 2905static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
2908{ 2906{
2909 return rtlpriv->io.read8_sync(rtlpriv, addr); 2907 return rtlpriv->io.read8_sync(rtlpriv, addr);
diff --git a/drivers/net/wireless/st/cw1200/cw1200_spi.c b/drivers/net/wireless/st/cw1200/cw1200_spi.c
index a740083634d8..63f95e9c2992 100644
--- a/drivers/net/wireless/st/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/st/cw1200/cw1200_spi.c
@@ -446,8 +446,7 @@ static int cw1200_spi_disconnect(struct spi_device *func)
446 return 0; 446 return 0;
447} 447}
448 448
449#ifdef CONFIG_PM 449static int __maybe_unused cw1200_spi_suspend(struct device *dev)
450static int cw1200_spi_suspend(struct device *dev)
451{ 450{
452 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev)); 451 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
453 452
@@ -460,16 +459,12 @@ static int cw1200_spi_suspend(struct device *dev)
460 459
461static SIMPLE_DEV_PM_OPS(cw1200_pm_ops, cw1200_spi_suspend, NULL); 460static SIMPLE_DEV_PM_OPS(cw1200_pm_ops, cw1200_spi_suspend, NULL);
462 461
463#endif
464
465static struct spi_driver spi_driver = { 462static struct spi_driver spi_driver = {
466 .probe = cw1200_spi_probe, 463 .probe = cw1200_spi_probe,
467 .remove = cw1200_spi_disconnect, 464 .remove = cw1200_spi_disconnect,
468 .driver = { 465 .driver = {
469 .name = "cw1200_wlan_spi", 466 .name = "cw1200_wlan_spi",
470#ifdef CONFIG_PM 467 .pm = IS_ENABLED(CONFIG_PM) ? &cw1200_pm_ops : NULL,
471 .pm = &cw1200_pm_ops,
472#endif
473 }, 468 },
474}; 469};
475 470
diff --git a/drivers/net/wireless/st/cw1200/pm.h b/drivers/net/wireless/st/cw1200/pm.h
index 3ed90ff22bb8..534548470ebc 100644
--- a/drivers/net/wireless/st/cw1200/pm.h
+++ b/drivers/net/wireless/st/cw1200/pm.h
@@ -31,13 +31,18 @@ int cw1200_pm_init(struct cw1200_pm_state *pm,
31void cw1200_pm_deinit(struct cw1200_pm_state *pm); 31void cw1200_pm_deinit(struct cw1200_pm_state *pm);
32int cw1200_wow_suspend(struct ieee80211_hw *hw, 32int cw1200_wow_suspend(struct ieee80211_hw *hw,
33 struct cfg80211_wowlan *wowlan); 33 struct cfg80211_wowlan *wowlan);
34int cw1200_wow_resume(struct ieee80211_hw *hw);
35int cw1200_can_suspend(struct cw1200_common *priv); 34int cw1200_can_suspend(struct cw1200_common *priv);
35int cw1200_wow_resume(struct ieee80211_hw *hw);
36void cw1200_pm_stay_awake(struct cw1200_pm_state *pm, 36void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
37 unsigned long tmo); 37 unsigned long tmo);
38#else 38#else
39static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm, 39static inline void cw1200_pm_stay_awake(struct cw1200_pm_state *pm,
40 unsigned long tmo) { 40 unsigned long tmo)
41{
42}
43static inline int cw1200_can_suspend(struct cw1200_common *priv)
44{
45 return 0;
41} 46}
42#endif 47#endif
43#endif 48#endif
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 700d0c6f7480..846513c73606 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -576,13 +576,11 @@ struct bcma_chipcommon_pmu {
576 u32 crystalfreq; /* The active crystal frequency (in kHz) */ 576 u32 crystalfreq; /* The active crystal frequency (in kHz) */
577}; 577};
578 578
579#ifdef CONFIG_BCMA_DRIVER_MIPS 579#ifdef CONFIG_BCMA_PFLASH
580struct bcma_pflash { 580struct bcma_pflash {
581 bool present; 581 bool present;
582 u8 buswidth;
583 u32 window;
584 u32 window_size;
585}; 582};
583#endif
586 584
587#ifdef CONFIG_BCMA_SFLASH 585#ifdef CONFIG_BCMA_SFLASH
588struct mtd_info; 586struct mtd_info;
@@ -606,6 +604,7 @@ struct bcma_nflash {
606}; 604};
607#endif 605#endif
608 606
607#ifdef CONFIG_BCMA_DRIVER_MIPS
609struct bcma_serial_port { 608struct bcma_serial_port {
610 void *regs; 609 void *regs;
611 unsigned long clockspeed; 610 unsigned long clockspeed;
@@ -625,8 +624,9 @@ struct bcma_drv_cc {
625 /* Fast Powerup Delay constant */ 624 /* Fast Powerup Delay constant */
626 u16 fast_pwrup_delay; 625 u16 fast_pwrup_delay;
627 struct bcma_chipcommon_pmu pmu; 626 struct bcma_chipcommon_pmu pmu;
628#ifdef CONFIG_BCMA_DRIVER_MIPS 627#ifdef CONFIG_BCMA_PFLASH
629 struct bcma_pflash pflash; 628 struct bcma_pflash pflash;
629#endif
630#ifdef CONFIG_BCMA_SFLASH 630#ifdef CONFIG_BCMA_SFLASH
631 struct bcma_sflash sflash; 631 struct bcma_sflash sflash;
632#endif 632#endif
@@ -634,6 +634,7 @@ struct bcma_drv_cc {
634 struct bcma_nflash nflash; 634 struct bcma_nflash nflash;
635#endif 635#endif
636 636
637#ifdef CONFIG_BCMA_DRIVER_MIPS
637 int nr_serial_ports; 638 int nr_serial_ports;
638 struct bcma_serial_port serial_ports[4]; 639 struct bcma_serial_port serial_ports[4];
639#endif /* CONFIG_BCMA_DRIVER_MIPS */ 640#endif /* CONFIG_BCMA_DRIVER_MIPS */
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h
deleted file mode 100644
index e75dcbf2b230..000000000000
--- a/include/linux/platform_data/brcmfmac-sdio.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
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 ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _LINUX_BRCMFMAC_PLATFORM_H
18#define _LINUX_BRCMFMAC_PLATFORM_H
19
20/*
21 * Platform specific driver functions and data. Through the platform specific
22 * device data functions can be provided to help the brcmfmac driver to
23 * operate with the device in combination with the used platform.
24 *
25 * Use the platform data in the following (similar) way:
26 *
27 *
28#include <brcmfmac_platform.h>
29
30
31static void brcmfmac_power_on(void)
32{
33}
34
35static void brcmfmac_power_off(void)
36{
37}
38
39static void brcmfmac_reset(void)
40{
41}
42
43static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = {
44 .power_on = brcmfmac_power_on,
45 .power_off = brcmfmac_power_off,
46 .reset = brcmfmac_reset
47};
48
49static struct platform_device brcmfmac_device = {
50 .name = BRCMFMAC_SDIO_PDATA_NAME,
51 .id = PLATFORM_DEVID_NONE,
52 .dev.platform_data = &brcmfmac_sdio_pdata
53};
54
55void __init brcmfmac_init_pdata(void)
56{
57 brcmfmac_sdio_pdata.oob_irq_supported = true;
58 brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB);
59 brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ |
60 IORESOURCE_IRQ_HIGHLEVEL;
61 platform_device_register(&brcmfmac_device);
62}
63 *
64 *
65 * Note: the brcmfmac can be loaded as module or be statically built-in into
66 * the kernel. If built-in then do note that it uses module_init (and
67 * module_exit) routines which equal device_initcall. So if you intend to
68 * create a module with the platform specific data for the brcmfmac and have
69 * it built-in to the kernel then use a higher initcall then device_initcall
70 * (see init.h). If this is not done then brcmfmac will load without problems
71 * but will not pickup the platform data.
72 *
73 * When the driver does not "detect" platform driver data then it will continue
74 * without reporting anything and just assume there is no data needed. Which is
75 * probably true for most platforms.
76 *
77 * Explanation of the platform_data fields:
78 *
79 * drive_strength: is the preferred drive_strength to be used for the SDIO
80 * pins. If 0 then a default value will be used. This is the target drive
81 * strength, the exact drive strength which will be used depends on the
82 * capabilities of the device.
83 *
84 * oob_irq_supported: does the board have support for OOB interrupts. SDIO
85 * in-band interrupts are relatively slow and for having less overhead on
86 * interrupt processing an out of band interrupt can be used. If the HW
87 * supports this then enable this by setting this field to true and configure
88 * the oob related fields.
89 *
90 * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are
91 * used for registering the irq using request_irq function.
92 *
93 * broken_sg_support: flag for broken sg list support of SDIO host controller.
94 * Set this to true if the SDIO host controller has higher align requirement
95 * than 32 bytes for each scatterlist item.
96 *
97 * sd_head_align: alignment requirement for start of data buffer
98 *
99 * sd_sgentry_align: length alignment requirement for each sg entry
100 *
101 * power_on: This function is called by the brcmfmac when the module gets
102 * loaded. This can be particularly useful for low power devices. The platform
103 * spcific routine may for example decide to power up the complete device.
104 * If there is no use-case for this function then provide NULL.
105 *
106 * power_off: This function is called by the brcmfmac when the module gets
107 * unloaded. At this point the device can be powered down or otherwise be reset.
108 * So if an actual power_off is not supported but reset is then reset the device
109 * when this function gets called. This can be particularly useful for low power
110 * devices. If there is no use-case for this function (either power-down or
111 * reset) then provide NULL.
112 *
113 * reset: This function can get called if the device communication broke down.
114 * This functionality is particularly useful in case of SDIO type devices. It is
115 * possible to reset a dongle via sdio data interface, but it requires that
116 * this is fully functional. This function is chip/module specific and this
117 * function should return only after the complete reset has completed.
118 */
119
120#define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio"
121
122struct brcmfmac_sdio_platform_data {
123 unsigned int drive_strength;
124 bool oob_irq_supported;
125 unsigned int oob_irq_nr;
126 unsigned long oob_irq_flags;
127 bool broken_sg_support;
128 unsigned short sd_head_align;
129 unsigned short sd_sgentry_align;
130 void (*power_on)(void);
131 void (*power_off)(void);
132 void (*reset)(void);
133};
134
135#endif /* _LINUX_BRCMFMAC_PLATFORM_H */
diff --git a/include/linux/platform_data/brcmfmac.h b/include/linux/platform_data/brcmfmac.h
new file mode 100644
index 000000000000..1d30bf278231
--- /dev/null
+++ b/include/linux/platform_data/brcmfmac.h
@@ -0,0 +1,185 @@
1/*
2 * Copyright (c) 201 Broadcom Corporation
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 ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _LINUX_BRCMFMAC_PLATFORM_H
18#define _LINUX_BRCMFMAC_PLATFORM_H
19
20
21#define BRCMFMAC_PDATA_NAME "brcmfmac"
22
23#define BRCMFMAC_COUNTRY_BUF_SZ 4
24
25
26/*
27 * Platform specific driver functions and data. Through the platform specific
28 * device data functions and data can be provided to help the brcmfmac driver to
29 * operate with the device in combination with the used platform.
30 */
31
32
33/**
34 * Note: the brcmfmac can be loaded as module or be statically built-in into
35 * the kernel. If built-in then do note that it uses module_init (and
36 * module_exit) routines which equal device_initcall. So if you intend to
37 * create a module with the platform specific data for the brcmfmac and have
38 * it built-in to the kernel then use a higher initcall then device_initcall
39 * (see init.h). If this is not done then brcmfmac will load without problems
40 * but will not pickup the platform data.
41 *
42 * When the driver does not "detect" platform driver data then it will continue
43 * without reporting anything and just assume there is no data needed. Which is
44 * probably true for most platforms.
45 */
46
47/**
48 * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are
49 * supported.
50 */
51enum brcmf_bus_type {
52 BRCMF_BUSTYPE_SDIO,
53 BRCMF_BUSTYPE_USB,
54 BRCMF_BUSTYPE_PCIE
55};
56
57
58/**
59 * struct brcmfmac_sdio_pd - SDIO Device specific platform data.
60 *
61 * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be
62 * used.
63 * @drive_strength: is the preferred drive_strength to be used for the SDIO
64 * pins. If 0 then a default value will be used. This is
65 * the target drive strength, the exact drive strength
66 * which will be used depends on the capabilities of the
67 * device.
68 * @oob_irq_supported: does the board have support for OOB interrupts. SDIO
69 * in-band interrupts are relatively slow and for having
70 * less overhead on interrupt processing an out of band
71 * interrupt can be used. If the HW supports this then
72 * enable this by setting this field to true and configure
73 * the oob related fields.
74 * @oob_irq_nr,
75 * @oob_irq_flags: the OOB interrupt information. The values are used for
76 * registering the irq using request_irq function.
77 * @broken_sg_support: flag for broken sg list support of SDIO host controller.
78 * Set this to true if the SDIO host controller has higher
79 * align requirement than 32 bytes for each scatterlist
80 * item.
81 * @sd_head_align: alignment requirement for start of data buffer.
82 * @sd_sgentry_align: length alignment requirement for each sg entry.
83 * @reset: This function can get called if the device communication
84 * broke down. This functionality is particularly useful in
85 * case of SDIO type devices. It is possible to reset a
86 * dongle via sdio data interface, but it requires that
87 * this is fully functional. This function is chip/module
88 * specific and this function should return only after the
89 * complete reset has completed.
90 */
91struct brcmfmac_sdio_pd {
92 int txglomsz;
93 unsigned int drive_strength;
94 bool oob_irq_supported;
95 unsigned int oob_irq_nr;
96 unsigned long oob_irq_flags;
97 bool broken_sg_support;
98 unsigned short sd_head_align;
99 unsigned short sd_sgentry_align;
100 void (*reset)(void);
101};
102
103/**
104 * struct brcmfmac_pd_cc_entry - Struct for translating user space country code
105 * (iso3166) to firmware country code and
106 * revision.
107 *
108 * @iso3166: iso3166 alpha 2 country code string.
109 * @cc: firmware country code string.
110 * @rev: firmware country code revision.
111 */
112struct brcmfmac_pd_cc_entry {
113 char iso3166[BRCMFMAC_COUNTRY_BUF_SZ];
114 char cc[BRCMFMAC_COUNTRY_BUF_SZ];
115 s32 rev;
116};
117
118/**
119 * struct brcmfmac_pd_cc - Struct for translating country codes as set by user
120 * space to a country code and rev which can be used by
121 * firmware.
122 *
123 * @table_size: number of entries in table (> 0)
124 * @table: array of 1 or more elements with translation information.
125 */
126struct brcmfmac_pd_cc {
127 int table_size;
128 struct brcmfmac_pd_cc_entry table[0];
129};
130
131/**
132 * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type)
133 * is the unique identifier of the device.
134 *
135 * @id: ID of the device for which this data is. In case of SDIO
136 * or PCIE this is the chipid as identified by chip.c In
137 * case of USB this is the chipid as identified by the
138 * device query.
139 * @rev: chip revision, see id.
140 * @bus_type: The type of bus. Some chipid/rev exist for different bus
141 * types. Each bus type has its own set of settings.
142 * @feature_disable: Bitmask of features to disable (override), See feature.c
143 * in brcmfmac for details.
144 * @country_codes: If available, pointer to struct for translating country
145 * codes.
146 * @bus: Bus specific (union) device settings. Currently only
147 * SDIO.
148 */
149struct brcmfmac_pd_device {
150 unsigned int id;
151 unsigned int rev;
152 enum brcmf_bus_type bus_type;
153 unsigned int feature_disable;
154 struct brcmfmac_pd_cc *country_codes;
155 union {
156 struct brcmfmac_sdio_pd sdio;
157 } bus;
158};
159
160/**
161 * struct brcmfmac_platform_data - BRCMFMAC specific platform data.
162 *
163 * @power_on: This function is called by the brcmfmac driver when the module
164 * gets loaded. This can be particularly useful for low power
165 * devices. The platform spcific routine may for example decide to
166 * power up the complete device. If there is no use-case for this
167 * function then provide NULL.
168 * @power_off: This function is called by the brcmfmac when the module gets
169 * unloaded. At this point the devices can be powered down or
170 * otherwise be reset. So if an actual power_off is not supported
171 * but reset is supported by the devices then reset the devices
172 * when this function gets called. This can be particularly useful
173 * for low power devices. If there is no use-case for this
174 * function then provide NULL.
175 */
176struct brcmfmac_platform_data {
177 void (*power_on)(void);
178 void (*power_off)(void);
179 char *fw_alternative_path;
180 int device_count;
181 struct brcmfmac_pd_device devices[0];
182};
183
184
185#endif /* _LINUX_BRCMFMAC_PLATFORM_H */