aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-01-26 19:09:45 -0500
committerDavid S. Miller <davem@davemloft.net>2015-01-26 19:09:45 -0500
commit9c5d94bc18782ab3c48aa2df4ad6c451286a7bb3 (patch)
tree4fc63e45729fe4cba491c9a7abc9d9e9f72372f2
parentfd3e646c87ab3f2ba98aa25394581af27cc78dc5 (diff)
parentc5ed1df781cb544d4e4d189bb5b6ec7336d8888c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== pull-request: wireless-drivers-next 2015-01-22 now a bigger pull request for net-next. Rafal found a UTF-8 bug in patchwork[1] and because of that two commits (d0c102f70aec and d0f66df5392a) have his name corrupted: Acked-by: Rafa? Mi?ecki <zajec5@gmail.com> Somehow I failed to spot that when I commited the patches. As rebasing public git trees is bad, I thought we can live with these and decided not to rebase. But I'll pay close attention to this in the future to make sure that it won't happen again. Also we requested an update to patchwork.kernel.org, the latest patchwork doesn't seem to have this bug. Also please note this pull request also adds one DT binding doc, but this was reviewed in the device tree list: .../bindings/net/wireless/qcom,ath10k.txt | 30 + Please let me know if you have any issues. [1] https://lists.ozlabs.org/pipermail/patchwork/2015-January/001261.html ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt30
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/bcma/bcma_private.h10
-rw-r--r--drivers/bcma/driver_chipcommon.c10
-rw-r--r--drivers/bcma/host_soc.c2
-rw-r--r--drivers/bcma/main.c49
-rw-r--r--drivers/bcma/scan.c67
-rw-r--r--drivers/net/wireless/adm8211.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c250
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h21
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c88
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h30
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c192
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c31
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h5
-rw-r--r--drivers/net/wireless/ath/ath10k/spectral.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/testmode.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.c243
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.h58
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h860
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c2222
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h1380
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c1731
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h302
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c80
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c61
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c47
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h19
-rw-r--r--drivers/net/wireless/ath/ath9k/ar956x_initvals.h1046
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c134
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c85
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c77
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c3
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c16
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c73
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.c83
-rw-r--r--drivers/net/wireless/ath/wcn36xx/txrx.h9
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h20
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c164
-rw-r--r--drivers/net/wireless/ath/wil6210/ethtool.c46
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c109
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c194
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c65
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c275
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c70
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h158
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h161
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c221
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h12
-rw-r--r--drivers/net/wireless/atmel.c12
-rw-r--r--drivers/net/wireless/b43/main.c1
-rw-r--r--drivers/net/wireless/b43legacy/radio.c19
-rw-r--r--drivers/net/wireless/b43legacy/radio.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c20
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c185
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c15
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/common.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/common.h20
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h14
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c7
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h12
-rw-r--r--drivers/net/wireless/cw1200/main.c5
-rw-r--r--drivers/net/wireless/cw1200/pm.c5
-rw-r--r--drivers/net/wireless/cw1200/queue.c4
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c4
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c24
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c31
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h43
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h33
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c51
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c33
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c247
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h20
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h277
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h301
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c116
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c325
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h67
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c55
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c340
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c97
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c23
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c73
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h8
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c73
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c48
-rw-r--r--drivers/net/wireless/mwifiex/11n.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.h14
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c15
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c14
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c107
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c18
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c6
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c281
-rw-r--r--drivers/net/wireless/mwifiex/decl.h34
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c16
-rw-r--r--drivers/net/wireless/mwifiex/fw.h3
-rw-r--r--drivers/net/wireless/mwifiex/init.c23
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h11
-rw-r--r--drivers/net/wireless/mwifiex/main.c133
-rw-r--r--drivers/net/wireless/mwifiex/main.h24
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c6
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c104
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h26
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c7
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c7
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c6
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c9
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c19
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c35
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c28
-rw-r--r--drivers/net/wireless/mwifiex/usb.c11
-rw-r--r--drivers/net/wireless/mwifiex/usb.h7
-rw-r--r--drivers/net/wireless/mwifiex/util.c220
-rw-r--r--drivers/net/wireless/mwifiex/util.h20
-rw-r--r--drivers/net/wireless/orinoco/Kconfig3
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c4
-rw-r--r--drivers/net/wireless/p54/fwio.c9
-rw-r--r--drivers/net/wireless/p54/p54pci.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00firmware.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c18
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c8
-rw-r--r--drivers/net/wireless/rtlwifi/core.c37
-rw-r--r--drivers/net/wireless/rtlwifi/core.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c36
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.h41
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c45
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.c1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/dm.h13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.c33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/dm.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/dm.c55
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/dm.h16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.h28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.c42
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/dm.h38
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.c55
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/dm.h33
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c10
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/dm.c58
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/dm.h41
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h2
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c4
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.c88
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.h46
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.c93
-rw-r--r--drivers/net/wireless/ti/wl18xx/cmd.h27
-rw-r--r--drivers/net/wireless/ti/wl18xx/conf.h23
-rw-r--r--drivers/net/wireless/ti/wl18xx/debugfs.c43
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.c21
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.h14
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c37
-rw-r--r--drivers/net/wireless/ti/wl18xx/wl18xx.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c20
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h8
-rw-r--r--drivers/net/wireless/ti/wlcore/conf.h7
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h48
-rw-r--r--drivers/net/wireless/ti/wlcore/init.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c383
-rw-r--r--drivers/net/wireless/ti/wlcore/ps.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/vendor_cmd.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h12
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h7
-rw-r--r--include/linux/bcma/bcma_soc.h2
-rw-r--r--include/linux/mmc/sdio_ids.h6
233 files changed, 13702 insertions, 3323 deletions
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
new file mode 100644
index 000000000000..edefc26c6204
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath10k.txt
@@ -0,0 +1,30 @@
1* Qualcomm Atheros ath10k wireless devices
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:
7-compatible : Should be "qcom,ath10k"
8
9Optional properties:
10- qcom,ath10k-calibration-data : calibration data as an array, the
11 length can vary between hw versions
12
13
14Example:
15
16pci {
17 pcie@0 {
18 reg = <0 0 0 0 0>;
19 #interrupt-cells = <1>;
20 #size-cells = <2>;
21 #address-cells = <3>;
22 device_type = "pci";
23
24 ath10k@0,0 {
25 reg = <0 0 0 0 0>;
26 device_type = "pci";
27 qcom,ath10k-calibration-data = [ 01 02 03 ... ];
28 };
29 };
30};
diff --git a/MAINTAINERS b/MAINTAINERS
index e1ff4ce5bcab..aca34098415d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1657,7 +1657,6 @@ M: Jiri Slaby <jirislaby@gmail.com>
1657M: Nick Kossifidis <mickflemm@gmail.com> 1657M: Nick Kossifidis <mickflemm@gmail.com>
1658M: "Luis R. Rodriguez" <mcgrof@do-not-panic.com> 1658M: "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
1659L: linux-wireless@vger.kernel.org 1659L: linux-wireless@vger.kernel.org
1660L: ath5k-devel@lists.ath5k.org
1661W: http://wireless.kernel.org/en/users/Drivers/ath5k 1660W: http://wireless.kernel.org/en/users/Drivers/ath5k
1662S: Maintained 1661S: Maintained
1663F: drivers/net/wireless/ath/ath5k/ 1662F: drivers/net/wireless/ath/ath5k/
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 314ae4032f3e..3f314c98d089 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -25,22 +25,18 @@ struct bcma_bus;
25bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, 25bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
26 int timeout); 26 int timeout);
27void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core); 27void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core);
28void bcma_init_bus(struct bcma_bus *bus);
28int bcma_bus_register(struct bcma_bus *bus); 29int bcma_bus_register(struct bcma_bus *bus);
29void bcma_bus_unregister(struct bcma_bus *bus); 30void bcma_bus_unregister(struct bcma_bus *bus);
30int __init bcma_bus_early_register(struct bcma_bus *bus, 31int __init bcma_bus_early_register(struct bcma_bus *bus);
31 struct bcma_device *core_cc,
32 struct bcma_device *core_mips);
33#ifdef CONFIG_PM 32#ifdef CONFIG_PM
34int bcma_bus_suspend(struct bcma_bus *bus); 33int bcma_bus_suspend(struct bcma_bus *bus);
35int bcma_bus_resume(struct bcma_bus *bus); 34int bcma_bus_resume(struct bcma_bus *bus);
36#endif 35#endif
37 36
38/* scan.c */ 37/* scan.c */
38void bcma_detect_chip(struct bcma_bus *bus);
39int bcma_bus_scan(struct bcma_bus *bus); 39int bcma_bus_scan(struct bcma_bus *bus);
40int __init bcma_bus_scan_early(struct bcma_bus *bus,
41 struct bcma_device_id *match,
42 struct bcma_device *core);
43void bcma_init_bus(struct bcma_bus *bus);
44 40
45/* sprom.c */ 41/* sprom.c */
46int bcma_sprom_get(struct bcma_bus *bus); 42int bcma_sprom_get(struct bcma_bus *bus);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 19f679667ca4..84d4a95e6caf 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -79,7 +79,9 @@ static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
79 79
80 if (cc->capabilities & BCMA_CC_CAP_PMU) { 80 if (cc->capabilities & BCMA_CC_CAP_PMU) {
81 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) 81 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
82 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */ 82 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP
83 * clock
84 */
83 return bcma_chipco_get_alp_clock(cc) / 4000; 85 return bcma_chipco_get_alp_clock(cc) / 4000;
84 else 86 else
85 /* based on 32KHz ILP clock */ 87 /* based on 32KHz ILP clock */
@@ -97,7 +99,8 @@ int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
97 wdt.driver_data = cc; 99 wdt.driver_data = cc;
98 wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt; 100 wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
99 wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt; 101 wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
100 wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms; 102 wdt.max_timer_ms =
103 bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
101 104
102 pdev = platform_device_register_data(NULL, "bcm47xx-wdt", 105 pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
103 cc->core->bus->num, &wdt, 106 cc->core->bus->num, &wdt,
@@ -335,7 +338,8 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
335 | BCMA_CC_CORECTL_UARTCLKEN); 338 | BCMA_CC_CORECTL_UARTCLKEN);
336 } 339 }
337 } else { 340 } else {
338 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); 341 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n",
342 ccrev);
339 return; 343 return;
340 } 344 }
341 345
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
index 335cbcfd945b..2dce34789329 100644
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -193,7 +193,7 @@ int __init bcma_host_soc_init(struct bcma_soc *soc)
193 int err; 193 int err;
194 194
195 /* Scan bus and initialize it */ 195 /* Scan bus and initialize it */
196 err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); 196 err = bcma_bus_early_register(bus);
197 if (err) 197 if (err)
198 iounmap(bus->mmio); 198 iounmap(bus->mmio);
199 199
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 534e1337766d..c3c5e0a2d5be 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -268,6 +268,18 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
268 } 268 }
269} 269}
270 270
271void bcma_init_bus(struct bcma_bus *bus)
272{
273 mutex_lock(&bcma_buses_mutex);
274 bus->num = bcma_bus_next_num++;
275 mutex_unlock(&bcma_buses_mutex);
276
277 INIT_LIST_HEAD(&bus->cores);
278 bus->nr_cores = 0;
279
280 bcma_detect_chip(bus);
281}
282
271static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) 283static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
272{ 284{
273 int err; 285 int err;
@@ -369,10 +381,6 @@ int bcma_bus_register(struct bcma_bus *bus)
369 int err; 381 int err;
370 struct bcma_device *core; 382 struct bcma_device *core;
371 383
372 mutex_lock(&bcma_buses_mutex);
373 bus->num = bcma_bus_next_num++;
374 mutex_unlock(&bcma_buses_mutex);
375
376 /* Scan for devices (cores) */ 384 /* Scan for devices (cores) */
377 err = bcma_bus_scan(bus); 385 err = bcma_bus_scan(bus);
378 if (err) { 386 if (err) {
@@ -481,35 +489,20 @@ void bcma_bus_unregister(struct bcma_bus *bus)
481 kfree(cores[0]); 489 kfree(cores[0]);
482} 490}
483 491
484int __init bcma_bus_early_register(struct bcma_bus *bus, 492/*
485 struct bcma_device *core_cc, 493 * This is a special version of bus registration function designed for SoCs.
486 struct bcma_device *core_mips) 494 * It scans bus and performs basic initialization of main cores only.
495 * Please note it requires memory allocation, however it won't try to sleep.
496 */
497int __init bcma_bus_early_register(struct bcma_bus *bus)
487{ 498{
488 int err; 499 int err;
489 struct bcma_device *core; 500 struct bcma_device *core;
490 struct bcma_device_id match;
491 501
492 match.manuf = BCMA_MANUF_BCM; 502 /* Scan for devices (cores) */
493 match.id = bcma_cc_core_id(bus); 503 err = bcma_bus_scan(bus);
494 match.class = BCMA_CL_SIM;
495 match.rev = BCMA_ANY_REV;
496
497 /* Scan for chip common core */
498 err = bcma_bus_scan_early(bus, &match, core_cc);
499 if (err) {
500 bcma_err(bus, "Failed to scan for common core: %d\n", err);
501 return -1;
502 }
503
504 match.manuf = BCMA_MANUF_MIPS;
505 match.id = BCMA_CORE_MIPS_74K;
506 match.class = BCMA_CL_SIM;
507 match.rev = BCMA_ANY_REV;
508
509 /* Scan for mips core */
510 err = bcma_bus_scan_early(bus, &match, core_mips);
511 if (err) { 504 if (err) {
512 bcma_err(bus, "Failed to scan for mips core: %d\n", err); 505 bcma_err(bus, "Failed to scan bus: %d\n", err);
513 return -1; 506 return -1;
514 } 507 }
515 508
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 917520776879..df806b9c5490 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -435,15 +435,12 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
435 return 0; 435 return 0;
436} 436}
437 437
438void bcma_init_bus(struct bcma_bus *bus) 438void bcma_detect_chip(struct bcma_bus *bus)
439{ 439{
440 s32 tmp; 440 s32 tmp;
441 struct bcma_chipinfo *chipinfo = &(bus->chipinfo); 441 struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
442 char chip_id[8]; 442 char chip_id[8];
443 443
444 INIT_LIST_HEAD(&bus->cores);
445 bus->nr_cores = 0;
446
447 bcma_scan_switch_core(bus, BCMA_ADDR_BASE); 444 bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
448 445
449 tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID); 446 tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
@@ -464,6 +461,10 @@ int bcma_bus_scan(struct bcma_bus *bus)
464 461
465 int err, core_num = 0; 462 int err, core_num = 0;
466 463
464 /* Skip if bus was already scanned (e.g. during early register) */
465 if (bus->nr_cores)
466 return 0;
467
467 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); 468 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
468 if (bus->hosttype == BCMA_HOSTTYPE_SOC) { 469 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
469 eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); 470 eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
@@ -522,61 +523,3 @@ out:
522 523
523 return err; 524 return err;
524} 525}
525
526int __init bcma_bus_scan_early(struct bcma_bus *bus,
527 struct bcma_device_id *match,
528 struct bcma_device *core)
529{
530 u32 erombase;
531 u32 __iomem *eromptr, *eromend;
532
533 int err = -ENODEV;
534 int core_num = 0;
535
536 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
537 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
538 eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
539 if (!eromptr)
540 return -ENOMEM;
541 } else {
542 eromptr = bus->mmio;
543 }
544
545 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
546
547 bcma_scan_switch_core(bus, erombase);
548
549 while (eromptr < eromend) {
550 memset(core, 0, sizeof(*core));
551 INIT_LIST_HEAD(&core->list);
552 core->bus = bus;
553
554 err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
555 if (err == -ENODEV) {
556 core_num++;
557 continue;
558 } else if (err == -ENXIO)
559 continue;
560 else if (err == -ESPIPE)
561 break;
562 else if (err < 0)
563 goto out;
564
565 core->core_index = core_num++;
566 bus->nr_cores++;
567 bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
568 core->core_index, bcma_device_name(&core->id),
569 core->id.manuf, core->id.id, core->id.rev,
570 core->id.class);
571
572 list_add_tail(&core->list, &bus->cores);
573 err = 0;
574 break;
575 }
576
577out:
578 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
579 iounmap(eromptr);
580
581 return err;
582}
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 17fcaabb2687..f07a61899545 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1837,6 +1837,7 @@ static int adm8211_probe(struct pci_dev *pdev,
1837 if (!priv->map) { 1837 if (!priv->map) {
1838 printk(KERN_ERR "%s (adm8211): Cannot map device memory\n", 1838 printk(KERN_ERR "%s (adm8211): Cannot map device memory\n",
1839 pci_name(pdev)); 1839 pci_name(pdev));
1840 err = -ENOMEM;
1840 goto err_free_dev; 1841 goto err_free_dev;
1841 } 1842 }
1842 1843
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
index 8b1b1adb477a..ffa3b1a8745f 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -8,11 +8,13 @@ ath10k_core-y += mac.o \
8 htt_tx.o \ 8 htt_tx.o \
9 txrx.o \ 9 txrx.o \
10 wmi.o \ 10 wmi.o \
11 wmi-tlv.o \
11 bmi.o 12 bmi.o
12 13
13ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o 14ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
14ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o 15ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
15ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o 16ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
17ath10k_core-$(CONFIG_THERMAL) += thermal.o
16 18
17obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o 19obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
18ath10k_pci-y += pci.o \ 20ath10k_pci-y += pci.o \
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index a156e6e48708..42ec79327943 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -1093,6 +1093,8 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
1093 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); 1093 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
1094 BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > 1094 BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
1095 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); 1095 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
1096 BUILD_BUG_ON(2*TARGET_TLV_NUM_MSDU_DESC >
1097 (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
1096 1098
1097 ce_state->ar = ar; 1099 ce_state->ar = ar;
1098 ce_state->id = ce_id; 1100 ce_state->id = ce_id;
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 7762061a1944..2d0671ebcf2b 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -17,6 +17,7 @@
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/firmware.h> 19#include <linux/firmware.h>
20#include <linux/of.h>
20 21
21#include "core.h" 22#include "core.h"
22#include "mac.h" 23#include "mac.h"
@@ -27,20 +28,18 @@
27#include "debug.h" 28#include "debug.h"
28#include "htt.h" 29#include "htt.h"
29#include "testmode.h" 30#include "testmode.h"
31#include "wmi-ops.h"
30 32
31unsigned int ath10k_debug_mask; 33unsigned int ath10k_debug_mask;
32static bool uart_print; 34static bool uart_print;
33static unsigned int ath10k_p2p;
34static bool skip_otp; 35static bool skip_otp;
35 36
36module_param_named(debug_mask, ath10k_debug_mask, uint, 0644); 37module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
37module_param(uart_print, bool, 0644); 38module_param(uart_print, bool, 0644);
38module_param_named(p2p, ath10k_p2p, uint, 0644);
39module_param(skip_otp, bool, 0644); 39module_param(skip_otp, bool, 0644);
40 40
41MODULE_PARM_DESC(debug_mask, "Debugging mask"); 41MODULE_PARM_DESC(debug_mask, "Debugging mask");
42MODULE_PARM_DESC(uart_print, "Uart target debugging"); 42MODULE_PARM_DESC(uart_print, "Uart target debugging");
43MODULE_PARM_DESC(p2p, "Enable ath10k P2P support");
44MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); 43MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
45 44
46static const struct ath10k_hw_params ath10k_hw_params_list[] = { 45static const struct ath10k_hw_params ath10k_hw_params_list[] = {
@@ -48,11 +47,14 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
48 .id = QCA988X_HW_2_0_VERSION, 47 .id = QCA988X_HW_2_0_VERSION,
49 .name = "qca988x hw2.0", 48 .name = "qca988x hw2.0",
50 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, 49 .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
50 .uart_pin = 7,
51 .fw = { 51 .fw = {
52 .dir = QCA988X_HW_2_0_FW_DIR, 52 .dir = QCA988X_HW_2_0_FW_DIR,
53 .fw = QCA988X_HW_2_0_FW_FILE, 53 .fw = QCA988X_HW_2_0_FW_FILE,
54 .otp = QCA988X_HW_2_0_OTP_FILE, 54 .otp = QCA988X_HW_2_0_OTP_FILE,
55 .board = QCA988X_HW_2_0_BOARD_DATA_FILE, 55 .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
56 .board_size = QCA988X_BOARD_DATA_SZ,
57 .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
56 }, 58 },
57 }, 59 },
58}; 60};
@@ -146,8 +148,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
146static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data, 148static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
147 size_t data_len) 149 size_t data_len)
148{ 150{
149 u32 board_data_size = QCA988X_BOARD_DATA_SZ; 151 u32 board_data_size = ar->hw_params.fw.board_size;
150 u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; 152 u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
151 u32 board_ext_data_addr; 153 u32 board_ext_data_addr;
152 int ret; 154 int ret;
153 155
@@ -193,7 +195,7 @@ static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
193static int ath10k_download_board_data(struct ath10k *ar, const void *data, 195static int ath10k_download_board_data(struct ath10k *ar, const void *data,
194 size_t data_len) 196 size_t data_len)
195{ 197{
196 u32 board_data_size = QCA988X_BOARD_DATA_SZ; 198 u32 board_data_size = ar->hw_params.fw.board_size;
197 u32 address; 199 u32 address;
198 int ret; 200 int ret;
199 201
@@ -249,6 +251,63 @@ static int ath10k_download_cal_file(struct ath10k *ar)
249 return 0; 251 return 0;
250} 252}
251 253
254static int ath10k_download_cal_dt(struct ath10k *ar)
255{
256 struct device_node *node;
257 int data_len;
258 void *data;
259 int ret;
260
261 node = ar->dev->of_node;
262 if (!node)
263 /* Device Tree is optional, don't print any warnings if
264 * there's no node for ath10k.
265 */
266 return -ENOENT;
267
268 if (!of_get_property(node, "qcom,ath10k-calibration-data",
269 &data_len)) {
270 /* The calibration data node is optional */
271 return -ENOENT;
272 }
273
274 if (data_len != QCA988X_CAL_DATA_LEN) {
275 ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
276 data_len);
277 ret = -EMSGSIZE;
278 goto out;
279 }
280
281 data = kmalloc(data_len, GFP_KERNEL);
282 if (!data) {
283 ret = -ENOMEM;
284 goto out;
285 }
286
287 ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
288 data, data_len);
289 if (ret) {
290 ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
291 ret);
292 goto out_free;
293 }
294
295 ret = ath10k_download_board_data(ar, data, data_len);
296 if (ret) {
297 ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
298 ret);
299 goto out_free;
300 }
301
302 ret = 0;
303
304out_free:
305 kfree(data);
306
307out:
308 return ret;
309}
310
252static int ath10k_download_and_run_otp(struct ath10k *ar) 311static int ath10k_download_and_run_otp(struct ath10k *ar)
253{ 312{
254 u32 result, address = ar->hw_params.patch_load_addr; 313 u32 result, address = ar->hw_params.patch_load_addr;
@@ -447,7 +506,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
447 int ie_id, i, index, bit, ret; 506 int ie_id, i, index, bit, ret;
448 struct ath10k_fw_ie *hdr; 507 struct ath10k_fw_ie *hdr;
449 const u8 *data; 508 const u8 *data;
450 __le32 *timestamp; 509 __le32 *timestamp, *version;
451 510
452 /* first fetch the firmware file (firmware-*.bin) */ 511 /* first fetch the firmware file (firmware-*.bin) */
453 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); 512 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
@@ -562,6 +621,17 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
562 ar->otp_len = ie_len; 621 ar->otp_len = ie_len;
563 622
564 break; 623 break;
624 case ATH10K_FW_IE_WMI_OP_VERSION:
625 if (ie_len != sizeof(u32))
626 break;
627
628 version = (__le32 *)data;
629
630 ar->wmi.op_version = le32_to_cpup(version);
631
632 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
633 ar->wmi.op_version);
634 break;
565 default: 635 default:
566 ath10k_warn(ar, "Unknown FW IE: %u\n", 636 ath10k_warn(ar, "Unknown FW IE: %u\n",
567 le32_to_cpu(hdr->id)); 637 le32_to_cpu(hdr->id));
@@ -582,13 +652,6 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
582 goto err; 652 goto err;
583 } 653 }
584 654
585 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
586 !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
587 ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
588 ret = -EINVAL;
589 goto err;
590 }
591
592 /* now fetch the board file */ 655 /* now fetch the board file */
593 if (ar->hw_params.fw.board == NULL) { 656 if (ar->hw_params.fw.board == NULL) {
594 ath10k_err(ar, "board data file not defined"); 657 ath10k_err(ar, "board data file not defined");
@@ -624,6 +687,13 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
624 /* calibration file is optional, don't check for any errors */ 687 /* calibration file is optional, don't check for any errors */
625 ath10k_fetch_cal_file(ar); 688 ath10k_fetch_cal_file(ar);
626 689
690 ar->fw_api = 4;
691 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
692
693 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
694 if (ret == 0)
695 goto success;
696
627 ar->fw_api = 3; 697 ar->fw_api = 3;
628 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); 698 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
629 699
@@ -662,7 +732,17 @@ static int ath10k_download_cal_data(struct ath10k *ar)
662 } 732 }
663 733
664 ath10k_dbg(ar, ATH10K_DBG_BOOT, 734 ath10k_dbg(ar, ATH10K_DBG_BOOT,
665 "boot did not find a calibration file, try OTP next: %d\n", 735 "boot did not find a calibration file, try DT next: %d\n",
736 ret);
737
738 ret = ath10k_download_cal_dt(ar);
739 if (ret == 0) {
740 ar->cal_mode = ATH10K_CAL_MODE_DT;
741 goto done;
742 }
743
744 ath10k_dbg(ar, ATH10K_DBG_BOOT,
745 "boot did not find DT entry, try OTP next: %d\n",
666 ret); 746 ret);
667 747
668 ret = ath10k_download_and_run_otp(ar); 748 ret = ath10k_download_and_run_otp(ar);
@@ -696,7 +776,7 @@ static int ath10k_init_uart(struct ath10k *ar)
696 if (!uart_print) 776 if (!uart_print)
697 return 0; 777 return 0;
698 778
699 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); 779 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
700 if (ret) { 780 if (ret) {
701 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); 781 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
702 return ret; 782 return ret;
@@ -764,6 +844,7 @@ static void ath10k_core_restart(struct work_struct *work)
764 complete_all(&ar->offchan_tx_completed); 844 complete_all(&ar->offchan_tx_completed);
765 complete_all(&ar->install_key_done); 845 complete_all(&ar->install_key_done);
766 complete_all(&ar->vdev_setup_done); 846 complete_all(&ar->vdev_setup_done);
847 complete_all(&ar->thermal.wmi_sync);
767 wake_up(&ar->htt.empty_tx_wq); 848 wake_up(&ar->htt.empty_tx_wq);
768 wake_up(&ar->wmi.tx_credits_wq); 849 wake_up(&ar->wmi.tx_credits_wq);
769 wake_up(&ar->peer_mapping_wq); 850 wake_up(&ar->peer_mapping_wq);
@@ -799,15 +880,62 @@ static void ath10k_core_restart(struct work_struct *work)
799 mutex_unlock(&ar->conf_mutex); 880 mutex_unlock(&ar->conf_mutex);
800} 881}
801 882
802static void ath10k_core_init_max_sta_count(struct ath10k *ar) 883static int ath10k_core_init_firmware_features(struct ath10k *ar)
803{ 884{
804 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 885 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
805 ar->max_num_peers = TARGET_10X_NUM_PEERS; 886 !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
806 ar->max_num_stations = TARGET_10X_NUM_STATIONS; 887 ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
807 } else { 888 return -EINVAL;
889 }
890
891 if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
892 ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
893 ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
894 return -EINVAL;
895 }
896
897 /* Backwards compatibility for firmwares without
898 * ATH10K_FW_IE_WMI_OP_VERSION.
899 */
900 if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
901 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
902 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
903 ar->fw_features))
904 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
905 else
906 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
907 } else {
908 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
909 }
910 }
911
912 switch (ar->wmi.op_version) {
913 case ATH10K_FW_WMI_OP_VERSION_MAIN:
808 ar->max_num_peers = TARGET_NUM_PEERS; 914 ar->max_num_peers = TARGET_NUM_PEERS;
809 ar->max_num_stations = TARGET_NUM_STATIONS; 915 ar->max_num_stations = TARGET_NUM_STATIONS;
916 ar->max_num_vdevs = TARGET_NUM_VDEVS;
917 ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
918 break;
919 case ATH10K_FW_WMI_OP_VERSION_10_1:
920 case ATH10K_FW_WMI_OP_VERSION_10_2:
921 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
922 ar->max_num_peers = TARGET_10X_NUM_PEERS;
923 ar->max_num_stations = TARGET_10X_NUM_STATIONS;
924 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
925 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
926 break;
927 case ATH10K_FW_WMI_OP_VERSION_TLV:
928 ar->max_num_peers = TARGET_TLV_NUM_PEERS;
929 ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
930 ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
931 break;
932 case ATH10K_FW_WMI_OP_VERSION_UNSET:
933 case ATH10K_FW_WMI_OP_VERSION_MAX:
934 WARN_ON(1);
935 return -EINVAL;
810 } 936 }
937
938 return 0;
811} 939}
812 940
813int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) 941int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
@@ -945,10 +1073,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
945 if (status) 1073 if (status)
946 goto err_hif_stop; 1074 goto err_hif_stop;
947 1075
948 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) 1076 ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
949 ar->free_vdev_map = (1LL << TARGET_10X_NUM_VDEVS) - 1;
950 else
951 ar->free_vdev_map = (1LL << TARGET_NUM_VDEVS) - 1;
952 1077
953 INIT_LIST_HEAD(&ar->arvifs); 1078 INIT_LIST_HEAD(&ar->arvifs);
954 1079
@@ -1025,8 +1150,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1025 ret = ath10k_bmi_get_target_info(ar, &target_info); 1150 ret = ath10k_bmi_get_target_info(ar, &target_info);
1026 if (ret) { 1151 if (ret) {
1027 ath10k_err(ar, "could not get target info (%d)\n", ret); 1152 ath10k_err(ar, "could not get target info (%d)\n", ret);
1028 ath10k_hif_power_down(ar); 1153 goto err_power_down;
1029 return ret;
1030 } 1154 }
1031 1155
1032 ar->target_version = target_info.version; 1156 ar->target_version = target_info.version;
@@ -1035,28 +1159,28 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1035 ret = ath10k_init_hw_params(ar); 1159 ret = ath10k_init_hw_params(ar);
1036 if (ret) { 1160 if (ret) {
1037 ath10k_err(ar, "could not get hw params (%d)\n", ret); 1161 ath10k_err(ar, "could not get hw params (%d)\n", ret);
1038 ath10k_hif_power_down(ar); 1162 goto err_power_down;
1039 return ret;
1040 } 1163 }
1041 1164
1042 ret = ath10k_core_fetch_firmware_files(ar); 1165 ret = ath10k_core_fetch_firmware_files(ar);
1043 if (ret) { 1166 if (ret) {
1044 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); 1167 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
1045 ath10k_hif_power_down(ar); 1168 goto err_power_down;
1046 return ret;
1047 } 1169 }
1048 1170
1049 ath10k_core_init_max_sta_count(ar); 1171 ret = ath10k_core_init_firmware_features(ar);
1172 if (ret) {
1173 ath10k_err(ar, "fatal problem with firmware features: %d\n",
1174 ret);
1175 goto err_free_firmware_files;
1176 }
1050 1177
1051 mutex_lock(&ar->conf_mutex); 1178 mutex_lock(&ar->conf_mutex);
1052 1179
1053 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); 1180 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
1054 if (ret) { 1181 if (ret) {
1055 ath10k_err(ar, "could not init core (%d)\n", ret); 1182 ath10k_err(ar, "could not init core (%d)\n", ret);
1056 ath10k_core_free_firmware_files(ar); 1183 goto err_unlock;
1057 ath10k_hif_power_down(ar);
1058 mutex_unlock(&ar->conf_mutex);
1059 return ret;
1060 } 1184 }
1061 1185
1062 ath10k_print_driver_info(ar); 1186 ath10k_print_driver_info(ar);
@@ -1066,34 +1190,17 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1066 1190
1067 ath10k_hif_power_down(ar); 1191 ath10k_hif_power_down(ar);
1068 return 0; 1192 return 0;
1069}
1070
1071static int ath10k_core_check_chip_id(struct ath10k *ar)
1072{
1073 u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);
1074
1075 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
1076 ar->chip_id, hw_revision);
1077 1193
1078 /* Check that we are not using hw1.0 (some of them have same pci id 1194err_unlock:
1079 * as hw2.0) before doing anything else as ath10k crashes horribly 1195 mutex_unlock(&ar->conf_mutex);
1080 * due to missing hw1.0 workarounds. */
1081 switch (hw_revision) {
1082 case QCA988X_HW_1_0_CHIP_ID_REV:
1083 ath10k_err(ar, "ERROR: qca988x hw1.0 is not supported\n");
1084 return -EOPNOTSUPP;
1085 1196
1086 case QCA988X_HW_2_0_CHIP_ID_REV: 1197err_free_firmware_files:
1087 /* known hardware revision, continue normally */ 1198 ath10k_core_free_firmware_files(ar);
1088 return 0;
1089 1199
1090 default: 1200err_power_down:
1091 ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n", 1201 ath10k_hif_power_down(ar);
1092 ar->chip_id);
1093 return 0;
1094 }
1095 1202
1096 return 0; 1203 return ret;
1097} 1204}
1098 1205
1099static void ath10k_core_register_work(struct work_struct *work) 1206static void ath10k_core_register_work(struct work_struct *work)
@@ -1125,9 +1232,18 @@ static void ath10k_core_register_work(struct work_struct *work)
1125 goto err_debug_destroy; 1232 goto err_debug_destroy;
1126 } 1233 }
1127 1234
1235 status = ath10k_thermal_register(ar);
1236 if (status) {
1237 ath10k_err(ar, "could not register thermal device: %d\n",
1238 status);
1239 goto err_spectral_destroy;
1240 }
1241
1128 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); 1242 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
1129 return; 1243 return;
1130 1244
1245err_spectral_destroy:
1246 ath10k_spectral_destroy(ar);
1131err_debug_destroy: 1247err_debug_destroy:
1132 ath10k_debug_destroy(ar); 1248 ath10k_debug_destroy(ar);
1133err_unregister_mac: 1249err_unregister_mac:
@@ -1143,16 +1259,7 @@ err:
1143 1259
1144int ath10k_core_register(struct ath10k *ar, u32 chip_id) 1260int ath10k_core_register(struct ath10k *ar, u32 chip_id)
1145{ 1261{
1146 int status;
1147
1148 ar->chip_id = chip_id; 1262 ar->chip_id = chip_id;
1149
1150 status = ath10k_core_check_chip_id(ar);
1151 if (status) {
1152 ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id);
1153 return status;
1154 }
1155
1156 queue_work(ar->workqueue, &ar->register_work); 1263 queue_work(ar->workqueue, &ar->register_work);
1157 1264
1158 return 0; 1265 return 0;
@@ -1166,6 +1273,7 @@ void ath10k_core_unregister(struct ath10k *ar)
1166 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) 1273 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
1167 return; 1274 return;
1168 1275
1276 ath10k_thermal_unregister(ar);
1169 /* Stop spectral before unregistering from mac80211 to remove the 1277 /* Stop spectral before unregistering from mac80211 to remove the
1170 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree 1278 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
1171 * would be already be free'd recursively, leading to a double free. 1279 * would be already be free'd recursively, leading to a double free.
@@ -1198,10 +1306,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1198 1306
1199 ar->ath_common.priv = ar; 1307 ar->ath_common.priv = ar;
1200 ar->ath_common.hw = ar->hw; 1308 ar->ath_common.hw = ar->hw;
1201
1202 ar->p2p = !!ath10k_p2p;
1203 ar->dev = dev; 1309 ar->dev = dev;
1204
1205 ar->hif.ops = hif_ops; 1310 ar->hif.ops = hif_ops;
1206 ar->hif.bus = bus; 1311 ar->hif.bus = bus;
1207 1312
@@ -1212,6 +1317,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1212 1317
1213 init_completion(&ar->install_key_done); 1318 init_completion(&ar->install_key_done);
1214 init_completion(&ar->vdev_setup_done); 1319 init_completion(&ar->vdev_setup_done);
1320 init_completion(&ar->thermal.wmi_sync);
1215 1321
1216 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); 1322 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
1217 1323
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 514c219263a5..7b6d9e4567a3 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -34,6 +34,7 @@
34#include "../regd.h" 34#include "../regd.h"
35#include "../dfs_pattern_detector.h" 35#include "../dfs_pattern_detector.h"
36#include "spectral.h" 36#include "spectral.h"
37#include "thermal.h"
37 38
38#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) 39#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
39#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) 40#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -120,6 +121,7 @@ struct ath10k_mem_chunk {
120}; 121};
121 122
122struct ath10k_wmi { 123struct ath10k_wmi {
124 enum ath10k_fw_wmi_op_version op_version;
123 enum ath10k_htc_ep_id eid; 125 enum ath10k_htc_ep_id eid;
124 struct completion service_ready; 126 struct completion service_ready;
125 struct completion unified_ready; 127 struct completion unified_ready;
@@ -128,6 +130,7 @@ struct ath10k_wmi {
128 struct wmi_cmd_map *cmd; 130 struct wmi_cmd_map *cmd;
129 struct wmi_vdev_param_map *vdev_param; 131 struct wmi_vdev_param_map *vdev_param;
130 struct wmi_pdev_param_map *pdev_param; 132 struct wmi_pdev_param_map *pdev_param;
133 const struct wmi_ops *ops;
131 134
132 u32 num_mem_chunks; 135 u32 num_mem_chunks;
133 struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS]; 136 struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
@@ -325,6 +328,7 @@ struct ath10k_debug {
325 u32 fw_dbglog_mask; 328 u32 fw_dbglog_mask;
326 u32 pktlog_filter; 329 u32 pktlog_filter;
327 u32 reg_addr; 330 u32 reg_addr;
331 u32 nf_cal_period;
328 332
329 u8 htt_max_amsdu; 333 u8 htt_max_amsdu;
330 u8 htt_max_ampdu; 334 u8 htt_max_ampdu;
@@ -369,7 +373,7 @@ enum ath10k_fw_features {
369 /* wmi_mgmt_rx_hdr contains extra RSSI information */ 373 /* wmi_mgmt_rx_hdr contains extra RSSI information */
370 ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0, 374 ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0,
371 375
372 /* firmware from 10X branch */ 376 /* Firmware from 10X branch. Deprecated, don't use in new code. */
373 ATH10K_FW_FEATURE_WMI_10X = 1, 377 ATH10K_FW_FEATURE_WMI_10X = 1,
374 378
375 /* firmware support tx frame management over WMI, otherwise it's HTT */ 379 /* firmware support tx frame management over WMI, otherwise it's HTT */
@@ -378,8 +382,9 @@ enum ath10k_fw_features {
378 /* Firmware does not support P2P */ 382 /* Firmware does not support P2P */
379 ATH10K_FW_FEATURE_NO_P2P = 3, 383 ATH10K_FW_FEATURE_NO_P2P = 3,
380 384
381 /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit 385 /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature
382 * is required to be set as well. 386 * bit is required to be set as well. Deprecated, don't use in new
387 * code.
383 */ 388 */
384 ATH10K_FW_FEATURE_WMI_10_2 = 4, 389 ATH10K_FW_FEATURE_WMI_10_2 = 4,
385 390
@@ -401,6 +406,7 @@ enum ath10k_dev_flags {
401enum ath10k_cal_mode { 406enum ath10k_cal_mode {
402 ATH10K_CAL_MODE_FILE, 407 ATH10K_CAL_MODE_FILE,
403 ATH10K_CAL_MODE_OTP, 408 ATH10K_CAL_MODE_OTP,
409 ATH10K_CAL_MODE_DT,
404}; 410};
405 411
406static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) 412static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
@@ -410,6 +416,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
410 return "file"; 416 return "file";
411 case ATH10K_CAL_MODE_OTP: 417 case ATH10K_CAL_MODE_OTP:
412 return "otp"; 418 return "otp";
419 case ATH10K_CAL_MODE_DT:
420 return "dt";
413 } 421 }
414 422
415 return "unknown"; 423 return "unknown";
@@ -480,12 +488,15 @@ struct ath10k {
480 u32 id; 488 u32 id;
481 const char *name; 489 const char *name;
482 u32 patch_load_addr; 490 u32 patch_load_addr;
491 int uart_pin;
483 492
484 struct ath10k_hw_params_fw { 493 struct ath10k_hw_params_fw {
485 const char *dir; 494 const char *dir;
486 const char *fw; 495 const char *fw;
487 const char *otp; 496 const char *otp;
488 const char *board; 497 const char *board;
498 size_t board_size;
499 size_t board_ext_size;
489 } fw; 500 } fw;
490 } hw_params; 501 } hw_params;
491 502
@@ -571,6 +582,7 @@ struct ath10k {
571 582
572 int max_num_peers; 583 int max_num_peers;
573 int max_num_stations; 584 int max_num_stations;
585 int max_num_vdevs;
574 586
575 struct work_struct offchan_tx_work; 587 struct work_struct offchan_tx_work;
576 struct sk_buff_head offchan_tx_queue; 588 struct sk_buff_head offchan_tx_queue;
@@ -610,6 +622,7 @@ struct ath10k {
610 /* protected by conf_mutex */ 622 /* protected by conf_mutex */
611 const struct firmware *utf; 623 const struct firmware *utf;
612 DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT); 624 DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT);
625 enum ath10k_fw_wmi_op_version orig_wmi_op_version;
613 626
614 /* protected by data_lock */ 627 /* protected by data_lock */
615 bool utf_monitor; 628 bool utf_monitor;
@@ -622,6 +635,8 @@ struct ath10k {
622 u32 fw_cold_reset_counter; 635 u32 fw_cold_reset_counter;
623 } stats; 636 } stats;
624 637
638 struct ath10k_thermal thermal;
639
625 /* must be last */ 640 /* must be last */
626 u8 drv_priv[0] __aligned(sizeof(void *)); 641 u8 drv_priv[0] __aligned(sizeof(void *));
627}; 642};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index a716758f14b0..6ca24427e184 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -23,6 +23,7 @@
23#include "core.h" 23#include "core.h"
24#include "debug.h" 24#include "debug.h"
25#include "hif.h" 25#include "hif.h"
26#include "wmi-ops.h"
26 27
27/* ms */ 28/* ms */
28#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 29#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
@@ -123,7 +124,7 @@ EXPORT_SYMBOL(ath10k_info);
123 124
124void ath10k_print_driver_info(struct ath10k *ar) 125void ath10k_print_driver_info(struct ath10k *ar)
125{ 126{
126 ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n", 127 ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d cal %s max_sta %d\n",
127 ar->hw_params.name, 128 ar->hw_params.name,
128 ar->target_version, 129 ar->target_version,
129 ar->chip_id, 130 ar->chip_id,
@@ -131,10 +132,7 @@ void ath10k_print_driver_info(struct ath10k *ar)
131 ar->fw_api, 132 ar->fw_api,
132 ar->htt.target_version_major, 133 ar->htt.target_version_major,
133 ar->htt.target_version_minor, 134 ar->htt.target_version_minor,
134 ar->fw_version_major, 135 ar->wmi.op_version,
135 ar->fw_version_minor,
136 ar->fw_version_release,
137 ar->fw_version_build,
138 ath10k_cal_mode_str(ar->cal_mode), 136 ath10k_cal_mode_str(ar->cal_mode),
139 ar->max_num_stations); 137 ar->max_num_stations);
140 ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", 138 ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
@@ -1607,6 +1605,73 @@ static const struct file_operations fops_cal_data = {
1607 .llseek = default_llseek, 1605 .llseek = default_llseek,
1608}; 1606};
1609 1607
1608static ssize_t ath10k_read_nf_cal_period(struct file *file,
1609 char __user *user_buf,
1610 size_t count, loff_t *ppos)
1611{
1612 struct ath10k *ar = file->private_data;
1613 unsigned int len;
1614 char buf[32];
1615
1616 len = scnprintf(buf, sizeof(buf), "%d\n",
1617 ar->debug.nf_cal_period);
1618
1619 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1620}
1621
1622static ssize_t ath10k_write_nf_cal_period(struct file *file,
1623 const char __user *user_buf,
1624 size_t count, loff_t *ppos)
1625{
1626 struct ath10k *ar = file->private_data;
1627 unsigned long period;
1628 int ret;
1629
1630 ret = kstrtoul_from_user(user_buf, count, 0, &period);
1631 if (ret)
1632 return ret;
1633
1634 if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1635 return -EINVAL;
1636
1637 /* there's no way to switch back to the firmware default */
1638 if (period == 0)
1639 return -EINVAL;
1640
1641 mutex_lock(&ar->conf_mutex);
1642
1643 ar->debug.nf_cal_period = period;
1644
1645 if (ar->state != ATH10K_STATE_ON) {
1646 /* firmware is not running, nothing else to do */
1647 ret = count;
1648 goto exit;
1649 }
1650
1651 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1652 ar->debug.nf_cal_period);
1653 if (ret) {
1654 ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1655 ret);
1656 goto exit;
1657 }
1658
1659 ret = count;
1660
1661exit:
1662 mutex_unlock(&ar->conf_mutex);
1663
1664 return ret;
1665}
1666
1667static const struct file_operations fops_nf_cal_period = {
1668 .read = ath10k_read_nf_cal_period,
1669 .write = ath10k_write_nf_cal_period,
1670 .open = simple_open,
1671 .owner = THIS_MODULE,
1672 .llseek = default_llseek,
1673};
1674
1610int ath10k_debug_start(struct ath10k *ar) 1675int ath10k_debug_start(struct ath10k *ar)
1611{ 1676{
1612 int ret; 1677 int ret;
@@ -1642,6 +1707,16 @@ int ath10k_debug_start(struct ath10k *ar)
1642 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1707 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1643 } 1708 }
1644 1709
1710 if (ar->debug.nf_cal_period) {
1711 ret = ath10k_wmi_pdev_set_param(ar,
1712 ar->wmi.pdev_param->cal_period,
1713 ar->debug.nf_cal_period);
1714 if (ret)
1715 /* not serious */
1716 ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1717 ret);
1718 }
1719
1645 return ret; 1720 return ret;
1646} 1721}
1647 1722
@@ -1880,6 +1955,9 @@ int ath10k_debug_register(struct ath10k *ar)
1880 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy, 1955 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
1881 ar, &fops_cal_data); 1956 ar, &fops_cal_data);
1882 1957
1958 debugfs_create_file("nf_cal_period", S_IRUSR | S_IWUSR,
1959 ar->debug.debugfs_phy, ar, &fops_nf_cal_period);
1960
1883 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { 1961 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
1884 debugfs_create_file("dfs_simulate_radar", S_IWUSR, 1962 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
1885 ar->debug.debugfs_phy, ar, 1963 ar->debug.debugfs_phy, ar,
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 4bc51d8a14a3..a1bda41fb543 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -93,11 +93,6 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
93 93
94 spin_lock_init(&htt->tx_lock); 94 spin_lock_init(&htt->tx_lock);
95 95
96 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, htt->ar->fw_features))
97 htt->max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
98 else
99 htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC;
100
101 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", 96 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
102 htt->max_num_pending_tx); 97 htt->max_num_pending_tx);
103 98
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index dfedfd0e0f34..5729901923ac 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -37,6 +37,9 @@
37#define ATH10K_FW_API2_FILE "firmware-2.bin" 37#define ATH10K_FW_API2_FILE "firmware-2.bin"
38#define ATH10K_FW_API3_FILE "firmware-3.bin" 38#define ATH10K_FW_API3_FILE "firmware-3.bin"
39 39
40/* added support for ATH10K_FW_IE_WMI_OP_VERSION */
41#define ATH10K_FW_API4_FILE "firmware-4.bin"
42
40#define ATH10K_FW_UTF_FILE "utf.bin" 43#define ATH10K_FW_UTF_FILE "utf.bin"
41 44
42/* includes also the null byte */ 45/* includes also the null byte */
@@ -58,6 +61,24 @@ enum ath10k_fw_ie_type {
58 ATH10K_FW_IE_FEATURES = 2, 61 ATH10K_FW_IE_FEATURES = 2,
59 ATH10K_FW_IE_FW_IMAGE = 3, 62 ATH10K_FW_IE_FW_IMAGE = 3,
60 ATH10K_FW_IE_OTP_IMAGE = 4, 63 ATH10K_FW_IE_OTP_IMAGE = 4,
64
65 /* WMI "operations" interface version, 32 bit value. Supported from
66 * FW API 4 and above.
67 */
68 ATH10K_FW_IE_WMI_OP_VERSION = 5,
69};
70
71enum ath10k_fw_wmi_op_version {
72 ATH10K_FW_WMI_OP_VERSION_UNSET = 0,
73
74 ATH10K_FW_WMI_OP_VERSION_MAIN = 1,
75 ATH10K_FW_WMI_OP_VERSION_10_1 = 2,
76 ATH10K_FW_WMI_OP_VERSION_10_2 = 3,
77 ATH10K_FW_WMI_OP_VERSION_TLV = 4,
78 ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5,
79
80 /* keep last */
81 ATH10K_FW_WMI_OP_VERSION_MAX,
61}; 82};
62 83
63/* Known pecularities: 84/* Known pecularities:
@@ -162,6 +183,15 @@ struct ath10k_pktlog_hdr {
162#define TARGET_10X_NUM_MSDU_DESC (1024 + 400) 183#define TARGET_10X_NUM_MSDU_DESC (1024 + 400)
163#define TARGET_10X_MAX_FRAG_ENTRIES 0 184#define TARGET_10X_MAX_FRAG_ENTRIES 0
164 185
186/* Target specific defines for WMI-TLV firmware */
187#define TARGET_TLV_NUM_VDEVS 3
188#define TARGET_TLV_NUM_STATIONS 32
189#define TARGET_TLV_NUM_PEERS ((TARGET_TLV_NUM_STATIONS) + \
190 (TARGET_TLV_NUM_VDEVS) + \
191 2)
192#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
193#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
194
165/* Number of Copy Engines supported */ 195/* Number of Copy Engines supported */
166#define CE_COUNT 8 196#define CE_COUNT 8
167 197
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 2619db1e3e74..08f293411bf0 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -27,6 +27,8 @@
27#include "htt.h" 27#include "htt.h"
28#include "txrx.h" 28#include "txrx.h"
29#include "testmode.h" 29#include "testmode.h"
30#include "wmi.h"
31#include "wmi-ops.h"
30 32
31/**********/ 33/**********/
32/* Crypto */ 34/* Crypto */
@@ -267,7 +269,10 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
267 case IEEE80211_BAND_2GHZ: 269 case IEEE80211_BAND_2GHZ:
268 switch (chandef->width) { 270 switch (chandef->width) {
269 case NL80211_CHAN_WIDTH_20_NOHT: 271 case NL80211_CHAN_WIDTH_20_NOHT:
270 phymode = MODE_11G; 272 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
273 phymode = MODE_11B;
274 else
275 phymode = MODE_11G;
271 break; 276 break;
272 case NL80211_CHAN_WIDTH_20: 277 case NL80211_CHAN_WIDTH_20:
273 phymode = MODE_11NG_HT20; 278 phymode = MODE_11NG_HT20;
@@ -1046,28 +1051,85 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
1046 arvif->vdev_id, ret); 1051 arvif->vdev_id, ret);
1047} 1052}
1048 1053
1049/* 1054static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1050 * Review this when mac80211 gains per-interface powersave support. 1055{
1051 */ 1056 struct ath10k *ar = arvif->ar;
1057 u32 param;
1058 u32 value;
1059 int ret;
1060
1061 lockdep_assert_held(&arvif->ar->conf_mutex);
1062
1063 if (arvif->u.sta.uapsd)
1064 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1065 else
1066 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1067
1068 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1069 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1070 if (ret) {
1071 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1072 value, arvif->vdev_id, ret);
1073 return ret;
1074 }
1075
1076 return 0;
1077}
1078
1079static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1080{
1081 struct ath10k *ar = arvif->ar;
1082 u32 param;
1083 u32 value;
1084 int ret;
1085
1086 lockdep_assert_held(&arvif->ar->conf_mutex);
1087
1088 if (arvif->u.sta.uapsd)
1089 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1090 else
1091 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1092
1093 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1094 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1095 param, value);
1096 if (ret) {
1097 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1098 value, arvif->vdev_id, ret);
1099 return ret;
1100 }
1101
1102 return 0;
1103}
1104
1052static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) 1105static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1053{ 1106{
1054 struct ath10k *ar = arvif->ar; 1107 struct ath10k *ar = arvif->ar;
1108 struct ieee80211_vif *vif = arvif->vif;
1055 struct ieee80211_conf *conf = &ar->hw->conf; 1109 struct ieee80211_conf *conf = &ar->hw->conf;
1056 enum wmi_sta_powersave_param param; 1110 enum wmi_sta_powersave_param param;
1057 enum wmi_sta_ps_mode psmode; 1111 enum wmi_sta_ps_mode psmode;
1058 int ret; 1112 int ret;
1113 int ps_timeout;
1059 1114
1060 lockdep_assert_held(&arvif->ar->conf_mutex); 1115 lockdep_assert_held(&arvif->ar->conf_mutex);
1061 1116
1062 if (arvif->vif->type != NL80211_IFTYPE_STATION) 1117 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1063 return 0; 1118 return 0;
1064 1119
1065 if (conf->flags & IEEE80211_CONF_PS) { 1120 if (vif->bss_conf.ps) {
1066 psmode = WMI_STA_PS_MODE_ENABLED; 1121 psmode = WMI_STA_PS_MODE_ENABLED;
1067 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1122 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1068 1123
1124 ps_timeout = conf->dynamic_ps_timeout;
1125 if (ps_timeout == 0) {
1126 /* Firmware doesn't like 0 */
1127 ps_timeout = ieee80211_tu_to_usec(
1128 vif->bss_conf.beacon_int) / 1000;
1129 }
1130
1069 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, 1131 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
1070 conf->dynamic_ps_timeout); 1132 ps_timeout);
1071 if (ret) { 1133 if (ret) {
1072 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n", 1134 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
1073 arvif->vdev_id, ret); 1135 arvif->vdev_id, ret);
@@ -1409,9 +1471,22 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
1409 if (vif->bss_conf.qos) 1471 if (vif->bss_conf.qos)
1410 arg->peer_flags |= WMI_PEER_QOS; 1472 arg->peer_flags |= WMI_PEER_QOS;
1411 break; 1473 break;
1474 case WMI_VDEV_TYPE_IBSS:
1475 if (sta->wme)
1476 arg->peer_flags |= WMI_PEER_QOS;
1477 break;
1412 default: 1478 default:
1413 break; 1479 break;
1414 } 1480 }
1481
1482 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
1483 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
1484}
1485
1486static bool ath10k_mac_sta_has_11g_rates(struct ieee80211_sta *sta)
1487{
1488 /* First 4 rates in ath10k_rates are CCK (11b) rates. */
1489 return sta->supp_rates[IEEE80211_BAND_2GHZ] >> 4;
1415} 1490}
1416 1491
1417static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, 1492static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
@@ -1428,8 +1503,10 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
1428 phymode = MODE_11NG_HT40; 1503 phymode = MODE_11NG_HT40;
1429 else 1504 else
1430 phymode = MODE_11NG_HT20; 1505 phymode = MODE_11NG_HT20;
1431 } else { 1506 } else if (ath10k_mac_sta_has_11g_rates(sta)) {
1432 phymode = MODE_11G; 1507 phymode = MODE_11G;
1508 } else {
1509 phymode = MODE_11B;
1433 } 1510 }
1434 1511
1435 break; 1512 break;
@@ -2896,10 +2973,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2896 arvif->vdev_id = bit; 2973 arvif->vdev_id = bit;
2897 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; 2974 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
2898 2975
2899 if (ar->p2p)
2900 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
2901
2902 switch (vif->type) { 2976 switch (vif->type) {
2977 case NL80211_IFTYPE_P2P_DEVICE:
2978 arvif->vdev_type = WMI_VDEV_TYPE_STA;
2979 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
2980 break;
2903 case NL80211_IFTYPE_UNSPECIFIED: 2981 case NL80211_IFTYPE_UNSPECIFIED:
2904 case NL80211_IFTYPE_STATION: 2982 case NL80211_IFTYPE_STATION:
2905 arvif->vdev_type = WMI_VDEV_TYPE_STA; 2983 arvif->vdev_type = WMI_VDEV_TYPE_STA;
@@ -3028,22 +3106,16 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
3028 goto err_peer_delete; 3106 goto err_peer_delete;
3029 } 3107 }
3030 3108
3031 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; 3109 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
3032 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
3033 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
3034 param, value);
3035 if (ret) { 3110 if (ret) {
3036 ath10k_warn(ar, "failed to set vdev %i TX wake thresh: %d\n", 3111 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
3037 arvif->vdev_id, ret); 3112 arvif->vdev_id, ret);
3038 goto err_peer_delete; 3113 goto err_peer_delete;
3039 } 3114 }
3040 3115
3041 param = WMI_STA_PS_PARAM_PSPOLL_COUNT; 3116 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
3042 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
3043 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
3044 param, value);
3045 if (ret) { 3117 if (ret) {
3046 ath10k_warn(ar, "failed to set vdev %i PSPOLL count: %d\n", 3118 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
3047 arvif->vdev_id, ret); 3119 arvif->vdev_id, ret);
3048 goto err_peer_delete; 3120 goto err_peer_delete;
3049 } 3121 }
@@ -3316,6 +3388,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3316 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); 3388 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
3317 } 3389 }
3318 3390
3391 if (changed & BSS_CHANGED_PS) {
3392 ret = ath10k_mac_vif_setup_ps(arvif);
3393 if (ret)
3394 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
3395 arvif->vdev_id, ret);
3396 }
3397
3319 mutex_unlock(&ar->conf_mutex); 3398 mutex_unlock(&ar->conf_mutex);
3320} 3399}
3321 3400
@@ -3585,8 +3664,9 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
3585 sta->addr, smps, err); 3664 sta->addr, smps, err);
3586 } 3665 }
3587 3666
3588 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { 3667 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
3589 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", 3668 changed & IEEE80211_RC_NSS_CHANGED) {
3669 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
3590 sta->addr); 3670 sta->addr);
3591 3671
3592 err = ath10k_station_assoc(ar, arvif->vif, sta, true); 3672 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
@@ -3810,6 +3890,20 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
3810 if (ret) 3890 if (ret)
3811 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret); 3891 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
3812 3892
3893 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
3894 if (ret) {
3895 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
3896 arvif->vdev_id, ret);
3897 return ret;
3898 }
3899
3900 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
3901 if (ret) {
3902 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
3903 arvif->vdev_id, ret);
3904 return ret;
3905 }
3906
3813exit: 3907exit:
3814 return ret; 3908 return ret;
3815} 3909}
@@ -3991,29 +4085,6 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3991 return ret; 4085 return ret;
3992} 4086}
3993 4087
3994static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
3995{
3996 struct ath10k *ar = hw->priv;
3997 struct ath10k_vif *arvif;
3998 int ret = 0;
3999
4000 mutex_lock(&ar->conf_mutex);
4001 list_for_each_entry(arvif, &ar->arvifs, list) {
4002 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n",
4003 arvif->vdev_id, value);
4004
4005 ret = ath10k_mac_set_frag(arvif, value);
4006 if (ret) {
4007 ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n",
4008 arvif->vdev_id, ret);
4009 break;
4010 }
4011 }
4012 mutex_unlock(&ar->conf_mutex);
4013
4014 return ret;
4015}
4016
4017static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4088static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4018 u32 queues, bool drop) 4089 u32 queues, bool drop)
4019{ 4090{
@@ -4657,7 +4728,6 @@ static const struct ieee80211_ops ath10k_ops = {
4657 .remain_on_channel = ath10k_remain_on_channel, 4728 .remain_on_channel = ath10k_remain_on_channel,
4658 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel, 4729 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
4659 .set_rts_threshold = ath10k_set_rts_threshold, 4730 .set_rts_threshold = ath10k_set_rts_threshold,
4660 .set_frag_threshold = ath10k_set_frag_threshold,
4661 .flush = ath10k_flush, 4731 .flush = ath10k_flush,
4662 .tx_last_beacon = ath10k_tx_last_beacon, 4732 .tx_last_beacon = ath10k_tx_last_beacon,
4663 .set_antenna = ath10k_set_antenna, 4733 .set_antenna = ath10k_set_antenna,
@@ -4748,6 +4818,9 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
4748 CHAN5G(165, 5825, 0), 4818 CHAN5G(165, 5825, 0),
4749}; 4819};
4750 4820
4821/* Note: Be careful if you re-order these. There is code which depends on this
4822 * ordering.
4823 */
4751static struct ieee80211_rate ath10k_rates[] = { 4824static struct ieee80211_rate ath10k_rates[] = {
4752 /* CCK */ 4825 /* CCK */
4753 RATETAB_ENT(10, 0x82, 0), 4826 RATETAB_ENT(10, 0x82, 0),
@@ -4801,6 +4874,10 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
4801 .types = BIT(NL80211_IFTYPE_P2P_GO) 4874 .types = BIT(NL80211_IFTYPE_P2P_GO)
4802 }, 4875 },
4803 { 4876 {
4877 .max = 1,
4878 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4879 },
4880 {
4804 .max = 7, 4881 .max = 7,
4805 .types = BIT(NL80211_IFTYPE_AP) 4882 .types = BIT(NL80211_IFTYPE_AP)
4806 }, 4883 },
@@ -5020,6 +5097,7 @@ int ath10k_mac_register(struct ath10k *ar)
5020 5097
5021 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) 5098 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
5022 ar->hw->wiphy->interface_modes |= 5099 ar->hw->wiphy->interface_modes |=
5100 BIT(NL80211_IFTYPE_P2P_DEVICE) |
5023 BIT(NL80211_IFTYPE_P2P_CLIENT) | 5101 BIT(NL80211_IFTYPE_P2P_CLIENT) |
5024 BIT(NL80211_IFTYPE_P2P_GO); 5102 BIT(NL80211_IFTYPE_P2P_GO);
5025 5103
@@ -5063,16 +5141,26 @@ int ath10k_mac_register(struct ath10k *ar)
5063 */ 5141 */
5064 ar->hw->queues = 4; 5142 ar->hw->queues = 4;
5065 5143
5066 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 5144 switch (ar->wmi.op_version) {
5067 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; 5145 case ATH10K_FW_WMI_OP_VERSION_MAIN:
5068 ar->hw->wiphy->n_iface_combinations = 5146 case ATH10K_FW_WMI_OP_VERSION_TLV:
5069 ARRAY_SIZE(ath10k_10x_if_comb);
5070 } else {
5071 ar->hw->wiphy->iface_combinations = ath10k_if_comb; 5147 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
5072 ar->hw->wiphy->n_iface_combinations = 5148 ar->hw->wiphy->n_iface_combinations =
5073 ARRAY_SIZE(ath10k_if_comb); 5149 ARRAY_SIZE(ath10k_if_comb);
5074
5075 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 5150 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
5151 break;
5152 case ATH10K_FW_WMI_OP_VERSION_10_1:
5153 case ATH10K_FW_WMI_OP_VERSION_10_2:
5154 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
5155 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
5156 ar->hw->wiphy->n_iface_combinations =
5157 ARRAY_SIZE(ath10k_10x_if_comb);
5158 break;
5159 case ATH10K_FW_WMI_OP_VERSION_UNSET:
5160 case ATH10K_FW_WMI_OP_VERSION_MAX:
5161 WARN_ON(1);
5162 ret = -EINVAL;
5163 goto err_free;
5076 } 5164 }
5077 5165
5078 ar->hw->netdev_features = NETIF_F_HW_CSUM; 5166 ar->hw->netdev_features = NETIF_F_HW_CSUM;
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 7abb8367119a..5e50214246f8 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -64,6 +64,14 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
64 {0} 64 {0}
65}; 65};
66 66
67static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
68 /* QCA988X pre 2.0 chips are not supported because they need some nasty
69 * hacks. ath10k doesn't have them and these devices crash horribly
70 * because of that.
71 */
72 { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
73};
74
67static void ath10k_pci_buffer_cleanup(struct ath10k *ar); 75static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
68static int ath10k_pci_cold_reset(struct ath10k *ar); 76static int ath10k_pci_cold_reset(struct ath10k *ar);
69static int ath10k_pci_warm_reset(struct ath10k *ar); 77static int ath10k_pci_warm_reset(struct ath10k *ar);
@@ -2476,6 +2484,23 @@ static void ath10k_pci_release(struct ath10k *ar)
2476 pci_disable_device(pdev); 2484 pci_disable_device(pdev);
2477} 2485}
2478 2486
2487static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id)
2488{
2489 const struct ath10k_pci_supp_chip *supp_chip;
2490 int i;
2491 u32 rev_id = MS(chip_id, SOC_CHIP_ID_REV);
2492
2493 for (i = 0; i < ARRAY_SIZE(ath10k_pci_supp_chips); i++) {
2494 supp_chip = &ath10k_pci_supp_chips[i];
2495
2496 if (supp_chip->dev_id == dev_id &&
2497 supp_chip->rev_id == rev_id)
2498 return true;
2499 }
2500
2501 return false;
2502}
2503
2479static int ath10k_pci_probe(struct pci_dev *pdev, 2504static int ath10k_pci_probe(struct pci_dev *pdev,
2480 const struct pci_device_id *pci_dev) 2505 const struct pci_device_id *pci_dev)
2481{ 2506{
@@ -2521,6 +2546,12 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2521 goto err_sleep; 2546 goto err_sleep;
2522 } 2547 }
2523 2548
2549 if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) {
2550 ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
2551 pdev->device, chip_id);
2552 goto err_sleep;
2553 }
2554
2524 ret = ath10k_pci_alloc_pipes(ar); 2555 ret = ath10k_pci_alloc_pipes(ar);
2525 if (ret) { 2556 if (ret) {
2526 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", 2557 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index cf36511c7f4d..ce4a1ef89961 100644
--- a/drivers/net/wireless/ath/ath10k/pci.h
+++ b/drivers/net/wireless/ath/ath10k/pci.h
@@ -152,6 +152,11 @@ struct ath10k_pci_pipe {
152 struct tasklet_struct intr; 152 struct tasklet_struct intr;
153}; 153};
154 154
155struct ath10k_pci_supp_chip {
156 u32 dev_id;
157 u32 rev_id;
158};
159
155struct ath10k_pci { 160struct ath10k_pci {
156 struct pci_dev *pdev; 161 struct pci_dev *pdev;
157 struct device *dev; 162 struct device *dev;
diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c
index 63ce61fcdac8..d22addf6118b 100644
--- a/drivers/net/wireless/ath/ath10k/spectral.c
+++ b/drivers/net/wireless/ath/ath10k/spectral.c
@@ -17,6 +17,7 @@
17#include <linux/relay.h> 17#include <linux/relay.h>
18#include "core.h" 18#include "core.h"
19#include "debug.h" 19#include "debug.h"
20#include "wmi-ops.h"
20 21
21static void send_fft_sample(struct ath10k *ar, 22static void send_fft_sample(struct ath10k *ar,
22 const struct fft_sample_tlv *fft_sample_tlv) 23 const struct fft_sample_tlv *fft_sample_tlv)
diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c
index 483db9cb8c96..b084f88da102 100644
--- a/drivers/net/wireless/ath/ath10k/testmode.c
+++ b/drivers/net/wireless/ath/ath10k/testmode.c
@@ -187,13 +187,14 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
187 187
188 memcpy(ar->testmode.orig_fw_features, ar->fw_features, 188 memcpy(ar->testmode.orig_fw_features, ar->fw_features,
189 sizeof(ar->fw_features)); 189 sizeof(ar->fw_features));
190 ar->testmode.orig_wmi_op_version = ar->wmi.op_version;
190 191
191 /* utf.bin firmware image does not advertise firmware features. Do 192 /* utf.bin firmware image does not advertise firmware features. Do
192 * an ugly hack where we force the firmware features so that wmi.c 193 * an ugly hack where we force the firmware features so that wmi.c
193 * will use the correct WMI interface. 194 * will use the correct WMI interface.
194 */ 195 */
195 memset(ar->fw_features, 0, sizeof(ar->fw_features)); 196 memset(ar->fw_features, 0, sizeof(ar->fw_features));
196 __set_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features); 197 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
197 198
198 ret = ath10k_hif_power_up(ar); 199 ret = ath10k_hif_power_up(ar);
199 if (ret) { 200 if (ret) {
@@ -224,6 +225,7 @@ err_fw_features:
224 /* return the original firmware features */ 225 /* return the original firmware features */
225 memcpy(ar->fw_features, ar->testmode.orig_fw_features, 226 memcpy(ar->fw_features, ar->testmode.orig_fw_features,
226 sizeof(ar->fw_features)); 227 sizeof(ar->fw_features));
228 ar->wmi.op_version = ar->testmode.orig_wmi_op_version;
227 229
228 release_firmware(ar->testmode.utf); 230 release_firmware(ar->testmode.utf);
229 ar->testmode.utf = NULL; 231 ar->testmode.utf = NULL;
@@ -250,6 +252,7 @@ static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar)
250 /* return the original firmware features */ 252 /* return the original firmware features */
251 memcpy(ar->fw_features, ar->testmode.orig_fw_features, 253 memcpy(ar->fw_features, ar->testmode.orig_fw_features,
252 sizeof(ar->fw_features)); 254 sizeof(ar->fw_features));
255 ar->wmi.op_version = ar->testmode.orig_wmi_op_version;
253 256
254 release_firmware(ar->testmode.utf); 257 release_firmware(ar->testmode.utf);
255 ar->testmode.utf = NULL; 258 ar->testmode.utf = NULL;
diff --git a/drivers/net/wireless/ath/ath10k/thermal.c b/drivers/net/wireless/ath/ath10k/thermal.c
new file mode 100644
index 000000000000..b14ae8d135f6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/device.h>
18#include <linux/sysfs.h>
19#include <linux/thermal.h>
20#include <linux/hwmon.h>
21#include <linux/hwmon-sysfs.h>
22#include "core.h"
23#include "debug.h"
24#include "wmi-ops.h"
25
26static int ath10k_thermal_get_active_vifs(struct ath10k *ar,
27 enum wmi_vdev_type type)
28{
29 struct ath10k_vif *arvif;
30 int count = 0;
31
32 lockdep_assert_held(&ar->conf_mutex);
33
34 list_for_each_entry(arvif, &ar->arvifs, list) {
35 if (!arvif->is_started)
36 continue;
37
38 if (!arvif->is_up)
39 continue;
40
41 if (arvif->vdev_type != type)
42 continue;
43
44 count++;
45 }
46 return count;
47}
48
49static int ath10k_thermal_get_max_dutycycle(struct thermal_cooling_device *cdev,
50 unsigned long *state)
51{
52 *state = ATH10K_QUIET_DUTY_CYCLE_MAX;
53
54 return 0;
55}
56
57static int ath10k_thermal_get_cur_dutycycle(struct thermal_cooling_device *cdev,
58 unsigned long *state)
59{
60 struct ath10k *ar = cdev->devdata;
61
62 mutex_lock(&ar->conf_mutex);
63 *state = ar->thermal.duty_cycle;
64 mutex_unlock(&ar->conf_mutex);
65
66 return 0;
67}
68
69static int ath10k_thermal_set_cur_dutycycle(struct thermal_cooling_device *cdev,
70 unsigned long duty_cycle)
71{
72 struct ath10k *ar = cdev->devdata;
73 u32 period, duration, enabled;
74 int num_bss, ret = 0;
75
76 mutex_lock(&ar->conf_mutex);
77 if (ar->state != ATH10K_STATE_ON) {
78 ret = -ENETDOWN;
79 goto out;
80 }
81
82 if (duty_cycle > ATH10K_QUIET_DUTY_CYCLE_MAX) {
83 ath10k_warn(ar, "duty cycle %ld is exceeding the limit %d\n",
84 duty_cycle, ATH10K_QUIET_DUTY_CYCLE_MAX);
85 ret = -EINVAL;
86 goto out;
87 }
88 /* TODO: Right now, thermal mitigation is handled only for single/multi
89 * vif AP mode. Since quiet param is not validated in STA mode, it needs
90 * to be investigated further to handle multi STA and multi-vif (AP+STA)
91 * mode properly.
92 */
93 num_bss = ath10k_thermal_get_active_vifs(ar, WMI_VDEV_TYPE_AP);
94 if (!num_bss) {
95 ath10k_warn(ar, "no active AP interfaces\n");
96 ret = -ENETDOWN;
97 goto out;
98 }
99 period = max(ATH10K_QUIET_PERIOD_MIN,
100 (ATH10K_QUIET_PERIOD_DEFAULT / num_bss));
101 duration = period * (duty_cycle / 100);
102 enabled = duration ? 1 : 0;
103
104 ret = ath10k_wmi_pdev_set_quiet_mode(ar, period, duration,
105 ATH10K_QUIET_START_OFFSET,
106 enabled);
107 if (ret) {
108 ath10k_warn(ar, "failed to set quiet mode period %u duarion %u enabled %u ret %d\n",
109 period, duration, enabled, ret);
110 goto out;
111 }
112 ar->thermal.duty_cycle = duty_cycle;
113out:
114 mutex_unlock(&ar->conf_mutex);
115 return ret;
116}
117
118static struct thermal_cooling_device_ops ath10k_thermal_ops = {
119 .get_max_state = ath10k_thermal_get_max_dutycycle,
120 .get_cur_state = ath10k_thermal_get_cur_dutycycle,
121 .set_cur_state = ath10k_thermal_set_cur_dutycycle,
122};
123
124static ssize_t ath10k_thermal_show_temp(struct device *dev,
125 struct device_attribute *attr,
126 char *buf)
127{
128 struct ath10k *ar = dev_get_drvdata(dev);
129 int ret, temperature;
130
131 mutex_lock(&ar->conf_mutex);
132
133 /* Can't get temperature when the card is off */
134 if (ar->state != ATH10K_STATE_ON) {
135 ret = -ENETDOWN;
136 goto out;
137 }
138
139 reinit_completion(&ar->thermal.wmi_sync);
140 ret = ath10k_wmi_pdev_get_temperature(ar);
141 if (ret) {
142 ath10k_warn(ar, "failed to read temperature %d\n", ret);
143 goto out;
144 }
145
146 if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
147 ret = -ESHUTDOWN;
148 goto out;
149 }
150
151 ret = wait_for_completion_timeout(&ar->thermal.wmi_sync,
152 ATH10K_THERMAL_SYNC_TIMEOUT_HZ);
153 if (ret == 0) {
154 ath10k_warn(ar, "failed to synchronize thermal read\n");
155 ret = -ETIMEDOUT;
156 goto out;
157 }
158
159 spin_lock_bh(&ar->data_lock);
160 temperature = ar->thermal.temperature;
161 spin_unlock_bh(&ar->data_lock);
162
163 ret = snprintf(buf, PAGE_SIZE, "%d", temperature);
164out:
165 mutex_unlock(&ar->conf_mutex);
166 return ret;
167}
168
169void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
170{
171 spin_lock_bh(&ar->data_lock);
172 ar->thermal.temperature = temperature;
173 spin_unlock_bh(&ar->data_lock);
174 complete(&ar->thermal.wmi_sync);
175}
176
177static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ath10k_thermal_show_temp,
178 NULL, 0);
179
180static struct attribute *ath10k_hwmon_attrs[] = {
181 &sensor_dev_attr_temp1_input.dev_attr.attr,
182 NULL,
183};
184ATTRIBUTE_GROUPS(ath10k_hwmon);
185
186int ath10k_thermal_register(struct ath10k *ar)
187{
188 struct thermal_cooling_device *cdev;
189 struct device *hwmon_dev;
190 int ret;
191
192 cdev = thermal_cooling_device_register("ath10k_thermal", ar,
193 &ath10k_thermal_ops);
194
195 if (IS_ERR(cdev)) {
196 ath10k_err(ar, "failed to setup thermal device result: %ld\n",
197 PTR_ERR(cdev));
198 return -EINVAL;
199 }
200
201 ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
202 "cooling_device");
203 if (ret) {
204 ath10k_err(ar, "failed to create thermal symlink\n");
205 goto err_cooling_destroy;
206 }
207
208 ar->thermal.cdev = cdev;
209
210 /* Do not register hwmon device when temperature reading is not
211 * supported by firmware
212 */
213 if (ar->wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4)
214 return 0;
215
216 /* Avoid linking error on devm_hwmon_device_register_with_groups, I
217 * guess linux/hwmon.h is missing proper stubs. */
218 if (!config_enabled(HWMON))
219 return 0;
220
221 hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
222 "ath10k_hwmon", ar,
223 ath10k_hwmon_groups);
224 if (IS_ERR(hwmon_dev)) {
225 ath10k_err(ar, "failed to register hwmon device: %ld\n",
226 PTR_ERR(hwmon_dev));
227 ret = -EINVAL;
228 goto err_remove_link;
229 }
230 return 0;
231
232err_remove_link:
233 sysfs_remove_link(&ar->dev->kobj, "thermal_sensor");
234err_cooling_destroy:
235 thermal_cooling_device_unregister(cdev);
236 return ret;
237}
238
239void ath10k_thermal_unregister(struct ath10k *ar)
240{
241 thermal_cooling_device_unregister(ar->thermal.cdev);
242 sysfs_remove_link(&ar->dev->kobj, "cooling_device");
243}
diff --git a/drivers/net/wireless/ath/ath10k/thermal.h b/drivers/net/wireless/ath/ath10k/thermal.h
new file mode 100644
index 000000000000..bccc17ae0fde
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef _THERMAL_
17#define _THERMAL_
18
19#define ATH10K_QUIET_PERIOD_DEFAULT 100
20#define ATH10K_QUIET_PERIOD_MIN 25
21#define ATH10K_QUIET_START_OFFSET 10
22#define ATH10K_QUIET_DUTY_CYCLE_MAX 70
23#define ATH10K_HWMON_NAME_LEN 15
24#define ATH10K_THERMAL_SYNC_TIMEOUT_HZ (5*HZ)
25
26struct ath10k_thermal {
27 struct thermal_cooling_device *cdev;
28 struct completion wmi_sync;
29
30 /* protected by conf_mutex */
31 u32 duty_cycle;
32 /* temperature value in Celcius degree
33 * protected by data_lock
34 */
35 int temperature;
36};
37
38#ifdef CONFIG_THERMAL
39int ath10k_thermal_register(struct ath10k *ar);
40void ath10k_thermal_unregister(struct ath10k *ar);
41void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
42#else
43static inline int ath10k_thermal_register(struct ath10k *ar)
44{
45 return 0;
46}
47
48static inline void ath10k_thermal_unregister(struct ath10k *ar)
49{
50}
51
52static inline void ath10k_thermal_event_temperature(struct ath10k *ar,
53 int temperature)
54{
55}
56
57#endif
58#endif /* _THERMAL_ */
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
new file mode 100644
index 000000000000..20e2c3002bb5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -0,0 +1,860 @@
1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
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 _WMI_OPS_H_
19#define _WMI_OPS_H_
20
21struct ath10k;
22struct sk_buff;
23
24struct wmi_ops {
25 void (*rx)(struct ath10k *ar, struct sk_buff *skb);
26 void (*map_svc)(const __le32 *in, unsigned long *out, size_t len);
27
28 int (*pull_scan)(struct ath10k *ar, struct sk_buff *skb,
29 struct wmi_scan_ev_arg *arg);
30 int (*pull_mgmt_rx)(struct ath10k *ar, struct sk_buff *skb,
31 struct wmi_mgmt_rx_ev_arg *arg);
32 int (*pull_ch_info)(struct ath10k *ar, struct sk_buff *skb,
33 struct wmi_ch_info_ev_arg *arg);
34 int (*pull_vdev_start)(struct ath10k *ar, struct sk_buff *skb,
35 struct wmi_vdev_start_ev_arg *arg);
36 int (*pull_peer_kick)(struct ath10k *ar, struct sk_buff *skb,
37 struct wmi_peer_kick_ev_arg *arg);
38 int (*pull_swba)(struct ath10k *ar, struct sk_buff *skb,
39 struct wmi_swba_ev_arg *arg);
40 int (*pull_phyerr)(struct ath10k *ar, struct sk_buff *skb,
41 struct wmi_phyerr_ev_arg *arg);
42 int (*pull_svc_rdy)(struct ath10k *ar, struct sk_buff *skb,
43 struct wmi_svc_rdy_ev_arg *arg);
44 int (*pull_rdy)(struct ath10k *ar, struct sk_buff *skb,
45 struct wmi_rdy_ev_arg *arg);
46 int (*pull_fw_stats)(struct ath10k *ar, struct sk_buff *skb,
47 struct ath10k_fw_stats *stats);
48
49 struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
50 struct sk_buff *(*gen_pdev_resume)(struct ath10k *ar);
51 struct sk_buff *(*gen_pdev_set_rd)(struct ath10k *ar, u16 rd, u16 rd2g,
52 u16 rd5g, u16 ctl2g, u16 ctl5g,
53 enum wmi_dfs_region dfs_reg);
54 struct sk_buff *(*gen_pdev_set_param)(struct ath10k *ar, u32 id,
55 u32 value);
56 struct sk_buff *(*gen_init)(struct ath10k *ar);
57 struct sk_buff *(*gen_start_scan)(struct ath10k *ar,
58 const struct wmi_start_scan_arg *arg);
59 struct sk_buff *(*gen_stop_scan)(struct ath10k *ar,
60 const struct wmi_stop_scan_arg *arg);
61 struct sk_buff *(*gen_vdev_create)(struct ath10k *ar, u32 vdev_id,
62 enum wmi_vdev_type type,
63 enum wmi_vdev_subtype subtype,
64 const u8 macaddr[ETH_ALEN]);
65 struct sk_buff *(*gen_vdev_delete)(struct ath10k *ar, u32 vdev_id);
66 struct sk_buff *(*gen_vdev_start)(struct ath10k *ar,
67 const struct wmi_vdev_start_request_arg *arg,
68 bool restart);
69 struct sk_buff *(*gen_vdev_stop)(struct ath10k *ar, u32 vdev_id);
70 struct sk_buff *(*gen_vdev_up)(struct ath10k *ar, u32 vdev_id, u32 aid,
71 const u8 *bssid);
72 struct sk_buff *(*gen_vdev_down)(struct ath10k *ar, u32 vdev_id);
73 struct sk_buff *(*gen_vdev_set_param)(struct ath10k *ar, u32 vdev_id,
74 u32 param_id, u32 param_value);
75 struct sk_buff *(*gen_vdev_install_key)(struct ath10k *ar,
76 const struct wmi_vdev_install_key_arg *arg);
77 struct sk_buff *(*gen_vdev_spectral_conf)(struct ath10k *ar,
78 const struct wmi_vdev_spectral_conf_arg *arg);
79 struct sk_buff *(*gen_vdev_spectral_enable)(struct ath10k *ar, u32 vdev_id,
80 u32 trigger, u32 enable);
81 struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id,
82 const u8 peer_addr[ETH_ALEN]);
83 struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id,
84 const u8 peer_addr[ETH_ALEN]);
85 struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id,
86 const u8 peer_addr[ETH_ALEN],
87 u32 tid_bitmap);
88 struct sk_buff *(*gen_peer_set_param)(struct ath10k *ar, u32 vdev_id,
89 const u8 *peer_addr,
90 enum wmi_peer_param param_id,
91 u32 param_value);
92 struct sk_buff *(*gen_peer_assoc)(struct ath10k *ar,
93 const struct wmi_peer_assoc_complete_arg *arg);
94 struct sk_buff *(*gen_set_psmode)(struct ath10k *ar, u32 vdev_id,
95 enum wmi_sta_ps_mode psmode);
96 struct sk_buff *(*gen_set_sta_ps)(struct ath10k *ar, u32 vdev_id,
97 enum wmi_sta_powersave_param param_id,
98 u32 value);
99 struct sk_buff *(*gen_set_ap_ps)(struct ath10k *ar, u32 vdev_id,
100 const u8 *mac,
101 enum wmi_ap_ps_peer_param param_id,
102 u32 value);
103 struct sk_buff *(*gen_scan_chan_list)(struct ath10k *ar,
104 const struct wmi_scan_chan_list_arg *arg);
105 struct sk_buff *(*gen_beacon_dma)(struct ath10k_vif *arvif);
106 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
107 const struct wmi_pdev_set_wmm_params_arg *arg);
108 struct sk_buff *(*gen_request_stats)(struct ath10k *ar,
109 enum wmi_stats_id stats_id);
110 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
111 enum wmi_force_fw_hang_type type,
112 u32 delay_ms);
113 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb);
114 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable);
115 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
116 struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar);
117 struct sk_buff *(*gen_pdev_set_quiet_mode)(struct ath10k *ar,
118 u32 period, u32 duration,
119 u32 next_offset,
120 u32 enabled);
121 struct sk_buff *(*gen_pdev_get_temperature)(struct ath10k *ar);
122};
123
124int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
125
126static inline int
127ath10k_wmi_rx(struct ath10k *ar, struct sk_buff *skb)
128{
129 if (WARN_ON_ONCE(!ar->wmi.ops->rx))
130 return -EOPNOTSUPP;
131
132 ar->wmi.ops->rx(ar, skb);
133 return 0;
134}
135
136static inline int
137ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out,
138 size_t len)
139{
140 if (!ar->wmi.ops->map_svc)
141 return -EOPNOTSUPP;
142
143 ar->wmi.ops->map_svc(in, out, len);
144 return 0;
145}
146
147static inline int
148ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb,
149 struct wmi_scan_ev_arg *arg)
150{
151 if (!ar->wmi.ops->pull_scan)
152 return -EOPNOTSUPP;
153
154 return ar->wmi.ops->pull_scan(ar, skb, arg);
155}
156
157static inline int
158ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb,
159 struct wmi_mgmt_rx_ev_arg *arg)
160{
161 if (!ar->wmi.ops->pull_mgmt_rx)
162 return -EOPNOTSUPP;
163
164 return ar->wmi.ops->pull_mgmt_rx(ar, skb, arg);
165}
166
167static inline int
168ath10k_wmi_pull_ch_info(struct ath10k *ar, struct sk_buff *skb,
169 struct wmi_ch_info_ev_arg *arg)
170{
171 if (!ar->wmi.ops->pull_ch_info)
172 return -EOPNOTSUPP;
173
174 return ar->wmi.ops->pull_ch_info(ar, skb, arg);
175}
176
177static inline int
178ath10k_wmi_pull_vdev_start(struct ath10k *ar, struct sk_buff *skb,
179 struct wmi_vdev_start_ev_arg *arg)
180{
181 if (!ar->wmi.ops->pull_vdev_start)
182 return -EOPNOTSUPP;
183
184 return ar->wmi.ops->pull_vdev_start(ar, skb, arg);
185}
186
187static inline int
188ath10k_wmi_pull_peer_kick(struct ath10k *ar, struct sk_buff *skb,
189 struct wmi_peer_kick_ev_arg *arg)
190{
191 if (!ar->wmi.ops->pull_peer_kick)
192 return -EOPNOTSUPP;
193
194 return ar->wmi.ops->pull_peer_kick(ar, skb, arg);
195}
196
197static inline int
198ath10k_wmi_pull_swba(struct ath10k *ar, struct sk_buff *skb,
199 struct wmi_swba_ev_arg *arg)
200{
201 if (!ar->wmi.ops->pull_swba)
202 return -EOPNOTSUPP;
203
204 return ar->wmi.ops->pull_swba(ar, skb, arg);
205}
206
207static inline int
208ath10k_wmi_pull_phyerr(struct ath10k *ar, struct sk_buff *skb,
209 struct wmi_phyerr_ev_arg *arg)
210{
211 if (!ar->wmi.ops->pull_phyerr)
212 return -EOPNOTSUPP;
213
214 return ar->wmi.ops->pull_phyerr(ar, skb, arg);
215}
216
217static inline int
218ath10k_wmi_pull_svc_rdy(struct ath10k *ar, struct sk_buff *skb,
219 struct wmi_svc_rdy_ev_arg *arg)
220{
221 if (!ar->wmi.ops->pull_svc_rdy)
222 return -EOPNOTSUPP;
223
224 return ar->wmi.ops->pull_svc_rdy(ar, skb, arg);
225}
226
227static inline int
228ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb,
229 struct wmi_rdy_ev_arg *arg)
230{
231 if (!ar->wmi.ops->pull_rdy)
232 return -EOPNOTSUPP;
233
234 return ar->wmi.ops->pull_rdy(ar, skb, arg);
235}
236
237static inline int
238ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
239 struct ath10k_fw_stats *stats)
240{
241 if (!ar->wmi.ops->pull_fw_stats)
242 return -EOPNOTSUPP;
243
244 return ar->wmi.ops->pull_fw_stats(ar, skb, stats);
245}
246
247static inline int
248ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
249{
250 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
251 struct sk_buff *skb;
252 int ret;
253
254 if (!ar->wmi.ops->gen_mgmt_tx)
255 return -EOPNOTSUPP;
256
257 skb = ar->wmi.ops->gen_mgmt_tx(ar, msdu);
258 if (IS_ERR(skb))
259 return PTR_ERR(skb);
260
261 ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid);
262 if (ret)
263 return ret;
264
265 /* FIXME There's no ACK event for Management Tx. This probably
266 * shouldn't be called here either. */
267 info->flags |= IEEE80211_TX_STAT_ACK;
268 ieee80211_tx_status_irqsafe(ar->hw, msdu);
269
270 return 0;
271}
272
273static inline int
274ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
275 u16 ctl2g, u16 ctl5g,
276 enum wmi_dfs_region dfs_reg)
277{
278 struct sk_buff *skb;
279
280 if (!ar->wmi.ops->gen_pdev_set_rd)
281 return -EOPNOTSUPP;
282
283 skb = ar->wmi.ops->gen_pdev_set_rd(ar, rd, rd2g, rd5g, ctl2g, ctl5g,
284 dfs_reg);
285 if (IS_ERR(skb))
286 return PTR_ERR(skb);
287
288 return ath10k_wmi_cmd_send(ar, skb,
289 ar->wmi.cmd->pdev_set_regdomain_cmdid);
290}
291
292static inline int
293ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
294{
295 struct sk_buff *skb;
296
297 if (!ar->wmi.ops->gen_pdev_suspend)
298 return -EOPNOTSUPP;
299
300 skb = ar->wmi.ops->gen_pdev_suspend(ar, suspend_opt);
301 if (IS_ERR(skb))
302 return PTR_ERR(skb);
303
304 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
305}
306
307static inline int
308ath10k_wmi_pdev_resume_target(struct ath10k *ar)
309{
310 struct sk_buff *skb;
311
312 if (!ar->wmi.ops->gen_pdev_resume)
313 return -EOPNOTSUPP;
314
315 skb = ar->wmi.ops->gen_pdev_resume(ar);
316 if (IS_ERR(skb))
317 return PTR_ERR(skb);
318
319 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid);
320}
321
322static inline int
323ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
324{
325 struct sk_buff *skb;
326
327 if (!ar->wmi.ops->gen_pdev_set_param)
328 return -EOPNOTSUPP;
329
330 skb = ar->wmi.ops->gen_pdev_set_param(ar, id, value);
331 if (IS_ERR(skb))
332 return PTR_ERR(skb);
333
334 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid);
335}
336
337static inline int
338ath10k_wmi_cmd_init(struct ath10k *ar)
339{
340 struct sk_buff *skb;
341
342 if (!ar->wmi.ops->gen_init)
343 return -EOPNOTSUPP;
344
345 skb = ar->wmi.ops->gen_init(ar);
346 if (IS_ERR(skb))
347 return PTR_ERR(skb);
348
349 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->init_cmdid);
350}
351
352static inline int
353ath10k_wmi_start_scan(struct ath10k *ar,
354 const struct wmi_start_scan_arg *arg)
355{
356 struct sk_buff *skb;
357
358 if (!ar->wmi.ops->gen_start_scan)
359 return -EOPNOTSUPP;
360
361 skb = ar->wmi.ops->gen_start_scan(ar, arg);
362 if (IS_ERR(skb))
363 return PTR_ERR(skb);
364
365 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid);
366}
367
368static inline int
369ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
370{
371 struct sk_buff *skb;
372
373 if (!ar->wmi.ops->gen_stop_scan)
374 return -EOPNOTSUPP;
375
376 skb = ar->wmi.ops->gen_stop_scan(ar, arg);
377 if (IS_ERR(skb))
378 return PTR_ERR(skb);
379
380 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid);
381}
382
383static inline int
384ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
385 enum wmi_vdev_type type,
386 enum wmi_vdev_subtype subtype,
387 const u8 macaddr[ETH_ALEN])
388{
389 struct sk_buff *skb;
390
391 if (!ar->wmi.ops->gen_vdev_create)
392 return -EOPNOTSUPP;
393
394 skb = ar->wmi.ops->gen_vdev_create(ar, vdev_id, type, subtype, macaddr);
395 if (IS_ERR(skb))
396 return PTR_ERR(skb);
397
398 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid);
399}
400
401static inline int
402ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
403{
404 struct sk_buff *skb;
405
406 if (!ar->wmi.ops->gen_vdev_delete)
407 return -EOPNOTSUPP;
408
409 skb = ar->wmi.ops->gen_vdev_delete(ar, vdev_id);
410 if (IS_ERR(skb))
411 return PTR_ERR(skb);
412
413 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
414}
415
416static inline int
417ath10k_wmi_vdev_start(struct ath10k *ar,
418 const struct wmi_vdev_start_request_arg *arg)
419{
420 struct sk_buff *skb;
421
422 if (!ar->wmi.ops->gen_vdev_start)
423 return -EOPNOTSUPP;
424
425 skb = ar->wmi.ops->gen_vdev_start(ar, arg, false);
426 if (IS_ERR(skb))
427 return PTR_ERR(skb);
428
429 return ath10k_wmi_cmd_send(ar, skb,
430 ar->wmi.cmd->vdev_start_request_cmdid);
431}
432
433static inline int
434ath10k_wmi_vdev_restart(struct ath10k *ar,
435 const struct wmi_vdev_start_request_arg *arg)
436{
437 struct sk_buff *skb;
438
439 if (!ar->wmi.ops->gen_vdev_start)
440 return -EOPNOTSUPP;
441
442 skb = ar->wmi.ops->gen_vdev_start(ar, arg, true);
443 if (IS_ERR(skb))
444 return PTR_ERR(skb);
445
446 return ath10k_wmi_cmd_send(ar, skb,
447 ar->wmi.cmd->vdev_restart_request_cmdid);
448}
449
450static inline int
451ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id)
452{
453 struct sk_buff *skb;
454
455 if (!ar->wmi.ops->gen_vdev_stop)
456 return -EOPNOTSUPP;
457
458 skb = ar->wmi.ops->gen_vdev_stop(ar, vdev_id);
459 if (IS_ERR(skb))
460 return PTR_ERR(skb);
461
462 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid);
463}
464
465static inline int
466ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
467{
468 struct sk_buff *skb;
469
470 if (!ar->wmi.ops->gen_vdev_up)
471 return -EOPNOTSUPP;
472
473 skb = ar->wmi.ops->gen_vdev_up(ar, vdev_id, aid, bssid);
474 if (IS_ERR(skb))
475 return PTR_ERR(skb);
476
477 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid);
478}
479
480static inline int
481ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id)
482{
483 struct sk_buff *skb;
484
485 if (!ar->wmi.ops->gen_vdev_down)
486 return -EOPNOTSUPP;
487
488 skb = ar->wmi.ops->gen_vdev_down(ar, vdev_id);
489 if (IS_ERR(skb))
490 return PTR_ERR(skb);
491
492 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid);
493}
494
495static inline int
496ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, u32 param_id,
497 u32 param_value)
498{
499 struct sk_buff *skb;
500
501 if (!ar->wmi.ops->gen_vdev_set_param)
502 return -EOPNOTSUPP;
503
504 skb = ar->wmi.ops->gen_vdev_set_param(ar, vdev_id, param_id,
505 param_value);
506 if (IS_ERR(skb))
507 return PTR_ERR(skb);
508
509 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid);
510}
511
512static inline int
513ath10k_wmi_vdev_install_key(struct ath10k *ar,
514 const struct wmi_vdev_install_key_arg *arg)
515{
516 struct sk_buff *skb;
517
518 if (!ar->wmi.ops->gen_vdev_install_key)
519 return -EOPNOTSUPP;
520
521 skb = ar->wmi.ops->gen_vdev_install_key(ar, arg);
522 if (IS_ERR(skb))
523 return PTR_ERR(skb);
524
525 return ath10k_wmi_cmd_send(ar, skb,
526 ar->wmi.cmd->vdev_install_key_cmdid);
527}
528
529static inline int
530ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
531 const struct wmi_vdev_spectral_conf_arg *arg)
532{
533 struct sk_buff *skb;
534 u32 cmd_id;
535
536 skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
537 if (IS_ERR(skb))
538 return PTR_ERR(skb);
539
540 cmd_id = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid;
541 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
542}
543
544static inline int
545ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
546 u32 enable)
547{
548 struct sk_buff *skb;
549 u32 cmd_id;
550
551 skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
552 enable);
553 if (IS_ERR(skb))
554 return PTR_ERR(skb);
555
556 cmd_id = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid;
557 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
558}
559
560static inline int
561ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
562 const u8 peer_addr[ETH_ALEN])
563{
564 struct sk_buff *skb;
565
566 if (!ar->wmi.ops->gen_peer_create)
567 return -EOPNOTSUPP;
568
569 skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr);
570 if (IS_ERR(skb))
571 return PTR_ERR(skb);
572
573 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid);
574}
575
576static inline int
577ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
578 const u8 peer_addr[ETH_ALEN])
579{
580 struct sk_buff *skb;
581
582 if (!ar->wmi.ops->gen_peer_delete)
583 return -EOPNOTSUPP;
584
585 skb = ar->wmi.ops->gen_peer_delete(ar, vdev_id, peer_addr);
586 if (IS_ERR(skb))
587 return PTR_ERR(skb);
588
589 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid);
590}
591
592static inline int
593ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
594 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
595{
596 struct sk_buff *skb;
597
598 if (!ar->wmi.ops->gen_peer_flush)
599 return -EOPNOTSUPP;
600
601 skb = ar->wmi.ops->gen_peer_flush(ar, vdev_id, peer_addr, tid_bitmap);
602 if (IS_ERR(skb))
603 return PTR_ERR(skb);
604
605 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid);
606}
607
608static inline int
609ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, const u8 *peer_addr,
610 enum wmi_peer_param param_id, u32 param_value)
611{
612 struct sk_buff *skb;
613
614 if (!ar->wmi.ops->gen_peer_set_param)
615 return -EOPNOTSUPP;
616
617 skb = ar->wmi.ops->gen_peer_set_param(ar, vdev_id, peer_addr, param_id,
618 param_value);
619 if (IS_ERR(skb))
620 return PTR_ERR(skb);
621
622 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid);
623}
624
625static inline int
626ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
627 enum wmi_sta_ps_mode psmode)
628{
629 struct sk_buff *skb;
630
631 if (!ar->wmi.ops->gen_set_psmode)
632 return -EOPNOTSUPP;
633
634 skb = ar->wmi.ops->gen_set_psmode(ar, vdev_id, psmode);
635 if (IS_ERR(skb))
636 return PTR_ERR(skb);
637
638 return ath10k_wmi_cmd_send(ar, skb,
639 ar->wmi.cmd->sta_powersave_mode_cmdid);
640}
641
642static inline int
643ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
644 enum wmi_sta_powersave_param param_id, u32 value)
645{
646 struct sk_buff *skb;
647
648 if (!ar->wmi.ops->gen_set_sta_ps)
649 return -EOPNOTSUPP;
650
651 skb = ar->wmi.ops->gen_set_sta_ps(ar, vdev_id, param_id, value);
652 if (IS_ERR(skb))
653 return PTR_ERR(skb);
654
655 return ath10k_wmi_cmd_send(ar, skb,
656 ar->wmi.cmd->sta_powersave_param_cmdid);
657}
658
659static inline int
660ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
661 enum wmi_ap_ps_peer_param param_id, u32 value)
662{
663 struct sk_buff *skb;
664
665 if (!ar->wmi.ops->gen_set_ap_ps)
666 return -EOPNOTSUPP;
667
668 skb = ar->wmi.ops->gen_set_ap_ps(ar, vdev_id, mac, param_id, value);
669 if (IS_ERR(skb))
670 return PTR_ERR(skb);
671
672 return ath10k_wmi_cmd_send(ar, skb,
673 ar->wmi.cmd->ap_ps_peer_param_cmdid);
674}
675
676static inline int
677ath10k_wmi_scan_chan_list(struct ath10k *ar,
678 const struct wmi_scan_chan_list_arg *arg)
679{
680 struct sk_buff *skb;
681
682 if (!ar->wmi.ops->gen_scan_chan_list)
683 return -EOPNOTSUPP;
684
685 skb = ar->wmi.ops->gen_scan_chan_list(ar, arg);
686 if (IS_ERR(skb))
687 return PTR_ERR(skb);
688
689 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid);
690}
691
692static inline int
693ath10k_wmi_peer_assoc(struct ath10k *ar,
694 const struct wmi_peer_assoc_complete_arg *arg)
695{
696 struct sk_buff *skb;
697
698 if (!ar->wmi.ops->gen_peer_assoc)
699 return -EOPNOTSUPP;
700
701 skb = ar->wmi.ops->gen_peer_assoc(ar, arg);
702 if (IS_ERR(skb))
703 return PTR_ERR(skb);
704
705 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
706}
707
708static inline int
709ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif)
710{
711 struct ath10k *ar = arvif->ar;
712 struct sk_buff *skb;
713 int ret;
714
715 if (!ar->wmi.ops->gen_beacon_dma)
716 return -EOPNOTSUPP;
717
718 skb = ar->wmi.ops->gen_beacon_dma(arvif);
719 if (IS_ERR(skb))
720 return PTR_ERR(skb);
721
722 ret = ath10k_wmi_cmd_send_nowait(ar, skb,
723 ar->wmi.cmd->pdev_send_bcn_cmdid);
724 if (ret) {
725 dev_kfree_skb(skb);
726 return ret;
727 }
728
729 return 0;
730}
731
732static inline int
733ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
734 const struct wmi_pdev_set_wmm_params_arg *arg)
735{
736 struct sk_buff *skb;
737
738 if (!ar->wmi.ops->gen_pdev_set_wmm)
739 return -EOPNOTSUPP;
740
741 skb = ar->wmi.ops->gen_pdev_set_wmm(ar, arg);
742 if (IS_ERR(skb))
743 return PTR_ERR(skb);
744
745 return ath10k_wmi_cmd_send(ar, skb,
746 ar->wmi.cmd->pdev_set_wmm_params_cmdid);
747}
748
749static inline int
750ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
751{
752 struct sk_buff *skb;
753
754 if (!ar->wmi.ops->gen_request_stats)
755 return -EOPNOTSUPP;
756
757 skb = ar->wmi.ops->gen_request_stats(ar, stats_id);
758 if (IS_ERR(skb))
759 return PTR_ERR(skb);
760
761 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid);
762}
763
764static inline int
765ath10k_wmi_force_fw_hang(struct ath10k *ar,
766 enum wmi_force_fw_hang_type type, u32 delay_ms)
767{
768 struct sk_buff *skb;
769
770 if (!ar->wmi.ops->gen_force_fw_hang)
771 return -EOPNOTSUPP;
772
773 skb = ar->wmi.ops->gen_force_fw_hang(ar, type, delay_ms);
774 if (IS_ERR(skb))
775 return PTR_ERR(skb);
776
777 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
778}
779
780static inline int
781ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
782{
783 struct sk_buff *skb;
784
785 if (!ar->wmi.ops->gen_dbglog_cfg)
786 return -EOPNOTSUPP;
787
788 skb = ar->wmi.ops->gen_dbglog_cfg(ar, module_enable);
789 if (IS_ERR(skb))
790 return PTR_ERR(skb);
791
792 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
793}
794
795static inline int
796ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 filter)
797{
798 struct sk_buff *skb;
799
800 if (!ar->wmi.ops->gen_pktlog_enable)
801 return -EOPNOTSUPP;
802
803 skb = ar->wmi.ops->gen_pktlog_enable(ar, filter);
804 if (IS_ERR(skb))
805 return PTR_ERR(skb);
806
807 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_pktlog_enable_cmdid);
808}
809
810static inline int
811ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar)
812{
813 struct sk_buff *skb;
814
815 if (!ar->wmi.ops->gen_pktlog_disable)
816 return -EOPNOTSUPP;
817
818 skb = ar->wmi.ops->gen_pktlog_disable(ar);
819 if (IS_ERR(skb))
820 return PTR_ERR(skb);
821
822 return ath10k_wmi_cmd_send(ar, skb,
823 ar->wmi.cmd->pdev_pktlog_disable_cmdid);
824}
825
826static inline int
827ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 period, u32 duration,
828 u32 next_offset, u32 enabled)
829{
830 struct sk_buff *skb;
831
832 if (!ar->wmi.ops->gen_pdev_set_quiet_mode)
833 return -EOPNOTSUPP;
834
835 skb = ar->wmi.ops->gen_pdev_set_quiet_mode(ar, period, duration,
836 next_offset, enabled);
837 if (IS_ERR(skb))
838 return PTR_ERR(skb);
839
840 return ath10k_wmi_cmd_send(ar, skb,
841 ar->wmi.cmd->pdev_set_quiet_mode_cmdid);
842}
843
844static inline int
845ath10k_wmi_pdev_get_temperature(struct ath10k *ar)
846{
847 struct sk_buff *skb;
848
849 if (!ar->wmi.ops->gen_pdev_get_temperature)
850 return -EOPNOTSUPP;
851
852 skb = ar->wmi.ops->gen_pdev_get_temperature(ar);
853 if (IS_ERR(skb))
854 return PTR_ERR(skb);
855
856 return ath10k_wmi_cmd_send(ar, skb,
857 ar->wmi.cmd->pdev_get_temperature_cmdid);
858}
859
860#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
new file mode 100644
index 000000000000..4c050cec3966
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -0,0 +1,2222 @@
1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
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 "core.h"
18#include "debug.h"
19#include "hw.h"
20#include "wmi.h"
21#include "wmi-ops.h"
22#include "wmi-tlv.h"
23
24/***************/
25/* TLV helpers */
26/**************/
27
28struct wmi_tlv_policy {
29 size_t min_len;
30};
31
32static const struct wmi_tlv_policy wmi_tlv_policies[] = {
33 [WMI_TLV_TAG_ARRAY_BYTE]
34 = { .min_len = sizeof(u8) },
35 [WMI_TLV_TAG_ARRAY_UINT32]
36 = { .min_len = sizeof(u32) },
37 [WMI_TLV_TAG_STRUCT_SCAN_EVENT]
38 = { .min_len = sizeof(struct wmi_scan_event) },
39 [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]
40 = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) },
41 [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]
42 = { .min_len = sizeof(struct wmi_chan_info_event) },
43 [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]
44 = { .min_len = sizeof(struct wmi_vdev_start_response_event) },
45 [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]
46 = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) },
47 [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT]
48 = { .min_len = sizeof(struct wmi_host_swba_event) },
49 [WMI_TLV_TAG_STRUCT_TIM_INFO]
50 = { .min_len = sizeof(struct wmi_tim_info) },
51 [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO]
52 = { .min_len = sizeof(struct wmi_p2p_noa_info) },
53 [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]
54 = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) },
55 [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]
56 = { .min_len = sizeof(struct hal_reg_capabilities) },
57 [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ]
58 = { .min_len = sizeof(struct wlan_host_mem_req) },
59 [WMI_TLV_TAG_STRUCT_READY_EVENT]
60 = { .min_len = sizeof(struct wmi_tlv_rdy_ev) },
61};
62
63static int
64ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
65 int (*iter)(struct ath10k *ar, u16 tag, u16 len,
66 const void *ptr, void *data),
67 void *data)
68{
69 const void *begin = ptr;
70 const struct wmi_tlv *tlv;
71 u16 tlv_tag, tlv_len;
72 int ret;
73
74 while (len > 0) {
75 if (len < sizeof(*tlv)) {
76 ath10k_dbg(ar, ATH10K_DBG_WMI,
77 "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
78 ptr - begin, len, sizeof(*tlv));
79 return -EINVAL;
80 }
81
82 tlv = ptr;
83 tlv_tag = __le16_to_cpu(tlv->tag);
84 tlv_len = __le16_to_cpu(tlv->len);
85 ptr += sizeof(*tlv);
86 len -= sizeof(*tlv);
87
88 if (tlv_len > len) {
89 ath10k_dbg(ar, ATH10K_DBG_WMI,
90 "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n",
91 tlv_tag, ptr - begin, len, tlv_len);
92 return -EINVAL;
93 }
94
95 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
96 wmi_tlv_policies[tlv_tag].min_len &&
97 wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
98 ath10k_dbg(ar, ATH10K_DBG_WMI,
99 "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n",
100 tlv_tag, ptr - begin, tlv_len,
101 wmi_tlv_policies[tlv_tag].min_len);
102 return -EINVAL;
103 }
104
105 ret = iter(ar, tlv_tag, tlv_len, ptr, data);
106 if (ret)
107 return ret;
108
109 ptr += tlv_len;
110 len -= tlv_len;
111 }
112
113 return 0;
114}
115
116static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
117 const void *ptr, void *data)
118{
119 const void **tb = data;
120
121 if (tag < WMI_TLV_TAG_MAX)
122 tb[tag] = ptr;
123
124 return 0;
125}
126
127static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
128 const void *ptr, size_t len)
129{
130 return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
131 (void *)tb);
132}
133
134static const void **
135ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
136 size_t len, gfp_t gfp)
137{
138 const void **tb;
139 int ret;
140
141 tb = kzalloc(sizeof(*tb) * WMI_TLV_TAG_MAX, gfp);
142 if (!tb)
143 return ERR_PTR(-ENOMEM);
144
145 ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
146 if (ret) {
147 kfree(tb);
148 return ERR_PTR(ret);
149 }
150
151 return tb;
152}
153
154static u16 ath10k_wmi_tlv_len(const void *ptr)
155{
156 return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
157}
158
159/***********/
160/* TLV ops */
161/***********/
162
163static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
164{
165 struct wmi_cmd_hdr *cmd_hdr;
166 enum wmi_tlv_event_id id;
167
168 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
169 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
170
171 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
172 return;
173
174 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
175
176 switch (id) {
177 case WMI_TLV_MGMT_RX_EVENTID:
178 ath10k_wmi_event_mgmt_rx(ar, skb);
179 /* mgmt_rx() owns the skb now! */
180 return;
181 case WMI_TLV_SCAN_EVENTID:
182 ath10k_wmi_event_scan(ar, skb);
183 break;
184 case WMI_TLV_CHAN_INFO_EVENTID:
185 ath10k_wmi_event_chan_info(ar, skb);
186 break;
187 case WMI_TLV_ECHO_EVENTID:
188 ath10k_wmi_event_echo(ar, skb);
189 break;
190 case WMI_TLV_DEBUG_MESG_EVENTID:
191 ath10k_wmi_event_debug_mesg(ar, skb);
192 break;
193 case WMI_TLV_UPDATE_STATS_EVENTID:
194 ath10k_wmi_event_update_stats(ar, skb);
195 break;
196 case WMI_TLV_VDEV_START_RESP_EVENTID:
197 ath10k_wmi_event_vdev_start_resp(ar, skb);
198 break;
199 case WMI_TLV_VDEV_STOPPED_EVENTID:
200 ath10k_wmi_event_vdev_stopped(ar, skb);
201 break;
202 case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
203 ath10k_wmi_event_peer_sta_kickout(ar, skb);
204 break;
205 case WMI_TLV_HOST_SWBA_EVENTID:
206 ath10k_wmi_event_host_swba(ar, skb);
207 break;
208 case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
209 ath10k_wmi_event_tbttoffset_update(ar, skb);
210 break;
211 case WMI_TLV_PHYERR_EVENTID:
212 ath10k_wmi_event_phyerr(ar, skb);
213 break;
214 case WMI_TLV_ROAM_EVENTID:
215 ath10k_wmi_event_roam(ar, skb);
216 break;
217 case WMI_TLV_PROFILE_MATCH:
218 ath10k_wmi_event_profile_match(ar, skb);
219 break;
220 case WMI_TLV_DEBUG_PRINT_EVENTID:
221 ath10k_wmi_event_debug_print(ar, skb);
222 break;
223 case WMI_TLV_PDEV_QVIT_EVENTID:
224 ath10k_wmi_event_pdev_qvit(ar, skb);
225 break;
226 case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
227 ath10k_wmi_event_wlan_profile_data(ar, skb);
228 break;
229 case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
230 ath10k_wmi_event_rtt_measurement_report(ar, skb);
231 break;
232 case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
233 ath10k_wmi_event_tsf_measurement_report(ar, skb);
234 break;
235 case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
236 ath10k_wmi_event_rtt_error_report(ar, skb);
237 break;
238 case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
239 ath10k_wmi_event_wow_wakeup_host(ar, skb);
240 break;
241 case WMI_TLV_DCS_INTERFERENCE_EVENTID:
242 ath10k_wmi_event_dcs_interference(ar, skb);
243 break;
244 case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
245 ath10k_wmi_event_pdev_tpc_config(ar, skb);
246 break;
247 case WMI_TLV_PDEV_FTM_INTG_EVENTID:
248 ath10k_wmi_event_pdev_ftm_intg(ar, skb);
249 break;
250 case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
251 ath10k_wmi_event_gtk_offload_status(ar, skb);
252 break;
253 case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
254 ath10k_wmi_event_gtk_rekey_fail(ar, skb);
255 break;
256 case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
257 ath10k_wmi_event_delba_complete(ar, skb);
258 break;
259 case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
260 ath10k_wmi_event_addba_complete(ar, skb);
261 break;
262 case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
263 ath10k_wmi_event_vdev_install_key_complete(ar, skb);
264 break;
265 case WMI_TLV_SERVICE_READY_EVENTID:
266 ath10k_wmi_event_service_ready(ar, skb);
267 break;
268 case WMI_TLV_READY_EVENTID:
269 ath10k_wmi_event_ready(ar, skb);
270 break;
271 default:
272 ath10k_warn(ar, "Unknown eventid: %d\n", id);
273 break;
274 }
275
276 dev_kfree_skb(skb);
277}
278
279static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
280 struct sk_buff *skb,
281 struct wmi_scan_ev_arg *arg)
282{
283 const void **tb;
284 const struct wmi_scan_event *ev;
285 int ret;
286
287 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
288 if (IS_ERR(tb)) {
289 ret = PTR_ERR(tb);
290 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
291 return ret;
292 }
293
294 ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
295 if (!ev) {
296 kfree(tb);
297 return -EPROTO;
298 }
299
300 arg->event_type = ev->event_type;
301 arg->reason = ev->reason;
302 arg->channel_freq = ev->channel_freq;
303 arg->scan_req_id = ev->scan_req_id;
304 arg->scan_id = ev->scan_id;
305 arg->vdev_id = ev->vdev_id;
306
307 kfree(tb);
308 return 0;
309}
310
311static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
312 struct sk_buff *skb,
313 struct wmi_mgmt_rx_ev_arg *arg)
314{
315 const void **tb;
316 const struct wmi_tlv_mgmt_rx_ev *ev;
317 const u8 *frame;
318 u32 msdu_len;
319 int ret;
320
321 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
322 if (IS_ERR(tb)) {
323 ret = PTR_ERR(tb);
324 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
325 return ret;
326 }
327
328 ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
329 frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
330
331 if (!ev || !frame) {
332 kfree(tb);
333 return -EPROTO;
334 }
335
336 arg->channel = ev->channel;
337 arg->buf_len = ev->buf_len;
338 arg->status = ev->status;
339 arg->snr = ev->snr;
340 arg->phy_mode = ev->phy_mode;
341 arg->rate = ev->rate;
342
343 msdu_len = __le32_to_cpu(arg->buf_len);
344
345 if (skb->len < (frame - skb->data) + msdu_len) {
346 kfree(tb);
347 return -EPROTO;
348 }
349
350 /* shift the sk_buff to point to `frame` */
351 skb_trim(skb, 0);
352 skb_put(skb, frame - skb->data);
353 skb_pull(skb, frame - skb->data);
354 skb_put(skb, msdu_len);
355
356 kfree(tb);
357 return 0;
358}
359
360static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
361 struct sk_buff *skb,
362 struct wmi_ch_info_ev_arg *arg)
363{
364 const void **tb;
365 const struct wmi_chan_info_event *ev;
366 int ret;
367
368 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
369 if (IS_ERR(tb)) {
370 ret = PTR_ERR(tb);
371 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
372 return ret;
373 }
374
375 ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
376 if (!ev) {
377 kfree(tb);
378 return -EPROTO;
379 }
380
381 arg->err_code = ev->err_code;
382 arg->freq = ev->freq;
383 arg->cmd_flags = ev->cmd_flags;
384 arg->noise_floor = ev->noise_floor;
385 arg->rx_clear_count = ev->rx_clear_count;
386 arg->cycle_count = ev->cycle_count;
387
388 kfree(tb);
389 return 0;
390}
391
392static int
393ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
394 struct wmi_vdev_start_ev_arg *arg)
395{
396 const void **tb;
397 const struct wmi_vdev_start_response_event *ev;
398 int ret;
399
400 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
401 if (IS_ERR(tb)) {
402 ret = PTR_ERR(tb);
403 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
404 return ret;
405 }
406
407 ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
408 if (!ev) {
409 kfree(tb);
410 return -EPROTO;
411 }
412
413 skb_pull(skb, sizeof(*ev));
414 arg->vdev_id = ev->vdev_id;
415 arg->req_id = ev->req_id;
416 arg->resp_type = ev->resp_type;
417 arg->status = ev->status;
418
419 kfree(tb);
420 return 0;
421}
422
423static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
424 struct sk_buff *skb,
425 struct wmi_peer_kick_ev_arg *arg)
426{
427 const void **tb;
428 const struct wmi_peer_sta_kickout_event *ev;
429 int ret;
430
431 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
432 if (IS_ERR(tb)) {
433 ret = PTR_ERR(tb);
434 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
435 return ret;
436 }
437
438 ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
439 if (!ev) {
440 kfree(tb);
441 return -EPROTO;
442 }
443
444 arg->mac_addr = ev->peer_macaddr.addr;
445
446 kfree(tb);
447 return 0;
448}
449
450struct wmi_tlv_swba_parse {
451 const struct wmi_host_swba_event *ev;
452 bool tim_done;
453 bool noa_done;
454 size_t n_tim;
455 size_t n_noa;
456 struct wmi_swba_ev_arg *arg;
457};
458
459static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
460 const void *ptr, void *data)
461{
462 struct wmi_tlv_swba_parse *swba = data;
463
464 if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
465 return -EPROTO;
466
467 if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
468 return -ENOBUFS;
469
470 swba->arg->tim_info[swba->n_tim++] = ptr;
471 return 0;
472}
473
474static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
475 const void *ptr, void *data)
476{
477 struct wmi_tlv_swba_parse *swba = data;
478
479 if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
480 return -EPROTO;
481
482 if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
483 return -ENOBUFS;
484
485 swba->arg->noa_info[swba->n_noa++] = ptr;
486 return 0;
487}
488
489static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
490 const void *ptr, void *data)
491{
492 struct wmi_tlv_swba_parse *swba = data;
493 int ret;
494
495 switch (tag) {
496 case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
497 swba->ev = ptr;
498 break;
499 case WMI_TLV_TAG_ARRAY_STRUCT:
500 if (!swba->tim_done) {
501 swba->tim_done = true;
502 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
503 ath10k_wmi_tlv_swba_tim_parse,
504 swba);
505 if (ret)
506 return ret;
507 } else if (!swba->noa_done) {
508 swba->noa_done = true;
509 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
510 ath10k_wmi_tlv_swba_noa_parse,
511 swba);
512 if (ret)
513 return ret;
514 }
515 break;
516 default:
517 break;
518 }
519 return 0;
520}
521
522static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
523 struct sk_buff *skb,
524 struct wmi_swba_ev_arg *arg)
525{
526 struct wmi_tlv_swba_parse swba = { .arg = arg };
527 u32 map;
528 size_t n_vdevs;
529 int ret;
530
531 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
532 ath10k_wmi_tlv_swba_parse, &swba);
533 if (ret) {
534 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
535 return ret;
536 }
537
538 if (!swba.ev)
539 return -EPROTO;
540
541 arg->vdev_map = swba.ev->vdev_map;
542
543 for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
544 if (map & BIT(0))
545 n_vdevs++;
546
547 if (n_vdevs != swba.n_tim ||
548 n_vdevs != swba.n_noa)
549 return -EPROTO;
550
551 return 0;
552}
553
554static int ath10k_wmi_tlv_op_pull_phyerr_ev(struct ath10k *ar,
555 struct sk_buff *skb,
556 struct wmi_phyerr_ev_arg *arg)
557{
558 const void **tb;
559 const struct wmi_tlv_phyerr_ev *ev;
560 const void *phyerrs;
561 int ret;
562
563 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
564 if (IS_ERR(tb)) {
565 ret = PTR_ERR(tb);
566 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
567 return ret;
568 }
569
570 ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
571 phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
572
573 if (!ev || !phyerrs) {
574 kfree(tb);
575 return -EPROTO;
576 }
577
578 arg->num_phyerrs = ev->num_phyerrs;
579 arg->tsf_l32 = ev->tsf_l32;
580 arg->tsf_u32 = ev->tsf_u32;
581 arg->buf_len = ev->buf_len;
582 arg->phyerrs = phyerrs;
583
584 kfree(tb);
585 return 0;
586}
587
588#define WMI_TLV_ABI_VER_NS0 0x5F414351
589#define WMI_TLV_ABI_VER_NS1 0x00004C4D
590#define WMI_TLV_ABI_VER_NS2 0x00000000
591#define WMI_TLV_ABI_VER_NS3 0x00000000
592
593#define WMI_TLV_ABI_VER0_MAJOR 1
594#define WMI_TLV_ABI_VER0_MINOR 0
595#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
596 (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF))
597#define WMI_TLV_ABI_VER1 53
598
599static int
600ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
601 const void *ptr, void *data)
602{
603 struct wmi_svc_rdy_ev_arg *arg = data;
604 int i;
605
606 if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
607 return -EPROTO;
608
609 for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
610 if (!arg->mem_reqs[i]) {
611 arg->mem_reqs[i] = ptr;
612 return 0;
613 }
614 }
615
616 return -ENOMEM;
617}
618
619static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
620 struct sk_buff *skb,
621 struct wmi_svc_rdy_ev_arg *arg)
622{
623 const void **tb;
624 const struct hal_reg_capabilities *reg;
625 const struct wmi_tlv_svc_rdy_ev *ev;
626 const __le32 *svc_bmap;
627 const struct wlan_host_mem_req *mem_reqs;
628 int ret;
629
630 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
631 if (IS_ERR(tb)) {
632 ret = PTR_ERR(tb);
633 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
634 return ret;
635 }
636
637 ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
638 reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
639 svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
640 mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
641
642 if (!ev || !reg || !svc_bmap || !mem_reqs) {
643 kfree(tb);
644 return -EPROTO;
645 }
646
647 /* This is an internal ABI compatibility check for WMI TLV so check it
648 * here instead of the generic WMI code.
649 */
650 ath10k_dbg(ar, ATH10K_DBG_WMI,
651 "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n",
652 __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
653 __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
654 __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
655 __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
656 __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
657
658 if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
659 __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
660 __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
661 __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
662 __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
663 kfree(tb);
664 return -ENOTSUPP;
665 }
666
667 arg->min_tx_power = ev->hw_min_tx_power;
668 arg->max_tx_power = ev->hw_max_tx_power;
669 arg->ht_cap = ev->ht_cap_info;
670 arg->vht_cap = ev->vht_cap_info;
671 arg->sw_ver0 = ev->abi.abi_ver0;
672 arg->sw_ver1 = ev->abi.abi_ver1;
673 arg->fw_build = ev->fw_build_vers;
674 arg->phy_capab = ev->phy_capability;
675 arg->num_rf_chains = ev->num_rf_chains;
676 arg->eeprom_rd = reg->eeprom_rd;
677 arg->num_mem_reqs = ev->num_mem_reqs;
678 arg->service_map = svc_bmap;
679 arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
680
681 ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
682 ath10k_wmi_tlv_parse_mem_reqs, arg);
683 if (ret) {
684 kfree(tb);
685 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
686 return ret;
687 }
688
689 kfree(tb);
690 return 0;
691}
692
693static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
694 struct sk_buff *skb,
695 struct wmi_rdy_ev_arg *arg)
696{
697 const void **tb;
698 const struct wmi_tlv_rdy_ev *ev;
699 int ret;
700
701 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
702 if (IS_ERR(tb)) {
703 ret = PTR_ERR(tb);
704 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
705 return ret;
706 }
707
708 ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
709 if (!ev) {
710 kfree(tb);
711 return -EPROTO;
712 }
713
714 arg->sw_version = ev->abi.abi_ver0;
715 arg->abi_version = ev->abi.abi_ver1;
716 arg->status = ev->status;
717 arg->mac_addr = ev->mac_addr.addr;
718
719 kfree(tb);
720 return 0;
721}
722
723static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
724 struct sk_buff *skb,
725 struct ath10k_fw_stats *stats)
726{
727 const void **tb;
728 const struct wmi_stats_event *ev;
729 const void *data;
730 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
731 size_t data_len;
732 int ret;
733
734 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
735 if (IS_ERR(tb)) {
736 ret = PTR_ERR(tb);
737 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
738 return ret;
739 }
740
741 ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
742 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
743
744 if (!ev || !data) {
745 kfree(tb);
746 return -EPROTO;
747 }
748
749 data_len = ath10k_wmi_tlv_len(data);
750 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
751 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
752 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
753
754 WARN_ON(1); /* FIXME: not implemented yet */
755
756 kfree(tb);
757 return 0;
758}
759
760static struct sk_buff *
761ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
762{
763 struct wmi_tlv_pdev_suspend *cmd;
764 struct wmi_tlv *tlv;
765 struct sk_buff *skb;
766
767 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
768 if (!skb)
769 return ERR_PTR(-ENOMEM);
770
771 tlv = (void *)skb->data;
772 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
773 tlv->len = __cpu_to_le16(sizeof(*cmd));
774 cmd = (void *)tlv->value;
775 cmd->opt = __cpu_to_le32(opt);
776
777 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
778 return skb;
779}
780
781static struct sk_buff *
782ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
783{
784 struct wmi_tlv_resume_cmd *cmd;
785 struct wmi_tlv *tlv;
786 struct sk_buff *skb;
787
788 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
789 if (!skb)
790 return ERR_PTR(-ENOMEM);
791
792 tlv = (void *)skb->data;
793 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
794 tlv->len = __cpu_to_le16(sizeof(*cmd));
795 cmd = (void *)tlv->value;
796 cmd->reserved = __cpu_to_le32(0);
797
798 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
799 return skb;
800}
801
802static struct sk_buff *
803ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
804 u16 rd, u16 rd2g, u16 rd5g,
805 u16 ctl2g, u16 ctl5g,
806 enum wmi_dfs_region dfs_reg)
807{
808 struct wmi_tlv_pdev_set_rd_cmd *cmd;
809 struct wmi_tlv *tlv;
810 struct sk_buff *skb;
811
812 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
813 if (!skb)
814 return ERR_PTR(-ENOMEM);
815
816 tlv = (void *)skb->data;
817 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
818 tlv->len = __cpu_to_le16(sizeof(*cmd));
819 cmd = (void *)tlv->value;
820 cmd->regd = __cpu_to_le32(rd);
821 cmd->regd_2ghz = __cpu_to_le32(rd2g);
822 cmd->regd_5ghz = __cpu_to_le32(rd5g);
823 cmd->conform_limit_2ghz = __cpu_to_le32(rd2g);
824 cmd->conform_limit_5ghz = __cpu_to_le32(rd5g);
825
826 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
827 return skb;
828}
829
830static struct sk_buff *
831ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
832 u32 param_value)
833{
834 struct wmi_tlv_pdev_set_param_cmd *cmd;
835 struct wmi_tlv *tlv;
836 struct sk_buff *skb;
837
838 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
839 if (!skb)
840 return ERR_PTR(-ENOMEM);
841
842 tlv = (void *)skb->data;
843 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
844 tlv->len = __cpu_to_le16(sizeof(*cmd));
845 cmd = (void *)tlv->value;
846 cmd->param_id = __cpu_to_le32(param_id);
847 cmd->param_value = __cpu_to_le32(param_value);
848
849 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param\n");
850 return skb;
851}
852
853static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
854{
855 struct sk_buff *skb;
856 struct wmi_tlv *tlv;
857 struct wmi_tlv_init_cmd *cmd;
858 struct wmi_tlv_resource_config *cfg;
859 struct wmi_host_mem_chunks *chunks;
860 size_t len, chunks_len;
861 void *ptr;
862
863 chunks_len = ar->wmi.num_mem_chunks * sizeof(struct host_memory_chunk);
864 len = (sizeof(*tlv) + sizeof(*cmd)) +
865 (sizeof(*tlv) + sizeof(*cfg)) +
866 (sizeof(*tlv) + chunks_len);
867
868 skb = ath10k_wmi_alloc_skb(ar, len);
869 if (!skb)
870 return ERR_PTR(-ENOMEM);
871
872 ptr = skb->data;
873
874 tlv = ptr;
875 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
876 tlv->len = __cpu_to_le16(sizeof(*cmd));
877 cmd = (void *)tlv->value;
878 ptr += sizeof(*tlv);
879 ptr += sizeof(*cmd);
880
881 tlv = ptr;
882 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
883 tlv->len = __cpu_to_le16(sizeof(*cfg));
884 cfg = (void *)tlv->value;
885 ptr += sizeof(*tlv);
886 ptr += sizeof(*cfg);
887
888 tlv = ptr;
889 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
890 tlv->len = __cpu_to_le16(chunks_len);
891 chunks = (void *)tlv->value;
892
893 ptr += sizeof(*tlv);
894 ptr += chunks_len;
895
896 cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
897 cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
898 cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
899 cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
900 cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
901 cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
902 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
903
904 cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
905 cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
906 cfg->num_offload_peers = __cpu_to_le32(0);
907 cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
908 cfg->num_peer_keys = __cpu_to_le32(2);
909 cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
910 cfg->ast_skid_limit = __cpu_to_le32(0x10);
911 cfg->tx_chain_mask = __cpu_to_le32(0x7);
912 cfg->rx_chain_mask = __cpu_to_le32(0x7);
913 cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
914 cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
915 cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
916 cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
917 cfg->rx_decap_mode = __cpu_to_le32(1);
918 cfg->scan_max_pending_reqs = __cpu_to_le32(4);
919 cfg->bmiss_offload_max_vdev = __cpu_to_le32(3);
920 cfg->roam_offload_max_vdev = __cpu_to_le32(3);
921 cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
922 cfg->num_mcast_groups = __cpu_to_le32(0);
923 cfg->num_mcast_table_elems = __cpu_to_le32(0);
924 cfg->mcast2ucast_mode = __cpu_to_le32(0);
925 cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
926 cfg->num_wds_entries = __cpu_to_le32(0x20);
927 cfg->dma_burst_size = __cpu_to_le32(0);
928 cfg->mac_aggr_delim = __cpu_to_le32(0);
929 cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
930 cfg->vow_config = __cpu_to_le32(0);
931 cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
932 cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
933 cfg->max_frag_entries = __cpu_to_le32(2);
934 cfg->num_tdls_vdevs = __cpu_to_le32(1);
935 cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
936 cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
937 cfg->num_multicast_filter_entries = __cpu_to_le32(5);
938 cfg->num_wow_filters = __cpu_to_le32(0x16);
939 cfg->num_keep_alive_pattern = __cpu_to_le32(6);
940 cfg->keep_alive_pattern_size = __cpu_to_le32(0);
941 cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
942 cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
943
944 ath10k_wmi_put_host_mem_chunks(ar, chunks);
945
946 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
947 return skb;
948}
949
950static struct sk_buff *
951ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
952 const struct wmi_start_scan_arg *arg)
953{
954 struct wmi_tlv_start_scan_cmd *cmd;
955 struct wmi_tlv *tlv;
956 struct sk_buff *skb;
957 size_t len, chan_len, ssid_len, bssid_len, ie_len;
958 __le32 *chans;
959 struct wmi_ssid *ssids;
960 struct wmi_mac_addr *addrs;
961 void *ptr;
962 int i, ret;
963
964 ret = ath10k_wmi_start_scan_verify(arg);
965 if (ret)
966 return ERR_PTR(ret);
967
968 chan_len = arg->n_channels * sizeof(__le32);
969 ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
970 bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
971 ie_len = roundup(arg->ie_len, 4);
972 len = (sizeof(*tlv) + sizeof(*cmd)) +
973 (arg->n_channels ? sizeof(*tlv) + chan_len : 0) +
974 (arg->n_ssids ? sizeof(*tlv) + ssid_len : 0) +
975 (arg->n_bssids ? sizeof(*tlv) + bssid_len : 0) +
976 (arg->ie_len ? sizeof(*tlv) + ie_len : 0);
977
978 skb = ath10k_wmi_alloc_skb(ar, len);
979 if (!skb)
980 return ERR_PTR(-ENOMEM);
981
982 ptr = (void *)skb->data;
983 tlv = ptr;
984 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
985 tlv->len = __cpu_to_le16(sizeof(*cmd));
986 cmd = (void *)tlv->value;
987
988 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
989 cmd->burst_duration_ms = __cpu_to_le32(0);
990 cmd->num_channels = __cpu_to_le32(arg->n_channels);
991 cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
992 cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
993 cmd->ie_len = __cpu_to_le32(arg->ie_len);
994 cmd->num_probes = __cpu_to_le32(3);
995
996 /* FIXME: There are some scan flag inconsistencies across firmwares,
997 * e.g. WMI-TLV inverts the logic behind the following flag.
998 */
999 cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
1000
1001 ptr += sizeof(*tlv);
1002 ptr += sizeof(*cmd);
1003
1004 tlv = ptr;
1005 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1006 tlv->len = __cpu_to_le16(chan_len);
1007 chans = (void *)tlv->value;
1008 for (i = 0; i < arg->n_channels; i++)
1009 chans[i] = __cpu_to_le32(arg->channels[i]);
1010
1011 ptr += sizeof(*tlv);
1012 ptr += chan_len;
1013
1014 tlv = ptr;
1015 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1016 tlv->len = __cpu_to_le16(ssid_len);
1017 ssids = (void *)tlv->value;
1018 for (i = 0; i < arg->n_ssids; i++) {
1019 ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
1020 memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
1021 }
1022
1023 ptr += sizeof(*tlv);
1024 ptr += ssid_len;
1025
1026 tlv = ptr;
1027 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1028 tlv->len = __cpu_to_le16(bssid_len);
1029 addrs = (void *)tlv->value;
1030 for (i = 0; i < arg->n_bssids; i++)
1031 ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
1032
1033 ptr += sizeof(*tlv);
1034 ptr += bssid_len;
1035
1036 tlv = ptr;
1037 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1038 tlv->len = __cpu_to_le16(ie_len);
1039 memcpy(tlv->value, arg->ie, arg->ie_len);
1040
1041 ptr += sizeof(*tlv);
1042 ptr += ie_len;
1043
1044 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
1045 return skb;
1046}
1047
1048static struct sk_buff *
1049ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
1050 const struct wmi_stop_scan_arg *arg)
1051{
1052 struct wmi_stop_scan_cmd *cmd;
1053 struct wmi_tlv *tlv;
1054 struct sk_buff *skb;
1055 u32 scan_id;
1056 u32 req_id;
1057
1058 if (arg->req_id > 0xFFF)
1059 return ERR_PTR(-EINVAL);
1060 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
1061 return ERR_PTR(-EINVAL);
1062
1063 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1064 if (!skb)
1065 return ERR_PTR(-ENOMEM);
1066
1067 scan_id = arg->u.scan_id;
1068 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
1069
1070 req_id = arg->req_id;
1071 req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
1072
1073 tlv = (void *)skb->data;
1074 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
1075 tlv->len = __cpu_to_le16(sizeof(*cmd));
1076 cmd = (void *)tlv->value;
1077 cmd->req_type = __cpu_to_le32(arg->req_type);
1078 cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
1079 cmd->scan_id = __cpu_to_le32(scan_id);
1080 cmd->scan_req_id = __cpu_to_le32(req_id);
1081
1082 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
1083 return skb;
1084}
1085
1086static struct sk_buff *
1087ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
1088 u32 vdev_id,
1089 enum wmi_vdev_type vdev_type,
1090 enum wmi_vdev_subtype vdev_subtype,
1091 const u8 mac_addr[ETH_ALEN])
1092{
1093 struct wmi_vdev_create_cmd *cmd;
1094 struct wmi_tlv *tlv;
1095 struct sk_buff *skb;
1096
1097 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1098 if (!skb)
1099 return ERR_PTR(-ENOMEM);
1100
1101 tlv = (void *)skb->data;
1102 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
1103 tlv->len = __cpu_to_le16(sizeof(*cmd));
1104 cmd = (void *)tlv->value;
1105 cmd->vdev_id = __cpu_to_le32(vdev_id);
1106 cmd->vdev_type = __cpu_to_le32(vdev_type);
1107 cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
1108 ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
1109
1110 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
1111 return skb;
1112}
1113
1114static struct sk_buff *
1115ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
1116{
1117 struct wmi_vdev_delete_cmd *cmd;
1118 struct wmi_tlv *tlv;
1119 struct sk_buff *skb;
1120
1121 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1122 if (!skb)
1123 return ERR_PTR(-ENOMEM);
1124
1125 tlv = (void *)skb->data;
1126 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
1127 tlv->len = __cpu_to_le16(sizeof(*cmd));
1128 cmd = (void *)tlv->value;
1129 cmd->vdev_id = __cpu_to_le32(vdev_id);
1130
1131 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
1132 return skb;
1133}
1134
1135static struct sk_buff *
1136ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
1137 const struct wmi_vdev_start_request_arg *arg,
1138 bool restart)
1139{
1140 struct wmi_tlv_vdev_start_cmd *cmd;
1141 struct wmi_channel *ch;
1142 struct wmi_p2p_noa_descriptor *noa;
1143 struct wmi_tlv *tlv;
1144 struct sk_buff *skb;
1145 size_t len;
1146 void *ptr;
1147 u32 flags = 0;
1148
1149 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
1150 return ERR_PTR(-EINVAL);
1151 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
1152 return ERR_PTR(-EINVAL);
1153 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
1154 return ERR_PTR(-EINVAL);
1155
1156 len = (sizeof(*tlv) + sizeof(*cmd)) +
1157 (sizeof(*tlv) + sizeof(*ch)) +
1158 (sizeof(*tlv) + 0);
1159 skb = ath10k_wmi_alloc_skb(ar, len);
1160 if (!skb)
1161 return ERR_PTR(-ENOMEM);
1162
1163 if (arg->hidden_ssid)
1164 flags |= WMI_VDEV_START_HIDDEN_SSID;
1165 if (arg->pmf_enabled)
1166 flags |= WMI_VDEV_START_PMF_ENABLED;
1167
1168 ptr = (void *)skb->data;
1169
1170 tlv = ptr;
1171 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
1172 tlv->len = __cpu_to_le16(sizeof(*cmd));
1173 cmd = (void *)tlv->value;
1174 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1175 cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
1176 cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
1177 cmd->flags = __cpu_to_le32(flags);
1178 cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
1179 cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
1180 cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
1181
1182 if (arg->ssid) {
1183 cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
1184 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
1185 }
1186
1187 ptr += sizeof(*tlv);
1188 ptr += sizeof(*cmd);
1189
1190 tlv = ptr;
1191 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1192 tlv->len = __cpu_to_le16(sizeof(*ch));
1193 ch = (void *)tlv->value;
1194 ath10k_wmi_put_wmi_channel(ch, &arg->channel);
1195
1196 ptr += sizeof(*tlv);
1197 ptr += sizeof(*ch);
1198
1199 tlv = ptr;
1200 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1201 tlv->len = 0;
1202 noa = (void *)tlv->value;
1203
1204 /* Note: This is a nested TLV containing:
1205 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
1206 */
1207
1208 ptr += sizeof(*tlv);
1209 ptr += 0;
1210
1211 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
1212 return skb;
1213}
1214
1215static struct sk_buff *
1216ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
1217{
1218 struct wmi_vdev_stop_cmd *cmd;
1219 struct wmi_tlv *tlv;
1220 struct sk_buff *skb;
1221
1222 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1223 if (!skb)
1224 return ERR_PTR(-ENOMEM);
1225
1226 tlv = (void *)skb->data;
1227 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
1228 tlv->len = __cpu_to_le16(sizeof(*cmd));
1229 cmd = (void *)tlv->value;
1230 cmd->vdev_id = __cpu_to_le32(vdev_id);
1231
1232 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
1233 return skb;
1234}
1235
1236static struct sk_buff *
1237ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
1238 const u8 *bssid)
1239
1240{
1241 struct wmi_vdev_up_cmd *cmd;
1242 struct wmi_tlv *tlv;
1243 struct sk_buff *skb;
1244
1245 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1246 if (!skb)
1247 return ERR_PTR(-ENOMEM);
1248
1249 tlv = (void *)skb->data;
1250 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
1251 tlv->len = __cpu_to_le16(sizeof(*cmd));
1252 cmd = (void *)tlv->value;
1253 cmd->vdev_id = __cpu_to_le32(vdev_id);
1254 cmd->vdev_assoc_id = __cpu_to_le32(aid);
1255 ether_addr_copy(cmd->vdev_bssid.addr, bssid);
1256
1257 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
1258 return skb;
1259}
1260
1261static struct sk_buff *
1262ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
1263{
1264 struct wmi_vdev_down_cmd *cmd;
1265 struct wmi_tlv *tlv;
1266 struct sk_buff *skb;
1267
1268 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1269 if (!skb)
1270 return ERR_PTR(-ENOMEM);
1271
1272 tlv = (void *)skb->data;
1273 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
1274 tlv->len = __cpu_to_le16(sizeof(*cmd));
1275 cmd = (void *)tlv->value;
1276 cmd->vdev_id = __cpu_to_le32(vdev_id);
1277
1278 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
1279 return skb;
1280}
1281
1282static struct sk_buff *
1283ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
1284 u32 param_id, u32 param_value)
1285{
1286 struct wmi_vdev_set_param_cmd *cmd;
1287 struct wmi_tlv *tlv;
1288 struct sk_buff *skb;
1289
1290 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1291 if (!skb)
1292 return ERR_PTR(-ENOMEM);
1293
1294 tlv = (void *)skb->data;
1295 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
1296 tlv->len = __cpu_to_le16(sizeof(*cmd));
1297 cmd = (void *)tlv->value;
1298 cmd->vdev_id = __cpu_to_le32(vdev_id);
1299 cmd->param_id = __cpu_to_le32(param_id);
1300 cmd->param_value = __cpu_to_le32(param_value);
1301
1302 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev set param\n");
1303 return skb;
1304}
1305
1306static struct sk_buff *
1307ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
1308 const struct wmi_vdev_install_key_arg *arg)
1309{
1310 struct wmi_vdev_install_key_cmd *cmd;
1311 struct wmi_tlv *tlv;
1312 struct sk_buff *skb;
1313 size_t len;
1314 void *ptr;
1315
1316 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
1317 return ERR_PTR(-EINVAL);
1318 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
1319 return ERR_PTR(-EINVAL);
1320
1321 len = sizeof(*tlv) + sizeof(*cmd) +
1322 sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
1323 skb = ath10k_wmi_alloc_skb(ar, len);
1324 if (!skb)
1325 return ERR_PTR(-ENOMEM);
1326
1327 ptr = (void *)skb->data;
1328 tlv = ptr;
1329 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
1330 tlv->len = __cpu_to_le16(sizeof(*cmd));
1331 cmd = (void *)tlv->value;
1332 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1333 cmd->key_idx = __cpu_to_le32(arg->key_idx);
1334 cmd->key_flags = __cpu_to_le32(arg->key_flags);
1335 cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
1336 cmd->key_len = __cpu_to_le32(arg->key_len);
1337 cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
1338 cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
1339
1340 if (arg->macaddr)
1341 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
1342
1343 ptr += sizeof(*tlv);
1344 ptr += sizeof(*cmd);
1345
1346 tlv = ptr;
1347 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1348 tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
1349 if (arg->key_data)
1350 memcpy(tlv->value, arg->key_data, arg->key_len);
1351
1352 ptr += sizeof(*tlv);
1353 ptr += roundup(arg->key_len, sizeof(__le32));
1354
1355 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
1356 return skb;
1357}
1358
1359static struct sk_buff *
1360ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
1361 const u8 peer_addr[ETH_ALEN])
1362{
1363 struct wmi_tlv_peer_create_cmd *cmd;
1364 struct wmi_tlv *tlv;
1365 struct sk_buff *skb;
1366
1367 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1368 if (!skb)
1369 return ERR_PTR(-ENOMEM);
1370
1371 tlv = (void *)skb->data;
1372 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
1373 tlv->len = __cpu_to_le16(sizeof(*cmd));
1374 cmd = (void *)tlv->value;
1375 cmd->vdev_id = __cpu_to_le32(vdev_id);
1376 cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */
1377 ether_addr_copy(cmd->peer_addr.addr, peer_addr);
1378
1379 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
1380 return skb;
1381}
1382
1383static struct sk_buff *
1384ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
1385 const u8 peer_addr[ETH_ALEN])
1386{
1387 struct wmi_peer_delete_cmd *cmd;
1388 struct wmi_tlv *tlv;
1389 struct sk_buff *skb;
1390
1391 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1392 if (!skb)
1393 return ERR_PTR(-ENOMEM);
1394
1395 tlv = (void *)skb->data;
1396 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
1397 tlv->len = __cpu_to_le16(sizeof(*cmd));
1398 cmd = (void *)tlv->value;
1399 cmd->vdev_id = __cpu_to_le32(vdev_id);
1400 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1401
1402 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
1403 return skb;
1404}
1405
1406static struct sk_buff *
1407ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
1408 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
1409{
1410 struct wmi_peer_flush_tids_cmd *cmd;
1411 struct wmi_tlv *tlv;
1412 struct sk_buff *skb;
1413
1414 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1415 if (!skb)
1416 return ERR_PTR(-ENOMEM);
1417
1418 tlv = (void *)skb->data;
1419 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
1420 tlv->len = __cpu_to_le16(sizeof(*cmd));
1421 cmd = (void *)tlv->value;
1422 cmd->vdev_id = __cpu_to_le32(vdev_id);
1423 cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
1424 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1425
1426 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
1427 return skb;
1428}
1429
1430static struct sk_buff *
1431ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
1432 const u8 *peer_addr,
1433 enum wmi_peer_param param_id,
1434 u32 param_value)
1435{
1436 struct wmi_peer_set_param_cmd *cmd;
1437 struct wmi_tlv *tlv;
1438 struct sk_buff *skb;
1439
1440 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1441 if (!skb)
1442 return ERR_PTR(-ENOMEM);
1443
1444 tlv = (void *)skb->data;
1445 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
1446 tlv->len = __cpu_to_le16(sizeof(*cmd));
1447 cmd = (void *)tlv->value;
1448 cmd->vdev_id = __cpu_to_le32(vdev_id);
1449 cmd->param_id = __cpu_to_le32(param_id);
1450 cmd->param_value = __cpu_to_le32(param_value);
1451 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1452
1453 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer set param\n");
1454 return skb;
1455}
1456
1457static struct sk_buff *
1458ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
1459 const struct wmi_peer_assoc_complete_arg *arg)
1460{
1461 struct wmi_tlv_peer_assoc_cmd *cmd;
1462 struct wmi_vht_rate_set *vht_rate;
1463 struct wmi_tlv *tlv;
1464 struct sk_buff *skb;
1465 size_t len, legacy_rate_len, ht_rate_len;
1466 void *ptr;
1467
1468 if (arg->peer_mpdu_density > 16)
1469 return ERR_PTR(-EINVAL);
1470 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
1471 return ERR_PTR(-EINVAL);
1472 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
1473 return ERR_PTR(-EINVAL);
1474
1475 legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
1476 sizeof(__le32));
1477 ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
1478 len = (sizeof(*tlv) + sizeof(*cmd)) +
1479 (sizeof(*tlv) + legacy_rate_len) +
1480 (sizeof(*tlv) + ht_rate_len) +
1481 (sizeof(*tlv) + sizeof(*vht_rate));
1482 skb = ath10k_wmi_alloc_skb(ar, len);
1483 if (!skb)
1484 return ERR_PTR(-ENOMEM);
1485
1486 ptr = (void *)skb->data;
1487 tlv = ptr;
1488 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
1489 tlv->len = __cpu_to_le16(sizeof(*cmd));
1490 cmd = (void *)tlv->value;
1491
1492 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1493 cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
1494 cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
1495 cmd->flags = __cpu_to_le32(arg->peer_flags);
1496 cmd->caps = __cpu_to_le32(arg->peer_caps);
1497 cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
1498 cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
1499 cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
1500 cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
1501 cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
1502 cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
1503 cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
1504 cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
1505 cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
1506 cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
1507 ether_addr_copy(cmd->mac_addr.addr, arg->addr);
1508
1509 ptr += sizeof(*tlv);
1510 ptr += sizeof(*cmd);
1511
1512 tlv = ptr;
1513 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1514 tlv->len = __cpu_to_le16(legacy_rate_len);
1515 memcpy(tlv->value, arg->peer_legacy_rates.rates,
1516 arg->peer_legacy_rates.num_rates);
1517
1518 ptr += sizeof(*tlv);
1519 ptr += legacy_rate_len;
1520
1521 tlv = ptr;
1522 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1523 tlv->len = __cpu_to_le16(ht_rate_len);
1524 memcpy(tlv->value, arg->peer_ht_rates.rates,
1525 arg->peer_ht_rates.num_rates);
1526
1527 ptr += sizeof(*tlv);
1528 ptr += ht_rate_len;
1529
1530 tlv = ptr;
1531 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
1532 tlv->len = __cpu_to_le16(sizeof(*vht_rate));
1533 vht_rate = (void *)tlv->value;
1534
1535 vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
1536 vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
1537 vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
1538 vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
1539
1540 ptr += sizeof(*tlv);
1541 ptr += sizeof(*vht_rate);
1542
1543 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
1544 return skb;
1545}
1546
1547static struct sk_buff *
1548ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
1549 enum wmi_sta_ps_mode psmode)
1550{
1551 struct wmi_sta_powersave_mode_cmd *cmd;
1552 struct wmi_tlv *tlv;
1553 struct sk_buff *skb;
1554
1555 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1556 if (!skb)
1557 return ERR_PTR(-ENOMEM);
1558
1559 tlv = (void *)skb->data;
1560 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
1561 tlv->len = __cpu_to_le16(sizeof(*cmd));
1562 cmd = (void *)tlv->value;
1563 cmd->vdev_id = __cpu_to_le32(vdev_id);
1564 cmd->sta_ps_mode = __cpu_to_le32(psmode);
1565
1566 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
1567 return skb;
1568}
1569
1570static struct sk_buff *
1571ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
1572 enum wmi_sta_powersave_param param_id,
1573 u32 param_value)
1574{
1575 struct wmi_sta_powersave_param_cmd *cmd;
1576 struct wmi_tlv *tlv;
1577 struct sk_buff *skb;
1578
1579 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1580 if (!skb)
1581 return ERR_PTR(-ENOMEM);
1582
1583 tlv = (void *)skb->data;
1584 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
1585 tlv->len = __cpu_to_le16(sizeof(*cmd));
1586 cmd = (void *)tlv->value;
1587 cmd->vdev_id = __cpu_to_le32(vdev_id);
1588 cmd->param_id = __cpu_to_le32(param_id);
1589 cmd->param_value = __cpu_to_le32(param_value);
1590
1591 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
1592 return skb;
1593}
1594
1595static struct sk_buff *
1596ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
1597 enum wmi_ap_ps_peer_param param_id, u32 value)
1598{
1599 struct wmi_ap_ps_peer_cmd *cmd;
1600 struct wmi_tlv *tlv;
1601 struct sk_buff *skb;
1602
1603 if (!mac)
1604 return ERR_PTR(-EINVAL);
1605
1606 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
1607 if (!skb)
1608 return ERR_PTR(-ENOMEM);
1609
1610 tlv = (void *)skb->data;
1611 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
1612 tlv->len = __cpu_to_le16(sizeof(*cmd));
1613 cmd = (void *)tlv->value;
1614 cmd->vdev_id = __cpu_to_le32(vdev_id);
1615 cmd->param_id = __cpu_to_le32(param_id);
1616 cmd->param_value = __cpu_to_le32(value);
1617 ether_addr_copy(cmd->peer_macaddr.addr, mac);
1618
1619 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
1620 return skb;
1621}
1622
1623static struct sk_buff *
1624ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
1625 const struct wmi_scan_chan_list_arg *arg)
1626{
1627 struct wmi_tlv_scan_chan_list_cmd *cmd;
1628 struct wmi_channel *ci;
1629 struct wmi_channel_arg *ch;
1630 struct wmi_tlv *tlv;
1631 struct sk_buff *skb;
1632 size_t chans_len, len;
1633 int i;
1634 void *ptr, *chans;
1635
1636 chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
1637 len = (sizeof(*tlv) + sizeof(*cmd)) +
1638 (sizeof(*tlv) + chans_len);
1639
1640 skb = ath10k_wmi_alloc_skb(ar, len);
1641 if (!skb)
1642 return ERR_PTR(-ENOMEM);
1643
1644 ptr = (void *)skb->data;
1645 tlv = ptr;
1646 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
1647 tlv->len = __cpu_to_le16(sizeof(*cmd));
1648 cmd = (void *)tlv->value;
1649 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
1650
1651 ptr += sizeof(*tlv);
1652 ptr += sizeof(*cmd);
1653
1654 tlv = ptr;
1655 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1656 tlv->len = __cpu_to_le16(chans_len);
1657 chans = (void *)tlv->value;
1658
1659 for (i = 0; i < arg->n_channels; i++) {
1660 ch = &arg->channels[i];
1661
1662 tlv = chans;
1663 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1664 tlv->len = __cpu_to_le16(sizeof(*ci));
1665 ci = (void *)tlv->value;
1666
1667 ath10k_wmi_put_wmi_channel(ci, ch);
1668
1669 chans += sizeof(*tlv);
1670 chans += sizeof(*ci);
1671 }
1672
1673 ptr += sizeof(*tlv);
1674 ptr += chans_len;
1675
1676 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
1677 return skb;
1678}
1679
1680static struct sk_buff *
1681ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k_vif *arvif)
1682{
1683 struct ath10k *ar = arvif->ar;
1684 struct wmi_bcn_tx_ref_cmd *cmd;
1685 struct wmi_tlv *tlv;
1686 struct sk_buff *skb;
1687 struct sk_buff *beacon = arvif->beacon;
1688 struct ieee80211_hdr *hdr;
1689 u16 fc;
1690
1691 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1692 if (!skb)
1693 return ERR_PTR(-ENOMEM);
1694
1695 hdr = (struct ieee80211_hdr *)beacon->data;
1696 fc = le16_to_cpu(hdr->frame_control);
1697
1698 tlv = (void *)skb->data;
1699 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
1700 tlv->len = __cpu_to_le16(sizeof(*cmd));
1701 cmd = (void *)tlv->value;
1702 cmd->vdev_id = __cpu_to_le32(arvif->vdev_id);
1703 cmd->data_len = __cpu_to_le32(beacon->len);
1704 cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr);
1705 cmd->msdu_id = 0;
1706 cmd->frame_control = __cpu_to_le32(fc);
1707 cmd->flags = 0;
1708
1709 if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero)
1710 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
1711
1712 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab)
1713 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
1714
1715 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
1716 return skb;
1717}
1718
1719static void *ath10k_wmi_tlv_put_wmm(void *ptr,
1720 const struct wmi_wmm_params_arg *arg)
1721{
1722 struct wmi_wmm_params *wmm;
1723 struct wmi_tlv *tlv;
1724
1725 tlv = ptr;
1726 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
1727 tlv->len = __cpu_to_le16(sizeof(*wmm));
1728 wmm = (void *)tlv->value;
1729 ath10k_wmi_pdev_set_wmm_param(wmm, arg);
1730
1731 return ptr + sizeof(*tlv) + sizeof(*wmm);
1732}
1733
1734static struct sk_buff *
1735ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
1736 const struct wmi_pdev_set_wmm_params_arg *arg)
1737{
1738 struct wmi_tlv_pdev_set_wmm_cmd *cmd;
1739 struct wmi_wmm_params *wmm;
1740 struct wmi_tlv *tlv;
1741 struct sk_buff *skb;
1742 size_t len;
1743 void *ptr;
1744
1745 len = (sizeof(*tlv) + sizeof(*cmd)) +
1746 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1747 skb = ath10k_wmi_alloc_skb(ar, len);
1748 if (!skb)
1749 return ERR_PTR(-ENOMEM);
1750
1751 ptr = (void *)skb->data;
1752
1753 tlv = ptr;
1754 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
1755 tlv->len = __cpu_to_le16(sizeof(*cmd));
1756 cmd = (void *)tlv->value;
1757
1758 /* nothing to set here */
1759
1760 ptr += sizeof(*tlv);
1761 ptr += sizeof(*cmd);
1762
1763 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
1764 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1765 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1766 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1767
1768 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
1769 return skb;
1770}
1771
1772static struct sk_buff *
1773ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
1774 enum wmi_stats_id stats_id)
1775{
1776 struct wmi_request_stats_cmd *cmd;
1777 struct wmi_tlv *tlv;
1778 struct sk_buff *skb;
1779
1780 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1781 if (!skb)
1782 return ERR_PTR(-ENOMEM);
1783
1784 tlv = (void *)skb->data;
1785 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
1786 tlv->len = __cpu_to_le16(sizeof(*cmd));
1787 cmd = (void *)tlv->value;
1788 cmd->stats_id = __cpu_to_le32(stats_id);
1789
1790 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
1791 return skb;
1792}
1793
1794static struct sk_buff *
1795ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
1796 enum wmi_force_fw_hang_type type,
1797 u32 delay_ms)
1798{
1799 struct wmi_force_fw_hang_cmd *cmd;
1800 struct wmi_tlv *tlv;
1801 struct sk_buff *skb;
1802
1803 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1804 if (!skb)
1805 return ERR_PTR(-ENOMEM);
1806
1807 tlv = (void *)skb->data;
1808 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
1809 tlv->len = __cpu_to_le16(sizeof(*cmd));
1810 cmd = (void *)tlv->value;
1811 cmd->type = __cpu_to_le32(type);
1812 cmd->delay_ms = __cpu_to_le32(delay_ms);
1813
1814 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
1815 return skb;
1816}
1817
1818static struct sk_buff *
1819ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable)
1820{
1821 struct wmi_tlv_dbglog_cmd *cmd;
1822 struct wmi_tlv *tlv;
1823 struct sk_buff *skb;
1824 size_t len, bmap_len;
1825 u32 value;
1826 void *ptr;
1827
1828 if (module_enable) {
1829 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
1830 module_enable,
1831 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
1832 } else {
1833 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
1834 WMI_TLV_DBGLOG_ALL_MODULES,
1835 WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
1836 }
1837
1838 bmap_len = 0;
1839 len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
1840 skb = ath10k_wmi_alloc_skb(ar, len);
1841 if (!skb)
1842 return ERR_PTR(-ENOMEM);
1843
1844 ptr = (void *)skb->data;
1845
1846 tlv = ptr;
1847 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
1848 tlv->len = __cpu_to_le16(sizeof(*cmd));
1849 cmd = (void *)tlv->value;
1850 cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
1851 cmd->value = __cpu_to_le32(value);
1852
1853 ptr += sizeof(*tlv);
1854 ptr += sizeof(*cmd);
1855
1856 tlv = ptr;
1857 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1858 tlv->len = __cpu_to_le16(bmap_len);
1859
1860 /* nothing to do here */
1861
1862 ptr += sizeof(*tlv);
1863 ptr += sizeof(bmap_len);
1864
1865 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
1866 return skb;
1867}
1868
1869static struct sk_buff *
1870ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
1871{
1872 struct wmi_tlv_pktlog_enable *cmd;
1873 struct wmi_tlv *tlv;
1874 struct sk_buff *skb;
1875 void *ptr;
1876 size_t len;
1877
1878 len = sizeof(*tlv) + sizeof(*cmd);
1879 skb = ath10k_wmi_alloc_skb(ar, len);
1880 if (!skb)
1881 return ERR_PTR(-ENOMEM);
1882
1883 ptr = (void *)skb->data;
1884 tlv = ptr;
1885 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
1886 tlv->len = __cpu_to_le16(sizeof(*cmd));
1887 cmd = (void *)tlv->value;
1888 cmd->filter = __cpu_to_le32(filter);
1889
1890 ptr += sizeof(*tlv);
1891 ptr += sizeof(*cmd);
1892
1893 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
1894 filter);
1895 return skb;
1896}
1897
1898static struct sk_buff *
1899ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
1900{
1901 struct wmi_tlv_pktlog_disable *cmd;
1902 struct wmi_tlv *tlv;
1903 struct sk_buff *skb;
1904 void *ptr;
1905 size_t len;
1906
1907 len = sizeof(*tlv) + sizeof(*cmd);
1908 skb = ath10k_wmi_alloc_skb(ar, len);
1909 if (!skb)
1910 return ERR_PTR(-ENOMEM);
1911
1912 ptr = (void *)skb->data;
1913 tlv = ptr;
1914 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
1915 tlv->len = __cpu_to_le16(sizeof(*cmd));
1916 cmd = (void *)tlv->value;
1917
1918 ptr += sizeof(*tlv);
1919 ptr += sizeof(*cmd);
1920
1921 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
1922 return skb;
1923}
1924
1925/****************/
1926/* TLV mappings */
1927/****************/
1928
1929static struct wmi_cmd_map wmi_tlv_cmd_map = {
1930 .init_cmdid = WMI_TLV_INIT_CMDID,
1931 .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
1932 .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
1933 .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
1934 .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
1935 .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
1936 .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
1937 .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
1938 .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
1939 .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
1940 .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
1941 .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
1942 .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
1943 .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
1944 .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
1945 .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
1946 .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
1947 .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
1948 .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
1949 .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
1950 .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
1951 .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
1952 .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
1953 .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
1954 .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
1955 .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
1956 .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
1957 .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
1958 .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
1959 .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
1960 .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
1961 .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
1962 .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
1963 .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
1964 .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
1965 .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
1966 .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
1967 .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
1968 .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
1969 .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
1970 .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
1971 .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
1972 .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
1973 .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
1974 .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
1975 .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
1976 .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
1977 .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
1978 .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
1979 .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
1980 .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
1981 .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
1982 .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
1983 .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
1984 .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
1985 .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
1986 .roam_scan_rssi_change_threshold =
1987 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
1988 .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
1989 .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
1990 .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
1991 .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
1992 .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
1993 .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
1994 .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
1995 .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
1996 .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
1997 .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
1998 .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
1999 .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
2000 .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
2001 .wlan_profile_set_hist_intvl_cmdid =
2002 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2003 .wlan_profile_get_profile_data_cmdid =
2004 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
2005 .wlan_profile_enable_profile_id_cmdid =
2006 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2007 .wlan_profile_list_profile_id_cmdid =
2008 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
2009 .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
2010 .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
2011 .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
2012 .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
2013 .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
2014 .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
2015 .wow_enable_disable_wake_event_cmdid =
2016 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
2017 .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
2018 .wow_hostwakeup_from_sleep_cmdid =
2019 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
2020 .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
2021 .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
2022 .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
2023 .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
2024 .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
2025 .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
2026 .network_list_offload_config_cmdid =
2027 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
2028 .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
2029 .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
2030 .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
2031 .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
2032 .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
2033 .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
2034 .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
2035 .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
2036 .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
2037 .echo_cmdid = WMI_TLV_ECHO_CMDID,
2038 .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
2039 .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
2040 .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
2041 .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
2042 .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
2043 .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
2044 .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
2045 .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
2046 .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
2047 .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
2048};
2049
2050static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
2051 .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
2052 .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
2053 .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
2054 .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
2055 .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
2056 .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
2057 .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
2058 .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
2059 .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
2060 .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
2061 .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
2062 .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
2063 .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
2064 .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
2065 .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
2066 .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
2067 .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
2068 .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
2069 .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
2070 .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
2071 .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
2072 .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
2073 .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
2074 .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
2075 .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
2076 .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
2077 .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2078 .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2079 .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
2080 .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
2081 .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
2082 .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
2083 .bcnflt_stats_update_period =
2084 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
2085 .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
2086 .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
2087 .dcs = WMI_TLV_PDEV_PARAM_DCS,
2088 .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
2089 .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
2090 .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
2091 .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
2092 .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
2093 .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
2094 .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
2095 .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
2096 .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
2097 .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
2098 .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
2099 .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
2100 .cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
2101};
2102
2103static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
2104 .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
2105 .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
2106 .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
2107 .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
2108 .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
2109 .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
2110 .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
2111 .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
2112 .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
2113 .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
2114 .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
2115 .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
2116 .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
2117 .wmi_vdev_oc_scheduler_air_time_limit =
2118 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
2119 .wds = WMI_TLV_VDEV_PARAM_WDS,
2120 .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
2121 .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
2122 .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
2123 .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
2124 .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
2125 .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
2126 .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
2127 .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
2128 .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
2129 .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
2130 .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
2131 .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
2132 .sgi = WMI_TLV_VDEV_PARAM_SGI,
2133 .ldpc = WMI_TLV_VDEV_PARAM_LDPC,
2134 .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
2135 .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
2136 .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
2137 .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
2138 .nss = WMI_TLV_VDEV_PARAM_NSS,
2139 .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
2140 .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
2141 .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
2142 .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
2143 .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
2144 .ap_keepalive_min_idle_inactive_time_secs =
2145 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
2146 .ap_keepalive_max_idle_inactive_time_secs =
2147 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
2148 .ap_keepalive_max_unresponsive_time_secs =
2149 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
2150 .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
2151 .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2152 .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
2153 .txbf = WMI_TLV_VDEV_PARAM_TXBF,
2154 .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
2155 .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
2156 .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
2157 .ap_detect_out_of_sync_sleeping_sta_time_secs =
2158 WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2159};
2160
2161static const struct wmi_ops wmi_tlv_ops = {
2162 .rx = ath10k_wmi_tlv_op_rx,
2163 .map_svc = wmi_tlv_svc_map,
2164
2165 .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
2166 .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
2167 .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
2168 .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
2169 .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
2170 .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
2171 .pull_phyerr = ath10k_wmi_tlv_op_pull_phyerr_ev,
2172 .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
2173 .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
2174 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
2175
2176 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
2177 .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
2178 .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
2179 .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
2180 .gen_init = ath10k_wmi_tlv_op_gen_init,
2181 .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
2182 .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
2183 .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
2184 .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
2185 .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
2186 .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
2187 .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
2188 .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
2189 .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
2190 .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
2191 .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
2192 .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
2193 .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
2194 .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
2195 .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
2196 .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
2197 .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
2198 .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
2199 .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
2200 .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
2201 .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
2202 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
2203 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
2204 /* .gen_mgmt_tx = not implemented; HTT is used */
2205 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
2206 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
2207 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
2208 /* .gen_pdev_set_quiet_mode not implemented */
2209 /* .gen_pdev_get_temperature not implemented */
2210};
2211
2212/************/
2213/* TLV init */
2214/************/
2215
2216void ath10k_wmi_tlv_attach(struct ath10k *ar)
2217{
2218 ar->wmi.cmd = &wmi_tlv_cmd_map;
2219 ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
2220 ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
2221 ar->wmi.ops = &wmi_tlv_ops;
2222}
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.h b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
new file mode 100644
index 000000000000..54ffa120cd60
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -0,0 +1,1380 @@
1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
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#ifndef _WMI_TLV_H
18#define _WMI_TLV_H
19
20#define WMI_TLV_CMD(grp_id) (((grp_id) << 12) | 0x1)
21#define WMI_TLV_EV(grp_id) (((grp_id) << 12) | 0x1)
22#define WMI_TLV_CMD_UNSUPPORTED 0
23#define WMI_TLV_PDEV_PARAM_UNSUPPORTED 0
24#define WMI_TLV_VDEV_PARAM_UNSUPPORTED 0
25
26enum wmi_tlv_grp_id {
27 WMI_TLV_GRP_START = 0x3,
28 WMI_TLV_GRP_SCAN = WMI_TLV_GRP_START,
29 WMI_TLV_GRP_PDEV,
30 WMI_TLV_GRP_VDEV,
31 WMI_TLV_GRP_PEER,
32 WMI_TLV_GRP_MGMT,
33 WMI_TLV_GRP_BA_NEG,
34 WMI_TLV_GRP_STA_PS,
35 WMI_TLV_GRP_DFS,
36 WMI_TLV_GRP_ROAM,
37 WMI_TLV_GRP_OFL_SCAN,
38 WMI_TLV_GRP_P2P,
39 WMI_TLV_GRP_AP_PS,
40 WMI_TLV_GRP_RATECTL,
41 WMI_TLV_GRP_PROFILE,
42 WMI_TLV_GRP_SUSPEND,
43 WMI_TLV_GRP_BCN_FILTER,
44 WMI_TLV_GRP_WOW,
45 WMI_TLV_GRP_RTT,
46 WMI_TLV_GRP_SPECTRAL,
47 WMI_TLV_GRP_STATS,
48 WMI_TLV_GRP_ARP_NS_OFL,
49 WMI_TLV_GRP_NLO_OFL,
50 WMI_TLV_GRP_GTK_OFL,
51 WMI_TLV_GRP_CSA_OFL,
52 WMI_TLV_GRP_CHATTER,
53 WMI_TLV_GRP_TID_ADDBA,
54 WMI_TLV_GRP_MISC,
55 WMI_TLV_GRP_GPIO,
56 WMI_TLV_GRP_FWTEST,
57 WMI_TLV_GRP_TDLS,
58 WMI_TLV_GRP_RESMGR,
59 WMI_TLV_GRP_STA_SMPS,
60 WMI_TLV_GRP_WLAN_HB,
61 WMI_TLV_GRP_RMC,
62 WMI_TLV_GRP_MHF_OFL,
63 WMI_TLV_GRP_LOCATION_SCAN,
64 WMI_TLV_GRP_OEM,
65 WMI_TLV_GRP_NAN,
66 WMI_TLV_GRP_COEX,
67 WMI_TLV_GRP_OBSS_OFL,
68 WMI_TLV_GRP_LPI,
69 WMI_TLV_GRP_EXTSCAN,
70 WMI_TLV_GRP_DHCP_OFL,
71 WMI_TLV_GRP_IPA,
72 WMI_TLV_GRP_MDNS_OFL,
73 WMI_TLV_GRP_SAP_OFL,
74};
75
76enum wmi_tlv_cmd_id {
77 WMI_TLV_INIT_CMDID = 0x1,
78 WMI_TLV_START_SCAN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SCAN),
79 WMI_TLV_STOP_SCAN_CMDID,
80 WMI_TLV_SCAN_CHAN_LIST_CMDID,
81 WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
82 WMI_TLV_SCAN_UPDATE_REQUEST_CMDID,
83 WMI_TLV_SCAN_PROB_REQ_OUI_CMDID,
84 WMI_TLV_PDEV_SET_REGDOMAIN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PDEV),
85 WMI_TLV_PDEV_SET_CHANNEL_CMDID,
86 WMI_TLV_PDEV_SET_PARAM_CMDID,
87 WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
88 WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
89 WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
90 WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
91 WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
92 WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
93 WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
94 WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
95 WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
96 WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
97 WMI_TLV_PDEV_DUMP_CMDID,
98 WMI_TLV_PDEV_SET_LED_CONFIG_CMDID,
99 WMI_TLV_PDEV_GET_TEMPERATURE_CMDID,
100 WMI_TLV_PDEV_SET_LED_FLASHING_CMDID,
101 WMI_TLV_VDEV_CREATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_VDEV),
102 WMI_TLV_VDEV_DELETE_CMDID,
103 WMI_TLV_VDEV_START_REQUEST_CMDID,
104 WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
105 WMI_TLV_VDEV_UP_CMDID,
106 WMI_TLV_VDEV_STOP_CMDID,
107 WMI_TLV_VDEV_DOWN_CMDID,
108 WMI_TLV_VDEV_SET_PARAM_CMDID,
109 WMI_TLV_VDEV_INSTALL_KEY_CMDID,
110 WMI_TLV_VDEV_WNM_SLEEPMODE_CMDID,
111 WMI_TLV_VDEV_WMM_ADDTS_CMDID,
112 WMI_TLV_VDEV_WMM_DELTS_CMDID,
113 WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
114 WMI_TLV_VDEV_SET_GTX_PARAMS_CMDID,
115 WMI_TLV_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID,
116 WMI_TLV_VDEV_PLMREQ_START_CMDID,
117 WMI_TLV_VDEV_PLMREQ_STOP_CMDID,
118 WMI_TLV_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PEER),
119 WMI_TLV_PEER_DELETE_CMDID,
120 WMI_TLV_PEER_FLUSH_TIDS_CMDID,
121 WMI_TLV_PEER_SET_PARAM_CMDID,
122 WMI_TLV_PEER_ASSOC_CMDID,
123 WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
124 WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
125 WMI_TLV_PEER_MCAST_GROUP_CMDID,
126 WMI_TLV_PEER_INFO_REQ_CMDID,
127 WMI_TLV_PEER_GET_ESTIMATED_LINKSPEED_CMDID,
128 WMI_TLV_BCN_TX_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MGMT),
129 WMI_TLV_PDEV_SEND_BCN_CMDID,
130 WMI_TLV_BCN_TMPL_CMDID,
131 WMI_TLV_BCN_FILTER_RX_CMDID,
132 WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
133 WMI_TLV_MGMT_TX_CMDID,
134 WMI_TLV_PRB_TMPL_CMDID,
135 WMI_TLV_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BA_NEG),
136 WMI_TLV_ADDBA_SEND_CMDID,
137 WMI_TLV_ADDBA_STATUS_CMDID,
138 WMI_TLV_DELBA_SEND_CMDID,
139 WMI_TLV_ADDBA_SET_RESP_CMDID,
140 WMI_TLV_SEND_SINGLEAMSDU_CMDID,
141 WMI_TLV_STA_POWERSAVE_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STA_PS),
142 WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
143 WMI_TLV_STA_MIMO_PS_MODE_CMDID,
144 WMI_TLV_PDEV_DFS_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_DFS),
145 WMI_TLV_PDEV_DFS_DISABLE_CMDID,
146 WMI_TLV_DFS_PHYERR_FILTER_ENA_CMDID,
147 WMI_TLV_DFS_PHYERR_FILTER_DIS_CMDID,
148 WMI_TLV_ROAM_SCAN_MODE = WMI_TLV_CMD(WMI_TLV_GRP_ROAM),
149 WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
150 WMI_TLV_ROAM_SCAN_PERIOD,
151 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
152 WMI_TLV_ROAM_AP_PROFILE,
153 WMI_TLV_ROAM_CHAN_LIST,
154 WMI_TLV_ROAM_SCAN_CMD,
155 WMI_TLV_ROAM_SYNCH_COMPLETE,
156 WMI_TLV_ROAM_SET_RIC_REQUEST_CMDID,
157 WMI_TLV_ROAM_INVOKE_CMDID,
158 WMI_TLV_OFL_SCAN_ADD_AP_PROFILE = WMI_TLV_CMD(WMI_TLV_GRP_OFL_SCAN),
159 WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
160 WMI_TLV_OFL_SCAN_PERIOD,
161 WMI_TLV_P2P_DEV_SET_DEVICE_INFO = WMI_TLV_CMD(WMI_TLV_GRP_P2P),
162 WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
163 WMI_TLV_P2P_GO_SET_BEACON_IE,
164 WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
165 WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
166 WMI_TLV_P2P_DISC_OFFLOAD_CONFIG_CMDID,
167 WMI_TLV_P2P_DISC_OFFLOAD_APPIE_CMDID,
168 WMI_TLV_P2P_DISC_OFFLOAD_PATTERN_CMDID,
169 WMI_TLV_P2P_SET_OPPPS_PARAM_CMDID,
170 WMI_TLV_AP_PS_PEER_PARAM_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_AP_PS),
171 WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
172 WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RATECTL),
173 WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PROFILE),
174 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
175 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
176 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
177 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
178 WMI_TLV_PDEV_SUSPEND_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SUSPEND),
179 WMI_TLV_PDEV_RESUME_CMDID,
180 WMI_TLV_ADD_BCN_FILTER_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BCN_FILTER),
181 WMI_TLV_RMV_BCN_FILTER_CMDID,
182 WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_WOW),
183 WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
184 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
185 WMI_TLV_WOW_ENABLE_CMDID,
186 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
187 WMI_TLV_WOW_ACER_IOAC_ADD_KEEPALIVE_CMDID,
188 WMI_TLV_WOW_ACER_IOAC_DEL_KEEPALIVE_CMDID,
189 WMI_TLV_WOW_ACER_IOAC_ADD_WAKE_PATTERN_CMDID,
190 WMI_TLV_WOW_ACER_IOAC_DEL_WAKE_PATTERN_CMDID,
191 WMI_TLV_D0_WOW_ENABLE_DISABLE_CMDID,
192 WMI_TLV_EXTWOW_ENABLE_CMDID,
193 WMI_TLV_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID,
194 WMI_TLV_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID,
195 WMI_TLV_RTT_MEASREQ_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RTT),
196 WMI_TLV_RTT_TSF_CMDID,
197 WMI_TLV_SPECTRAL_SCAN_CONF_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SPECTRAL),
198 WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
199 WMI_TLV_REQUEST_STATS_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STATS),
200 WMI_TLV_MCC_SCHED_TRAFFIC_STATS_CMDID,
201 WMI_TLV_REQUEST_STATS_EXT_CMDID,
202 WMI_TLV_REQUEST_LINK_STATS_CMDID,
203 WMI_TLV_START_LINK_STATS_CMDID,
204 WMI_TLV_CLEAR_LINK_STATS_CMDID,
205 WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_ARP_NS_OFL),
206 WMI_TLV_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID,
207 WMI_TLV_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID,
208 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID =
209 WMI_TLV_CMD(WMI_TLV_GRP_NLO_OFL),
210 WMI_TLV_APFIND_CMDID,
211 WMI_TLV_GTK_OFFLOAD_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_GTK_OFL),
212 WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_CSA_OFL),
213 WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
214 WMI_TLV_CHATTER_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_CHATTER),
215 WMI_TLV_CHATTER_ADD_COALESCING_FILTER_CMDID,
216 WMI_TLV_CHATTER_DELETE_COALESCING_FILTER_CMDID,
217 WMI_TLV_CHATTER_COALESCING_QUERY_CMDID,
218 WMI_TLV_PEER_TID_ADDBA_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_TID_ADDBA),
219 WMI_TLV_PEER_TID_DELBA_CMDID,
220 WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
221 WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
222 WMI_TLV_STA_KEEPALIVE_CMDID,
223 WMI_TLV_BA_REQ_SSN_CMDID,
224 WMI_TLV_ECHO_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MISC),
225 WMI_TLV_PDEV_UTF_CMDID,
226 WMI_TLV_DBGLOG_CFG_CMDID,
227 WMI_TLV_PDEV_QVIT_CMDID,
228 WMI_TLV_PDEV_FTM_INTG_CMDID,
229 WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
230 WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
231 WMI_TLV_FORCE_FW_HANG_CMDID,
232 WMI_TLV_SET_MCASTBCAST_FILTER_CMDID,
233 WMI_TLV_THERMAL_MGMT_CMDID,
234 WMI_TLV_HOST_AUTO_SHUTDOWN_CFG_CMDID,
235 WMI_TLV_TPC_CHAINMASK_CONFIG_CMDID,
236 WMI_TLV_SET_ANTENNA_DIVERSITY_CMDID,
237 WMI_TLV_GPIO_CONFIG_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_GPIO),
238 WMI_TLV_GPIO_OUTPUT_CMDID,
239 WMI_TLV_TXBF_CMDID,
240 WMI_TLV_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID =
241 WMI_TLV_CMD(WMI_TLV_GRP_FWTEST),
242 WMI_TLV_FWTEST_P2P_SET_NOA_PARAM_CMDID,
243 WMI_TLV_UNIT_TEST_CMDID,
244 WMI_TLV_TDLS_SET_STATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_TDLS),
245 WMI_TLV_TDLS_PEER_UPDATE_CMDID,
246 WMI_TLV_TDLS_SET_OFFCHAN_MODE_CMDID,
247 WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RESMGR),
248 WMI_TLV_RESMGR_SET_CHAN_TIME_QUOTA_CMDID,
249 WMI_TLV_RESMGR_SET_CHAN_LATENCY_CMDID,
250 WMI_TLV_STA_SMPS_FORCE_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STA_SMPS),
251 WMI_TLV_STA_SMPS_PARAM_CMDID,
252 WMI_TLV_HB_SET_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_WLAN_HB),
253 WMI_TLV_HB_SET_TCP_PARAMS_CMDID,
254 WMI_TLV_HB_SET_TCP_PKT_FILTER_CMDID,
255 WMI_TLV_HB_SET_UDP_PARAMS_CMDID,
256 WMI_TLV_HB_SET_UDP_PKT_FILTER_CMDID,
257 WMI_TLV_RMC_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RMC),
258 WMI_TLV_RMC_SET_ACTION_PERIOD_CMDID,
259 WMI_TLV_RMC_CONFIG_CMDID,
260 WMI_TLV_MHF_OFFLOAD_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MHF_OFL),
261 WMI_TLV_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID,
262 WMI_TLV_BATCH_SCAN_ENABLE_CMDID =
263 WMI_TLV_CMD(WMI_TLV_GRP_LOCATION_SCAN),
264 WMI_TLV_BATCH_SCAN_DISABLE_CMDID,
265 WMI_TLV_BATCH_SCAN_TRIGGER_RESULT_CMDID,
266 WMI_TLV_OEM_REQ_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_OEM),
267 WMI_TLV_NAN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_NAN),
268 WMI_TLV_MODEM_POWER_STATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_COEX),
269 WMI_TLV_CHAN_AVOID_UPDATE_CMDID,
270 WMI_TLV_OBSS_SCAN_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_OBSS_OFL),
271 WMI_TLV_OBSS_SCAN_DISABLE_CMDID,
272 WMI_TLV_LPI_MGMT_SNOOPING_CONFIG_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_LPI),
273 WMI_TLV_LPI_START_SCAN_CMDID,
274 WMI_TLV_LPI_STOP_SCAN_CMDID,
275 WMI_TLV_EXTSCAN_START_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_EXTSCAN),
276 WMI_TLV_EXTSCAN_STOP_CMDID,
277 WMI_TLV_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID,
278 WMI_TLV_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID,
279 WMI_TLV_EXTSCAN_GET_CACHED_RESULTS_CMDID,
280 WMI_TLV_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID,
281 WMI_TLV_EXTSCAN_SET_CAPABILITIES_CMDID,
282 WMI_TLV_EXTSCAN_GET_CAPABILITIES_CMDID,
283 WMI_TLV_SET_DHCP_SERVER_OFFLOAD_CMDID =
284 WMI_TLV_CMD(WMI_TLV_GRP_DHCP_OFL),
285 WMI_TLV_IPA_OFFLOAD_ENABLE_DISABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_IPA),
286 WMI_TLV_MDNS_OFFLOAD_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MDNS_OFL),
287 WMI_TLV_MDNS_SET_FQDN_CMDID,
288 WMI_TLV_MDNS_SET_RESPONSE_CMDID,
289 WMI_TLV_MDNS_GET_STATS_CMDID,
290 WMI_TLV_SAP_OFL_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SAP_OFL),
291};
292
293enum wmi_tlv_event_id {
294 WMI_TLV_SERVICE_READY_EVENTID = 0x1,
295 WMI_TLV_READY_EVENTID,
296 WMI_TLV_SCAN_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SCAN),
297 WMI_TLV_PDEV_TPC_CONFIG_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PDEV),
298 WMI_TLV_CHAN_INFO_EVENTID,
299 WMI_TLV_PHYERR_EVENTID,
300 WMI_TLV_PDEV_DUMP_EVENTID,
301 WMI_TLV_TX_PAUSE_EVENTID,
302 WMI_TLV_DFS_RADAR_EVENTID,
303 WMI_TLV_PDEV_L1SS_TRACK_EVENTID,
304 WMI_TLV_PDEV_TEMPERATURE_EVENTID,
305 WMI_TLV_VDEV_START_RESP_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_VDEV),
306 WMI_TLV_VDEV_STOPPED_EVENTID,
307 WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID,
308 WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID,
309 WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER),
310 WMI_TLV_PEER_INFO_EVENTID,
311 WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID,
312 WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID,
313 WMI_TLV_PEER_STATE_EVENTID,
314 WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT),
315 WMI_TLV_HOST_SWBA_EVENTID,
316 WMI_TLV_TBTTOFFSET_UPDATE_EVENTID,
317 WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID,
318 WMI_TLV_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID,
319 WMI_TLV_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_BA_NEG),
320 WMI_TLV_TX_ADDBA_COMPLETE_EVENTID,
321 WMI_TLV_BA_RSP_SSN_EVENTID,
322 WMI_TLV_AGGR_STATE_TRIG_EVENTID,
323 WMI_TLV_ROAM_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_ROAM),
324 WMI_TLV_PROFILE_MATCH,
325 WMI_TLV_ROAM_SYNCH_EVENTID,
326 WMI_TLV_P2P_DISC_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_P2P),
327 WMI_TLV_P2P_NOA_EVENTID,
328 WMI_TLV_PDEV_RESUME_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SUSPEND),
329 WMI_TLV_WOW_WAKEUP_HOST_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_WOW),
330 WMI_TLV_D0_WOW_DISABLE_ACK_EVENTID,
331 WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_RTT),
332 WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID,
333 WMI_TLV_RTT_ERROR_REPORT_EVENTID,
334 WMI_TLV_STATS_EXT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_STATS),
335 WMI_TLV_IFACE_LINK_STATS_EVENTID,
336 WMI_TLV_PEER_LINK_STATS_EVENTID,
337 WMI_TLV_RADIO_LINK_STATS_EVENTID,
338 WMI_TLV_NLO_MATCH_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_NLO_OFL),
339 WMI_TLV_NLO_SCAN_COMPLETE_EVENTID,
340 WMI_TLV_APFIND_EVENTID,
341 WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_GTK_OFL),
342 WMI_TLV_GTK_REKEY_FAIL_EVENTID,
343 WMI_TLV_CSA_HANDLING_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_CSA_OFL),
344 WMI_TLV_CHATTER_PC_QUERY_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_CHATTER),
345 WMI_TLV_ECHO_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MISC),
346 WMI_TLV_PDEV_UTF_EVENTID,
347 WMI_TLV_DEBUG_MESG_EVENTID,
348 WMI_TLV_UPDATE_STATS_EVENTID,
349 WMI_TLV_DEBUG_PRINT_EVENTID,
350 WMI_TLV_DCS_INTERFERENCE_EVENTID,
351 WMI_TLV_PDEV_QVIT_EVENTID,
352 WMI_TLV_WLAN_PROFILE_DATA_EVENTID,
353 WMI_TLV_PDEV_FTM_INTG_EVENTID,
354 WMI_TLV_WLAN_FREQ_AVOID_EVENTID,
355 WMI_TLV_VDEV_GET_KEEPALIVE_EVENTID,
356 WMI_TLV_THERMAL_MGMT_EVENTID,
357 WMI_TLV_DIAG_DATA_CONTAINER_EVENTID,
358 WMI_TLV_HOST_AUTO_SHUTDOWN_EVENTID,
359 WMI_TLV_UPDATE_WHAL_MIB_STATS_EVENTID,
360 WMI_TLV_UPDATE_VDEV_RATE_STATS_EVENTID,
361 WMI_TLV_DIAG_EVENTID,
362 WMI_TLV_GPIO_INPUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_GPIO),
363 WMI_TLV_UPLOADH_EVENTID,
364 WMI_TLV_CAPTUREH_EVENTID,
365 WMI_TLV_RFKILL_STATE_CHANGE_EVENTID,
366 WMI_TLV_TDLS_PEER_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_TDLS),
367 WMI_TLV_BATCH_SCAN_ENABLED_EVENTID =
368 WMI_TLV_EV(WMI_TLV_GRP_LOCATION_SCAN),
369 WMI_TLV_BATCH_SCAN_RESULT_EVENTID,
370 WMI_TLV_OEM_CAPABILITY_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_OEM),
371 WMI_TLV_OEM_MEASUREMENT_REPORT_EVENTID,
372 WMI_TLV_OEM_ERROR_REPORT_EVENTID,
373 WMI_TLV_NAN_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_NAN),
374 WMI_TLV_LPI_RESULT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_LPI),
375 WMI_TLV_LPI_STATUS_EVENTID,
376 WMI_TLV_LPI_HANDOFF_EVENTID,
377 WMI_TLV_EXTSCAN_START_STOP_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_EXTSCAN),
378 WMI_TLV_EXTSCAN_OPERATION_EVENTID,
379 WMI_TLV_EXTSCAN_TABLE_USAGE_EVENTID,
380 WMI_TLV_EXTSCAN_CACHED_RESULTS_EVENTID,
381 WMI_TLV_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID,
382 WMI_TLV_EXTSCAN_HOTLIST_MATCH_EVENTID,
383 WMI_TLV_EXTSCAN_CAPABILITIES_EVENTID,
384 WMI_TLV_MDNS_STATS_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MDNS_OFL),
385 WMI_TLV_SAP_OFL_ADD_STA_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SAP_OFL),
386 WMI_TLV_SAP_OFL_DEL_STA_EVENTID,
387};
388
389enum wmi_tlv_pdev_param {
390 WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK = 0x1,
391 WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
392 WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
393 WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
394 WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
395 WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
396 WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
397 WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
398 WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
399 WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
400 WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
401 WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
402 WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
403 WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
404 WMI_TLV_PDEV_PARAM_LTR_ENABLE,
405 WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
406 WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
407 WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
408 WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
409 WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
410 WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
411 WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
412 WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
413 WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
414 WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
415 WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
416 WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_WATERMARK,
417 WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
418 WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
419 WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
420 WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
421 WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
422 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
423 WMI_TLV_PDEV_PARAM_PMF_QOS,
424 WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
425 WMI_TLV_PDEV_PARAM_DCS,
426 WMI_TLV_PDEV_PARAM_ANI_ENABLE,
427 WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
428 WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
429 WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
430 WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
431 WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
432 WMI_TLV_PDEV_PARAM_PROXY_STA,
433 WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
434 WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
435 WMI_TLV_PDEV_PARAM_RFKILL_ENABLE,
436 WMI_TLV_PDEV_PARAM_BURST_DUR,
437 WMI_TLV_PDEV_PARAM_BURST_ENABLE,
438 WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG,
439 WMI_TLV_PDEV_PARAM_LOW_POWER_RF_ENABLE,
440 WMI_TLV_PDEV_PARAM_L1SS_TRACK,
441 WMI_TLV_PDEV_PARAM_HYST_EN,
442 WMI_TLV_PDEV_PARAM_POWER_COLLAPSE_ENABLE,
443 WMI_TLV_PDEV_PARAM_LED_SYS_STATE,
444 WMI_TLV_PDEV_PARAM_LED_ENABLE,
445 WMI_TLV_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY,
446 WMI_TLV_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE,
447 WMI_TLV_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE,
448 WMI_TLV_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD,
449 WMI_TLV_PDEV_PARAM_TXPOWER_REASON_NONE,
450 WMI_TLV_PDEV_PARAM_TXPOWER_REASON_SAR,
451 WMI_TLV_PDEV_PARAM_TXPOWER_REASON_MAX,
452};
453
454enum wmi_tlv_vdev_param {
455 WMI_TLV_VDEV_PARAM_RTS_THRESHOLD = 0x1,
456 WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
457 WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
458 WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
459 WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
460 WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
461 WMI_TLV_VDEV_PARAM_SLOT_TIME,
462 WMI_TLV_VDEV_PARAM_PREAMBLE,
463 WMI_TLV_VDEV_PARAM_SWBA_TIME,
464 WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
465 WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
466 WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
467 WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
468 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
469 WMI_TLV_VDEV_PARAM_WDS,
470 WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
471 WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
472 WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
473 WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
474 WMI_TLV_VDEV_PARAM_FEATURE_WMM,
475 WMI_TLV_VDEV_PARAM_CHWIDTH,
476 WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
477 WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
478 WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
479 WMI_TLV_VDEV_PARAM_MGMT_RATE,
480 WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
481 WMI_TLV_VDEV_PARAM_FIXED_RATE,
482 WMI_TLV_VDEV_PARAM_SGI,
483 WMI_TLV_VDEV_PARAM_LDPC,
484 WMI_TLV_VDEV_PARAM_TX_STBC,
485 WMI_TLV_VDEV_PARAM_RX_STBC,
486 WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
487 WMI_TLV_VDEV_PARAM_DEF_KEYID,
488 WMI_TLV_VDEV_PARAM_NSS,
489 WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
490 WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
491 WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
492 WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
493 WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
494 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
495 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
496 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
497 WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
498 WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
499 WMI_TLV_VDEV_PARAM_TXBF,
500 WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
501 WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
502 WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
503 WMI_TLV_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
504 WMI_TLV_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE,
505 WMI_TLV_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM,
506 WMI_TLV_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE,
507 WMI_TLV_VDEV_PARAM_EARLY_RX_SLOP_STEP,
508 WMI_TLV_VDEV_PARAM_EARLY_RX_INIT_SLOP,
509 WMI_TLV_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE,
510 WMI_TLV_VDEV_PARAM_TX_PWRLIMIT,
511 WMI_TLV_VDEV_PARAM_SNR_NUM_FOR_CAL,
512 WMI_TLV_VDEV_PARAM_ROAM_FW_OFFLOAD,
513 WMI_TLV_VDEV_PARAM_ENABLE_RMC,
514 WMI_TLV_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS,
515 WMI_TLV_VDEV_PARAM_MAX_RATE,
516 WMI_TLV_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE,
517 WMI_TLV_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR,
518 WMI_TLV_VDEV_PARAM_EBT_RESYNC_TIMEOUT,
519 WMI_TLV_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE,
520 WMI_TLV_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED,
521 WMI_TLV_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED,
522 WMI_TLV_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED,
523 WMI_TLV_VDEV_PARAM_INACTIVITY_CNT,
524 WMI_TLV_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS,
525 WMI_TLV_VDEV_PARAM_DTIM_POLICY,
526 WMI_TLV_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS,
527 WMI_TLV_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE,
528};
529
530enum wmi_tlv_tag {
531 WMI_TLV_TAG_LAST_RESERVED = 15,
532
533 WMI_TLV_TAG_FIRST_ARRAY_ENUM,
534 WMI_TLV_TAG_ARRAY_UINT32 = WMI_TLV_TAG_FIRST_ARRAY_ENUM,
535 WMI_TLV_TAG_ARRAY_BYTE,
536 WMI_TLV_TAG_ARRAY_STRUCT,
537 WMI_TLV_TAG_ARRAY_FIXED_STRUCT,
538 WMI_TLV_TAG_LAST_ARRAY_ENUM = 31,
539
540 WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT,
541 WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES,
542 WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ,
543 WMI_TLV_TAG_STRUCT_READY_EVENT,
544 WMI_TLV_TAG_STRUCT_SCAN_EVENT,
545 WMI_TLV_TAG_STRUCT_PDEV_TPC_CONFIG_EVENT,
546 WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT,
547 WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR,
548 WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT,
549 WMI_TLV_TAG_STRUCT_VDEV_STOPPED_EVENT,
550 WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_COMPLETE_EVENT,
551 WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT,
552 WMI_TLV_TAG_STRUCT_MGMT_RX_HDR,
553 WMI_TLV_TAG_STRUCT_TBTT_OFFSET_EVENT,
554 WMI_TLV_TAG_STRUCT_TX_DELBA_COMPLETE_EVENT,
555 WMI_TLV_TAG_STRUCT_TX_ADDBA_COMPLETE_EVENT,
556 WMI_TLV_TAG_STRUCT_ROAM_EVENT,
557 WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO,
558 WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO_SECTION_BITMAP,
559 WMI_TLV_TAG_STRUCT_RTT_EVENT_HEADER,
560 WMI_TLV_TAG_STRUCT_RTT_ERROR_REPORT_EVENT,
561 WMI_TLV_TAG_STRUCT_RTT_MEAS_EVENT,
562 WMI_TLV_TAG_STRUCT_ECHO_EVENT,
563 WMI_TLV_TAG_STRUCT_FTM_INTG_EVENT,
564 WMI_TLV_TAG_STRUCT_VDEV_GET_KEEPALIVE_EVENT,
565 WMI_TLV_TAG_STRUCT_GPIO_INPUT_EVENT,
566 WMI_TLV_TAG_STRUCT_CSA_EVENT,
567 WMI_TLV_TAG_STRUCT_GTK_OFFLOAD_STATUS_EVENT,
568 WMI_TLV_TAG_STRUCT_IGTK_INFO,
569 WMI_TLV_TAG_STRUCT_DCS_INTERFERENCE_EVENT,
570 WMI_TLV_TAG_STRUCT_ATH_DCS_CW_INT,
571 WMI_TLV_TAG_STRUCT_ATH_DCS_WLAN_INT_STAT,
572 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_CTX_T,
573 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_T,
574 WMI_TLV_TAG_STRUCT_PDEV_QVIT_EVENT,
575 WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT,
576 WMI_TLV_TAG_STRUCT_TIM_INFO,
577 WMI_TLV_TAG_STRUCT_P2P_NOA_INFO,
578 WMI_TLV_TAG_STRUCT_STATS_EVENT,
579 WMI_TLV_TAG_STRUCT_AVOID_FREQ_RANGES_EVENT,
580 WMI_TLV_TAG_STRUCT_AVOID_FREQ_RANGE_DESC,
581 WMI_TLV_TAG_STRUCT_GTK_REKEY_FAIL_EVENT,
582 WMI_TLV_TAG_STRUCT_INIT_CMD,
583 WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG,
584 WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK,
585 WMI_TLV_TAG_STRUCT_START_SCAN_CMD,
586 WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD,
587 WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD,
588 WMI_TLV_TAG_STRUCT_CHANNEL,
589 WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD,
590 WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD,
591 WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD,
592 WMI_TLV_TAG_STRUCT_WMM_PARAMS,
593 WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD,
594 WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD,
595 WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD,
596 WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD,
597 WMI_TLV_TAG_STRUCT_P2P_NOA_DESCRIPTOR,
598 WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE,
599 WMI_TLV_TAG_STRUCT_GTK_OFFLOAD_CMD,
600 WMI_TLV_TAG_STRUCT_VDEV_UP_CMD,
601 WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD,
602 WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD,
603 WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD,
604 WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD,
605 WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD,
606 WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD,
607 WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD,
608 WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD,
609 WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD,
610 WMI_TLV_TAG_STRUCT_VHT_RATE_SET,
611 WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD,
612 WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD,
613 WMI_TLV_TAG_STRUCT_BCN_PRB_INFO,
614 WMI_TLV_TAG_STRUCT_PEER_TID_ADDBA_CMD,
615 WMI_TLV_TAG_STRUCT_PEER_TID_DELBA_CMD,
616 WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD,
617 WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD,
618 WMI_TLV_TAG_STRUCT_STA_DTIM_PS_METHOD_CMD,
619 WMI_TLV_TAG_STRUCT_ROAM_SCAN_MODE,
620 WMI_TLV_TAG_STRUCT_ROAM_SCAN_RSSI_THRESHOLD,
621 WMI_TLV_TAG_STRUCT_ROAM_SCAN_PERIOD,
622 WMI_TLV_TAG_STRUCT_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
623 WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD,
624 WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD,
625 WMI_TLV_TAG_STRUCT_ADD_BCN_FILTER_CMD,
626 WMI_TLV_TAG_STRUCT_RMV_BCN_FILTER_CMD,
627 WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD,
628 WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD,
629 WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD,
630 WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM,
631 WMI_TLV_TAG_STRUCT_SET_ARP_NS_OFFLOAD_CMD,
632 WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE,
633 WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE,
634 WMI_TLV_TAG_STRUCT_FTM_INTG_CMD,
635 WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD,
636 WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE,
637 WMI_TLV_TAG_STRUCT_P2P_SET_VENDOR_IE_DATA_CMD,
638 WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD,
639 WMI_TLV_TAG_STRUCT_PEER_RATE_RETRY_SCHED_CMD,
640 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_TRIGGER_CMD,
641 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_SET_HIST_INTVL_CMD,
642 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_GET_PROF_DATA_CMD,
643 WMI_TLV_TAG_STRUCT_WLAN_PROFILE_ENABLE_PROFILE_ID_CMD,
644 WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD,
645 WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD,
646 WMI_TLV_TAG_STRUCT_RTT_MEASREQ_HEAD,
647 WMI_TLV_TAG_STRUCT_RTT_MEASREQ_BODY,
648 WMI_TLV_TAG_STRUCT_RTT_TSF_CMD,
649 WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD,
650 WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD,
651 WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD,
652 WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD,
653 WMI_TLV_TAG_STRUCT_NLO_CONFIGURED_PARAMETERS,
654 WMI_TLV_TAG_STRUCT_CSA_OFFLOAD_ENABLE_CMD,
655 WMI_TLV_TAG_STRUCT_CSA_OFFLOAD_CHANSWITCH_CMD,
656 WMI_TLV_TAG_STRUCT_CHATTER_SET_MODE_CMD,
657 WMI_TLV_TAG_STRUCT_ECHO_CMD,
658 WMI_TLV_TAG_STRUCT_VDEV_SET_KEEPALIVE_CMD,
659 WMI_TLV_TAG_STRUCT_VDEV_GET_KEEPALIVE_CMD,
660 WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD,
661 WMI_TLV_TAG_STRUCT_GPIO_CONFIG_CMD,
662 WMI_TLV_TAG_STRUCT_GPIO_OUTPUT_CMD,
663 WMI_TLV_TAG_STRUCT_PEER_ADD_WDS_ENTRY_CMD,
664 WMI_TLV_TAG_STRUCT_PEER_REMOVE_WDS_ENTRY_CMD,
665 WMI_TLV_TAG_STRUCT_BCN_TX_HDR,
666 WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD,
667 WMI_TLV_TAG_STRUCT_MGMT_TX_HDR,
668 WMI_TLV_TAG_STRUCT_ADDBA_CLEAR_RESP_CMD,
669 WMI_TLV_TAG_STRUCT_ADDBA_SEND_CMD,
670 WMI_TLV_TAG_STRUCT_DELBA_SEND_CMD,
671 WMI_TLV_TAG_STRUCT_ADDBA_SETRESPONSE_CMD,
672 WMI_TLV_TAG_STRUCT_SEND_SINGLEAMSDU_CMD,
673 WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD,
674 WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD,
675 WMI_TLV_TAG_STRUCT_PDEV_SET_HT_IE_CMD,
676 WMI_TLV_TAG_STRUCT_PDEV_SET_VHT_IE_CMD,
677 WMI_TLV_TAG_STRUCT_PDEV_SET_DSCP_TID_MAP_CMD,
678 WMI_TLV_TAG_STRUCT_PDEV_GREEN_AP_PS_ENABLE_CMD,
679 WMI_TLV_TAG_STRUCT_PDEV_GET_TPC_CONFIG_CMD,
680 WMI_TLV_TAG_STRUCT_PDEV_SET_BASE_MACADDR_CMD,
681 WMI_TLV_TAG_STRUCT_PEER_MCAST_GROUP_CMD,
682 WMI_TLV_TAG_STRUCT_ROAM_AP_PROFILE,
683 WMI_TLV_TAG_STRUCT_AP_PROFILE,
684 WMI_TLV_TAG_STRUCT_SCAN_SCH_PRIORITY_TABLE_CMD,
685 WMI_TLV_TAG_STRUCT_PDEV_DFS_ENABLE_CMD,
686 WMI_TLV_TAG_STRUCT_PDEV_DFS_DISABLE_CMD,
687 WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD,
688 WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T,
689 WMI_TLV_TAG_STRUCT_WOW_IPV4_SYNC_PATTERN_T,
690 WMI_TLV_TAG_STRUCT_WOW_IPV6_SYNC_PATTERN_T,
691 WMI_TLV_TAG_STRUCT_WOW_MAGIC_PATTERN_CMD,
692 WMI_TLV_TAG_STRUCT_SCAN_UPDATE_REQUEST_CMD,
693 WMI_TLV_TAG_STRUCT_CHATTER_PKT_COALESCING_FILTER,
694 WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_ADD_FILTER_CMD,
695 WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_DELETE_FILTER_CMD,
696 WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_QUERY_CMD,
697 WMI_TLV_TAG_STRUCT_TXBF_CMD,
698 WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD,
699 WMI_TLV_TAG_STRUCT_NLO_EVENT,
700 WMI_TLV_TAG_STRUCT_CHATTER_QUERY_REPLY_EVENT,
701 WMI_TLV_TAG_STRUCT_UPLOAD_H_HDR,
702 WMI_TLV_TAG_STRUCT_CAPTURE_H_EVENT_HDR,
703 WMI_TLV_TAG_STRUCT_VDEV_WNM_SLEEPMODE_CMD,
704 WMI_TLV_TAG_STRUCT_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD,
705 WMI_TLV_TAG_STRUCT_VDEV_WMM_ADDTS_CMD,
706 WMI_TLV_TAG_STRUCT_VDEV_WMM_DELTS_CMD,
707 WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD,
708 WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD,
709 WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD,
710 WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT,
711 WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES,
712 WMI_TLV_TAG_STRUCT_VDEV_MCC_SET_TBTT_MODE_CMD,
713 WMI_TLV_TAG_STRUCT_ROAM_CHAN_LIST,
714 WMI_TLV_TAG_STRUCT_VDEV_MCC_BCN_INTVL_CHANGE_EVENT,
715 WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD,
716 WMI_TLV_TAG_STRUCT_RESMGR_SET_CHAN_TIME_QUOTA_CMD,
717 WMI_TLV_TAG_STRUCT_RESMGR_SET_CHAN_LATENCY_CMD,
718 WMI_TLV_TAG_STRUCT_BA_REQ_SSN_CMD,
719 WMI_TLV_TAG_STRUCT_BA_RSP_SSN_EVENT,
720 WMI_TLV_TAG_STRUCT_STA_SMPS_FORCE_MODE_CMD,
721 WMI_TLV_TAG_STRUCT_SET_MCASTBCAST_FILTER_CMD,
722 WMI_TLV_TAG_STRUCT_P2P_SET_OPPPS_CMD,
723 WMI_TLV_TAG_STRUCT_P2P_SET_NOA_CMD,
724 WMI_TLV_TAG_STRUCT_BA_REQ_SSN_CMD_SUB_STRUCT_PARAM,
725 WMI_TLV_TAG_STRUCT_BA_REQ_SSN_EVENT_SUB_STRUCT_PARAM,
726 WMI_TLV_TAG_STRUCT_STA_SMPS_PARAM_CMD,
727 WMI_TLV_TAG_STRUCT_VDEV_SET_GTX_PARAMS_CMD,
728 WMI_TLV_TAG_STRUCT_MCC_SCHED_TRAFFIC_STATS_CMD,
729 WMI_TLV_TAG_STRUCT_MCC_SCHED_STA_TRAFFIC_STATS,
730 WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT,
731 WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT,
732 WMI_TLV_TAG_STRUCT_HB_SET_ENABLE_CMD,
733 WMI_TLV_TAG_STRUCT_HB_SET_TCP_PARAMS_CMD,
734 WMI_TLV_TAG_STRUCT_HB_SET_TCP_PKT_FILTER_CMD,
735 WMI_TLV_TAG_STRUCT_HB_SET_UDP_PARAMS_CMD,
736 WMI_TLV_TAG_STRUCT_HB_SET_UDP_PKT_FILTER_CMD,
737 WMI_TLV_TAG_STRUCT_HB_IND_EVENT,
738 WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT,
739 WMI_TLV_TAG_STRUCT_RFKILL_EVENT,
740 WMI_TLV_TAG_STRUCT_DFS_RADAR_EVENT,
741 WMI_TLV_TAG_STRUCT_DFS_PHYERR_FILTER_ENA_CMD,
742 WMI_TLV_TAG_STRUCT_DFS_PHYERR_FILTER_DIS_CMD,
743 WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_SCAN_LIST,
744 WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_NETWORK_INFO,
745 WMI_TLV_TAG_STRUCT_BATCH_SCAN_ENABLE_CMD,
746 WMI_TLV_TAG_STRUCT_BATCH_SCAN_DISABLE_CMD,
747 WMI_TLV_TAG_STRUCT_BATCH_SCAN_TRIGGER_RESULT_CMD,
748 WMI_TLV_TAG_STRUCT_BATCH_SCAN_ENABLED_EVENT,
749 WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_EVENT,
750 WMI_TLV_TAG_STRUCT_VDEV_PLMREQ_START_CMD,
751 WMI_TLV_TAG_STRUCT_VDEV_PLMREQ_STOP_CMD,
752 WMI_TLV_TAG_STRUCT_THERMAL_MGMT_CMD,
753 WMI_TLV_TAG_STRUCT_THERMAL_MGMT_EVENT,
754 WMI_TLV_TAG_STRUCT_PEER_INFO_REQ_CMD,
755 WMI_TLV_TAG_STRUCT_PEER_INFO_EVENT,
756 WMI_TLV_TAG_STRUCT_PEER_INFO,
757 WMI_TLV_TAG_STRUCT_PEER_TX_FAIL_CNT_THR_EVENT,
758 WMI_TLV_TAG_STRUCT_RMC_SET_MODE_CMD,
759 WMI_TLV_TAG_STRUCT_RMC_SET_ACTION_PERIOD_CMD,
760 WMI_TLV_TAG_STRUCT_RMC_CONFIG_CMD,
761 WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_SET_MODE_CMD,
762 WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_PLUMB_ROUTING_TABLE_CMD,
763 WMI_TLV_TAG_STRUCT_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD,
764 WMI_TLV_TAG_STRUCT_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD,
765 WMI_TLV_TAG_STRUCT_NAN_CMD_PARAM,
766 WMI_TLV_TAG_STRUCT_NAN_EVENT_HDR,
767 WMI_TLV_TAG_STRUCT_PDEV_L1SS_TRACK_EVENT,
768 WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT,
769 WMI_TLV_TAG_STRUCT_MODEM_POWER_STATE_CMD_PARAM,
770 WMI_TLV_TAG_STRUCT_PEER_GET_ESTIMATED_LINKSPEED_CMD,
771 WMI_TLV_TAG_STRUCT_PEER_ESTIMATED_LINKSPEED_EVENT,
772 WMI_TLV_TAG_STRUCT_AGGR_STATE_TRIG_EVENT,
773 WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_ROUTING_TABLE_ENTRY,
774 WMI_TLV_TAG_STRUCT_ROAM_SCAN_CMD,
775 WMI_TLV_TAG_STRUCT_REQ_STATS_EXT_CMD,
776 WMI_TLV_TAG_STRUCT_STATS_EXT_EVENT,
777 WMI_TLV_TAG_STRUCT_OBSS_SCAN_ENABLE_CMD,
778 WMI_TLV_TAG_STRUCT_OBSS_SCAN_DISABLE_CMD,
779 WMI_TLV_TAG_STRUCT_OFFLOAD_PRB_RSP_TX_STATUS_EVENT,
780 WMI_TLV_TAG_STRUCT_PDEV_SET_LED_CONFIG_CMD,
781 WMI_TLV_TAG_STRUCT_HOST_AUTO_SHUTDOWN_CFG_CMD,
782 WMI_TLV_TAG_STRUCT_HOST_AUTO_SHUTDOWN_EVENT,
783 WMI_TLV_TAG_STRUCT_UPDATE_WHAL_MIB_STATS_EVENT,
784 WMI_TLV_TAG_STRUCT_CHAN_AVOID_UPDATE_CMD_PARAM,
785 WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_PKT_PATTERN_T,
786 WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_TMR_PATTERN_T,
787 WMI_TLV_TAG_STRUCT_WOW_IOAC_ADD_KEEPALIVE_CMD,
788 WMI_TLV_TAG_STRUCT_WOW_IOAC_DEL_KEEPALIVE_CMD,
789 WMI_TLV_TAG_STRUCT_WOW_IOAC_KEEPALIVE_T,
790 WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_ADD_PATTERN_CMD,
791 WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_DEL_PATTERN_CMD,
792 WMI_TLV_TAG_STRUCT_START_LINK_STATS_CMD,
793 WMI_TLV_TAG_STRUCT_CLEAR_LINK_STATS_CMD,
794 WMI_TLV_TAG_STRUCT_REQUEST_LINK_STATS_CMD,
795 WMI_TLV_TAG_STRUCT_IFACE_LINK_STATS_EVENT,
796 WMI_TLV_TAG_STRUCT_RADIO_LINK_STATS_EVENT,
797 WMI_TLV_TAG_STRUCT_PEER_STATS_EVENT,
798 WMI_TLV_TAG_STRUCT_CHANNEL_STATS,
799 WMI_TLV_TAG_STRUCT_RADIO_LINK_STATS,
800 WMI_TLV_TAG_STRUCT_RATE_STATS,
801 WMI_TLV_TAG_STRUCT_PEER_LINK_STATS,
802 WMI_TLV_TAG_STRUCT_WMM_AC_STATS,
803 WMI_TLV_TAG_STRUCT_IFACE_LINK_STATS,
804 WMI_TLV_TAG_STRUCT_LPI_MGMT_SNOOPING_CONFIG_CMD,
805 WMI_TLV_TAG_STRUCT_LPI_START_SCAN_CMD,
806 WMI_TLV_TAG_STRUCT_LPI_STOP_SCAN_CMD,
807 WMI_TLV_TAG_STRUCT_LPI_RESULT_EVENT,
808 WMI_TLV_TAG_STRUCT_PEER_STATE_EVENT,
809 WMI_TLV_TAG_STRUCT_EXTSCAN_BUCKET_CMD,
810 WMI_TLV_TAG_STRUCT_EXTSCAN_BUCKET_CHANNEL_EVENT,
811 WMI_TLV_TAG_STRUCT_EXTSCAN_START_CMD,
812 WMI_TLV_TAG_STRUCT_EXTSCAN_STOP_CMD,
813 WMI_TLV_TAG_STRUCT_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMD,
814 WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_BSSID_PARAM_CMD,
815 WMI_TLV_TAG_STRUCT_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMD,
816 WMI_TLV_TAG_STRUCT_EXTSCAN_GET_CACHED_RESULTS_CMD,
817 WMI_TLV_TAG_STRUCT_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMD,
818 WMI_TLV_TAG_STRUCT_EXTSCAN_SET_CAPABILITIES_CMD,
819 WMI_TLV_TAG_STRUCT_EXTSCAN_GET_CAPABILITIES_CMD,
820 WMI_TLV_TAG_STRUCT_EXTSCAN_OPERATION_EVENT,
821 WMI_TLV_TAG_STRUCT_EXTSCAN_START_STOP_EVENT,
822 WMI_TLV_TAG_STRUCT_EXTSCAN_TABLE_USAGE_EVENT,
823 WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_DESCRIPTOR_EVENT,
824 WMI_TLV_TAG_STRUCT_EXTSCAN_RSSI_INFO_EVENT,
825 WMI_TLV_TAG_STRUCT_EXTSCAN_CACHED_RESULTS_EVENT,
826 WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_RESULTS_EVENT,
827 WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_RESULT_BSSID_EVENT,
828 WMI_TLV_TAG_STRUCT_EXTSCAN_HOTLIST_MATCH_EVENT,
829 WMI_TLV_TAG_STRUCT_EXTSCAN_CAPABILITIES_EVENT,
830 WMI_TLV_TAG_STRUCT_EXTSCAN_CACHE_CAPABILITIES_EVENT,
831 WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_MONITOR_CAPABILITIES_EVENT,
832 WMI_TLV_TAG_STRUCT_EXTSCAN_HOTLIST_MONITOR_CAPABILITIES_EVENT,
833 WMI_TLV_TAG_STRUCT_D0_WOW_ENABLE_DISABLE_CMD,
834 WMI_TLV_TAG_STRUCT_D0_WOW_DISABLE_ACK_EVENT,
835 WMI_TLV_TAG_STRUCT_UNIT_TEST_CMD,
836 WMI_TLV_TAG_STRUCT_ROAM_OFFLOAD_TLV_PARAM,
837 WMI_TLV_TAG_STRUCT_ROAM_11I_OFFLOAD_TLV_PARAM,
838 WMI_TLV_TAG_STRUCT_ROAM_11R_OFFLOAD_TLV_PARAM,
839 WMI_TLV_TAG_STRUCT_ROAM_ESE_OFFLOAD_TLV_PARAM,
840 WMI_TLV_TAG_STRUCT_ROAM_SYNCH_EVENT,
841 WMI_TLV_TAG_STRUCT_ROAM_SYNCH_COMPLETE,
842 WMI_TLV_TAG_STRUCT_EXTWOW_ENABLE_CMD,
843 WMI_TLV_TAG_STRUCT_EXTWOW_SET_APP_TYPE1_PARAMS_CMD,
844 WMI_TLV_TAG_STRUCT_EXTWOW_SET_APP_TYPE2_PARAMS_CMD,
845 WMI_TLV_TAG_STRUCT_LPI_STATUS_EVENT,
846 WMI_TLV_TAG_STRUCT_LPI_HANDOFF_EVENT,
847 WMI_TLV_TAG_STRUCT_VDEV_RATE_STATS_EVENT,
848 WMI_TLV_TAG_STRUCT_VDEV_RATE_HT_INFO,
849 WMI_TLV_TAG_STRUCT_RIC_REQUEST,
850 WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD,
851 WMI_TLV_TAG_STRUCT_PDEV_TEMPERATURE_EVENT,
852 WMI_TLV_TAG_STRUCT_SET_DHCP_SERVER_OFFLOAD_CMD,
853 WMI_TLV_TAG_STRUCT_TPC_CHAINMASK_CONFIG_CMD,
854 WMI_TLV_TAG_STRUCT_RIC_TSPEC,
855 WMI_TLV_TAG_STRUCT_TPC_CHAINMASK_CONFIG,
856 WMI_TLV_TAG_STRUCT_IPA_OFFLOAD_CMD,
857 WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD,
858 WMI_TLV_TAG_STRUCT_KEY_MATERIAL,
859 WMI_TLV_TAG_STRUCT_TDLS_SET_OFFCHAN_MODE_CMD,
860 WMI_TLV_TAG_STRUCT_SET_LED_FLASHING_CMD,
861 WMI_TLV_TAG_STRUCT_MDNS_OFFLOAD_CMD,
862 WMI_TLV_TAG_STRUCT_MDNS_SET_FQDN_CMD,
863 WMI_TLV_TAG_STRUCT_MDNS_SET_RESP_CMD,
864 WMI_TLV_TAG_STRUCT_MDNS_GET_STATS_CMD,
865 WMI_TLV_TAG_STRUCT_MDNS_STATS_EVENT,
866 WMI_TLV_TAG_STRUCT_ROAM_INVOKE_CMD,
867 WMI_TLV_TAG_STRUCT_PDEV_RESUME_EVENT,
868 WMI_TLV_TAG_STRUCT_PDEV_SET_ANTENNA_DIVERSITY_CMD,
869 WMI_TLV_TAG_STRUCT_SAP_OFL_ENABLE_CMD,
870 WMI_TLV_TAG_STRUCT_SAP_OFL_ADD_STA_EVENT,
871 WMI_TLV_TAG_STRUCT_SAP_OFL_DEL_STA_EVENT,
872 WMI_TLV_TAG_STRUCT_APFIND_CMD_PARAM,
873 WMI_TLV_TAG_STRUCT_APFIND_EVENT_HDR,
874
875 WMI_TLV_TAG_MAX
876};
877
878enum wmi_tlv_service {
879 WMI_TLV_SERVICE_BEACON_OFFLOAD = 0,
880 WMI_TLV_SERVICE_SCAN_OFFLOAD,
881 WMI_TLV_SERVICE_ROAM_SCAN_OFFLOAD,
882 WMI_TLV_SERVICE_BCN_MISS_OFFLOAD,
883 WMI_TLV_SERVICE_STA_PWRSAVE,
884 WMI_TLV_SERVICE_STA_ADVANCED_PWRSAVE,
885 WMI_TLV_SERVICE_AP_UAPSD,
886 WMI_TLV_SERVICE_AP_DFS,
887 WMI_TLV_SERVICE_11AC,
888 WMI_TLV_SERVICE_BLOCKACK,
889 WMI_TLV_SERVICE_PHYERR,
890 WMI_TLV_SERVICE_BCN_FILTER,
891 WMI_TLV_SERVICE_RTT,
892 WMI_TLV_SERVICE_WOW,
893 WMI_TLV_SERVICE_RATECTRL_CACHE,
894 WMI_TLV_SERVICE_IRAM_TIDS,
895 WMI_TLV_SERVICE_ARPNS_OFFLOAD,
896 WMI_TLV_SERVICE_NLO,
897 WMI_TLV_SERVICE_GTK_OFFLOAD,
898 WMI_TLV_SERVICE_SCAN_SCH,
899 WMI_TLV_SERVICE_CSA_OFFLOAD,
900 WMI_TLV_SERVICE_CHATTER,
901 WMI_TLV_SERVICE_COEX_FREQAVOID,
902 WMI_TLV_SERVICE_PACKET_POWER_SAVE,
903 WMI_TLV_SERVICE_FORCE_FW_HANG,
904 WMI_TLV_SERVICE_GPIO,
905 WMI_TLV_SERVICE_STA_DTIM_PS_MODULATED_DTIM,
906 WMI_TLV_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG,
907 WMI_TLV_SERVICE_STA_UAPSD_VAR_AUTO_TRIG,
908 WMI_TLV_SERVICE_STA_KEEP_ALIVE,
909 WMI_TLV_SERVICE_TX_ENCAP,
910 WMI_TLV_SERVICE_AP_PS_DETECT_OUT_OF_SYNC,
911 WMI_TLV_SERVICE_EARLY_RX,
912 WMI_TLV_SERVICE_STA_SMPS,
913 WMI_TLV_SERVICE_FWTEST,
914 WMI_TLV_SERVICE_STA_WMMAC,
915 WMI_TLV_SERVICE_TDLS,
916 WMI_TLV_SERVICE_BURST,
917 WMI_TLV_SERVICE_MCC_BCN_INTERVAL_CHANGE,
918 WMI_TLV_SERVICE_ADAPTIVE_OCS,
919 WMI_TLV_SERVICE_BA_SSN_SUPPORT,
920 WMI_TLV_SERVICE_FILTER_IPSEC_NATKEEPALIVE,
921 WMI_TLV_SERVICE_WLAN_HB,
922 WMI_TLV_SERVICE_LTE_ANT_SHARE_SUPPORT,
923 WMI_TLV_SERVICE_BATCH_SCAN,
924 WMI_TLV_SERVICE_QPOWER,
925 WMI_TLV_SERVICE_PLMREQ,
926 WMI_TLV_SERVICE_THERMAL_MGMT,
927 WMI_TLV_SERVICE_RMC,
928 WMI_TLV_SERVICE_MHF_OFFLOAD,
929 WMI_TLV_SERVICE_COEX_SAR,
930 WMI_TLV_SERVICE_BCN_TXRATE_OVERRIDE,
931 WMI_TLV_SERVICE_NAN,
932 WMI_TLV_SERVICE_L1SS_STAT,
933 WMI_TLV_SERVICE_ESTIMATE_LINKSPEED,
934 WMI_TLV_SERVICE_OBSS_SCAN,
935 WMI_TLV_SERVICE_TDLS_OFFCHAN,
936 WMI_TLV_SERVICE_TDLS_UAPSD_BUFFER_STA,
937 WMI_TLV_SERVICE_TDLS_UAPSD_SLEEP_STA,
938 WMI_TLV_SERVICE_IBSS_PWRSAVE,
939 WMI_TLV_SERVICE_LPASS,
940 WMI_TLV_SERVICE_EXTSCAN,
941 WMI_TLV_SERVICE_D0WOW,
942 WMI_TLV_SERVICE_HSOFFLOAD,
943 WMI_TLV_SERVICE_ROAM_HO_OFFLOAD,
944 WMI_TLV_SERVICE_RX_FULL_REORDER,
945 WMI_TLV_SERVICE_DHCP_OFFLOAD,
946 WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
947 WMI_TLV_SERVICE_MDNS_OFFLOAD,
948 WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
949};
950
951#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
952 ((svc_id) < (len) && \
953 __le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \
954 BIT((svc_id)%(sizeof(u32))))
955
956#define SVCMAP(x, y, len) \
957 do { \
958 if (WMI_SERVICE_IS_ENABLED((in), (x), (len))) \
959 __set_bit(y, out); \
960 } while (0)
961
962static inline void
963wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len)
964{
965 SVCMAP(WMI_TLV_SERVICE_BEACON_OFFLOAD,
966 WMI_SERVICE_BEACON_OFFLOAD, len);
967 SVCMAP(WMI_TLV_SERVICE_SCAN_OFFLOAD,
968 WMI_SERVICE_SCAN_OFFLOAD, len);
969 SVCMAP(WMI_TLV_SERVICE_ROAM_SCAN_OFFLOAD,
970 WMI_SERVICE_ROAM_SCAN_OFFLOAD, len);
971 SVCMAP(WMI_TLV_SERVICE_BCN_MISS_OFFLOAD,
972 WMI_SERVICE_BCN_MISS_OFFLOAD, len);
973 SVCMAP(WMI_TLV_SERVICE_STA_PWRSAVE,
974 WMI_SERVICE_STA_PWRSAVE, len);
975 SVCMAP(WMI_TLV_SERVICE_STA_ADVANCED_PWRSAVE,
976 WMI_SERVICE_STA_ADVANCED_PWRSAVE, len);
977 SVCMAP(WMI_TLV_SERVICE_AP_UAPSD,
978 WMI_SERVICE_AP_UAPSD, len);
979 SVCMAP(WMI_TLV_SERVICE_AP_DFS,
980 WMI_SERVICE_AP_DFS, len);
981 SVCMAP(WMI_TLV_SERVICE_11AC,
982 WMI_SERVICE_11AC, len);
983 SVCMAP(WMI_TLV_SERVICE_BLOCKACK,
984 WMI_SERVICE_BLOCKACK, len);
985 SVCMAP(WMI_TLV_SERVICE_PHYERR,
986 WMI_SERVICE_PHYERR, len);
987 SVCMAP(WMI_TLV_SERVICE_BCN_FILTER,
988 WMI_SERVICE_BCN_FILTER, len);
989 SVCMAP(WMI_TLV_SERVICE_RTT,
990 WMI_SERVICE_RTT, len);
991 SVCMAP(WMI_TLV_SERVICE_WOW,
992 WMI_SERVICE_WOW, len);
993 SVCMAP(WMI_TLV_SERVICE_RATECTRL_CACHE,
994 WMI_SERVICE_RATECTRL_CACHE, len);
995 SVCMAP(WMI_TLV_SERVICE_IRAM_TIDS,
996 WMI_SERVICE_IRAM_TIDS, len);
997 SVCMAP(WMI_TLV_SERVICE_ARPNS_OFFLOAD,
998 WMI_SERVICE_ARPNS_OFFLOAD, len);
999 SVCMAP(WMI_TLV_SERVICE_NLO,
1000 WMI_SERVICE_NLO, len);
1001 SVCMAP(WMI_TLV_SERVICE_GTK_OFFLOAD,
1002 WMI_SERVICE_GTK_OFFLOAD, len);
1003 SVCMAP(WMI_TLV_SERVICE_SCAN_SCH,
1004 WMI_SERVICE_SCAN_SCH, len);
1005 SVCMAP(WMI_TLV_SERVICE_CSA_OFFLOAD,
1006 WMI_SERVICE_CSA_OFFLOAD, len);
1007 SVCMAP(WMI_TLV_SERVICE_CHATTER,
1008 WMI_SERVICE_CHATTER, len);
1009 SVCMAP(WMI_TLV_SERVICE_COEX_FREQAVOID,
1010 WMI_SERVICE_COEX_FREQAVOID, len);
1011 SVCMAP(WMI_TLV_SERVICE_PACKET_POWER_SAVE,
1012 WMI_SERVICE_PACKET_POWER_SAVE, len);
1013 SVCMAP(WMI_TLV_SERVICE_FORCE_FW_HANG,
1014 WMI_SERVICE_FORCE_FW_HANG, len);
1015 SVCMAP(WMI_TLV_SERVICE_GPIO,
1016 WMI_SERVICE_GPIO, len);
1017 SVCMAP(WMI_TLV_SERVICE_STA_DTIM_PS_MODULATED_DTIM,
1018 WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, len);
1019 SVCMAP(WMI_TLV_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG,
1020 WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, len);
1021 SVCMAP(WMI_TLV_SERVICE_STA_UAPSD_VAR_AUTO_TRIG,
1022 WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, len);
1023 SVCMAP(WMI_TLV_SERVICE_STA_KEEP_ALIVE,
1024 WMI_SERVICE_STA_KEEP_ALIVE, len);
1025 SVCMAP(WMI_TLV_SERVICE_TX_ENCAP,
1026 WMI_SERVICE_TX_ENCAP, len);
1027 SVCMAP(WMI_TLV_SERVICE_AP_PS_DETECT_OUT_OF_SYNC,
1028 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, len);
1029 SVCMAP(WMI_TLV_SERVICE_EARLY_RX,
1030 WMI_SERVICE_EARLY_RX, len);
1031 SVCMAP(WMI_TLV_SERVICE_STA_SMPS,
1032 WMI_SERVICE_STA_SMPS, len);
1033 SVCMAP(WMI_TLV_SERVICE_FWTEST,
1034 WMI_SERVICE_FWTEST, len);
1035 SVCMAP(WMI_TLV_SERVICE_STA_WMMAC,
1036 WMI_SERVICE_STA_WMMAC, len);
1037 SVCMAP(WMI_TLV_SERVICE_TDLS,
1038 WMI_SERVICE_TDLS, len);
1039 SVCMAP(WMI_TLV_SERVICE_BURST,
1040 WMI_SERVICE_BURST, len);
1041 SVCMAP(WMI_TLV_SERVICE_MCC_BCN_INTERVAL_CHANGE,
1042 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE, len);
1043 SVCMAP(WMI_TLV_SERVICE_ADAPTIVE_OCS,
1044 WMI_SERVICE_ADAPTIVE_OCS, len);
1045 SVCMAP(WMI_TLV_SERVICE_BA_SSN_SUPPORT,
1046 WMI_SERVICE_BA_SSN_SUPPORT, len);
1047 SVCMAP(WMI_TLV_SERVICE_FILTER_IPSEC_NATKEEPALIVE,
1048 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE, len);
1049 SVCMAP(WMI_TLV_SERVICE_WLAN_HB,
1050 WMI_SERVICE_WLAN_HB, len);
1051 SVCMAP(WMI_TLV_SERVICE_LTE_ANT_SHARE_SUPPORT,
1052 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT, len);
1053 SVCMAP(WMI_TLV_SERVICE_BATCH_SCAN,
1054 WMI_SERVICE_BATCH_SCAN, len);
1055 SVCMAP(WMI_TLV_SERVICE_QPOWER,
1056 WMI_SERVICE_QPOWER, len);
1057 SVCMAP(WMI_TLV_SERVICE_PLMREQ,
1058 WMI_SERVICE_PLMREQ, len);
1059 SVCMAP(WMI_TLV_SERVICE_THERMAL_MGMT,
1060 WMI_SERVICE_THERMAL_MGMT, len);
1061 SVCMAP(WMI_TLV_SERVICE_RMC,
1062 WMI_SERVICE_RMC, len);
1063 SVCMAP(WMI_TLV_SERVICE_MHF_OFFLOAD,
1064 WMI_SERVICE_MHF_OFFLOAD, len);
1065 SVCMAP(WMI_TLV_SERVICE_COEX_SAR,
1066 WMI_SERVICE_COEX_SAR, len);
1067 SVCMAP(WMI_TLV_SERVICE_BCN_TXRATE_OVERRIDE,
1068 WMI_SERVICE_BCN_TXRATE_OVERRIDE, len);
1069 SVCMAP(WMI_TLV_SERVICE_NAN,
1070 WMI_SERVICE_NAN, len);
1071 SVCMAP(WMI_TLV_SERVICE_L1SS_STAT,
1072 WMI_SERVICE_L1SS_STAT, len);
1073 SVCMAP(WMI_TLV_SERVICE_ESTIMATE_LINKSPEED,
1074 WMI_SERVICE_ESTIMATE_LINKSPEED, len);
1075 SVCMAP(WMI_TLV_SERVICE_OBSS_SCAN,
1076 WMI_SERVICE_OBSS_SCAN, len);
1077 SVCMAP(WMI_TLV_SERVICE_TDLS_OFFCHAN,
1078 WMI_SERVICE_TDLS_OFFCHAN, len);
1079 SVCMAP(WMI_TLV_SERVICE_TDLS_UAPSD_BUFFER_STA,
1080 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, len);
1081 SVCMAP(WMI_TLV_SERVICE_TDLS_UAPSD_SLEEP_STA,
1082 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, len);
1083 SVCMAP(WMI_TLV_SERVICE_IBSS_PWRSAVE,
1084 WMI_SERVICE_IBSS_PWRSAVE, len);
1085 SVCMAP(WMI_TLV_SERVICE_LPASS,
1086 WMI_SERVICE_LPASS, len);
1087 SVCMAP(WMI_TLV_SERVICE_EXTSCAN,
1088 WMI_SERVICE_EXTSCAN, len);
1089 SVCMAP(WMI_TLV_SERVICE_D0WOW,
1090 WMI_SERVICE_D0WOW, len);
1091 SVCMAP(WMI_TLV_SERVICE_HSOFFLOAD,
1092 WMI_SERVICE_HSOFFLOAD, len);
1093 SVCMAP(WMI_TLV_SERVICE_ROAM_HO_OFFLOAD,
1094 WMI_SERVICE_ROAM_HO_OFFLOAD, len);
1095 SVCMAP(WMI_TLV_SERVICE_RX_FULL_REORDER,
1096 WMI_SERVICE_RX_FULL_REORDER, len);
1097 SVCMAP(WMI_TLV_SERVICE_DHCP_OFFLOAD,
1098 WMI_SERVICE_DHCP_OFFLOAD, len);
1099 SVCMAP(WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
1100 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, len);
1101 SVCMAP(WMI_TLV_SERVICE_MDNS_OFFLOAD,
1102 WMI_SERVICE_MDNS_OFFLOAD, len);
1103 SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
1104 WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
1105}
1106
1107#undef SVCMAP
1108
1109struct wmi_tlv {
1110 __le16 len;
1111 __le16 tag;
1112 u8 value[0];
1113} __packed;
1114
1115#define WMI_TLV_MGMT_RX_NUM_RSSI 4
1116
1117struct wmi_tlv_mgmt_rx_ev {
1118 __le32 channel;
1119 __le32 snr;
1120 __le32 rate;
1121 __le32 phy_mode;
1122 __le32 buf_len;
1123 __le32 status;
1124 __le32 rssi[WMI_TLV_MGMT_RX_NUM_RSSI];
1125} __packed;
1126
1127struct wmi_tlv_abi_version {
1128 __le32 abi_ver0;
1129 __le32 abi_ver1;
1130 __le32 abi_ver_ns0;
1131 __le32 abi_ver_ns1;
1132 __le32 abi_ver_ns2;
1133 __le32 abi_ver_ns3;
1134} __packed;
1135
1136enum wmi_tlv_hw_bd_id {
1137 WMI_TLV_HW_BD_LEGACY = 0,
1138 WMI_TLV_HW_BD_QCA6174 = 1,
1139 WMI_TLV_HW_BD_QCA2582 = 2,
1140};
1141
1142struct wmi_tlv_hw_bd_info {
1143 u8 rev;
1144 u8 project_id;
1145 u8 custom_id;
1146 u8 reference_design_id;
1147} __packed;
1148
1149struct wmi_tlv_svc_rdy_ev {
1150 __le32 fw_build_vers;
1151 struct wmi_tlv_abi_version abi;
1152 __le32 phy_capability;
1153 __le32 max_frag_entry;
1154 __le32 num_rf_chains;
1155 __le32 ht_cap_info;
1156 __le32 vht_cap_info;
1157 __le32 vht_supp_mcs;
1158 __le32 hw_min_tx_power;
1159 __le32 hw_max_tx_power;
1160 __le32 sys_cap_info;
1161 __le32 min_pkt_size_enable;
1162 __le32 max_bcn_ie_size;
1163 __le32 num_mem_reqs;
1164 __le32 max_num_scan_chans;
1165 __le32 hw_bd_id; /* 0 means hw_bd_info is invalid */
1166 struct wmi_tlv_hw_bd_info hw_bd_info[5];
1167} __packed;
1168
1169struct wmi_tlv_rdy_ev {
1170 struct wmi_tlv_abi_version abi;
1171 struct wmi_mac_addr mac_addr;
1172 __le32 status;
1173} __packed;
1174
1175struct wmi_tlv_resource_config {
1176 __le32 num_vdevs;
1177 __le32 num_peers;
1178 __le32 num_offload_peers;
1179 __le32 num_offload_reorder_bufs;
1180 __le32 num_peer_keys;
1181 __le32 num_tids;
1182 __le32 ast_skid_limit;
1183 __le32 tx_chain_mask;
1184 __le32 rx_chain_mask;
1185 __le32 rx_timeout_pri[4];
1186 __le32 rx_decap_mode;
1187 __le32 scan_max_pending_reqs;
1188 __le32 bmiss_offload_max_vdev;
1189 __le32 roam_offload_max_vdev;
1190 __le32 roam_offload_max_ap_profiles;
1191 __le32 num_mcast_groups;
1192 __le32 num_mcast_table_elems;
1193 __le32 mcast2ucast_mode;
1194 __le32 tx_dbg_log_size;
1195 __le32 num_wds_entries;
1196 __le32 dma_burst_size;
1197 __le32 mac_aggr_delim;
1198 __le32 rx_skip_defrag_timeout_dup_detection_check;
1199 __le32 vow_config;
1200 __le32 gtk_offload_max_vdev;
1201 __le32 num_msdu_desc;
1202 __le32 max_frag_entries;
1203 __le32 num_tdls_vdevs;
1204 __le32 num_tdls_conn_table_entries;
1205 __le32 beacon_tx_offload_max_vdev;
1206 __le32 num_multicast_filter_entries;
1207 __le32 num_wow_filters;
1208 __le32 num_keep_alive_pattern;
1209 __le32 keep_alive_pattern_size;
1210 __le32 max_tdls_concurrent_sleep_sta;
1211 __le32 max_tdls_concurrent_buffer_sta;
1212} __packed;
1213
1214struct wmi_tlv_init_cmd {
1215 struct wmi_tlv_abi_version abi;
1216 __le32 num_host_mem_chunks;
1217} __packed;
1218
1219struct wmi_tlv_pdev_set_param_cmd {
1220 __le32 pdev_id; /* not used yet */
1221 __le32 param_id;
1222 __le32 param_value;
1223} __packed;
1224
1225struct wmi_tlv_pdev_set_rd_cmd {
1226 __le32 pdev_id; /* not used yet */
1227 __le32 regd;
1228 __le32 regd_2ghz;
1229 __le32 regd_5ghz;
1230 __le32 conform_limit_2ghz;
1231 __le32 conform_limit_5ghz;
1232} __packed;
1233
1234struct wmi_tlv_scan_chan_list_cmd {
1235 __le32 num_scan_chans;
1236} __packed;
1237
1238struct wmi_tlv_start_scan_cmd {
1239 struct wmi_start_scan_common common;
1240 __le32 burst_duration_ms;
1241 __le32 num_channels;
1242 __le32 num_bssids;
1243 __le32 num_ssids;
1244 __le32 ie_len;
1245 __le32 num_probes;
1246} __packed;
1247
1248struct wmi_tlv_vdev_start_cmd {
1249 __le32 vdev_id;
1250 __le32 requestor_id;
1251 __le32 bcn_intval;
1252 __le32 dtim_period;
1253 __le32 flags;
1254 struct wmi_ssid ssid;
1255 __le32 bcn_tx_rate;
1256 __le32 bcn_tx_power;
1257 __le32 num_noa_descr;
1258 __le32 disable_hw_ack;
1259} __packed;
1260
1261enum {
1262 WMI_TLV_PEER_TYPE_DEFAULT = 0, /* generic / non-BSS / self-peer */
1263 WMI_TLV_PEER_TYPE_BSS = 1,
1264 WMI_TLV_PEER_TYPE_TDLS = 2,
1265 WMI_TLV_PEER_TYPE_HOST_MAX = 127,
1266 WMI_TLV_PEER_TYPE_ROAMOFFLOAD_TMP = 128,
1267};
1268
1269struct wmi_tlv_peer_create_cmd {
1270 __le32 vdev_id;
1271 struct wmi_mac_addr peer_addr;
1272 __le32 peer_type;
1273} __packed;
1274
1275struct wmi_tlv_peer_assoc_cmd {
1276 struct wmi_mac_addr mac_addr;
1277 __le32 vdev_id;
1278 __le32 new_assoc;
1279 __le32 assoc_id;
1280 __le32 flags;
1281 __le32 caps;
1282 __le32 listen_intval;
1283 __le32 ht_caps;
1284 __le32 max_mpdu;
1285 __le32 mpdu_density;
1286 __le32 rate_caps;
1287 __le32 nss;
1288 __le32 vht_caps;
1289 __le32 phy_mode;
1290 __le32 ht_info[2];
1291 __le32 num_legacy_rates;
1292 __le32 num_ht_rates;
1293} __packed;
1294
1295struct wmi_tlv_pdev_suspend {
1296 __le32 pdev_id; /* not used yet */
1297 __le32 opt;
1298} __packed;
1299
1300struct wmi_tlv_pdev_set_wmm_cmd {
1301 __le32 pdev_id; /* not used yet */
1302 __le32 dg_type; /* no idea.. */
1303} __packed;
1304
1305struct wmi_tlv_phyerr_ev {
1306 __le32 num_phyerrs;
1307 __le32 tsf_l32;
1308 __le32 tsf_u32;
1309 __le32 buf_len;
1310} __packed;
1311
1312enum wmi_tlv_dbglog_param {
1313 WMI_TLV_DBGLOG_PARAM_LOG_LEVEL = 1,
1314 WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE,
1315 WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE,
1316 WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE_BITMAP,
1317 WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE_BITMAP,
1318};
1319
1320enum wmi_tlv_dbglog_log_level {
1321 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE = 0,
1322 WMI_TLV_DBGLOG_LOG_LEVEL_INFO,
1323 WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_1,
1324 WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_2,
1325 WMI_TLV_DBGLOG_LOG_LEVEL_WARN,
1326 WMI_TLV_DBGLOG_LOG_LEVEL_ERR,
1327};
1328
1329#define WMI_TLV_DBGLOG_BITMAP_MAX_IDS 512
1330#define WMI_TLV_DBGLOG_BITMAP_MAX_WORDS (WMI_TLV_DBGLOG_BITMAP_MAX_IDS / \
1331 sizeof(__le32))
1332#define WMI_TLV_DBGLOG_ALL_MODULES 0xffff
1333#define WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(module_id, log_level) \
1334 (((module_id << 16) & 0xffff0000) | \
1335 ((log_level << 0) & 0x000000ff))
1336
1337struct wmi_tlv_dbglog_cmd {
1338 __le32 param;
1339 __le32 value;
1340} __packed;
1341
1342struct wmi_tlv_resume_cmd {
1343 __le32 reserved;
1344} __packed;
1345
1346struct wmi_tlv_req_stats_cmd {
1347 __le32 stats_id; /* wmi_stats_id */
1348 __le32 vdev_id;
1349 struct wmi_mac_addr peer_macaddr;
1350} __packed;
1351
1352struct wmi_tlv_vdev_stats {
1353 __le32 vdev_id;
1354 __le32 beacon_snr;
1355 __le32 data_snr;
1356 __le32 num_tx_frames[4]; /* per-AC */
1357 __le32 num_rx_frames;
1358 __le32 num_tx_frames_retries[4];
1359 __le32 num_tx_frames_failures[4];
1360 __le32 num_rts_fail;
1361 __le32 num_rts_success;
1362 __le32 num_rx_err;
1363 __le32 num_rx_discard;
1364 __le32 num_tx_not_acked;
1365 __le32 tx_rate_history[10];
1366 __le32 beacon_rssi_history[10];
1367} __packed;
1368
1369struct wmi_tlv_pktlog_enable {
1370 __le32 reserved;
1371 __le32 filter;
1372} __packed;
1373
1374struct wmi_tlv_pktlog_disable {
1375 __le32 reserved;
1376} __packed;
1377
1378void ath10k_wmi_tlv_attach(struct ath10k *ar);
1379
1380#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 721631c3dd3e..23eca8bc85d1 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -22,8 +22,10 @@
22#include "htc.h" 22#include "htc.h"
23#include "debug.h" 23#include "debug.h"
24#include "wmi.h" 24#include "wmi.h"
25#include "wmi-tlv.h"
25#include "mac.h" 26#include "mac.h"
26#include "testmode.h" 27#include "testmode.h"
28#include "wmi-ops.h"
27 29
28/* MAIN WMI cmd track */ 30/* MAIN WMI cmd track */
29static struct wmi_cmd_map wmi_cmd_map = { 31static struct wmi_cmd_map wmi_cmd_map = {
@@ -143,6 +145,7 @@ static struct wmi_cmd_map wmi_cmd_map = {
143 .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID, 145 .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID,
144 .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, 146 .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID,
145 .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, 147 .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID,
148 .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
146}; 149};
147 150
148/* 10.X WMI cmd track */ 151/* 10.X WMI cmd track */
@@ -265,6 +268,129 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
265 .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, 268 .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
266 .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID, 269 .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID,
267 .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID, 270 .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID,
271 .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
272};
273
274/* 10.2.4 WMI cmd track */
275static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
276 .init_cmdid = WMI_10_2_INIT_CMDID,
277 .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID,
278 .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID,
279 .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID,
280 .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED,
281 .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID,
282 .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID,
283 .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID,
284 .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID,
285 .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID,
286 .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID,
287 .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID,
288 .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID,
289 .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID,
290 .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID,
291 .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID,
292 .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID,
293 .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID,
294 .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID,
295 .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID,
296 .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID,
297 .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID,
298 .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID,
299 .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID,
300 .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID,
301 .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID,
302 .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID,
303 .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID,
304 .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID,
305 .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID,
306 .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID,
307 .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID,
308 .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID,
309 .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID,
310 .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID,
311 .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID,
312 .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
313 .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID,
314 .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID,
315 .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID,
316 .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED,
317 .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID,
318 .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID,
319 .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID,
320 .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID,
321 .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID,
322 .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID,
323 .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID,
324 .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID,
325 .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID,
326 .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID,
327 .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID,
328 .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE,
329 .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD,
330 .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD,
331 .roam_scan_rssi_change_threshold =
332 WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
333 .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE,
334 .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE,
335 .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE,
336 .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD,
337 .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO,
338 .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY,
339 .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE,
340 .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE,
341 .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED,
342 .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID,
343 .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED,
344 .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID,
345 .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID,
346 .wlan_profile_set_hist_intvl_cmdid =
347 WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
348 .wlan_profile_get_profile_data_cmdid =
349 WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
350 .wlan_profile_enable_profile_id_cmdid =
351 WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
352 .wlan_profile_list_profile_id_cmdid =
353 WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
354 .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID,
355 .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID,
356 .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID,
357 .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID,
358 .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID,
359 .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID,
360 .wow_enable_disable_wake_event_cmdid =
361 WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
362 .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID,
363 .wow_hostwakeup_from_sleep_cmdid =
364 WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
365 .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID,
366 .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID,
367 .vdev_spectral_scan_configure_cmdid =
368 WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID,
369 .vdev_spectral_scan_enable_cmdid =
370 WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID,
371 .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID,
372 .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED,
373 .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED,
374 .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED,
375 .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED,
376 .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED,
377 .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED,
378 .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED,
379 .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED,
380 .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED,
381 .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED,
382 .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED,
383 .echo_cmdid = WMI_10_2_ECHO_CMDID,
384 .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID,
385 .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID,
386 .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID,
387 .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED,
388 .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
389 .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED,
390 .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
391 .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
392 .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
393 .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
268}; 394};
269 395
270/* MAIN WMI VDEV param map */ 396/* MAIN WMI VDEV param map */
@@ -385,6 +511,64 @@ static struct wmi_vdev_param_map wmi_10x_vdev_param_map = {
385 WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, 511 WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
386}; 512};
387 513
514static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = {
515 .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD,
516 .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
517 .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL,
518 .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL,
519 .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE,
520 .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE,
521 .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME,
522 .preamble = WMI_10X_VDEV_PARAM_PREAMBLE,
523 .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME,
524 .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD,
525 .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME,
526 .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL,
527 .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD,
528 .wmi_vdev_oc_scheduler_air_time_limit =
529 WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
530 .wds = WMI_10X_VDEV_PARAM_WDS,
531 .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW,
532 .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX,
533 .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
534 .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED,
535 .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM,
536 .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH,
537 .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET,
538 .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION,
539 .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT,
540 .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE,
541 .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE,
542 .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE,
543 .sgi = WMI_10X_VDEV_PARAM_SGI,
544 .ldpc = WMI_10X_VDEV_PARAM_LDPC,
545 .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC,
546 .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC,
547 .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD,
548 .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID,
549 .nss = WMI_10X_VDEV_PARAM_NSS,
550 .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE,
551 .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE,
552 .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE,
553 .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE,
554 .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
555 .ap_keepalive_min_idle_inactive_time_secs =
556 WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
557 .ap_keepalive_max_idle_inactive_time_secs =
558 WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
559 .ap_keepalive_max_unresponsive_time_secs =
560 WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
561 .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS,
562 .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET,
563 .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS,
564 .txbf = WMI_VDEV_PARAM_UNSUPPORTED,
565 .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED,
566 .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED,
567 .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED,
568 .ap_detect_out_of_sync_sleeping_sta_time_secs =
569 WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS,
570};
571
388static struct wmi_pdev_param_map wmi_pdev_param_map = { 572static struct wmi_pdev_param_map wmi_pdev_param_map = {
389 .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK, 573 .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK,
390 .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK, 574 .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK,
@@ -434,6 +618,7 @@ static struct wmi_pdev_param_map wmi_pdev_param_map = {
434 .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED, 618 .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED,
435 .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, 619 .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED,
436 .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, 620 .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED,
621 .cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
437}; 622};
438 623
439static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { 624static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
@@ -486,6 +671,60 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = {
486 .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, 671 .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
487 .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, 672 .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR,
488 .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, 673 .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE,
674 .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD,
675};
676
677static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = {
678 .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK,
679 .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK,
680 .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G,
681 .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G,
682 .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE,
683 .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE,
684 .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE,
685 .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
686 .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE,
687 .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW,
688 .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
689 .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH,
690 .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH,
691 .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING,
692 .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE,
693 .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE,
694 .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK,
695 .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI,
696 .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO,
697 .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
698 .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
699 .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE,
700 .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
701 .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE,
702 .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE,
703 .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED,
704 .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED,
705 .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED,
706 .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED,
707 .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
708 .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
709 .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
710 .bcnflt_stats_update_period =
711 WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
712 .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS,
713 .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE,
714 .dcs = WMI_10X_PDEV_PARAM_DCS,
715 .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE,
716 .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD,
717 .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD,
718 .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL,
719 .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL,
720 .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN,
721 .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED,
722 .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED,
723 .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED,
724 .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET,
725 .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR,
726 .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE,
727 .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD,
489}; 728};
490 729
491/* firmware 10.2 specific mappings */ 730/* firmware 10.2 specific mappings */
@@ -607,11 +846,11 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
607 .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, 846 .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED,
608 .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, 847 .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID,
609 .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, 848 .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID,
849 .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED,
610}; 850};
611 851
612static void 852void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
613ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, 853 const struct wmi_channel_arg *arg)
614 const struct wmi_channel_arg *arg)
615{ 854{
616 u32 flags = 0; 855 u32 flags = 0;
617 856
@@ -685,8 +924,8 @@ static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
685 dev_kfree_skb(skb); 924 dev_kfree_skb(skb);
686} 925}
687 926
688static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, 927int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
689 u32 cmd_id) 928 u32 cmd_id)
690{ 929{
691 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); 930 struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
692 struct wmi_cmd_hdr *cmd_hdr; 931 struct wmi_cmd_hdr *cmd_hdr;
@@ -792,24 +1031,23 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
792 return ret; 1031 return ret;
793} 1032}
794 1033
795int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) 1034static struct sk_buff *
1035ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
796{ 1036{
797 int ret = 0;
798 struct wmi_mgmt_tx_cmd *cmd; 1037 struct wmi_mgmt_tx_cmd *cmd;
799 struct ieee80211_hdr *hdr; 1038 struct ieee80211_hdr *hdr;
800 struct sk_buff *wmi_skb; 1039 struct sk_buff *skb;
801 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
802 int len; 1040 int len;
803 u32 buf_len = skb->len; 1041 u32 buf_len = msdu->len;
804 u16 fc; 1042 u16 fc;
805 1043
806 hdr = (struct ieee80211_hdr *)skb->data; 1044 hdr = (struct ieee80211_hdr *)msdu->data;
807 fc = le16_to_cpu(hdr->frame_control); 1045 fc = le16_to_cpu(hdr->frame_control);
808 1046
809 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) 1047 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
810 return -EINVAL; 1048 return ERR_PTR(-EINVAL);
811 1049
812 len = sizeof(cmd->hdr) + skb->len; 1050 len = sizeof(cmd->hdr) + msdu->len;
813 1051
814 if ((ieee80211_is_action(hdr->frame_control) || 1052 if ((ieee80211_is_action(hdr->frame_control) ||
815 ieee80211_is_deauth(hdr->frame_control) || 1053 ieee80211_is_deauth(hdr->frame_control) ||
@@ -821,36 +1059,27 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
821 1059
822 len = round_up(len, 4); 1060 len = round_up(len, 4);
823 1061
824 wmi_skb = ath10k_wmi_alloc_skb(ar, len); 1062 skb = ath10k_wmi_alloc_skb(ar, len);
825 if (!wmi_skb) 1063 if (!skb)
826 return -ENOMEM; 1064 return ERR_PTR(-ENOMEM);
827 1065
828 cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data; 1066 cmd = (struct wmi_mgmt_tx_cmd *)skb->data;
829 1067
830 cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); 1068 cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
831 cmd->hdr.tx_rate = 0; 1069 cmd->hdr.tx_rate = 0;
832 cmd->hdr.tx_power = 0; 1070 cmd->hdr.tx_power = 0;
833 cmd->hdr.buf_len = __cpu_to_le32(buf_len); 1071 cmd->hdr.buf_len = __cpu_to_le32(buf_len);
834 1072
835 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); 1073 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
836 memcpy(cmd->buf, skb->data, skb->len); 1074 memcpy(cmd->buf, msdu->data, msdu->len);
837 1075
838 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", 1076 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
839 wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, 1077 msdu, skb->len, fc & IEEE80211_FCTL_FTYPE,
840 fc & IEEE80211_FCTL_STYPE); 1078 fc & IEEE80211_FCTL_STYPE);
841 trace_ath10k_tx_hdr(ar, skb->data, skb->len); 1079 trace_ath10k_tx_hdr(ar, skb->data, skb->len);
842 trace_ath10k_tx_payload(ar, skb->data, skb->len); 1080 trace_ath10k_tx_payload(ar, skb->data, skb->len);
843 1081
844 /* Send the management frame buffer to the target */ 1082 return skb;
845 ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid);
846 if (ret)
847 return ret;
848
849 /* TODO: report tx status to mac80211 - temporary just ACK */
850 info->flags |= IEEE80211_TX_STAT_ACK;
851 ieee80211_tx_status_irqsafe(ar->hw, skb);
852
853 return ret;
854} 1083}
855 1084
856static void ath10k_wmi_event_scan_started(struct ath10k *ar) 1085static void ath10k_wmi_event_scan_started(struct ath10k *ar)
@@ -977,22 +1206,48 @@ ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type,
977 } 1206 }
978} 1207}
979 1208
980static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) 1209static int ath10k_wmi_op_pull_scan_ev(struct ath10k *ar, struct sk_buff *skb,
1210 struct wmi_scan_ev_arg *arg)
981{ 1211{
982 struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; 1212 struct wmi_scan_event *ev = (void *)skb->data;
1213
1214 if (skb->len < sizeof(*ev))
1215 return -EPROTO;
1216
1217 skb_pull(skb, sizeof(*ev));
1218 arg->event_type = ev->event_type;
1219 arg->reason = ev->reason;
1220 arg->channel_freq = ev->channel_freq;
1221 arg->scan_req_id = ev->scan_req_id;
1222 arg->scan_id = ev->scan_id;
1223 arg->vdev_id = ev->vdev_id;
1224
1225 return 0;
1226}
1227
1228int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
1229{
1230 struct wmi_scan_ev_arg arg = {};
983 enum wmi_scan_event_type event_type; 1231 enum wmi_scan_event_type event_type;
984 enum wmi_scan_completion_reason reason; 1232 enum wmi_scan_completion_reason reason;
985 u32 freq; 1233 u32 freq;
986 u32 req_id; 1234 u32 req_id;
987 u32 scan_id; 1235 u32 scan_id;
988 u32 vdev_id; 1236 u32 vdev_id;
1237 int ret;
989 1238
990 event_type = __le32_to_cpu(event->event_type); 1239 ret = ath10k_wmi_pull_scan(ar, skb, &arg);
991 reason = __le32_to_cpu(event->reason); 1240 if (ret) {
992 freq = __le32_to_cpu(event->channel_freq); 1241 ath10k_warn(ar, "failed to parse scan event: %d\n", ret);
993 req_id = __le32_to_cpu(event->scan_req_id); 1242 return ret;
994 scan_id = __le32_to_cpu(event->scan_id); 1243 }
995 vdev_id = __le32_to_cpu(event->vdev_id); 1244
1245 event_type = __le32_to_cpu(arg.event_type);
1246 reason = __le32_to_cpu(arg.reason);
1247 freq = __le32_to_cpu(arg.channel_freq);
1248 req_id = __le32_to_cpu(arg.scan_req_id);
1249 scan_id = __le32_to_cpu(arg.scan_id);
1250 vdev_id = __le32_to_cpu(arg.vdev_id);
996 1251
997 spin_lock_bh(&ar->data_lock); 1252 spin_lock_bh(&ar->data_lock);
998 1253
@@ -1147,11 +1402,51 @@ static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar,
1147 } 1402 }
1148} 1403}
1149 1404
1150static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) 1405static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb,
1406 struct wmi_mgmt_rx_ev_arg *arg)
1151{ 1407{
1152 struct wmi_mgmt_rx_event_v1 *ev_v1; 1408 struct wmi_mgmt_rx_event_v1 *ev_v1;
1153 struct wmi_mgmt_rx_event_v2 *ev_v2; 1409 struct wmi_mgmt_rx_event_v2 *ev_v2;
1154 struct wmi_mgmt_rx_hdr_v1 *ev_hdr; 1410 struct wmi_mgmt_rx_hdr_v1 *ev_hdr;
1411 size_t pull_len;
1412 u32 msdu_len;
1413
1414 if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) {
1415 ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data;
1416 ev_hdr = &ev_v2->hdr.v1;
1417 pull_len = sizeof(*ev_v2);
1418 } else {
1419 ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data;
1420 ev_hdr = &ev_v1->hdr;
1421 pull_len = sizeof(*ev_v1);
1422 }
1423
1424 if (skb->len < pull_len)
1425 return -EPROTO;
1426
1427 skb_pull(skb, pull_len);
1428 arg->channel = ev_hdr->channel;
1429 arg->buf_len = ev_hdr->buf_len;
1430 arg->status = ev_hdr->status;
1431 arg->snr = ev_hdr->snr;
1432 arg->phy_mode = ev_hdr->phy_mode;
1433 arg->rate = ev_hdr->rate;
1434
1435 msdu_len = __le32_to_cpu(arg->buf_len);
1436 if (skb->len < msdu_len)
1437 return -EPROTO;
1438
1439 /* the WMI buffer might've ended up being padded to 4 bytes due to HTC
1440 * trailer with credit update. Trim the excess garbage.
1441 */
1442 skb_trim(skb, msdu_len);
1443
1444 return 0;
1445}
1446
1447int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1448{
1449 struct wmi_mgmt_rx_ev_arg arg = {};
1155 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1450 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1156 struct ieee80211_hdr *hdr; 1451 struct ieee80211_hdr *hdr;
1157 u32 rx_status; 1452 u32 rx_status;
@@ -1161,24 +1456,20 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1161 u32 rate; 1456 u32 rate;
1162 u32 buf_len; 1457 u32 buf_len;
1163 u16 fc; 1458 u16 fc;
1164 int pull_len; 1459 int ret;
1165 1460
1166 if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { 1461 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
1167 ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; 1462 if (ret) {
1168 ev_hdr = &ev_v2->hdr.v1; 1463 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
1169 pull_len = sizeof(*ev_v2); 1464 return ret;
1170 } else {
1171 ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data;
1172 ev_hdr = &ev_v1->hdr;
1173 pull_len = sizeof(*ev_v1);
1174 } 1465 }
1175 1466
1176 channel = __le32_to_cpu(ev_hdr->channel); 1467 channel = __le32_to_cpu(arg.channel);
1177 buf_len = __le32_to_cpu(ev_hdr->buf_len); 1468 buf_len = __le32_to_cpu(arg.buf_len);
1178 rx_status = __le32_to_cpu(ev_hdr->status); 1469 rx_status = __le32_to_cpu(arg.status);
1179 snr = __le32_to_cpu(ev_hdr->snr); 1470 snr = __le32_to_cpu(arg.snr);
1180 phy_mode = __le32_to_cpu(ev_hdr->phy_mode); 1471 phy_mode = __le32_to_cpu(arg.phy_mode);
1181 rate = __le32_to_cpu(ev_hdr->rate); 1472 rate = __le32_to_cpu(arg.rate);
1182 1473
1183 memset(status, 0, sizeof(*status)); 1474 memset(status, 0, sizeof(*status));
1184 1475
@@ -1232,8 +1523,6 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1232 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; 1523 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
1233 status->rate_idx = get_rate_idx(rate, status->band); 1524 status->rate_idx = get_rate_idx(rate, status->band);
1234 1525
1235 skb_pull(skb, pull_len);
1236
1237 hdr = (struct ieee80211_hdr *)skb->data; 1526 hdr = (struct ieee80211_hdr *)skb->data;
1238 fc = le16_to_cpu(hdr->frame_control); 1527 fc = le16_to_cpu(hdr->frame_control);
1239 1528
@@ -1266,12 +1555,6 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1266 status->freq, status->band, status->signal, 1555 status->freq, status->band, status->signal,
1267 status->rate_idx); 1556 status->rate_idx);
1268 1557
1269 /*
1270 * packets from HTC come aligned to 4byte boundaries
1271 * because they can originally come in along with a trailer
1272 */
1273 skb_trim(skb, buf_len);
1274
1275 ieee80211_rx(ar->hw, skb); 1558 ieee80211_rx(ar->hw, skb);
1276 return 0; 1559 return 0;
1277} 1560}
@@ -1295,21 +1578,44 @@ exit:
1295 return idx; 1578 return idx;
1296} 1579}
1297 1580
1298static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) 1581static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb,
1582 struct wmi_ch_info_ev_arg *arg)
1299{ 1583{
1300 struct wmi_chan_info_event *ev; 1584 struct wmi_chan_info_event *ev = (void *)skb->data;
1585
1586 if (skb->len < sizeof(*ev))
1587 return -EPROTO;
1588
1589 skb_pull(skb, sizeof(*ev));
1590 arg->err_code = ev->err_code;
1591 arg->freq = ev->freq;
1592 arg->cmd_flags = ev->cmd_flags;
1593 arg->noise_floor = ev->noise_floor;
1594 arg->rx_clear_count = ev->rx_clear_count;
1595 arg->cycle_count = ev->cycle_count;
1596
1597 return 0;
1598}
1599
1600void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
1601{
1602 struct wmi_ch_info_ev_arg arg = {};
1301 struct survey_info *survey; 1603 struct survey_info *survey;
1302 u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count; 1604 u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count;
1303 int idx; 1605 int idx, ret;
1304 1606
1305 ev = (struct wmi_chan_info_event *)skb->data; 1607 ret = ath10k_wmi_pull_ch_info(ar, skb, &arg);
1608 if (ret) {
1609 ath10k_warn(ar, "failed to parse chan info event: %d\n", ret);
1610 return;
1611 }
1306 1612
1307 err_code = __le32_to_cpu(ev->err_code); 1613 err_code = __le32_to_cpu(arg.err_code);
1308 freq = __le32_to_cpu(ev->freq); 1614 freq = __le32_to_cpu(arg.freq);
1309 cmd_flags = __le32_to_cpu(ev->cmd_flags); 1615 cmd_flags = __le32_to_cpu(arg.cmd_flags);
1310 noise_floor = __le32_to_cpu(ev->noise_floor); 1616 noise_floor = __le32_to_cpu(arg.noise_floor);
1311 rx_clear_count = __le32_to_cpu(ev->rx_clear_count); 1617 rx_clear_count = __le32_to_cpu(arg.rx_clear_count);
1312 cycle_count = __le32_to_cpu(ev->cycle_count); 1618 cycle_count = __le32_to_cpu(arg.cycle_count);
1313 1619
1314 ath10k_dbg(ar, ATH10K_DBG_WMI, 1620 ath10k_dbg(ar, ATH10K_DBG_WMI,
1315 "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n", 1621 "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n",
@@ -1359,12 +1665,12 @@ exit:
1359 spin_unlock_bh(&ar->data_lock); 1665 spin_unlock_bh(&ar->data_lock);
1360} 1666}
1361 1667
1362static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) 1668void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
1363{ 1669{
1364 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); 1670 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");
1365} 1671}
1366 1672
1367static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 1673int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
1368{ 1674{
1369 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", 1675 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
1370 skb->len); 1676 skb->len);
@@ -1374,8 +1680,8 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
1374 return 0; 1680 return 0;
1375} 1681}
1376 1682
1377static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, 1683void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src,
1378 struct ath10k_fw_stats_pdev *dst) 1684 struct ath10k_fw_stats_pdev *dst)
1379{ 1685{
1380 const struct wal_dbg_tx_stats *tx = &src->wal.tx; 1686 const struct wal_dbg_tx_stats *tx = &src->wal.tx;
1381 const struct wal_dbg_rx_stats *rx = &src->wal.rx; 1687 const struct wal_dbg_rx_stats *rx = &src->wal.rx;
@@ -1427,17 +1733,17 @@ static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src,
1427 dst->mpdu_errs = __le32_to_cpu(rx->mpdu_errs); 1733 dst->mpdu_errs = __le32_to_cpu(rx->mpdu_errs);
1428} 1734}
1429 1735
1430static void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, 1736void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
1431 struct ath10k_fw_stats_peer *dst) 1737 struct ath10k_fw_stats_peer *dst)
1432{ 1738{
1433 ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); 1739 ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
1434 dst->peer_rssi = __le32_to_cpu(src->peer_rssi); 1740 dst->peer_rssi = __le32_to_cpu(src->peer_rssi);
1435 dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate); 1741 dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate);
1436} 1742}
1437 1743
1438static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, 1744static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar,
1439 struct sk_buff *skb, 1745 struct sk_buff *skb,
1440 struct ath10k_fw_stats *stats) 1746 struct ath10k_fw_stats *stats)
1441{ 1747{
1442 const struct wmi_stats_event *ev = (void *)skb->data; 1748 const struct wmi_stats_event *ev = (void *)skb->data;
1443 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1749 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
@@ -1487,9 +1793,9 @@ static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar,
1487 return 0; 1793 return 0;
1488} 1794}
1489 1795
1490static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, 1796static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
1491 struct sk_buff *skb, 1797 struct sk_buff *skb,
1492 struct ath10k_fw_stats *stats) 1798 struct ath10k_fw_stats *stats)
1493{ 1799{
1494 const struct wmi_stats_event *ev = (void *)skb->data; 1800 const struct wmi_stats_event *ev = (void *)skb->data;
1495 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1801 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
@@ -1550,61 +1856,92 @@ static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar,
1550 return 0; 1856 return 0;
1551} 1857}
1552 1858
1553int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, 1859void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb)
1554 struct ath10k_fw_stats *stats)
1555{ 1860{
1556 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) 1861 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
1557 return ath10k_wmi_10x_pull_fw_stats(ar, skb, stats); 1862 ath10k_debug_fw_stats_process(ar, skb);
1558 else
1559 return ath10k_wmi_main_pull_fw_stats(ar, skb, stats);
1560} 1863}
1561 1864
1562static void ath10k_wmi_event_update_stats(struct ath10k *ar, 1865static int
1563 struct sk_buff *skb) 1866ath10k_wmi_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
1867 struct wmi_vdev_start_ev_arg *arg)
1564{ 1868{
1565 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); 1869 struct wmi_vdev_start_response_event *ev = (void *)skb->data;
1566 ath10k_debug_fw_stats_process(ar, skb); 1870
1871 if (skb->len < sizeof(*ev))
1872 return -EPROTO;
1873
1874 skb_pull(skb, sizeof(*ev));
1875 arg->vdev_id = ev->vdev_id;
1876 arg->req_id = ev->req_id;
1877 arg->resp_type = ev->resp_type;
1878 arg->status = ev->status;
1879
1880 return 0;
1567} 1881}
1568 1882
1569static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, 1883void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb)
1570 struct sk_buff *skb)
1571{ 1884{
1572 struct wmi_vdev_start_response_event *ev; 1885 struct wmi_vdev_start_ev_arg arg = {};
1886 int ret;
1573 1887
1574 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); 1888 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n");
1575 1889
1576 ev = (struct wmi_vdev_start_response_event *)skb->data; 1890 ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg);
1891 if (ret) {
1892 ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret);
1893 return;
1894 }
1577 1895
1578 if (WARN_ON(__le32_to_cpu(ev->status))) 1896 if (WARN_ON(__le32_to_cpu(arg.status)))
1579 return; 1897 return;
1580 1898
1581 complete(&ar->vdev_setup_done); 1899 complete(&ar->vdev_setup_done);
1582} 1900}
1583 1901
1584static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, 1902void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb)
1585 struct sk_buff *skb)
1586{ 1903{
1587 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); 1904 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n");
1588 complete(&ar->vdev_setup_done); 1905 complete(&ar->vdev_setup_done);
1589} 1906}
1590 1907
1591static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, 1908static int
1592 struct sk_buff *skb) 1909ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb,
1910 struct wmi_peer_kick_ev_arg *arg)
1593{ 1911{
1594 struct wmi_peer_sta_kickout_event *ev; 1912 struct wmi_peer_sta_kickout_event *ev = (void *)skb->data;
1913
1914 if (skb->len < sizeof(*ev))
1915 return -EPROTO;
1916
1917 skb_pull(skb, sizeof(*ev));
1918 arg->mac_addr = ev->peer_macaddr.addr;
1919
1920 return 0;
1921}
1922
1923void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb)
1924{
1925 struct wmi_peer_kick_ev_arg arg = {};
1595 struct ieee80211_sta *sta; 1926 struct ieee80211_sta *sta;
1927 int ret;
1596 1928
1597 ev = (struct wmi_peer_sta_kickout_event *)skb->data; 1929 ret = ath10k_wmi_pull_peer_kick(ar, skb, &arg);
1930 if (ret) {
1931 ath10k_warn(ar, "failed to parse peer kickout event: %d\n",
1932 ret);
1933 return;
1934 }
1598 1935
1599 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", 1936 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n",
1600 ev->peer_macaddr.addr); 1937 arg.mac_addr);
1601 1938
1602 rcu_read_lock(); 1939 rcu_read_lock();
1603 1940
1604 sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); 1941 sta = ieee80211_find_sta_by_ifaddr(ar->hw, arg.mac_addr, NULL);
1605 if (!sta) { 1942 if (!sta) {
1606 ath10k_warn(ar, "Spurious quick kickout for STA %pM\n", 1943 ath10k_warn(ar, "Spurious quick kickout for STA %pM\n",
1607 ev->peer_macaddr.addr); 1944 arg.mac_addr);
1608 goto exit; 1945 goto exit;
1609 } 1946 }
1610 1947
@@ -1641,7 +1978,7 @@ exit:
1641static void ath10k_wmi_update_tim(struct ath10k *ar, 1978static void ath10k_wmi_update_tim(struct ath10k *ar,
1642 struct ath10k_vif *arvif, 1979 struct ath10k_vif *arvif,
1643 struct sk_buff *bcn, 1980 struct sk_buff *bcn,
1644 struct wmi_bcn_info *bcn_info) 1981 const struct wmi_tim_info *tim_info)
1645{ 1982{
1646 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; 1983 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data;
1647 struct ieee80211_tim_ie *tim; 1984 struct ieee80211_tim_ie *tim;
@@ -1652,14 +1989,14 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1652 1989
1653 /* if next SWBA has no tim_changed the tim_bitmap is garbage. 1990 /* if next SWBA has no tim_changed the tim_bitmap is garbage.
1654 * we must copy the bitmap upon change and reuse it later */ 1991 * we must copy the bitmap upon change and reuse it later */
1655 if (__le32_to_cpu(bcn_info->tim_info.tim_changed)) { 1992 if (__le32_to_cpu(tim_info->tim_changed)) {
1656 int i; 1993 int i;
1657 1994
1658 BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != 1995 BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) !=
1659 sizeof(bcn_info->tim_info.tim_bitmap)); 1996 sizeof(tim_info->tim_bitmap));
1660 1997
1661 for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { 1998 for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) {
1662 t = bcn_info->tim_info.tim_bitmap[i / 4]; 1999 t = tim_info->tim_bitmap[i / 4];
1663 v = __le32_to_cpu(t); 2000 v = __le32_to_cpu(t);
1664 arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; 2001 arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
1665 } 2002 }
@@ -1711,13 +2048,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1711 return; 2048 return;
1712 } 2049 }
1713 2050
1714 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast); 2051 tim->bitmap_ctrl = !!__le32_to_cpu(tim_info->tim_mcast);
1715 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); 2052 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
1716 2053
1717 if (tim->dtim_count == 0) { 2054 if (tim->dtim_count == 0) {
1718 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true; 2055 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
1719 2056
1720 if (__le32_to_cpu(bcn_info->tim_info.tim_mcast) == 1) 2057 if (__le32_to_cpu(tim_info->tim_mcast) == 1)
1721 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; 2058 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
1722 } 2059 }
1723 2060
@@ -1727,7 +2064,7 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1727} 2064}
1728 2065
1729static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len, 2066static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
1730 struct wmi_p2p_noa_info *noa) 2067 const struct wmi_p2p_noa_info *noa)
1731{ 2068{
1732 struct ieee80211_p2p_noa_attr *noa_attr; 2069 struct ieee80211_p2p_noa_attr *noa_attr;
1733 u8 ctwindow_oppps = noa->ctwindow_oppps; 2070 u8 ctwindow_oppps = noa->ctwindow_oppps;
@@ -1769,7 +2106,7 @@ static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
1769 *noa_attr_len = __cpu_to_le16(attr_len); 2106 *noa_attr_len = __cpu_to_le16(attr_len);
1770} 2107}
1771 2108
1772static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa) 2109static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa)
1773{ 2110{
1774 u32 len = 0; 2111 u32 len = 0;
1775 u8 noa_descriptors = noa->num_descriptors; 2112 u8 noa_descriptors = noa->num_descriptors;
@@ -1789,9 +2126,8 @@ static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa)
1789 2126
1790static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, 2127static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
1791 struct sk_buff *bcn, 2128 struct sk_buff *bcn,
1792 struct wmi_bcn_info *bcn_info) 2129 const struct wmi_p2p_noa_info *noa)
1793{ 2130{
1794 struct wmi_p2p_noa_info *noa = &bcn_info->p2p_noa_info;
1795 u8 *new_data, *old_data = arvif->u.ap.noa_data; 2131 u8 *new_data, *old_data = arvif->u.ap.noa_data;
1796 u32 new_len; 2132 u32 new_len;
1797 2133
@@ -1832,22 +2168,59 @@ cleanup:
1832 kfree(old_data); 2168 kfree(old_data);
1833} 2169}
1834 2170
1835static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) 2171static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
2172 struct wmi_swba_ev_arg *arg)
2173{
2174 struct wmi_host_swba_event *ev = (void *)skb->data;
2175 u32 map;
2176 size_t i;
2177
2178 if (skb->len < sizeof(*ev))
2179 return -EPROTO;
2180
2181 skb_pull(skb, sizeof(*ev));
2182 arg->vdev_map = ev->vdev_map;
2183
2184 for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
2185 if (!(map & BIT(0)))
2186 continue;
2187
2188 /* If this happens there were some changes in firmware and
2189 * ath10k should update the max size of tim_info array.
2190 */
2191 if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
2192 break;
2193
2194 arg->tim_info[i] = &ev->bcn_info[i].tim_info;
2195 arg->noa_info[i] = &ev->bcn_info[i].p2p_noa_info;
2196 i++;
2197 }
2198
2199 return 0;
2200}
2201
2202void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1836{ 2203{
1837 struct wmi_host_swba_event *ev; 2204 struct wmi_swba_ev_arg arg = {};
1838 u32 map; 2205 u32 map;
1839 int i = -1; 2206 int i = -1;
1840 struct wmi_bcn_info *bcn_info; 2207 const struct wmi_tim_info *tim_info;
2208 const struct wmi_p2p_noa_info *noa_info;
1841 struct ath10k_vif *arvif; 2209 struct ath10k_vif *arvif;
1842 struct sk_buff *bcn; 2210 struct sk_buff *bcn;
1843 dma_addr_t paddr; 2211 dma_addr_t paddr;
1844 int ret, vdev_id = 0; 2212 int ret, vdev_id = 0;
1845 2213
1846 ev = (struct wmi_host_swba_event *)skb->data; 2214 ret = ath10k_wmi_pull_swba(ar, skb, &arg);
1847 map = __le32_to_cpu(ev->vdev_map); 2215 if (ret) {
2216 ath10k_warn(ar, "failed to parse swba event: %d\n", ret);
2217 return;
2218 }
2219
2220 map = __le32_to_cpu(arg.vdev_map);
1848 2221
1849 ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", 2222 ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
1850 ev->vdev_map); 2223 map);
1851 2224
1852 for (; map; map >>= 1, vdev_id++) { 2225 for (; map; map >>= 1, vdev_id++) {
1853 if (!(map & 0x1)) 2226 if (!(map & 0x1))
@@ -1860,19 +2233,20 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1860 break; 2233 break;
1861 } 2234 }
1862 2235
1863 bcn_info = &ev->bcn_info[i]; 2236 tim_info = arg.tim_info[i];
2237 noa_info = arg.noa_info[i];
1864 2238
1865 ath10k_dbg(ar, ATH10K_DBG_MGMT, 2239 ath10k_dbg(ar, ATH10K_DBG_MGMT,
1866 "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n", 2240 "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n",
1867 i, 2241 i,
1868 __le32_to_cpu(bcn_info->tim_info.tim_len), 2242 __le32_to_cpu(tim_info->tim_len),
1869 __le32_to_cpu(bcn_info->tim_info.tim_mcast), 2243 __le32_to_cpu(tim_info->tim_mcast),
1870 __le32_to_cpu(bcn_info->tim_info.tim_changed), 2244 __le32_to_cpu(tim_info->tim_changed),
1871 __le32_to_cpu(bcn_info->tim_info.tim_num_ps_pending), 2245 __le32_to_cpu(tim_info->tim_num_ps_pending),
1872 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[3]), 2246 __le32_to_cpu(tim_info->tim_bitmap[3]),
1873 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[2]), 2247 __le32_to_cpu(tim_info->tim_bitmap[2]),
1874 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[1]), 2248 __le32_to_cpu(tim_info->tim_bitmap[1]),
1875 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[0])); 2249 __le32_to_cpu(tim_info->tim_bitmap[0]));
1876 2250
1877 arvif = ath10k_get_arvif(ar, vdev_id); 2251 arvif = ath10k_get_arvif(ar, vdev_id);
1878 if (arvif == NULL) { 2252 if (arvif == NULL) {
@@ -1899,8 +2273,8 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1899 } 2273 }
1900 2274
1901 ath10k_tx_h_seq_no(arvif->vif, bcn); 2275 ath10k_tx_h_seq_no(arvif->vif, bcn);
1902 ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info); 2276 ath10k_wmi_update_tim(ar, arvif, bcn, tim_info);
1903 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); 2277 ath10k_wmi_update_noa(ar, arvif, bcn, noa_info);
1904 2278
1905 spin_lock_bh(&ar->data_lock); 2279 spin_lock_bh(&ar->data_lock);
1906 2280
@@ -1946,8 +2320,7 @@ skip:
1946 } 2320 }
1947} 2321}
1948 2322
1949static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, 2323void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb)
1950 struct sk_buff *skb)
1951{ 2324{
1952 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); 2325 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
1953} 2326}
@@ -2068,9 +2441,9 @@ static int ath10k_dfs_fft_report(struct ath10k *ar,
2068 return 0; 2441 return 0;
2069} 2442}
2070 2443
2071static void ath10k_wmi_event_dfs(struct ath10k *ar, 2444void ath10k_wmi_event_dfs(struct ath10k *ar,
2072 const struct wmi_phyerr *phyerr, 2445 const struct wmi_phyerr *phyerr,
2073 u64 tsf) 2446 u64 tsf)
2074{ 2447{
2075 int buf_len, tlv_len, res, i = 0; 2448 int buf_len, tlv_len, res, i = 0;
2076 const struct phyerr_tlv *tlv; 2449 const struct phyerr_tlv *tlv;
@@ -2133,10 +2506,9 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar,
2133 } 2506 }
2134} 2507}
2135 2508
2136static void 2509void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
2137ath10k_wmi_event_spectral_scan(struct ath10k *ar, 2510 const struct wmi_phyerr *phyerr,
2138 const struct wmi_phyerr *phyerr, 2511 u64 tsf)
2139 u64 tsf)
2140{ 2512{
2141 int buf_len, tlv_len, res, i = 0; 2513 int buf_len, tlv_len, res, i = 0;
2142 struct phyerr_tlv *tlv; 2514 struct phyerr_tlv *tlv;
@@ -2188,37 +2560,53 @@ ath10k_wmi_event_spectral_scan(struct ath10k *ar,
2188 } 2560 }
2189} 2561}
2190 2562
2191static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) 2563static int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, struct sk_buff *skb,
2564 struct wmi_phyerr_ev_arg *arg)
2565{
2566 struct wmi_phyerr_event *ev = (void *)skb->data;
2567
2568 if (skb->len < sizeof(*ev))
2569 return -EPROTO;
2570
2571 arg->num_phyerrs = ev->num_phyerrs;
2572 arg->tsf_l32 = ev->tsf_l32;
2573 arg->tsf_u32 = ev->tsf_u32;
2574 arg->buf_len = __cpu_to_le32(skb->len - sizeof(*ev));
2575 arg->phyerrs = ev->phyerrs;
2576
2577 return 0;
2578}
2579
2580void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
2192{ 2581{
2193 const struct wmi_phyerr_event *ev; 2582 struct wmi_phyerr_ev_arg arg = {};
2194 const struct wmi_phyerr *phyerr; 2583 const struct wmi_phyerr *phyerr;
2195 u32 count, i, buf_len, phy_err_code; 2584 u32 count, i, buf_len, phy_err_code;
2196 u64 tsf; 2585 u64 tsf;
2197 int left_len = skb->len; 2586 int left_len, ret;
2198 2587
2199 ATH10K_DFS_STAT_INC(ar, phy_errors); 2588 ATH10K_DFS_STAT_INC(ar, phy_errors);
2200 2589
2201 /* Check if combined event available */ 2590 ret = ath10k_wmi_pull_phyerr(ar, skb, &arg);
2202 if (left_len < sizeof(*ev)) { 2591 if (ret) {
2203 ath10k_warn(ar, "wmi phyerr combined event wrong len\n"); 2592 ath10k_warn(ar, "failed to parse phyerr event: %d\n", ret);
2204 return; 2593 return;
2205 } 2594 }
2206 2595
2207 left_len -= sizeof(*ev); 2596 left_len = __le32_to_cpu(arg.buf_len);
2208 2597
2209 /* Check number of included events */ 2598 /* Check number of included events */
2210 ev = (const struct wmi_phyerr_event *)skb->data; 2599 count = __le32_to_cpu(arg.num_phyerrs);
2211 count = __le32_to_cpu(ev->num_phyerrs);
2212 2600
2213 tsf = __le32_to_cpu(ev->tsf_u32); 2601 tsf = __le32_to_cpu(arg.tsf_u32);
2214 tsf <<= 32; 2602 tsf <<= 32;
2215 tsf |= __le32_to_cpu(ev->tsf_l32); 2603 tsf |= __le32_to_cpu(arg.tsf_l32);
2216 2604
2217 ath10k_dbg(ar, ATH10K_DBG_WMI, 2605 ath10k_dbg(ar, ATH10K_DBG_WMI,
2218 "wmi event phyerr count %d tsf64 0x%llX\n", 2606 "wmi event phyerr count %d tsf64 0x%llX\n",
2219 count, tsf); 2607 count, tsf);
2220 2608
2221 phyerr = ev->phyerrs; 2609 phyerr = arg.phyerrs;
2222 for (i = 0; i < count; i++) { 2610 for (i = 0; i < count; i++) {
2223 /* Check if we can read event header */ 2611 /* Check if we can read event header */
2224 if (left_len < sizeof(*phyerr)) { 2612 if (left_len < sizeof(*phyerr)) {
@@ -2258,19 +2646,17 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
2258 } 2646 }
2259} 2647}
2260 2648
2261static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) 2649void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
2262{ 2650{
2263 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); 2651 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n");
2264} 2652}
2265 2653
2266static void ath10k_wmi_event_profile_match(struct ath10k *ar, 2654void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb)
2267 struct sk_buff *skb)
2268{ 2655{
2269 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); 2656 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
2270} 2657}
2271 2658
2272static void ath10k_wmi_event_debug_print(struct ath10k *ar, 2659void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb)
2273 struct sk_buff *skb)
2274{ 2660{
2275 char buf[101], c; 2661 char buf[101], c;
2276 int i; 2662 int i;
@@ -2303,103 +2689,90 @@ static void ath10k_wmi_event_debug_print(struct ath10k *ar,
2303 ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf); 2689 ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf);
2304} 2690}
2305 2691
2306static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) 2692void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
2307{ 2693{
2308 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); 2694 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n");
2309} 2695}
2310 2696
2311static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, 2697void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb)
2312 struct sk_buff *skb)
2313{ 2698{
2314 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); 2699 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n");
2315} 2700}
2316 2701
2317static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, 2702void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
2318 struct sk_buff *skb) 2703 struct sk_buff *skb)
2319{ 2704{
2320 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); 2705 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
2321} 2706}
2322 2707
2323static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, 2708void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
2324 struct sk_buff *skb) 2709 struct sk_buff *skb)
2325{ 2710{
2326 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); 2711 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
2327} 2712}
2328 2713
2329static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, 2714void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb)
2330 struct sk_buff *skb)
2331{ 2715{
2332 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); 2716 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n");
2333} 2717}
2334 2718
2335static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, 2719void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb)
2336 struct sk_buff *skb)
2337{ 2720{
2338 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); 2721 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n");
2339} 2722}
2340 2723
2341static void ath10k_wmi_event_dcs_interference(struct ath10k *ar, 2724void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb)
2342 struct sk_buff *skb)
2343{ 2725{
2344 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); 2726 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n");
2345} 2727}
2346 2728
2347static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, 2729void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
2348 struct sk_buff *skb)
2349{ 2730{
2350 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); 2731 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n");
2351} 2732}
2352 2733
2353static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, 2734void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb)
2354 struct sk_buff *skb)
2355{ 2735{
2356 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); 2736 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n");
2357} 2737}
2358 2738
2359static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, 2739void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, struct sk_buff *skb)
2360 struct sk_buff *skb)
2361{ 2740{
2362 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); 2741 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
2363} 2742}
2364 2743
2365static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, 2744void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb)
2366 struct sk_buff *skb)
2367{ 2745{
2368 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); 2746 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n");
2369} 2747}
2370 2748
2371static void ath10k_wmi_event_delba_complete(struct ath10k *ar, 2749void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb)
2372 struct sk_buff *skb)
2373{ 2750{
2374 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); 2751 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n");
2375} 2752}
2376 2753
2377static void ath10k_wmi_event_addba_complete(struct ath10k *ar, 2754void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb)
2378 struct sk_buff *skb)
2379{ 2755{
2380 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); 2756 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n");
2381} 2757}
2382 2758
2383static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, 2759void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
2384 struct sk_buff *skb) 2760 struct sk_buff *skb)
2385{ 2761{
2386 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); 2762 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
2387} 2763}
2388 2764
2389static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, 2765void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb)
2390 struct sk_buff *skb)
2391{ 2766{
2392 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); 2767 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n");
2393} 2768}
2394 2769
2395static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, 2770void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb)
2396 struct sk_buff *skb)
2397{ 2771{
2398 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); 2772 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n");
2399} 2773}
2400 2774
2401static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, 2775void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb)
2402 struct sk_buff *skb)
2403{ 2776{
2404 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); 2777 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
2405} 2778}
@@ -2435,8 +2808,9 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
2435 return 0; 2808 return 0;
2436} 2809}
2437 2810
2438static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb, 2811static int
2439 struct wmi_svc_rdy_ev_arg *arg) 2812ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
2813 struct wmi_svc_rdy_ev_arg *arg)
2440{ 2814{
2441 struct wmi_service_ready_event *ev; 2815 struct wmi_service_ready_event *ev;
2442 size_t i, n; 2816 size_t i, n;
@@ -2471,8 +2845,9 @@ static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb,
2471 return 0; 2845 return 0;
2472} 2846}
2473 2847
2474static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb, 2848static int
2475 struct wmi_svc_rdy_ev_arg *arg) 2849ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
2850 struct wmi_svc_rdy_ev_arg *arg)
2476{ 2851{
2477 struct wmi_10x_service_ready_event *ev; 2852 struct wmi_10x_service_ready_event *ev;
2478 int i, n; 2853 int i, n;
@@ -2506,30 +2881,22 @@ static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb,
2506 return 0; 2881 return 0;
2507} 2882}
2508 2883
2509static void ath10k_wmi_event_service_ready(struct ath10k *ar, 2884void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb)
2510 struct sk_buff *skb)
2511{ 2885{
2512 struct wmi_svc_rdy_ev_arg arg = {}; 2886 struct wmi_svc_rdy_ev_arg arg = {};
2513 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; 2887 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
2514 int ret; 2888 int ret;
2515 2889
2516 memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map)); 2890 ret = ath10k_wmi_pull_svc_rdy(ar, skb, &arg);
2517
2518 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
2519 ret = ath10k_wmi_10x_pull_svc_rdy_ev(skb, &arg);
2520 wmi_10x_svc_map(arg.service_map, ar->wmi.svc_map,
2521 arg.service_map_len);
2522 } else {
2523 ret = ath10k_wmi_main_pull_svc_rdy_ev(skb, &arg);
2524 wmi_main_svc_map(arg.service_map, ar->wmi.svc_map,
2525 arg.service_map_len);
2526 }
2527
2528 if (ret) { 2891 if (ret) {
2529 ath10k_warn(ar, "failed to parse service ready: %d\n", ret); 2892 ath10k_warn(ar, "failed to parse service ready: %d\n", ret);
2530 return; 2893 return;
2531 } 2894 }
2532 2895
2896 memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
2897 ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map,
2898 arg.service_map_len);
2899
2533 ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power); 2900 ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power);
2534 ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power); 2901 ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power);
2535 ar->ht_cap_info = __le32_to_cpu(arg.ht_cap); 2902 ar->ht_cap_info = __le32_to_cpu(arg.ht_cap);
@@ -2607,13 +2974,14 @@ static void ath10k_wmi_event_service_ready(struct ath10k *ar,
2607 } 2974 }
2608 2975
2609 ath10k_dbg(ar, ATH10K_DBG_WMI, 2976 ath10k_dbg(ar, ATH10K_DBG_WMI,
2610 "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n", 2977 "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x fw_build 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n",
2611 __le32_to_cpu(arg.min_tx_power), 2978 __le32_to_cpu(arg.min_tx_power),
2612 __le32_to_cpu(arg.max_tx_power), 2979 __le32_to_cpu(arg.max_tx_power),
2613 __le32_to_cpu(arg.ht_cap), 2980 __le32_to_cpu(arg.ht_cap),
2614 __le32_to_cpu(arg.vht_cap), 2981 __le32_to_cpu(arg.vht_cap),
2615 __le32_to_cpu(arg.sw_ver0), 2982 __le32_to_cpu(arg.sw_ver0),
2616 __le32_to_cpu(arg.sw_ver1), 2983 __le32_to_cpu(arg.sw_ver1),
2984 __le32_to_cpu(arg.fw_build),
2617 __le32_to_cpu(arg.phy_capab), 2985 __le32_to_cpu(arg.phy_capab),
2618 __le32_to_cpu(arg.num_rf_chains), 2986 __le32_to_cpu(arg.num_rf_chains),
2619 __le32_to_cpu(arg.eeprom_rd), 2987 __le32_to_cpu(arg.eeprom_rd),
@@ -2622,27 +2990,59 @@ static void ath10k_wmi_event_service_ready(struct ath10k *ar,
2622 complete(&ar->wmi.service_ready); 2990 complete(&ar->wmi.service_ready);
2623} 2991}
2624 2992
2625static int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) 2993static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
2994 struct wmi_rdy_ev_arg *arg)
2626{ 2995{
2627 struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; 2996 struct wmi_ready_event *ev = (void *)skb->data;
2628 2997
2629 if (WARN_ON(skb->len < sizeof(*ev))) 2998 if (skb->len < sizeof(*ev))
2630 return -EINVAL; 2999 return -EPROTO;
3000
3001 skb_pull(skb, sizeof(*ev));
3002 arg->sw_version = ev->sw_version;
3003 arg->abi_version = ev->abi_version;
3004 arg->status = ev->status;
3005 arg->mac_addr = ev->mac_addr.addr;
2631 3006
2632 ether_addr_copy(ar->mac_addr, ev->mac_addr.addr); 3007 return 0;
3008}
3009
3010int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
3011{
3012 struct wmi_rdy_ev_arg arg = {};
3013 int ret;
3014
3015 ret = ath10k_wmi_pull_rdy(ar, skb, &arg);
3016 if (ret) {
3017 ath10k_warn(ar, "failed to parse ready event: %d\n", ret);
3018 return ret;
3019 }
2633 3020
2634 ath10k_dbg(ar, ATH10K_DBG_WMI, 3021 ath10k_dbg(ar, ATH10K_DBG_WMI,
2635 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", 3022 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n",
2636 __le32_to_cpu(ev->sw_version), 3023 __le32_to_cpu(arg.sw_version),
2637 __le32_to_cpu(ev->abi_version), 3024 __le32_to_cpu(arg.abi_version),
2638 ev->mac_addr.addr, 3025 arg.mac_addr,
2639 __le32_to_cpu(ev->status), skb->len, sizeof(*ev)); 3026 __le32_to_cpu(arg.status));
2640 3027
3028 ether_addr_copy(ar->mac_addr, arg.mac_addr);
2641 complete(&ar->wmi.unified_ready); 3029 complete(&ar->wmi.unified_ready);
2642 return 0; 3030 return 0;
2643} 3031}
2644 3032
2645static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) 3033static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
3034{
3035 const struct wmi_pdev_temperature_event *ev;
3036
3037 ev = (struct wmi_pdev_temperature_event *)skb->data;
3038 if (WARN_ON(skb->len < sizeof(*ev)))
3039 return -EPROTO;
3040
3041 ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
3042 return 0;
3043}
3044
3045static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
2646{ 3046{
2647 struct wmi_cmd_hdr *cmd_hdr; 3047 struct wmi_cmd_hdr *cmd_hdr;
2648 enum wmi_event_id id; 3048 enum wmi_event_id id;
@@ -2758,7 +3158,7 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
2758 dev_kfree_skb(skb); 3158 dev_kfree_skb(skb);
2759} 3159}
2760 3160
2761static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) 3161static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
2762{ 3162{
2763 struct wmi_cmd_hdr *cmd_hdr; 3163 struct wmi_cmd_hdr *cmd_hdr;
2764 enum wmi_10x_event_id id; 3164 enum wmi_10x_event_id id;
@@ -2882,7 +3282,7 @@ out:
2882 dev_kfree_skb(skb); 3282 dev_kfree_skb(skb);
2883} 3283}
2884 3284
2885static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) 3285static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
2886{ 3286{
2887 struct wmi_cmd_hdr *cmd_hdr; 3287 struct wmi_cmd_hdr *cmd_hdr;
2888 enum wmi_10_2_event_id id; 3288 enum wmi_10_2_event_id id;
@@ -2981,6 +3381,9 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
2981 case WMI_10_2_READY_EVENTID: 3381 case WMI_10_2_READY_EVENTID:
2982 ath10k_wmi_event_ready(ar, skb); 3382 ath10k_wmi_event_ready(ar, skb);
2983 break; 3383 break;
3384 case WMI_10_2_PDEV_TEMPERATURE_EVENTID:
3385 ath10k_wmi_event_temperature(ar, skb);
3386 break;
2984 case WMI_10_2_RTT_KEEPALIVE_EVENTID: 3387 case WMI_10_2_RTT_KEEPALIVE_EVENTID:
2985 case WMI_10_2_GPIO_INPUT_EVENTID: 3388 case WMI_10_2_GPIO_INPUT_EVENTID:
2986 case WMI_10_2_PEER_RATECODE_LIST_EVENTID: 3389 case WMI_10_2_PEER_RATECODE_LIST_EVENTID:
@@ -3001,14 +3404,11 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
3001 3404
3002static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) 3405static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb)
3003{ 3406{
3004 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 3407 int ret;
3005 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 3408
3006 ath10k_wmi_10_2_process_rx(ar, skb); 3409 ret = ath10k_wmi_rx(ar, skb);
3007 else 3410 if (ret)
3008 ath10k_wmi_10x_process_rx(ar, skb); 3411 ath10k_warn(ar, "failed to process wmi rx: %d\n", ret);
3009 } else {
3010 ath10k_wmi_main_process_rx(ar, skb);
3011 }
3012} 3412}
3013 3413
3014int ath10k_wmi_connect(struct ath10k *ar) 3414int ath10k_wmi_connect(struct ath10k *ar)
@@ -3039,16 +3439,17 @@ int ath10k_wmi_connect(struct ath10k *ar)
3039 return 0; 3439 return 0;
3040} 3440}
3041 3441
3042static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd, 3442static struct sk_buff *
3043 u16 rd2g, u16 rd5g, u16 ctl2g, 3443ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
3044 u16 ctl5g) 3444 u16 ctl2g, u16 ctl5g,
3445 enum wmi_dfs_region dfs_reg)
3045{ 3446{
3046 struct wmi_pdev_set_regdomain_cmd *cmd; 3447 struct wmi_pdev_set_regdomain_cmd *cmd;
3047 struct sk_buff *skb; 3448 struct sk_buff *skb;
3048 3449
3049 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3450 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3050 if (!skb) 3451 if (!skb)
3051 return -ENOMEM; 3452 return ERR_PTR(-ENOMEM);
3052 3453
3053 cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data; 3454 cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data;
3054 cmd->reg_domain = __cpu_to_le32(rd); 3455 cmd->reg_domain = __cpu_to_le32(rd);
@@ -3060,22 +3461,20 @@ static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd,
3060 ath10k_dbg(ar, ATH10K_DBG_WMI, 3461 ath10k_dbg(ar, ATH10K_DBG_WMI,
3061 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", 3462 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n",
3062 rd, rd2g, rd5g, ctl2g, ctl5g); 3463 rd, rd2g, rd5g, ctl2g, ctl5g);
3063 3464 return skb;
3064 return ath10k_wmi_cmd_send(ar, skb,
3065 ar->wmi.cmd->pdev_set_regdomain_cmdid);
3066} 3465}
3067 3466
3068static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd, 3467static struct sk_buff *
3069 u16 rd2g, u16 rd5g, 3468ath10k_wmi_10x_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16
3070 u16 ctl2g, u16 ctl5g, 3469 rd5g, u16 ctl2g, u16 ctl5g,
3071 enum wmi_dfs_region dfs_reg) 3470 enum wmi_dfs_region dfs_reg)
3072{ 3471{
3073 struct wmi_pdev_set_regdomain_cmd_10x *cmd; 3472 struct wmi_pdev_set_regdomain_cmd_10x *cmd;
3074 struct sk_buff *skb; 3473 struct sk_buff *skb;
3075 3474
3076 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3475 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3077 if (!skb) 3476 if (!skb)
3078 return -ENOMEM; 3477 return ERR_PTR(-ENOMEM);
3079 3478
3080 cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data; 3479 cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data;
3081 cmd->reg_domain = __cpu_to_le32(rd); 3480 cmd->reg_domain = __cpu_to_le32(rd);
@@ -3088,50 +3487,39 @@ static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd,
3088 ath10k_dbg(ar, ATH10K_DBG_WMI, 3487 ath10k_dbg(ar, ATH10K_DBG_WMI,
3089 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", 3488 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n",
3090 rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg); 3489 rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg);
3091 3490 return skb;
3092 return ath10k_wmi_cmd_send(ar, skb,
3093 ar->wmi.cmd->pdev_set_regdomain_cmdid);
3094}
3095
3096int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
3097 u16 rd5g, u16 ctl2g, u16 ctl5g,
3098 enum wmi_dfs_region dfs_reg)
3099{
3100 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
3101 return ath10k_wmi_10x_pdev_set_regdomain(ar, rd, rd2g, rd5g,
3102 ctl2g, ctl5g, dfs_reg);
3103 else
3104 return ath10k_wmi_main_pdev_set_regdomain(ar, rd, rd2g, rd5g,
3105 ctl2g, ctl5g);
3106} 3491}
3107 3492
3108int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) 3493static struct sk_buff *
3494ath10k_wmi_op_gen_pdev_suspend(struct ath10k *ar, u32 suspend_opt)
3109{ 3495{
3110 struct wmi_pdev_suspend_cmd *cmd; 3496 struct wmi_pdev_suspend_cmd *cmd;
3111 struct sk_buff *skb; 3497 struct sk_buff *skb;
3112 3498
3113 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3499 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3114 if (!skb) 3500 if (!skb)
3115 return -ENOMEM; 3501 return ERR_PTR(-ENOMEM);
3116 3502
3117 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 3503 cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
3118 cmd->suspend_opt = __cpu_to_le32(suspend_opt); 3504 cmd->suspend_opt = __cpu_to_le32(suspend_opt);
3119 3505
3120 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); 3506 return skb;
3121} 3507}
3122 3508
3123int ath10k_wmi_pdev_resume_target(struct ath10k *ar) 3509static struct sk_buff *
3510ath10k_wmi_op_gen_pdev_resume(struct ath10k *ar)
3124{ 3511{
3125 struct sk_buff *skb; 3512 struct sk_buff *skb;
3126 3513
3127 skb = ath10k_wmi_alloc_skb(ar, 0); 3514 skb = ath10k_wmi_alloc_skb(ar, 0);
3128 if (skb == NULL) 3515 if (!skb)
3129 return -ENOMEM; 3516 return ERR_PTR(-ENOMEM);
3130 3517
3131 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); 3518 return skb;
3132} 3519}
3133 3520
3134int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) 3521static struct sk_buff *
3522ath10k_wmi_op_gen_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3135{ 3523{
3136 struct wmi_pdev_set_param_cmd *cmd; 3524 struct wmi_pdev_set_param_cmd *cmd;
3137 struct sk_buff *skb; 3525 struct sk_buff *skb;
@@ -3139,12 +3527,12 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3139 if (id == WMI_PDEV_PARAM_UNSUPPORTED) { 3527 if (id == WMI_PDEV_PARAM_UNSUPPORTED) {
3140 ath10k_warn(ar, "pdev param %d not supported by firmware\n", 3528 ath10k_warn(ar, "pdev param %d not supported by firmware\n",
3141 id); 3529 id);
3142 return -EOPNOTSUPP; 3530 return ERR_PTR(-EOPNOTSUPP);
3143 } 3531 }
3144 3532
3145 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3533 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3146 if (!skb) 3534 if (!skb)
3147 return -ENOMEM; 3535 return ERR_PTR(-ENOMEM);
3148 3536
3149 cmd = (struct wmi_pdev_set_param_cmd *)skb->data; 3537 cmd = (struct wmi_pdev_set_param_cmd *)skb->data;
3150 cmd->param_id = __cpu_to_le32(id); 3538 cmd->param_id = __cpu_to_le32(id);
@@ -3152,11 +3540,11 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3152 3540
3153 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", 3541 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n",
3154 id, value); 3542 id, value);
3155 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); 3543 return skb;
3156} 3544}
3157 3545
3158static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, 3546void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
3159 struct wmi_host_mem_chunks *chunks) 3547 struct wmi_host_mem_chunks *chunks)
3160{ 3548{
3161 struct host_memory_chunk *chunk; 3549 struct host_memory_chunk *chunk;
3162 int i; 3550 int i;
@@ -3177,7 +3565,7 @@ static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
3177 } 3565 }
3178} 3566}
3179 3567
3180static int ath10k_wmi_main_cmd_init(struct ath10k *ar) 3568static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar)
3181{ 3569{
3182 struct wmi_init_cmd *cmd; 3570 struct wmi_init_cmd *cmd;
3183 struct sk_buff *buf; 3571 struct sk_buff *buf;
@@ -3240,7 +3628,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
3240 3628
3241 buf = ath10k_wmi_alloc_skb(ar, len); 3629 buf = ath10k_wmi_alloc_skb(ar, len);
3242 if (!buf) 3630 if (!buf)
3243 return -ENOMEM; 3631 return ERR_PTR(-ENOMEM);
3244 3632
3245 cmd = (struct wmi_init_cmd *)buf->data; 3633 cmd = (struct wmi_init_cmd *)buf->data;
3246 3634
@@ -3248,10 +3636,10 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
3248 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3636 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3249 3637
3250 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); 3638 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n");
3251 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3639 return buf;
3252} 3640}
3253 3641
3254static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) 3642static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
3255{ 3643{
3256 struct wmi_init_cmd_10x *cmd; 3644 struct wmi_init_cmd_10x *cmd;
3257 struct sk_buff *buf; 3645 struct sk_buff *buf;
@@ -3306,7 +3694,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
3306 3694
3307 buf = ath10k_wmi_alloc_skb(ar, len); 3695 buf = ath10k_wmi_alloc_skb(ar, len);
3308 if (!buf) 3696 if (!buf)
3309 return -ENOMEM; 3697 return ERR_PTR(-ENOMEM);
3310 3698
3311 cmd = (struct wmi_init_cmd_10x *)buf->data; 3699 cmd = (struct wmi_init_cmd_10x *)buf->data;
3312 3700
@@ -3314,10 +3702,10 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
3314 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3702 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3315 3703
3316 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); 3704 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n");
3317 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3705 return buf;
3318} 3706}
3319 3707
3320static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) 3708static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
3321{ 3709{
3322 struct wmi_init_cmd_10_2 *cmd; 3710 struct wmi_init_cmd_10_2 *cmd;
3323 struct sk_buff *buf; 3711 struct sk_buff *buf;
@@ -3372,7 +3760,7 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
3372 3760
3373 buf = ath10k_wmi_alloc_skb(ar, len); 3761 buf = ath10k_wmi_alloc_skb(ar, len);
3374 if (!buf) 3762 if (!buf)
3375 return -ENOMEM; 3763 return ERR_PTR(-ENOMEM);
3376 3764
3377 cmd = (struct wmi_init_cmd_10_2 *)buf->data; 3765 cmd = (struct wmi_init_cmd_10_2 *)buf->data;
3378 3766
@@ -3380,26 +3768,10 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
3380 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3768 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3381 3769
3382 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); 3770 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n");
3383 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3771 return buf;
3384} 3772}
3385 3773
3386int ath10k_wmi_cmd_init(struct ath10k *ar) 3774int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg)
3387{
3388 int ret;
3389
3390 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
3391 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features))
3392 ret = ath10k_wmi_10_2_cmd_init(ar);
3393 else
3394 ret = ath10k_wmi_10x_cmd_init(ar);
3395 } else {
3396 ret = ath10k_wmi_main_cmd_init(ar);
3397 }
3398
3399 return ret;
3400}
3401
3402static int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg)
3403{ 3775{
3404 if (arg->ie_len && !arg->ie) 3776 if (arg->ie_len && !arg->ie)
3405 return -EINVAL; 3777 return -EINVAL;
@@ -3450,9 +3822,8 @@ ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg)
3450 return len; 3822 return len;
3451} 3823}
3452 3824
3453static void 3825void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
3454ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, 3826 const struct wmi_start_scan_arg *arg)
3455 const struct wmi_start_scan_arg *arg)
3456{ 3827{
3457 u32 scan_id; 3828 u32 scan_id;
3458 u32 scan_req_id; 3829 u32 scan_req_id;
@@ -3546,46 +3917,60 @@ ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs,
3546 } 3917 }
3547} 3918}
3548 3919
3549int ath10k_wmi_start_scan(struct ath10k *ar, 3920static struct sk_buff *
3550 const struct wmi_start_scan_arg *arg) 3921ath10k_wmi_op_gen_start_scan(struct ath10k *ar,
3922 const struct wmi_start_scan_arg *arg)
3551{ 3923{
3924 struct wmi_start_scan_cmd *cmd;
3552 struct sk_buff *skb; 3925 struct sk_buff *skb;
3553 size_t len; 3926 size_t len;
3554 int ret; 3927 int ret;
3555 3928
3556 ret = ath10k_wmi_start_scan_verify(arg); 3929 ret = ath10k_wmi_start_scan_verify(arg);
3557 if (ret) 3930 if (ret)
3558 return ret; 3931 return ERR_PTR(ret);
3559
3560 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
3561 len = sizeof(struct wmi_10x_start_scan_cmd) +
3562 ath10k_wmi_start_scan_tlvs_len(arg);
3563 else
3564 len = sizeof(struct wmi_start_scan_cmd) +
3565 ath10k_wmi_start_scan_tlvs_len(arg);
3566 3932
3933 len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
3567 skb = ath10k_wmi_alloc_skb(ar, len); 3934 skb = ath10k_wmi_alloc_skb(ar, len);
3568 if (!skb) 3935 if (!skb)
3569 return -ENOMEM; 3936 return ERR_PTR(-ENOMEM);
3570
3571 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
3572 struct wmi_10x_start_scan_cmd *cmd;
3573 3937
3574 cmd = (struct wmi_10x_start_scan_cmd *)skb->data; 3938 cmd = (struct wmi_start_scan_cmd *)skb->data;
3575 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
3576 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3577 } else {
3578 struct wmi_start_scan_cmd *cmd;
3579 3939
3580 cmd = (struct wmi_start_scan_cmd *)skb->data; 3940 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
3581 cmd->burst_duration_ms = __cpu_to_le32(0); 3941 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3582 3942
3583 ath10k_wmi_put_start_scan_common(&cmd->common, arg); 3943 cmd->burst_duration_ms = __cpu_to_le32(0);
3584 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3585 }
3586 3944
3587 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); 3945 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n");
3588 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); 3946 return skb;
3947}
3948
3949static struct sk_buff *
3950ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar,
3951 const struct wmi_start_scan_arg *arg)
3952{
3953 struct wmi_10x_start_scan_cmd *cmd;
3954 struct sk_buff *skb;
3955 size_t len;
3956 int ret;
3957
3958 ret = ath10k_wmi_start_scan_verify(arg);
3959 if (ret)
3960 return ERR_PTR(ret);
3961
3962 len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
3963 skb = ath10k_wmi_alloc_skb(ar, len);
3964 if (!skb)
3965 return ERR_PTR(-ENOMEM);
3966
3967 cmd = (struct wmi_10x_start_scan_cmd *)skb->data;
3968
3969 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
3970 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3971
3972 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n");
3973 return skb;
3589} 3974}
3590 3975
3591void ath10k_wmi_start_scan_init(struct ath10k *ar, 3976void ath10k_wmi_start_scan_init(struct ath10k *ar,
@@ -3614,7 +3999,9 @@ void ath10k_wmi_start_scan_init(struct ath10k *ar,
3614 arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF"; 3999 arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF";
3615} 4000}
3616 4001
3617int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) 4002static struct sk_buff *
4003ath10k_wmi_op_gen_stop_scan(struct ath10k *ar,
4004 const struct wmi_stop_scan_arg *arg)
3618{ 4005{
3619 struct wmi_stop_scan_cmd *cmd; 4006 struct wmi_stop_scan_cmd *cmd;
3620 struct sk_buff *skb; 4007 struct sk_buff *skb;
@@ -3622,13 +4009,13 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
3622 u32 req_id; 4009 u32 req_id;
3623 4010
3624 if (arg->req_id > 0xFFF) 4011 if (arg->req_id > 0xFFF)
3625 return -EINVAL; 4012 return ERR_PTR(-EINVAL);
3626 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) 4013 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
3627 return -EINVAL; 4014 return ERR_PTR(-EINVAL);
3628 4015
3629 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4016 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3630 if (!skb) 4017 if (!skb)
3631 return -ENOMEM; 4018 return ERR_PTR(-ENOMEM);
3632 4019
3633 scan_id = arg->u.scan_id; 4020 scan_id = arg->u.scan_id;
3634 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; 4021 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
@@ -3645,20 +4032,21 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
3645 ath10k_dbg(ar, ATH10K_DBG_WMI, 4032 ath10k_dbg(ar, ATH10K_DBG_WMI,
3646 "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", 4033 "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n",
3647 arg->req_id, arg->req_type, arg->u.scan_id); 4034 arg->req_id, arg->req_type, arg->u.scan_id);
3648 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); 4035 return skb;
3649} 4036}
3650 4037
3651int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, 4038static struct sk_buff *
3652 enum wmi_vdev_type type, 4039ath10k_wmi_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id,
3653 enum wmi_vdev_subtype subtype, 4040 enum wmi_vdev_type type,
3654 const u8 macaddr[ETH_ALEN]) 4041 enum wmi_vdev_subtype subtype,
4042 const u8 macaddr[ETH_ALEN])
3655{ 4043{
3656 struct wmi_vdev_create_cmd *cmd; 4044 struct wmi_vdev_create_cmd *cmd;
3657 struct sk_buff *skb; 4045 struct sk_buff *skb;
3658 4046
3659 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4047 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3660 if (!skb) 4048 if (!skb)
3661 return -ENOMEM; 4049 return ERR_PTR(-ENOMEM);
3662 4050
3663 cmd = (struct wmi_vdev_create_cmd *)skb->data; 4051 cmd = (struct wmi_vdev_create_cmd *)skb->data;
3664 cmd->vdev_id = __cpu_to_le32(vdev_id); 4052 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3669,58 +4057,52 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
3669 ath10k_dbg(ar, ATH10K_DBG_WMI, 4057 ath10k_dbg(ar, ATH10K_DBG_WMI,
3670 "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", 4058 "WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
3671 vdev_id, type, subtype, macaddr); 4059 vdev_id, type, subtype, macaddr);
3672 4060 return skb;
3673 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid);
3674} 4061}
3675 4062
3676int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) 4063static struct sk_buff *
4064ath10k_wmi_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
3677{ 4065{
3678 struct wmi_vdev_delete_cmd *cmd; 4066 struct wmi_vdev_delete_cmd *cmd;
3679 struct sk_buff *skb; 4067 struct sk_buff *skb;
3680 4068
3681 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4069 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3682 if (!skb) 4070 if (!skb)
3683 return -ENOMEM; 4071 return ERR_PTR(-ENOMEM);
3684 4072
3685 cmd = (struct wmi_vdev_delete_cmd *)skb->data; 4073 cmd = (struct wmi_vdev_delete_cmd *)skb->data;
3686 cmd->vdev_id = __cpu_to_le32(vdev_id); 4074 cmd->vdev_id = __cpu_to_le32(vdev_id);
3687 4075
3688 ath10k_dbg(ar, ATH10K_DBG_WMI, 4076 ath10k_dbg(ar, ATH10K_DBG_WMI,
3689 "WMI vdev delete id %d\n", vdev_id); 4077 "WMI vdev delete id %d\n", vdev_id);
3690 4078 return skb;
3691 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
3692} 4079}
3693 4080
3694static int 4081static struct sk_buff *
3695ath10k_wmi_vdev_start_restart(struct ath10k *ar, 4082ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
3696 const struct wmi_vdev_start_request_arg *arg, 4083 const struct wmi_vdev_start_request_arg *arg,
3697 u32 cmd_id) 4084 bool restart)
3698{ 4085{
3699 struct wmi_vdev_start_request_cmd *cmd; 4086 struct wmi_vdev_start_request_cmd *cmd;
3700 struct sk_buff *skb; 4087 struct sk_buff *skb;
3701 const char *cmdname; 4088 const char *cmdname;
3702 u32 flags = 0; 4089 u32 flags = 0;
3703 4090
3704 if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid &&
3705 cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid)
3706 return -EINVAL;
3707 if (WARN_ON(arg->ssid && arg->ssid_len == 0)) 4091 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
3708 return -EINVAL; 4092 return ERR_PTR(-EINVAL);
3709 if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 4093 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
3710 return -EINVAL; 4094 return ERR_PTR(-EINVAL);
3711 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 4095 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
3712 return -EINVAL; 4096 return ERR_PTR(-EINVAL);
3713 4097
3714 if (cmd_id == ar->wmi.cmd->vdev_start_request_cmdid) 4098 if (restart)
3715 cmdname = "start";
3716 else if (cmd_id == ar->wmi.cmd->vdev_restart_request_cmdid)
3717 cmdname = "restart"; 4099 cmdname = "restart";
3718 else 4100 else
3719 return -EINVAL; /* should not happen, we already check cmd_id */ 4101 cmdname = "start";
3720 4102
3721 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4103 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3722 if (!skb) 4104 if (!skb)
3723 return -ENOMEM; 4105 return ERR_PTR(-ENOMEM);
3724 4106
3725 if (arg->hidden_ssid) 4107 if (arg->hidden_ssid)
3726 flags |= WMI_VDEV_START_HIDDEN_SSID; 4108 flags |= WMI_VDEV_START_HIDDEN_SSID;
@@ -3749,50 +4131,36 @@ ath10k_wmi_vdev_start_restart(struct ath10k *ar,
3749 flags, arg->channel.freq, arg->channel.mode, 4131 flags, arg->channel.freq, arg->channel.mode,
3750 cmd->chan.flags, arg->channel.max_power); 4132 cmd->chan.flags, arg->channel.max_power);
3751 4133
3752 return ath10k_wmi_cmd_send(ar, skb, cmd_id); 4134 return skb;
3753}
3754
3755int ath10k_wmi_vdev_start(struct ath10k *ar,
3756 const struct wmi_vdev_start_request_arg *arg)
3757{
3758 u32 cmd_id = ar->wmi.cmd->vdev_start_request_cmdid;
3759
3760 return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id);
3761}
3762
3763int ath10k_wmi_vdev_restart(struct ath10k *ar,
3764 const struct wmi_vdev_start_request_arg *arg)
3765{
3766 u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid;
3767
3768 return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id);
3769} 4135}
3770 4136
3771int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) 4137static struct sk_buff *
4138ath10k_wmi_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
3772{ 4139{
3773 struct wmi_vdev_stop_cmd *cmd; 4140 struct wmi_vdev_stop_cmd *cmd;
3774 struct sk_buff *skb; 4141 struct sk_buff *skb;
3775 4142
3776 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4143 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3777 if (!skb) 4144 if (!skb)
3778 return -ENOMEM; 4145 return ERR_PTR(-ENOMEM);
3779 4146
3780 cmd = (struct wmi_vdev_stop_cmd *)skb->data; 4147 cmd = (struct wmi_vdev_stop_cmd *)skb->data;
3781 cmd->vdev_id = __cpu_to_le32(vdev_id); 4148 cmd->vdev_id = __cpu_to_le32(vdev_id);
3782 4149
3783 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); 4150 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id);
3784 4151 return skb;
3785 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid);
3786} 4152}
3787 4153
3788int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) 4154static struct sk_buff *
4155ath10k_wmi_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
4156 const u8 *bssid)
3789{ 4157{
3790 struct wmi_vdev_up_cmd *cmd; 4158 struct wmi_vdev_up_cmd *cmd;
3791 struct sk_buff *skb; 4159 struct sk_buff *skb;
3792 4160
3793 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4161 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3794 if (!skb) 4162 if (!skb)
3795 return -ENOMEM; 4163 return ERR_PTR(-ENOMEM);
3796 4164
3797 cmd = (struct wmi_vdev_up_cmd *)skb->data; 4165 cmd = (struct wmi_vdev_up_cmd *)skb->data;
3798 cmd->vdev_id = __cpu_to_le32(vdev_id); 4166 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3802,30 +4170,30 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
3802 ath10k_dbg(ar, ATH10K_DBG_WMI, 4170 ath10k_dbg(ar, ATH10K_DBG_WMI,
3803 "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", 4171 "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
3804 vdev_id, aid, bssid); 4172 vdev_id, aid, bssid);
3805 4173 return skb;
3806 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid);
3807} 4174}
3808 4175
3809int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) 4176static struct sk_buff *
4177ath10k_wmi_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
3810{ 4178{
3811 struct wmi_vdev_down_cmd *cmd; 4179 struct wmi_vdev_down_cmd *cmd;
3812 struct sk_buff *skb; 4180 struct sk_buff *skb;
3813 4181
3814 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4182 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3815 if (!skb) 4183 if (!skb)
3816 return -ENOMEM; 4184 return ERR_PTR(-ENOMEM);
3817 4185
3818 cmd = (struct wmi_vdev_down_cmd *)skb->data; 4186 cmd = (struct wmi_vdev_down_cmd *)skb->data;
3819 cmd->vdev_id = __cpu_to_le32(vdev_id); 4187 cmd->vdev_id = __cpu_to_le32(vdev_id);
3820 4188
3821 ath10k_dbg(ar, ATH10K_DBG_WMI, 4189 ath10k_dbg(ar, ATH10K_DBG_WMI,
3822 "wmi mgmt vdev down id 0x%x\n", vdev_id); 4190 "wmi mgmt vdev down id 0x%x\n", vdev_id);
3823 4191 return skb;
3824 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid);
3825} 4192}
3826 4193
3827int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, 4194static struct sk_buff *
3828 u32 param_id, u32 param_value) 4195ath10k_wmi_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
4196 u32 param_id, u32 param_value)
3829{ 4197{
3830 struct wmi_vdev_set_param_cmd *cmd; 4198 struct wmi_vdev_set_param_cmd *cmd;
3831 struct sk_buff *skb; 4199 struct sk_buff *skb;
@@ -3834,12 +4202,12 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
3834 ath10k_dbg(ar, ATH10K_DBG_WMI, 4202 ath10k_dbg(ar, ATH10K_DBG_WMI,
3835 "vdev param %d not supported by firmware\n", 4203 "vdev param %d not supported by firmware\n",
3836 param_id); 4204 param_id);
3837 return -EOPNOTSUPP; 4205 return ERR_PTR(-EOPNOTSUPP);
3838 } 4206 }
3839 4207
3840 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4208 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3841 if (!skb) 4209 if (!skb)
3842 return -ENOMEM; 4210 return ERR_PTR(-ENOMEM);
3843 4211
3844 cmd = (struct wmi_vdev_set_param_cmd *)skb->data; 4212 cmd = (struct wmi_vdev_set_param_cmd *)skb->data;
3845 cmd->vdev_id = __cpu_to_le32(vdev_id); 4213 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3849,24 +4217,24 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
3849 ath10k_dbg(ar, ATH10K_DBG_WMI, 4217 ath10k_dbg(ar, ATH10K_DBG_WMI,
3850 "wmi vdev id 0x%x set param %d value %d\n", 4218 "wmi vdev id 0x%x set param %d value %d\n",
3851 vdev_id, param_id, param_value); 4219 vdev_id, param_id, param_value);
3852 4220 return skb;
3853 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid);
3854} 4221}
3855 4222
3856int ath10k_wmi_vdev_install_key(struct ath10k *ar, 4223static struct sk_buff *
3857 const struct wmi_vdev_install_key_arg *arg) 4224ath10k_wmi_op_gen_vdev_install_key(struct ath10k *ar,
4225 const struct wmi_vdev_install_key_arg *arg)
3858{ 4226{
3859 struct wmi_vdev_install_key_cmd *cmd; 4227 struct wmi_vdev_install_key_cmd *cmd;
3860 struct sk_buff *skb; 4228 struct sk_buff *skb;
3861 4229
3862 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) 4230 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
3863 return -EINVAL; 4231 return ERR_PTR(-EINVAL);
3864 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) 4232 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
3865 return -EINVAL; 4233 return ERR_PTR(-EINVAL);
3866 4234
3867 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len); 4235 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len);
3868 if (!skb) 4236 if (!skb)
3869 return -ENOMEM; 4237 return ERR_PTR(-ENOMEM);
3870 4238
3871 cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 4239 cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
3872 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4240 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
@@ -3885,20 +4253,19 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar,
3885 ath10k_dbg(ar, ATH10K_DBG_WMI, 4253 ath10k_dbg(ar, ATH10K_DBG_WMI,
3886 "wmi vdev install key idx %d cipher %d len %d\n", 4254 "wmi vdev install key idx %d cipher %d len %d\n",
3887 arg->key_idx, arg->key_cipher, arg->key_len); 4255 arg->key_idx, arg->key_cipher, arg->key_len);
3888 return ath10k_wmi_cmd_send(ar, skb, 4256 return skb;
3889 ar->wmi.cmd->vdev_install_key_cmdid);
3890} 4257}
3891 4258
3892int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, 4259static struct sk_buff *
3893 const struct wmi_vdev_spectral_conf_arg *arg) 4260ath10k_wmi_op_gen_vdev_spectral_conf(struct ath10k *ar,
4261 const struct wmi_vdev_spectral_conf_arg *arg)
3894{ 4262{
3895 struct wmi_vdev_spectral_conf_cmd *cmd; 4263 struct wmi_vdev_spectral_conf_cmd *cmd;
3896 struct sk_buff *skb; 4264 struct sk_buff *skb;
3897 u32 cmdid;
3898 4265
3899 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4266 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3900 if (!skb) 4267 if (!skb)
3901 return -ENOMEM; 4268 return ERR_PTR(-ENOMEM);
3902 4269
3903 cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; 4270 cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data;
3904 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4271 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
@@ -3921,39 +4288,38 @@ int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
3921 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); 4288 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
3922 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); 4289 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
3923 4290
3924 cmdid = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid; 4291 return skb;
3925 return ath10k_wmi_cmd_send(ar, skb, cmdid);
3926} 4292}
3927 4293
3928int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, 4294static struct sk_buff *
3929 u32 enable) 4295ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
4296 u32 trigger, u32 enable)
3930{ 4297{
3931 struct wmi_vdev_spectral_enable_cmd *cmd; 4298 struct wmi_vdev_spectral_enable_cmd *cmd;
3932 struct sk_buff *skb; 4299 struct sk_buff *skb;
3933 u32 cmdid;
3934 4300
3935 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4301 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3936 if (!skb) 4302 if (!skb)
3937 return -ENOMEM; 4303 return ERR_PTR(-ENOMEM);
3938 4304
3939 cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; 4305 cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data;
3940 cmd->vdev_id = __cpu_to_le32(vdev_id); 4306 cmd->vdev_id = __cpu_to_le32(vdev_id);
3941 cmd->trigger_cmd = __cpu_to_le32(trigger); 4307 cmd->trigger_cmd = __cpu_to_le32(trigger);
3942 cmd->enable_cmd = __cpu_to_le32(enable); 4308 cmd->enable_cmd = __cpu_to_le32(enable);
3943 4309
3944 cmdid = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid; 4310 return skb;
3945 return ath10k_wmi_cmd_send(ar, skb, cmdid);
3946} 4311}
3947 4312
3948int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, 4313static struct sk_buff *
3949 const u8 peer_addr[ETH_ALEN]) 4314ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
4315 const u8 peer_addr[ETH_ALEN])
3950{ 4316{
3951 struct wmi_peer_create_cmd *cmd; 4317 struct wmi_peer_create_cmd *cmd;
3952 struct sk_buff *skb; 4318 struct sk_buff *skb;
3953 4319
3954 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4320 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3955 if (!skb) 4321 if (!skb)
3956 return -ENOMEM; 4322 return ERR_PTR(-ENOMEM);
3957 4323
3958 cmd = (struct wmi_peer_create_cmd *)skb->data; 4324 cmd = (struct wmi_peer_create_cmd *)skb->data;
3959 cmd->vdev_id = __cpu_to_le32(vdev_id); 4325 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3962,18 +4328,19 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
3962 ath10k_dbg(ar, ATH10K_DBG_WMI, 4328 ath10k_dbg(ar, ATH10K_DBG_WMI,
3963 "wmi peer create vdev_id %d peer_addr %pM\n", 4329 "wmi peer create vdev_id %d peer_addr %pM\n",
3964 vdev_id, peer_addr); 4330 vdev_id, peer_addr);
3965 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); 4331 return skb;
3966} 4332}
3967 4333
3968int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, 4334static struct sk_buff *
3969 const u8 peer_addr[ETH_ALEN]) 4335ath10k_wmi_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
4336 const u8 peer_addr[ETH_ALEN])
3970{ 4337{
3971 struct wmi_peer_delete_cmd *cmd; 4338 struct wmi_peer_delete_cmd *cmd;
3972 struct sk_buff *skb; 4339 struct sk_buff *skb;
3973 4340
3974 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4341 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3975 if (!skb) 4342 if (!skb)
3976 return -ENOMEM; 4343 return ERR_PTR(-ENOMEM);
3977 4344
3978 cmd = (struct wmi_peer_delete_cmd *)skb->data; 4345 cmd = (struct wmi_peer_delete_cmd *)skb->data;
3979 cmd->vdev_id = __cpu_to_le32(vdev_id); 4346 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3982,18 +4349,19 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
3982 ath10k_dbg(ar, ATH10K_DBG_WMI, 4349 ath10k_dbg(ar, ATH10K_DBG_WMI,
3983 "wmi peer delete vdev_id %d peer_addr %pM\n", 4350 "wmi peer delete vdev_id %d peer_addr %pM\n",
3984 vdev_id, peer_addr); 4351 vdev_id, peer_addr);
3985 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); 4352 return skb;
3986} 4353}
3987 4354
3988int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, 4355static struct sk_buff *
3989 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) 4356ath10k_wmi_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
4357 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
3990{ 4358{
3991 struct wmi_peer_flush_tids_cmd *cmd; 4359 struct wmi_peer_flush_tids_cmd *cmd;
3992 struct sk_buff *skb; 4360 struct sk_buff *skb;
3993 4361
3994 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4362 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3995 if (!skb) 4363 if (!skb)
3996 return -ENOMEM; 4364 return ERR_PTR(-ENOMEM);
3997 4365
3998 cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; 4366 cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
3999 cmd->vdev_id = __cpu_to_le32(vdev_id); 4367 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4003,19 +4371,21 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
4003 ath10k_dbg(ar, ATH10K_DBG_WMI, 4371 ath10k_dbg(ar, ATH10K_DBG_WMI,
4004 "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", 4372 "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
4005 vdev_id, peer_addr, tid_bitmap); 4373 vdev_id, peer_addr, tid_bitmap);
4006 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); 4374 return skb;
4007} 4375}
4008 4376
4009int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, 4377static struct sk_buff *
4010 const u8 *peer_addr, enum wmi_peer_param param_id, 4378ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
4011 u32 param_value) 4379 const u8 *peer_addr,
4380 enum wmi_peer_param param_id,
4381 u32 param_value)
4012{ 4382{
4013 struct wmi_peer_set_param_cmd *cmd; 4383 struct wmi_peer_set_param_cmd *cmd;
4014 struct sk_buff *skb; 4384 struct sk_buff *skb;
4015 4385
4016 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4386 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4017 if (!skb) 4387 if (!skb)
4018 return -ENOMEM; 4388 return ERR_PTR(-ENOMEM);
4019 4389
4020 cmd = (struct wmi_peer_set_param_cmd *)skb->data; 4390 cmd = (struct wmi_peer_set_param_cmd *)skb->data;
4021 cmd->vdev_id = __cpu_to_le32(vdev_id); 4391 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4026,19 +4396,19 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
4026 ath10k_dbg(ar, ATH10K_DBG_WMI, 4396 ath10k_dbg(ar, ATH10K_DBG_WMI,
4027 "wmi vdev %d peer 0x%pM set param %d value %d\n", 4397 "wmi vdev %d peer 0x%pM set param %d value %d\n",
4028 vdev_id, peer_addr, param_id, param_value); 4398 vdev_id, peer_addr, param_id, param_value);
4029 4399 return skb;
4030 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid);
4031} 4400}
4032 4401
4033int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, 4402static struct sk_buff *
4034 enum wmi_sta_ps_mode psmode) 4403ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
4404 enum wmi_sta_ps_mode psmode)
4035{ 4405{
4036 struct wmi_sta_powersave_mode_cmd *cmd; 4406 struct wmi_sta_powersave_mode_cmd *cmd;
4037 struct sk_buff *skb; 4407 struct sk_buff *skb;
4038 4408
4039 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4409 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4040 if (!skb) 4410 if (!skb)
4041 return -ENOMEM; 4411 return ERR_PTR(-ENOMEM);
4042 4412
4043 cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data; 4413 cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data;
4044 cmd->vdev_id = __cpu_to_le32(vdev_id); 4414 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4047,21 +4417,20 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
4047 ath10k_dbg(ar, ATH10K_DBG_WMI, 4417 ath10k_dbg(ar, ATH10K_DBG_WMI,
4048 "wmi set powersave id 0x%x mode %d\n", 4418 "wmi set powersave id 0x%x mode %d\n",
4049 vdev_id, psmode); 4419 vdev_id, psmode);
4050 4420 return skb;
4051 return ath10k_wmi_cmd_send(ar, skb,
4052 ar->wmi.cmd->sta_powersave_mode_cmdid);
4053} 4421}
4054 4422
4055int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, 4423static struct sk_buff *
4056 enum wmi_sta_powersave_param param_id, 4424ath10k_wmi_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
4057 u32 value) 4425 enum wmi_sta_powersave_param param_id,
4426 u32 value)
4058{ 4427{
4059 struct wmi_sta_powersave_param_cmd *cmd; 4428 struct wmi_sta_powersave_param_cmd *cmd;
4060 struct sk_buff *skb; 4429 struct sk_buff *skb;
4061 4430
4062 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4431 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4063 if (!skb) 4432 if (!skb)
4064 return -ENOMEM; 4433 return ERR_PTR(-ENOMEM);
4065 4434
4066 cmd = (struct wmi_sta_powersave_param_cmd *)skb->data; 4435 cmd = (struct wmi_sta_powersave_param_cmd *)skb->data;
4067 cmd->vdev_id = __cpu_to_le32(vdev_id); 4436 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4071,22 +4440,22 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
4071 ath10k_dbg(ar, ATH10K_DBG_WMI, 4440 ath10k_dbg(ar, ATH10K_DBG_WMI,
4072 "wmi sta ps param vdev_id 0x%x param %d value %d\n", 4441 "wmi sta ps param vdev_id 0x%x param %d value %d\n",
4073 vdev_id, param_id, value); 4442 vdev_id, param_id, value);
4074 return ath10k_wmi_cmd_send(ar, skb, 4443 return skb;
4075 ar->wmi.cmd->sta_powersave_param_cmdid);
4076} 4444}
4077 4445
4078int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, 4446static struct sk_buff *
4079 enum wmi_ap_ps_peer_param param_id, u32 value) 4447ath10k_wmi_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
4448 enum wmi_ap_ps_peer_param param_id, u32 value)
4080{ 4449{
4081 struct wmi_ap_ps_peer_cmd *cmd; 4450 struct wmi_ap_ps_peer_cmd *cmd;
4082 struct sk_buff *skb; 4451 struct sk_buff *skb;
4083 4452
4084 if (!mac) 4453 if (!mac)
4085 return -EINVAL; 4454 return ERR_PTR(-EINVAL);
4086 4455
4087 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4456 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4088 if (!skb) 4457 if (!skb)
4089 return -ENOMEM; 4458 return ERR_PTR(-ENOMEM);
4090 4459
4091 cmd = (struct wmi_ap_ps_peer_cmd *)skb->data; 4460 cmd = (struct wmi_ap_ps_peer_cmd *)skb->data;
4092 cmd->vdev_id = __cpu_to_le32(vdev_id); 4461 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4097,13 +4466,12 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
4097 ath10k_dbg(ar, ATH10K_DBG_WMI, 4466 ath10k_dbg(ar, ATH10K_DBG_WMI,
4098 "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", 4467 "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
4099 vdev_id, param_id, value, mac); 4468 vdev_id, param_id, value, mac);
4100 4469 return skb;
4101 return ath10k_wmi_cmd_send(ar, skb,
4102 ar->wmi.cmd->ap_ps_peer_param_cmdid);
4103} 4470}
4104 4471
4105int ath10k_wmi_scan_chan_list(struct ath10k *ar, 4472static struct sk_buff *
4106 const struct wmi_scan_chan_list_arg *arg) 4473ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
4474 const struct wmi_scan_chan_list_arg *arg)
4107{ 4475{
4108 struct wmi_scan_chan_list_cmd *cmd; 4476 struct wmi_scan_chan_list_cmd *cmd;
4109 struct sk_buff *skb; 4477 struct sk_buff *skb;
@@ -4116,7 +4484,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
4116 4484
4117 skb = ath10k_wmi_alloc_skb(ar, len); 4485 skb = ath10k_wmi_alloc_skb(ar, len);
4118 if (!skb) 4486 if (!skb)
4119 return -EINVAL; 4487 return ERR_PTR(-EINVAL);
4120 4488
4121 cmd = (struct wmi_scan_chan_list_cmd *)skb->data; 4489 cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
4122 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); 4490 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
@@ -4128,7 +4496,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
4128 ath10k_wmi_put_wmi_channel(ci, ch); 4496 ath10k_wmi_put_wmi_channel(ci, ch);
4129 } 4497 }
4130 4498
4131 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); 4499 return skb;
4132} 4500}
4133 4501
4134static void 4502static void
@@ -4209,12 +4577,9 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf,
4209 cmd->info0 = __cpu_to_le32(info0); 4577 cmd->info0 = __cpu_to_le32(info0);
4210} 4578}
4211 4579
4212int ath10k_wmi_peer_assoc(struct ath10k *ar, 4580static int
4213 const struct wmi_peer_assoc_complete_arg *arg) 4581ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
4214{ 4582{
4215 struct sk_buff *skb;
4216 int len;
4217
4218 if (arg->peer_mpdu_density > 16) 4583 if (arg->peer_mpdu_density > 16)
4219 return -EINVAL; 4584 return -EINVAL;
4220 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) 4585 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
@@ -4222,49 +4587,111 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
4222 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) 4587 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
4223 return -EINVAL; 4588 return -EINVAL;
4224 4589
4225 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 4590 return 0;
4226 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 4591}
4227 len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); 4592
4228 else 4593static struct sk_buff *
4229 len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); 4594ath10k_wmi_op_gen_peer_assoc(struct ath10k *ar,
4230 } else { 4595 const struct wmi_peer_assoc_complete_arg *arg)
4231 len = sizeof(struct wmi_main_peer_assoc_complete_cmd); 4596{
4232 } 4597 size_t len = sizeof(struct wmi_main_peer_assoc_complete_cmd);
4598 struct sk_buff *skb;
4599 int ret;
4600
4601 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4602 if (ret)
4603 return ERR_PTR(ret);
4233 4604
4234 skb = ath10k_wmi_alloc_skb(ar, len); 4605 skb = ath10k_wmi_alloc_skb(ar, len);
4235 if (!skb) 4606 if (!skb)
4236 return -ENOMEM; 4607 return ERR_PTR(-ENOMEM);
4237 4608
4238 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 4609 ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg);
4239 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 4610
4240 ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); 4611 ath10k_dbg(ar, ATH10K_DBG_WMI,
4241 else 4612 "wmi peer assoc vdev %d addr %pM (%s)\n",
4242 ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); 4613 arg->vdev_id, arg->addr,
4243 } else { 4614 arg->peer_reassoc ? "reassociate" : "new");
4244 ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); 4615 return skb;
4245 } 4616}
4617
4618static struct sk_buff *
4619ath10k_wmi_10_1_op_gen_peer_assoc(struct ath10k *ar,
4620 const struct wmi_peer_assoc_complete_arg *arg)
4621{
4622 size_t len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd);
4623 struct sk_buff *skb;
4624 int ret;
4625
4626 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4627 if (ret)
4628 return ERR_PTR(ret);
4629
4630 skb = ath10k_wmi_alloc_skb(ar, len);
4631 if (!skb)
4632 return ERR_PTR(-ENOMEM);
4633
4634 ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg);
4246 4635
4247 ath10k_dbg(ar, ATH10K_DBG_WMI, 4636 ath10k_dbg(ar, ATH10K_DBG_WMI,
4248 "wmi peer assoc vdev %d addr %pM (%s)\n", 4637 "wmi peer assoc vdev %d addr %pM (%s)\n",
4249 arg->vdev_id, arg->addr, 4638 arg->vdev_id, arg->addr,
4250 arg->peer_reassoc ? "reassociate" : "new"); 4639 arg->peer_reassoc ? "reassociate" : "new");
4251 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); 4640 return skb;
4641}
4642
4643static struct sk_buff *
4644ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
4645 const struct wmi_peer_assoc_complete_arg *arg)
4646{
4647 size_t len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd);
4648 struct sk_buff *skb;
4649 int ret;
4650
4651 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4652 if (ret)
4653 return ERR_PTR(ret);
4654
4655 skb = ath10k_wmi_alloc_skb(ar, len);
4656 if (!skb)
4657 return ERR_PTR(-ENOMEM);
4658
4659 ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg);
4660
4661 ath10k_dbg(ar, ATH10K_DBG_WMI,
4662 "wmi peer assoc vdev %d addr %pM (%s)\n",
4663 arg->vdev_id, arg->addr,
4664 arg->peer_reassoc ? "reassociate" : "new");
4665 return skb;
4666}
4667
4668static struct sk_buff *
4669ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
4670{
4671 struct sk_buff *skb;
4672
4673 skb = ath10k_wmi_alloc_skb(ar, 0);
4674 if (!skb)
4675 return ERR_PTR(-ENOMEM);
4676
4677 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature\n");
4678 return skb;
4252} 4679}
4253 4680
4254/* This function assumes the beacon is already DMA mapped */ 4681/* This function assumes the beacon is already DMA mapped */
4255int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) 4682static struct sk_buff *
4683ath10k_wmi_op_gen_beacon_dma(struct ath10k_vif *arvif)
4256{ 4684{
4685 struct ath10k *ar = arvif->ar;
4257 struct wmi_bcn_tx_ref_cmd *cmd; 4686 struct wmi_bcn_tx_ref_cmd *cmd;
4258 struct sk_buff *skb; 4687 struct sk_buff *skb;
4259 struct sk_buff *beacon = arvif->beacon; 4688 struct sk_buff *beacon = arvif->beacon;
4260 struct ath10k *ar = arvif->ar;
4261 struct ieee80211_hdr *hdr; 4689 struct ieee80211_hdr *hdr;
4262 int ret;
4263 u16 fc; 4690 u16 fc;
4264 4691
4265 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4692 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4266 if (!skb) 4693 if (!skb)
4267 return -ENOMEM; 4694 return ERR_PTR(-ENOMEM);
4268 4695
4269 hdr = (struct ieee80211_hdr *)beacon->data; 4696 hdr = (struct ieee80211_hdr *)beacon->data;
4270 fc = le16_to_cpu(hdr->frame_control); 4697 fc = le16_to_cpu(hdr->frame_control);
@@ -4284,17 +4711,11 @@ int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif)
4284 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab) 4711 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab)
4285 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); 4712 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
4286 4713
4287 ret = ath10k_wmi_cmd_send_nowait(ar, skb, 4714 return skb;
4288 ar->wmi.cmd->pdev_send_bcn_cmdid);
4289
4290 if (ret)
4291 dev_kfree_skb(skb);
4292
4293 return ret;
4294} 4715}
4295 4716
4296static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, 4717void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
4297 const struct wmi_wmm_params_arg *arg) 4718 const struct wmi_wmm_params_arg *arg)
4298{ 4719{
4299 params->cwmin = __cpu_to_le32(arg->cwmin); 4720 params->cwmin = __cpu_to_le32(arg->cwmin);
4300 params->cwmax = __cpu_to_le32(arg->cwmax); 4721 params->cwmax = __cpu_to_le32(arg->cwmax);
@@ -4304,15 +4725,16 @@ static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
4304 params->no_ack = __cpu_to_le32(arg->no_ack); 4725 params->no_ack = __cpu_to_le32(arg->no_ack);
4305} 4726}
4306 4727
4307int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 4728static struct sk_buff *
4308 const struct wmi_pdev_set_wmm_params_arg *arg) 4729ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
4730 const struct wmi_pdev_set_wmm_params_arg *arg)
4309{ 4731{
4310 struct wmi_pdev_set_wmm_params *cmd; 4732 struct wmi_pdev_set_wmm_params *cmd;
4311 struct sk_buff *skb; 4733 struct sk_buff *skb;
4312 4734
4313 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4735 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4314 if (!skb) 4736 if (!skb)
4315 return -ENOMEM; 4737 return ERR_PTR(-ENOMEM);
4316 4738
4317 cmd = (struct wmi_pdev_set_wmm_params *)skb->data; 4739 cmd = (struct wmi_pdev_set_wmm_params *)skb->data;
4318 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be); 4740 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be);
@@ -4321,35 +4743,36 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
4321 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); 4743 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo);
4322 4744
4323 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); 4745 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n");
4324 return ath10k_wmi_cmd_send(ar, skb, 4746 return skb;
4325 ar->wmi.cmd->pdev_set_wmm_params_cmdid);
4326} 4747}
4327 4748
4328int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 4749static struct sk_buff *
4750ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
4329{ 4751{
4330 struct wmi_request_stats_cmd *cmd; 4752 struct wmi_request_stats_cmd *cmd;
4331 struct sk_buff *skb; 4753 struct sk_buff *skb;
4332 4754
4333 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4755 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4334 if (!skb) 4756 if (!skb)
4335 return -ENOMEM; 4757 return ERR_PTR(-ENOMEM);
4336 4758
4337 cmd = (struct wmi_request_stats_cmd *)skb->data; 4759 cmd = (struct wmi_request_stats_cmd *)skb->data;
4338 cmd->stats_id = __cpu_to_le32(stats_id); 4760 cmd->stats_id = __cpu_to_le32(stats_id);
4339 4761
4340 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4762 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id);
4341 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); 4763 return skb;
4342} 4764}
4343 4765
4344int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4766static struct sk_buff *
4345 enum wmi_force_fw_hang_type type, u32 delay_ms) 4767ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar,
4768 enum wmi_force_fw_hang_type type, u32 delay_ms)
4346{ 4769{
4347 struct wmi_force_fw_hang_cmd *cmd; 4770 struct wmi_force_fw_hang_cmd *cmd;
4348 struct sk_buff *skb; 4771 struct sk_buff *skb;
4349 4772
4350 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4773 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4351 if (!skb) 4774 if (!skb)
4352 return -ENOMEM; 4775 return ERR_PTR(-ENOMEM);
4353 4776
4354 cmd = (struct wmi_force_fw_hang_cmd *)skb->data; 4777 cmd = (struct wmi_force_fw_hang_cmd *)skb->data;
4355 cmd->type = __cpu_to_le32(type); 4778 cmd->type = __cpu_to_le32(type);
@@ -4357,10 +4780,11 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar,
4357 4780
4358 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", 4781 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n",
4359 type, delay_ms); 4782 type, delay_ms);
4360 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); 4783 return skb;
4361} 4784}
4362 4785
4363int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) 4786static struct sk_buff *
4787ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable)
4364{ 4788{
4365 struct wmi_dbglog_cfg_cmd *cmd; 4789 struct wmi_dbglog_cfg_cmd *cmd;
4366 struct sk_buff *skb; 4790 struct sk_buff *skb;
@@ -4368,7 +4792,7 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
4368 4792
4369 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4793 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4370 if (!skb) 4794 if (!skb)
4371 return -ENOMEM; 4795 return ERR_PTR(-ENOMEM);
4372 4796
4373 cmd = (struct wmi_dbglog_cfg_cmd *)skb->data; 4797 cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;
4374 4798
@@ -4393,57 +4817,318 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
4393 __le32_to_cpu(cmd->module_valid), 4817 __le32_to_cpu(cmd->module_valid),
4394 __le32_to_cpu(cmd->config_enable), 4818 __le32_to_cpu(cmd->config_enable),
4395 __le32_to_cpu(cmd->config_valid)); 4819 __le32_to_cpu(cmd->config_valid));
4396 4820 return skb;
4397 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
4398} 4821}
4399 4822
4400int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) 4823static struct sk_buff *
4824ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap)
4401{ 4825{
4402 struct wmi_pdev_pktlog_enable_cmd *cmd; 4826 struct wmi_pdev_pktlog_enable_cmd *cmd;
4403 struct sk_buff *skb; 4827 struct sk_buff *skb;
4404 4828
4405 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4829 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4406 if (!skb) 4830 if (!skb)
4407 return -ENOMEM; 4831 return ERR_PTR(-ENOMEM);
4408 4832
4409 ev_bitmap &= ATH10K_PKTLOG_ANY; 4833 ev_bitmap &= ATH10K_PKTLOG_ANY;
4410 ath10k_dbg(ar, ATH10K_DBG_WMI,
4411 "wmi enable pktlog filter:%x\n", ev_bitmap);
4412 4834
4413 cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data; 4835 cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data;
4414 cmd->ev_bitmap = __cpu_to_le32(ev_bitmap); 4836 cmd->ev_bitmap = __cpu_to_le32(ev_bitmap);
4415 return ath10k_wmi_cmd_send(ar, skb, 4837
4416 ar->wmi.cmd->pdev_pktlog_enable_cmdid); 4838 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi enable pktlog filter 0x%08x\n",
4839 ev_bitmap);
4840 return skb;
4417} 4841}
4418 4842
4419int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar) 4843static struct sk_buff *
4844ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar)
4420{ 4845{
4421 struct sk_buff *skb; 4846 struct sk_buff *skb;
4422 4847
4423 skb = ath10k_wmi_alloc_skb(ar, 0); 4848 skb = ath10k_wmi_alloc_skb(ar, 0);
4424 if (!skb) 4849 if (!skb)
4425 return -ENOMEM; 4850 return ERR_PTR(-ENOMEM);
4426 4851
4427 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n"); 4852 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n");
4853 return skb;
4854}
4855
4856static struct sk_buff *
4857ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
4858 u32 duration, u32 next_offset,
4859 u32 enabled)
4860{
4861 struct wmi_pdev_set_quiet_cmd *cmd;
4862 struct sk_buff *skb;
4428 4863
4429 return ath10k_wmi_cmd_send(ar, skb, 4864 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4430 ar->wmi.cmd->pdev_pktlog_disable_cmdid); 4865 if (!skb)
4866 return ERR_PTR(-ENOMEM);
4867
4868 cmd = (struct wmi_pdev_set_quiet_cmd *)skb->data;
4869 cmd->period = __cpu_to_le32(period);
4870 cmd->duration = __cpu_to_le32(duration);
4871 cmd->next_start = __cpu_to_le32(next_offset);
4872 cmd->enabled = __cpu_to_le32(enabled);
4873
4874 ath10k_dbg(ar, ATH10K_DBG_WMI,
4875 "wmi quiet param: period %u duration %u enabled %d\n",
4876 period, duration, enabled);
4877 return skb;
4431} 4878}
4432 4879
4880static const struct wmi_ops wmi_ops = {
4881 .rx = ath10k_wmi_op_rx,
4882 .map_svc = wmi_main_svc_map,
4883
4884 .pull_scan = ath10k_wmi_op_pull_scan_ev,
4885 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
4886 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
4887 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
4888 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
4889 .pull_swba = ath10k_wmi_op_pull_swba_ev,
4890 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
4891 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
4892 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
4893 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats,
4894
4895 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
4896 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
4897 .gen_pdev_set_rd = ath10k_wmi_op_gen_pdev_set_rd,
4898 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
4899 .gen_init = ath10k_wmi_op_gen_init,
4900 .gen_start_scan = ath10k_wmi_op_gen_start_scan,
4901 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
4902 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
4903 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
4904 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
4905 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
4906 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
4907 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
4908 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
4909 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
4910 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
4911 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
4912 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
4913 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
4914 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
4915 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
4916 .gen_peer_assoc = ath10k_wmi_op_gen_peer_assoc,
4917 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
4918 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
4919 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
4920 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
4921 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
4922 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
4923 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
4924 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
4925 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
4926 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
4927 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
4928 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
4929 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
4930 /* .gen_pdev_get_temperature not implemented */
4931};
4932
4933static const struct wmi_ops wmi_10_1_ops = {
4934 .rx = ath10k_wmi_10_1_op_rx,
4935 .map_svc = wmi_10x_svc_map,
4936 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
4937 .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
4938 .gen_init = ath10k_wmi_10_1_op_gen_init,
4939 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
4940 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
4941 .gen_peer_assoc = ath10k_wmi_10_1_op_gen_peer_assoc,
4942 /* .gen_pdev_get_temperature not implemented */
4943
4944 /* shared with main branch */
4945 .pull_scan = ath10k_wmi_op_pull_scan_ev,
4946 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
4947 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
4948 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
4949 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
4950 .pull_swba = ath10k_wmi_op_pull_swba_ev,
4951 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
4952 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
4953
4954 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
4955 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
4956 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
4957 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
4958 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
4959 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
4960 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
4961 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
4962 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
4963 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
4964 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
4965 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
4966 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
4967 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
4968 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
4969 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
4970 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
4971 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
4972 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
4973 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
4974 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
4975 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
4976 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
4977 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
4978 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
4979 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
4980 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
4981 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
4982 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
4983 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
4984 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
4985};
4986
4987static const struct wmi_ops wmi_10_2_ops = {
4988 .rx = ath10k_wmi_10_2_op_rx,
4989 .gen_init = ath10k_wmi_10_2_op_gen_init,
4990 .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
4991 /* .gen_pdev_get_temperature not implemented */
4992
4993 /* shared with 10.1 */
4994 .map_svc = wmi_10x_svc_map,
4995 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
4996 .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
4997 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
4998 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
4999
5000 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5001 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5002 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5003 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5004 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5005 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5006 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5007 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5008
5009 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5010 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5011 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5012 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5013 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5014 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5015 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5016 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5017 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5018 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5019 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5020 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5021 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5022 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5023 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5024 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5025 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5026 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5027 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5028 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5029 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5030 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5031 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5032 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5033 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5034 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5035 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5036 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5037 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5038 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5039 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5040};
5041
5042static const struct wmi_ops wmi_10_2_4_ops = {
5043 .rx = ath10k_wmi_10_2_op_rx,
5044 .gen_init = ath10k_wmi_10_2_op_gen_init,
5045 .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
5046 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
5047
5048 /* shared with 10.1 */
5049 .map_svc = wmi_10x_svc_map,
5050 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
5051 .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
5052 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
5053 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
5054
5055 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5056 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5057 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5058 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5059 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5060 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5061 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5062 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5063
5064 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5065 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5066 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5067 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5068 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5069 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5070 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5071 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5072 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5073 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5074 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5075 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5076 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5077 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5078 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5079 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5080 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5081 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5082 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5083 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5084 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5085 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5086 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5087 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5088 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5089 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5090 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5091 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5092 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5093 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5094 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5095};
5096
4433int ath10k_wmi_attach(struct ath10k *ar) 5097int ath10k_wmi_attach(struct ath10k *ar)
4434{ 5098{
4435 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 5099 switch (ar->wmi.op_version) {
4436 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 5100 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
4437 ar->wmi.cmd = &wmi_10_2_cmd_map; 5101 ar->wmi.cmd = &wmi_10_2_4_cmd_map;
4438 else 5102 ar->wmi.ops = &wmi_10_2_4_ops;
4439 ar->wmi.cmd = &wmi_10x_cmd_map; 5103 ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map;
4440 5104 ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map;
5105 break;
5106 case ATH10K_FW_WMI_OP_VERSION_10_2:
5107 ar->wmi.cmd = &wmi_10_2_cmd_map;
5108 ar->wmi.ops = &wmi_10_2_ops;
4441 ar->wmi.vdev_param = &wmi_10x_vdev_param_map; 5109 ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
4442 ar->wmi.pdev_param = &wmi_10x_pdev_param_map; 5110 ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
4443 } else { 5111 break;
5112 case ATH10K_FW_WMI_OP_VERSION_10_1:
5113 ar->wmi.cmd = &wmi_10x_cmd_map;
5114 ar->wmi.ops = &wmi_10_1_ops;
5115 ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
5116 ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
5117 break;
5118 case ATH10K_FW_WMI_OP_VERSION_MAIN:
4444 ar->wmi.cmd = &wmi_cmd_map; 5119 ar->wmi.cmd = &wmi_cmd_map;
5120 ar->wmi.ops = &wmi_ops;
4445 ar->wmi.vdev_param = &wmi_vdev_param_map; 5121 ar->wmi.vdev_param = &wmi_vdev_param_map;
4446 ar->wmi.pdev_param = &wmi_pdev_param_map; 5122 ar->wmi.pdev_param = &wmi_pdev_param_map;
5123 break;
5124 case ATH10K_FW_WMI_OP_VERSION_TLV:
5125 ath10k_wmi_tlv_attach(ar);
5126 break;
5127 case ATH10K_FW_WMI_OP_VERSION_UNSET:
5128 case ATH10K_FW_WMI_OP_VERSION_MAX:
5129 ath10k_err(ar, "unsupported WMI op version: %d\n",
5130 ar->wmi.op_version);
5131 return -EINVAL;
4447 } 5132 }
4448 5133
4449 init_completion(&ar->wmi.service_ready); 5134 init_completion(&ar->wmi.service_ready);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 21391929d318..bd7f29a3a122 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -109,6 +109,45 @@ enum wmi_service {
109 WMI_SERVICE_BURST, 109 WMI_SERVICE_BURST,
110 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, 110 WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT,
111 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, 111 WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT,
112 WMI_SERVICE_ROAM_SCAN_OFFLOAD,
113 WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC,
114 WMI_SERVICE_EARLY_RX,
115 WMI_SERVICE_STA_SMPS,
116 WMI_SERVICE_FWTEST,
117 WMI_SERVICE_STA_WMMAC,
118 WMI_SERVICE_TDLS,
119 WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE,
120 WMI_SERVICE_ADAPTIVE_OCS,
121 WMI_SERVICE_BA_SSN_SUPPORT,
122 WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE,
123 WMI_SERVICE_WLAN_HB,
124 WMI_SERVICE_LTE_ANT_SHARE_SUPPORT,
125 WMI_SERVICE_BATCH_SCAN,
126 WMI_SERVICE_QPOWER,
127 WMI_SERVICE_PLMREQ,
128 WMI_SERVICE_THERMAL_MGMT,
129 WMI_SERVICE_RMC,
130 WMI_SERVICE_MHF_OFFLOAD,
131 WMI_SERVICE_COEX_SAR,
132 WMI_SERVICE_BCN_TXRATE_OVERRIDE,
133 WMI_SERVICE_NAN,
134 WMI_SERVICE_L1SS_STAT,
135 WMI_SERVICE_ESTIMATE_LINKSPEED,
136 WMI_SERVICE_OBSS_SCAN,
137 WMI_SERVICE_TDLS_OFFCHAN,
138 WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,
139 WMI_SERVICE_TDLS_UAPSD_SLEEP_STA,
140 WMI_SERVICE_IBSS_PWRSAVE,
141 WMI_SERVICE_LPASS,
142 WMI_SERVICE_EXTSCAN,
143 WMI_SERVICE_D0WOW,
144 WMI_SERVICE_HSOFFLOAD,
145 WMI_SERVICE_ROAM_HO_OFFLOAD,
146 WMI_SERVICE_RX_FULL_REORDER,
147 WMI_SERVICE_DHCP_OFFLOAD,
148 WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
149 WMI_SERVICE_MDNS_OFFLOAD,
150 WMI_SERVICE_SAP_AUTH_OFFLOAD,
112 151
113 /* keep last */ 152 /* keep last */
114 WMI_SERVICE_MAX, 153 WMI_SERVICE_MAX,
@@ -215,6 +254,45 @@ static inline char *wmi_service_name(int service_id)
215 SVCSTR(WMI_SERVICE_BURST); 254 SVCSTR(WMI_SERVICE_BURST);
216 SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); 255 SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT);
217 SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); 256 SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT);
257 SVCSTR(WMI_SERVICE_ROAM_SCAN_OFFLOAD);
258 SVCSTR(WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC);
259 SVCSTR(WMI_SERVICE_EARLY_RX);
260 SVCSTR(WMI_SERVICE_STA_SMPS);
261 SVCSTR(WMI_SERVICE_FWTEST);
262 SVCSTR(WMI_SERVICE_STA_WMMAC);
263 SVCSTR(WMI_SERVICE_TDLS);
264 SVCSTR(WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE);
265 SVCSTR(WMI_SERVICE_ADAPTIVE_OCS);
266 SVCSTR(WMI_SERVICE_BA_SSN_SUPPORT);
267 SVCSTR(WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE);
268 SVCSTR(WMI_SERVICE_WLAN_HB);
269 SVCSTR(WMI_SERVICE_LTE_ANT_SHARE_SUPPORT);
270 SVCSTR(WMI_SERVICE_BATCH_SCAN);
271 SVCSTR(WMI_SERVICE_QPOWER);
272 SVCSTR(WMI_SERVICE_PLMREQ);
273 SVCSTR(WMI_SERVICE_THERMAL_MGMT);
274 SVCSTR(WMI_SERVICE_RMC);
275 SVCSTR(WMI_SERVICE_MHF_OFFLOAD);
276 SVCSTR(WMI_SERVICE_COEX_SAR);
277 SVCSTR(WMI_SERVICE_BCN_TXRATE_OVERRIDE);
278 SVCSTR(WMI_SERVICE_NAN);
279 SVCSTR(WMI_SERVICE_L1SS_STAT);
280 SVCSTR(WMI_SERVICE_ESTIMATE_LINKSPEED);
281 SVCSTR(WMI_SERVICE_OBSS_SCAN);
282 SVCSTR(WMI_SERVICE_TDLS_OFFCHAN);
283 SVCSTR(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA);
284 SVCSTR(WMI_SERVICE_TDLS_UAPSD_SLEEP_STA);
285 SVCSTR(WMI_SERVICE_IBSS_PWRSAVE);
286 SVCSTR(WMI_SERVICE_LPASS);
287 SVCSTR(WMI_SERVICE_EXTSCAN);
288 SVCSTR(WMI_SERVICE_D0WOW);
289 SVCSTR(WMI_SERVICE_HSOFFLOAD);
290 SVCSTR(WMI_SERVICE_ROAM_HO_OFFLOAD);
291 SVCSTR(WMI_SERVICE_RX_FULL_REORDER);
292 SVCSTR(WMI_SERVICE_DHCP_OFFLOAD);
293 SVCSTR(WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT);
294 SVCSTR(WMI_SERVICE_MDNS_OFFLOAD);
295 SVCSTR(WMI_SERVICE_SAP_AUTH_OFFLOAD);
218 default: 296 default:
219 return NULL; 297 return NULL;
220 } 298 }
@@ -472,6 +550,7 @@ struct wmi_cmd_map {
472 u32 force_fw_hang_cmdid; 550 u32 force_fw_hang_cmdid;
473 u32 gpio_config_cmdid; 551 u32 gpio_config_cmdid;
474 u32 gpio_output_cmdid; 552 u32 gpio_output_cmdid;
553 u32 pdev_get_temperature_cmdid;
475}; 554};
476 555
477/* 556/*
@@ -1076,6 +1155,11 @@ enum wmi_10_2_cmd_id {
1076 WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID, 1155 WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID,
1077 WMI_10_2_PDEV_RATEPWR_TABLE_CMDID, 1156 WMI_10_2_PDEV_RATEPWR_TABLE_CMDID,
1078 WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID, 1157 WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID,
1158 WMI_10_2_PDEV_GET_INFO,
1159 WMI_10_2_VDEV_GET_INFO,
1160 WMI_10_2_VDEV_ATF_REQUEST_CMDID,
1161 WMI_10_2_PEER_ATF_REQUEST_CMDID,
1162 WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
1079 WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1, 1163 WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
1080}; 1164};
1081 1165
@@ -1117,6 +1201,8 @@ enum wmi_10_2_event_id {
1117 WMI_10_2_MCAST_BUF_RELEASE_EVENTID, 1201 WMI_10_2_MCAST_BUF_RELEASE_EVENTID,
1118 WMI_10_2_MCAST_LIST_AGEOUT_EVENTID, 1202 WMI_10_2_MCAST_LIST_AGEOUT_EVENTID,
1119 WMI_10_2_WDS_PEER_EVENTID, 1203 WMI_10_2_WDS_PEER_EVENTID,
1204 WMI_10_2_PEER_STA_PS_STATECHG_EVENTID,
1205 WMI_10_2_PDEV_TEMPERATURE_EVENTID,
1120 WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1, 1206 WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1,
1121}; 1207};
1122 1208
@@ -1862,6 +1948,11 @@ struct wmi_resource_config_10x {
1862 __le32 max_frag_entries; 1948 __le32 max_frag_entries;
1863} __packed; 1949} __packed;
1864 1950
1951enum wmi_10_2_feature_mask {
1952 WMI_10_2_RX_BATCH_MODE = BIT(0),
1953 WMI_10_2_ATF_CONFIG = BIT(1),
1954};
1955
1865struct wmi_resource_config_10_2 { 1956struct wmi_resource_config_10_2 {
1866 struct wmi_resource_config_10x common; 1957 struct wmi_resource_config_10x common;
1867 __le32 max_peer_ext_stats; 1958 __le32 max_peer_ext_stats;
@@ -1870,7 +1961,7 @@ struct wmi_resource_config_10_2 {
1870 __le32 be_min_free; 1961 __le32 be_min_free;
1871 __le32 vi_min_free; 1962 __le32 vi_min_free;
1872 __le32 vo_min_free; 1963 __le32 vo_min_free;
1873 __le32 rx_batchmode; /* 0-disable, 1-enable */ 1964 __le32 feature_mask;
1874} __packed; 1965} __packed;
1875 1966
1876#define NUM_UNITS_IS_NUM_VDEVS 0x1 1967#define NUM_UNITS_IS_NUM_VDEVS 0x1
@@ -2505,6 +2596,7 @@ struct wmi_pdev_param_map {
2505 u32 fast_channel_reset; 2596 u32 fast_channel_reset;
2506 u32 burst_dur; 2597 u32 burst_dur;
2507 u32 burst_enable; 2598 u32 burst_enable;
2599 u32 cal_period;
2508}; 2600};
2509 2601
2510#define WMI_PDEV_PARAM_UNSUPPORTED 0 2602#define WMI_PDEV_PARAM_UNSUPPORTED 0
@@ -2715,6 +2807,9 @@ enum wmi_10x_pdev_param {
2715 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE, 2807 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE,
2716 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 2808 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER,
2717 WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 2809 WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
2810 WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE,
2811 WMI_10X_PDEV_PARAM_RTS_FIXED_RATE,
2812 WMI_10X_PDEV_PARAM_CAL_PERIOD
2718}; 2813};
2719 2814
2720struct wmi_pdev_set_param_cmd { 2815struct wmi_pdev_set_param_cmd {
@@ -2722,6 +2817,9 @@ struct wmi_pdev_set_param_cmd {
2722 __le32 param_value; 2817 __le32 param_value;
2723} __packed; 2818} __packed;
2724 2819
2820/* valid period is 1 ~ 60000ms, unit in millisecond */
2821#define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000
2822
2725struct wmi_pdev_get_tpc_config_cmd { 2823struct wmi_pdev_get_tpc_config_cmd {
2726 /* parameter */ 2824 /* parameter */
2727 __le32 param; 2825 __le32 param;
@@ -3930,6 +4028,13 @@ enum wmi_sta_ps_param_pspoll_count {
3930 * Values greater than 0 indicate the maximum numer of PS-Poll frames 4028 * Values greater than 0 indicate the maximum numer of PS-Poll frames
3931 * FW will send before waking up. 4029 * FW will send before waking up.
3932 */ 4030 */
4031
4032 /* When u-APSD is enabled the firmware will be very reluctant to exit
4033 * STA PS. This could result in very poor Rx performance with STA doing
4034 * PS-Poll for each and every buffered frame. This value is a bit
4035 * arbitrary.
4036 */
4037 WMI_STA_PS_PSPOLL_COUNT_UAPSD = 3,
3933}; 4038};
3934 4039
3935/* 4040/*
@@ -4120,7 +4225,7 @@ struct wmi_bcn_info {
4120 4225
4121struct wmi_host_swba_event { 4226struct wmi_host_swba_event {
4122 __le32 vdev_map; 4227 __le32 vdev_map;
4123 struct wmi_bcn_info bcn_info[1]; 4228 struct wmi_bcn_info bcn_info[0];
4124} __packed; 4229} __packed;
4125 4230
4126#define WMI_MAX_AP_VDEV 16 4231#define WMI_MAX_AP_VDEV 16
@@ -4567,6 +4672,58 @@ struct wmi_dbglog_cfg_cmd {
4567 4672
4568#define WMI_MAX_MEM_REQS 16 4673#define WMI_MAX_MEM_REQS 16
4569 4674
4675struct wmi_scan_ev_arg {
4676 __le32 event_type; /* %WMI_SCAN_EVENT_ */
4677 __le32 reason; /* %WMI_SCAN_REASON_ */
4678 __le32 channel_freq; /* only valid for WMI_SCAN_EVENT_FOREIGN_CHANNEL */
4679 __le32 scan_req_id;
4680 __le32 scan_id;
4681 __le32 vdev_id;
4682};
4683
4684struct wmi_mgmt_rx_ev_arg {
4685 __le32 channel;
4686 __le32 snr;
4687 __le32 rate;
4688 __le32 phy_mode;
4689 __le32 buf_len;
4690 __le32 status; /* %WMI_RX_STATUS_ */
4691};
4692
4693struct wmi_ch_info_ev_arg {
4694 __le32 err_code;
4695 __le32 freq;
4696 __le32 cmd_flags;
4697 __le32 noise_floor;
4698 __le32 rx_clear_count;
4699 __le32 cycle_count;
4700};
4701
4702struct wmi_vdev_start_ev_arg {
4703 __le32 vdev_id;
4704 __le32 req_id;
4705 __le32 resp_type; /* %WMI_VDEV_RESP_ */
4706 __le32 status;
4707};
4708
4709struct wmi_peer_kick_ev_arg {
4710 const u8 *mac_addr;
4711};
4712
4713struct wmi_swba_ev_arg {
4714 __le32 vdev_map;
4715 const struct wmi_tim_info *tim_info[WMI_MAX_AP_VDEV];
4716 const struct wmi_p2p_noa_info *noa_info[WMI_MAX_AP_VDEV];
4717};
4718
4719struct wmi_phyerr_ev_arg {
4720 __le32 num_phyerrs;
4721 __le32 tsf_l32;
4722 __le32 tsf_u32;
4723 __le32 buf_len;
4724 const struct wmi_phyerr *phyerrs;
4725};
4726
4570struct wmi_svc_rdy_ev_arg { 4727struct wmi_svc_rdy_ev_arg {
4571 __le32 min_tx_power; 4728 __le32 min_tx_power;
4572 __le32 max_tx_power; 4729 __le32 max_tx_power;
@@ -4574,6 +4731,7 @@ struct wmi_svc_rdy_ev_arg {
4574 __le32 vht_cap; 4731 __le32 vht_cap;
4575 __le32 sw_ver0; 4732 __le32 sw_ver0;
4576 __le32 sw_ver1; 4733 __le32 sw_ver1;
4734 __le32 fw_build;
4577 __le32 phy_capab; 4735 __le32 phy_capab;
4578 __le32 num_rf_chains; 4736 __le32 num_rf_chains;
4579 __le32 eeprom_rd; 4737 __le32 eeprom_rd;
@@ -4583,83 +4741,93 @@ struct wmi_svc_rdy_ev_arg {
4583 const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; 4741 const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS];
4584}; 4742};
4585 4743
4744struct wmi_rdy_ev_arg {
4745 __le32 sw_version;
4746 __le32 abi_version;
4747 __le32 status;
4748 const u8 *mac_addr;
4749};
4750
4751struct wmi_pdev_temperature_event {
4752 /* temperature value in Celcius degree */
4753 __le32 temperature;
4754} __packed;
4755
4586struct ath10k; 4756struct ath10k;
4587struct ath10k_vif; 4757struct ath10k_vif;
4588struct ath10k_fw_stats; 4758struct ath10k_fw_stats_pdev;
4759struct ath10k_fw_stats_peer;
4589 4760
4590int ath10k_wmi_attach(struct ath10k *ar); 4761int ath10k_wmi_attach(struct ath10k *ar);
4591void ath10k_wmi_detach(struct ath10k *ar); 4762void ath10k_wmi_detach(struct ath10k *ar);
4592int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); 4763int ath10k_wmi_wait_for_service_ready(struct ath10k *ar);
4593int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); 4764int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
4594 4765
4766struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);
4595int ath10k_wmi_connect(struct ath10k *ar); 4767int ath10k_wmi_connect(struct ath10k *ar);
4596 4768
4597struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); 4769struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);
4598int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 4770int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
4599 4771int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
4600int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); 4772 u32 cmd_id);
4601int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
4602int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
4603 u16 rd5g, u16 ctl2g, u16 ctl5g,
4604 enum wmi_dfs_region dfs_reg);
4605int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
4606int ath10k_wmi_cmd_init(struct ath10k *ar);
4607int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
4608void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *); 4773void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *);
4609int ath10k_wmi_stop_scan(struct ath10k *ar, 4774
4610 const struct wmi_stop_scan_arg *arg); 4775void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src,
4611int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, 4776 struct ath10k_fw_stats_pdev *dst);
4612 enum wmi_vdev_type type, 4777void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
4613 enum wmi_vdev_subtype subtype, 4778 struct ath10k_fw_stats_peer *dst);
4614 const u8 macaddr[ETH_ALEN]); 4779void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
4615int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id); 4780 struct wmi_host_mem_chunks *chunks);
4616int ath10k_wmi_vdev_start(struct ath10k *ar, 4781void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
4617 const struct wmi_vdev_start_request_arg *); 4782 const struct wmi_start_scan_arg *arg);
4618int ath10k_wmi_vdev_restart(struct ath10k *ar, 4783void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
4619 const struct wmi_vdev_start_request_arg *); 4784 const struct wmi_wmm_params_arg *arg);
4620int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id); 4785void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
4621int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, 4786 const struct wmi_channel_arg *arg);
4622 const u8 *bssid); 4787int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
4623int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id); 4788
4624int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, 4789int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb);
4625 u32 param_id, u32 param_value); 4790int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb);
4626int ath10k_wmi_vdev_install_key(struct ath10k *ar, 4791void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb);
4627 const struct wmi_vdev_install_key_arg *arg); 4792void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb);
4628int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, 4793int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb);
4629 const struct wmi_vdev_spectral_conf_arg *arg); 4794void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb);
4630int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, 4795void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb);
4631 u32 enable); 4796void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb);
4632int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, 4797void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb);
4633 const u8 peer_addr[ETH_ALEN]); 4798void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb);
4634int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, 4799void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb);
4635 const u8 peer_addr[ETH_ALEN]); 4800void ath10k_wmi_event_dfs(struct ath10k *ar,
4636int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, 4801 const struct wmi_phyerr *phyerr, u64 tsf);
4637 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap); 4802void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
4638int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, 4803 const struct wmi_phyerr *phyerr,
4639 const u8 *peer_addr, 4804 u64 tsf);
4640 enum wmi_peer_param param_id, u32 param_value); 4805void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb);
4641int ath10k_wmi_peer_assoc(struct ath10k *ar, 4806void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb);
4642 const struct wmi_peer_assoc_complete_arg *arg); 4807void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb);
4643int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, 4808void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb);
4644 enum wmi_sta_ps_mode psmode); 4809void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb);
4645int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, 4810void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb);
4646 enum wmi_sta_powersave_param param_id, 4811void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
4647 u32 value); 4812 struct sk_buff *skb);
4648int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, 4813void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
4649 enum wmi_ap_ps_peer_param param_id, u32 value); 4814 struct sk_buff *skb);
4650int ath10k_wmi_scan_chan_list(struct ath10k *ar, 4815void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb);
4651 const struct wmi_scan_chan_list_arg *arg); 4816void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb);
4652int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif); 4817void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb);
4653int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 4818void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb);
4654 const struct wmi_pdev_set_wmm_params_arg *arg); 4819void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb);
4655int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); 4820void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
4656int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4821 struct sk_buff *skb);
4657 enum wmi_force_fw_hang_type type, u32 delay_ms); 4822void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb);
4658int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); 4823void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb);
4659int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); 4824void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb);
4660int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, 4825void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
4661 struct ath10k_fw_stats *stats); 4826 struct sk_buff *skb);
4662int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list); 4827void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb);
4663int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar); 4828void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb);
4829void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb);
4830void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb);
4831int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb);
4664 4832
4665#endif /* _WMI_H_ */ 4833#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c
index 8f387cf67340..2ca88b593e4c 100644
--- a/drivers/net/wireless/ath/ath5k/ahb.c
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -227,7 +227,6 @@ static struct platform_driver ath_ahb_driver = {
227 .remove = ath_ahb_remove, 227 .remove = ath_ahb_remove,
228 .driver = { 228 .driver = {
229 .name = "ar231x-wmac", 229 .name = "ar231x-wmac",
230 .owner = THIS_MODULE,
231 }, 230 },
232}; 231};
233 232
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index c60d36aa13e2..bf29da5e90da 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -912,6 +912,7 @@ ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
912 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE 912 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
913 | (ah->ah_version == AR5K_AR5210 ? 913 | (ah->ah_version == AR5K_AR5210 ?
914 AR5K_STA_ID1_PWR_SV : 0); 914 AR5K_STA_ID1_PWR_SV : 0);
915 /* fall through */
915 case NL80211_IFTYPE_MONITOR: 916 case NL80211_IFTYPE_MONITOR:
916 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE 917 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
917 | (ah->ah_version == AR5K_AR5210 ? 918 | (ah->ah_version == AR5K_AR5210 ?
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index e000c4c27881..bd4a1a655f42 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -43,6 +43,10 @@ static const struct platform_device_id ath9k_platform_id_table[] = {
43 .name = "qca953x_wmac", 43 .name = "qca953x_wmac",
44 .driver_data = AR9300_DEVID_AR953X, 44 .driver_data = AR9300_DEVID_AR953X,
45 }, 45 },
46 {
47 .name = "qca956x_wmac",
48 .driver_data = AR9300_DEVID_QCA956X,
49 },
46 {}, 50 {},
47}; 51};
48 52
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index ba502a2d199b..ca01d17d130f 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -259,7 +259,8 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
259 entry_cck->fir_step_level); 259 entry_cck->fir_step_level);
260 260
261 /* Skip MRC CCK for pre AR9003 families */ 261 /* Skip MRC CCK for pre AR9003 families */
262 if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) 262 if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) ||
263 AR_SREV_9565(ah) || AR_SREV_9561(ah))
263 return; 264 return;
264 265
265 if (aniState->mrcCCK != entry_cck->mrc_cck_on) 266 if (aniState->mrcCCK != entry_cck->mrc_cck_on)
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 5829074208fa..f273427fdd29 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -22,6 +22,21 @@
22 22
23/* All code below is for AR5008, AR9001, AR9002 */ 23/* All code below is for AR5008, AR9001, AR9002 */
24 24
25#define AR5008_OFDM_RATES 8
26#define AR5008_HT_SS_RATES 8
27#define AR5008_HT_DS_RATES 8
28
29#define AR5008_HT20_SHIFT 16
30#define AR5008_HT40_SHIFT 24
31
32#define AR5008_11NA_OFDM_SHIFT 0
33#define AR5008_11NA_HT_SS_SHIFT 8
34#define AR5008_11NA_HT_DS_SHIFT 16
35
36#define AR5008_11NG_OFDM_SHIFT 4
37#define AR5008_11NG_HT_SS_SHIFT 12
38#define AR5008_11NG_HT_DS_SHIFT 20
39
25static const int firstep_table[] = 40static const int firstep_table[] =
26/* level: 0 1 2 3 4 5 6 7 8 */ 41/* level: 0 1 2 3 4 5 6 7 8 */
27 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ 42 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */
@@ -1235,6 +1250,71 @@ static void ar5008_hw_set_radar_conf(struct ath_hw *ah)
1235 conf->radar_inband = 8; 1250 conf->radar_inband = 8;
1236} 1251}
1237 1252
1253static void ar5008_hw_init_txpower_cck(struct ath_hw *ah, int16_t *rate_array)
1254{
1255#define CCK_DELTA(x) ((OLC_FOR_AR9280_20_LATER) ? max((x) - 2, 0) : (x))
1256 ah->tx_power[0] = CCK_DELTA(rate_array[rate1l]);
1257 ah->tx_power[1] = CCK_DELTA(min(rate_array[rate2l],
1258 rate_array[rate2s]));
1259 ah->tx_power[2] = CCK_DELTA(min(rate_array[rate5_5l],
1260 rate_array[rate5_5s]));
1261 ah->tx_power[3] = CCK_DELTA(min(rate_array[rate11l],
1262 rate_array[rate11s]));
1263#undef CCK_DELTA
1264}
1265
1266static void ar5008_hw_init_txpower_ofdm(struct ath_hw *ah, int16_t *rate_array,
1267 int offset)
1268{
1269 int i, idx = 0;
1270
1271 for (i = offset; i < offset + AR5008_OFDM_RATES; i++) {
1272 ah->tx_power[i] = rate_array[idx];
1273 idx++;
1274 }
1275}
1276
1277static void ar5008_hw_init_txpower_ht(struct ath_hw *ah, int16_t *rate_array,
1278 int ss_offset, int ds_offset,
1279 bool is_40, int ht40_delta)
1280{
1281 int i, mcs_idx = (is_40) ? AR5008_HT40_SHIFT : AR5008_HT20_SHIFT;
1282
1283 for (i = ss_offset; i < ss_offset + AR5008_HT_SS_RATES; i++) {
1284 ah->tx_power[i] = rate_array[mcs_idx] + ht40_delta;
1285 mcs_idx++;
1286 }
1287 memcpy(&ah->tx_power[ds_offset], &ah->tx_power[ss_offset],
1288 AR5008_HT_SS_RATES);
1289}
1290
1291void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
1292 struct ath9k_channel *chan, int ht40_delta)
1293{
1294 if (IS_CHAN_5GHZ(chan)) {
1295 ar5008_hw_init_txpower_ofdm(ah, rate_array,
1296 AR5008_11NA_OFDM_SHIFT);
1297 if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
1298 ar5008_hw_init_txpower_ht(ah, rate_array,
1299 AR5008_11NA_HT_SS_SHIFT,
1300 AR5008_11NA_HT_DS_SHIFT,
1301 IS_CHAN_HT40(chan),
1302 ht40_delta);
1303 }
1304 } else {
1305 ar5008_hw_init_txpower_cck(ah, rate_array);
1306 ar5008_hw_init_txpower_ofdm(ah, rate_array,
1307 AR5008_11NG_OFDM_SHIFT);
1308 if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {
1309 ar5008_hw_init_txpower_ht(ah, rate_array,
1310 AR5008_11NG_HT_SS_SHIFT,
1311 AR5008_11NG_HT_DS_SHIFT,
1312 IS_CHAN_HT40(chan),
1313 ht40_delta);
1314 }
1315 }
1316}
1317
1238int ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1318int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
1239{ 1319{
1240 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1320 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 08225a0067c2..8b4561e8ce1a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3536,7 +3536,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3536 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl; 3536 int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl;
3537 3537
3538 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) || 3538 if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
3539 AR_SREV_9531(ah)) 3539 AR_SREV_9531(ah) || AR_SREV_9561(ah))
3540 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); 3540 REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
3541 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah)) 3541 else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
3542 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 3542 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
@@ -3599,7 +3599,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3599 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 3599 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
3600 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3600 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3601 AR_SWITCH_TABLE_COM_AR9462_ALL, value); 3601 AR_SWITCH_TABLE_COM_AR9462_ALL, value);
3602 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { 3602 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
3603 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, 3603 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
3604 AR_SWITCH_TABLE_COM_AR9550_ALL, value); 3604 AR_SWITCH_TABLE_COM_AR9550_ALL, value);
3605 } else 3605 } else
@@ -3929,9 +3929,13 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
3929 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); 3929 REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
3930 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) 3930 if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
3931 return; 3931 return;
3932 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 3932 } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah) ||
3933 AR_SREV_9561(ah)) {
3933 reg_val = le32_to_cpu(pBase->swreg); 3934 reg_val = le32_to_cpu(pBase->swreg);
3934 REG_WRITE(ah, AR_PHY_PMU1, reg_val); 3935 REG_WRITE(ah, AR_PHY_PMU1, reg_val);
3936
3937 if (AR_SREV_9561(ah))
3938 REG_WRITE(ah, AR_PHY_PMU2, 0x10200000);
3935 } else { 3939 } else {
3936 /* Internal regulator is ON. Write swreg register. */ 3940 /* Internal regulator is ON. Write swreg register. */
3937 reg_val = le32_to_cpu(pBase->swreg); 3941 reg_val = le32_to_cpu(pBase->swreg);
@@ -4034,7 +4038,8 @@ static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz)
4034 if (!AR_SREV_9300(ah) && 4038 if (!AR_SREV_9300(ah) &&
4035 !AR_SREV_9340(ah) && 4039 !AR_SREV_9340(ah) &&
4036 !AR_SREV_9580(ah) && 4040 !AR_SREV_9580(ah) &&
4037 !AR_SREV_9531(ah)) 4041 !AR_SREV_9531(ah) &&
4042 !AR_SREV_9561(ah))
4038 return; 4043 return;
4039 4044
4040 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; 4045 xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn;
@@ -4812,7 +4817,7 @@ static void ar9003_hw_power_control_override(struct ath_hw *ah,
4812 } 4817 }
4813 4818
4814tempslope: 4819tempslope:
4815 if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { 4820 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
4816 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4; 4821 u8 txmask = (eep->baseEepHeader.txrxMask & 0xf0) >> 4;
4817 4822
4818 /* 4823 /*
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 06ad2172030e..4335ccbe7d7e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -29,6 +29,7 @@
29#include "ar9565_1p0_initvals.h" 29#include "ar9565_1p0_initvals.h"
30#include "ar9565_1p1_initvals.h" 30#include "ar9565_1p1_initvals.h"
31#include "ar953x_initvals.h" 31#include "ar953x_initvals.h"
32#include "ar956x_initvals.h"
32 33
33/* General hardware code for the AR9003 hadware family */ 34/* General hardware code for the AR9003 hadware family */
34 35
@@ -358,6 +359,40 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
358 359
359 INIT_INI_ARRAY(&ah->iniModesFastClock, 360 INIT_INI_ARRAY(&ah->iniModesFastClock,
360 qca953x_1p0_modes_fast_clock); 361 qca953x_1p0_modes_fast_clock);
362 } else if (AR_SREV_9561(ah)) {
363 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
364 qca956x_1p0_mac_core);
365 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
366 qca956x_1p0_mac_postamble);
367
368 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
369 qca956x_1p0_baseband_core);
370 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
371 qca956x_1p0_baseband_postamble);
372
373 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
374 qca956x_1p0_radio_core);
375 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
376 qca956x_1p0_radio_postamble);
377
378 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
379 qca956x_1p0_soc_preamble);
380 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
381 qca956x_1p0_soc_postamble);
382
383 INIT_INI_ARRAY(&ah->iniModesRxGain,
384 qca956x_1p0_common_wo_xlna_rx_gain_table);
385 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
386 qca956x_1p0_common_wo_xlna_rx_gain_bounds);
387 INIT_INI_ARRAY(&ah->iniModesTxGain,
388 qca956x_1p0_modes_no_xpa_tx_gain_table);
389
390 INIT_INI_ARRAY(&ah->ini_dfs,
391 qca956x_1p0_baseband_postamble_dfs_channel);
392 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
393 qca956x_1p0_baseband_core_txfir_coeff_japan_2484);
394 INIT_INI_ARRAY(&ah->iniModesFastClock,
395 qca956x_1p0_modes_fast_clock);
361 } else if (AR_SREV_9580(ah)) { 396 } else if (AR_SREV_9580(ah)) {
362 /* mac */ 397 /* mac */
363 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 398 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -544,6 +579,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
544 else if (AR_SREV_9531_20(ah)) 579 else if (AR_SREV_9531_20(ah))
545 INIT_INI_ARRAY(&ah->iniModesTxGain, 580 INIT_INI_ARRAY(&ah->iniModesTxGain,
546 qca953x_2p0_modes_xpa_tx_gain_table); 581 qca953x_2p0_modes_xpa_tx_gain_table);
582 else if (AR_SREV_9561(ah))
583 INIT_INI_ARRAY(&ah->iniModesTxGain,
584 qca956x_1p0_modes_xpa_tx_gain_table);
547 else if (AR_SREV_9580(ah)) 585 else if (AR_SREV_9580(ah))
548 INIT_INI_ARRAY(&ah->iniModesTxGain, 586 INIT_INI_ARRAY(&ah->iniModesTxGain,
549 ar9580_1p0_lowest_ob_db_tx_gain_table); 587 ar9580_1p0_lowest_ob_db_tx_gain_table);
@@ -594,7 +632,10 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
594 else 632 else
595 INIT_INI_ARRAY(&ah->iniModesTxGain, 633 INIT_INI_ARRAY(&ah->iniModesTxGain,
596 qca953x_1p0_modes_no_xpa_tx_gain_table); 634 qca953x_1p0_modes_no_xpa_tx_gain_table);
597 } else if (AR_SREV_9462_21(ah)) 635 } else if (AR_SREV_9561(ah))
636 INIT_INI_ARRAY(&ah->iniModesTxGain,
637 qca956x_1p0_modes_no_xpa_tx_gain_table);
638 else if (AR_SREV_9462_21(ah))
598 INIT_INI_ARRAY(&ah->iniModesTxGain, 639 INIT_INI_ARRAY(&ah->iniModesTxGain,
599 ar9462_2p1_modes_high_ob_db_tx_gain); 640 ar9462_2p1_modes_high_ob_db_tx_gain);
600 else if (AR_SREV_9462_20(ah)) 641 else if (AR_SREV_9462_20(ah))
@@ -628,6 +669,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
628 else if (AR_SREV_9580(ah)) 669 else if (AR_SREV_9580(ah))
629 INIT_INI_ARRAY(&ah->iniModesTxGain, 670 INIT_INI_ARRAY(&ah->iniModesTxGain,
630 ar9580_1p0_low_ob_db_tx_gain_table); 671 ar9580_1p0_low_ob_db_tx_gain_table);
672 else if (AR_SREV_9561(ah))
673 INIT_INI_ARRAY(&ah->iniModesTxGain,
674 qca956x_1p0_modes_no_xpa_low_ob_db_tx_gain_table);
631 else if (AR_SREV_9565_11(ah)) 675 else if (AR_SREV_9565_11(ah))
632 INIT_INI_ARRAY(&ah->iniModesTxGain, 676 INIT_INI_ARRAY(&ah->iniModesTxGain,
633 ar9565_1p1_modes_low_ob_db_tx_gain_table); 677 ar9565_1p1_modes_low_ob_db_tx_gain_table);
@@ -699,6 +743,9 @@ static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
699 else if (AR_SREV_9580(ah)) 743 else if (AR_SREV_9580(ah))
700 INIT_INI_ARRAY(&ah->iniModesTxGain, 744 INIT_INI_ARRAY(&ah->iniModesTxGain,
701 ar9580_1p0_type5_tx_gain_table); 745 ar9580_1p0_type5_tx_gain_table);
746 else if (AR_SREV_9561(ah))
747 INIT_INI_ARRAY(&ah->iniModesTxGain,
748 qca956x_1p0_modes_no_xpa_green_tx_gain_table);
702 else if (AR_SREV_9300_22(ah)) 749 else if (AR_SREV_9300_22(ah))
703 INIT_INI_ARRAY(&ah->iniModesTxGain, 750 INIT_INI_ARRAY(&ah->iniModesTxGain,
704 ar9300Modes_type5_tx_gain_table_2p2); 751 ar9300Modes_type5_tx_gain_table_2p2);
@@ -770,6 +817,13 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
770 qca953x_1p0_common_rx_gain_table); 817 qca953x_1p0_common_rx_gain_table);
771 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, 818 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
772 qca953x_1p0_common_rx_gain_bounds); 819 qca953x_1p0_common_rx_gain_bounds);
820 } else if (AR_SREV_9561(ah)) {
821 INIT_INI_ARRAY(&ah->iniModesRxGain,
822 qca956x_1p0_common_rx_gain_table);
823 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
824 qca956x_1p0_common_rx_gain_bounds);
825 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
826 qca956x_1p0_xlna_only);
773 } else if (AR_SREV_9580(ah)) 827 } else if (AR_SREV_9580(ah))
774 INIT_INI_ARRAY(&ah->iniModesRxGain, 828 INIT_INI_ARRAY(&ah->iniModesRxGain,
775 ar9580_1p0_rx_gain_table); 829 ar9580_1p0_rx_gain_table);
@@ -825,6 +879,11 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
825 qca953x_2p0_common_wo_xlna_rx_gain_table); 879 qca953x_2p0_common_wo_xlna_rx_gain_table);
826 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, 880 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
827 qca953x_2p0_common_wo_xlna_rx_gain_bounds); 881 qca953x_2p0_common_wo_xlna_rx_gain_bounds);
882 } else if (AR_SREV_9561(ah)) {
883 INIT_INI_ARRAY(&ah->iniModesRxGain,
884 qca956x_1p0_common_wo_xlna_rx_gain_table);
885 INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds,
886 qca956x_1p0_common_wo_xlna_rx_gain_bounds);
828 } else if (AR_SREV_9580(ah)) 887 } else if (AR_SREV_9580(ah))
829 INIT_INI_ARRAY(&ah->iniModesRxGain, 888 INIT_INI_ARRAY(&ah->iniModesRxGain,
830 ar9580_1p0_wo_xlna_rx_gain_table); 889 ar9580_1p0_wo_xlna_rx_gain_table);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index ae6cde273414..1ad66b76749b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -183,7 +183,8 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
183 } else { 183 } else {
184 channelSel = CHANSEL_2G(freq) >> 1; 184 channelSel = CHANSEL_2G(freq) >> 1;
185 } 185 }
186 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { 186 } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
187 AR_SREV_9561(ah)) {
187 if (ah->is_clk_25mhz) 188 if (ah->is_clk_25mhz)
188 div = 75; 189 div = 75;
189 else 190 else
@@ -198,7 +199,8 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
198 /* Set to 2G mode */ 199 /* Set to 2G mode */
199 bMode = 1; 200 bMode = 1;
200 } else { 201 } else {
201 if ((AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) && 202 if ((AR_SREV_9340(ah) || AR_SREV_9550(ah) ||
203 AR_SREV_9531(ah) || AR_SREV_9561(ah)) &&
202 ah->is_clk_25mhz) { 204 ah->is_clk_25mhz) {
203 channelSel = freq / 75; 205 channelSel = freq / 75;
204 chan_frac = ((freq % 75) * 0x20000) / 75; 206 chan_frac = ((freq % 75) * 0x20000) / 75;
@@ -265,7 +267,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
265 */ 267 */
266 268
267 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) || 269 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) ||
268 AR_SREV_9550(ah)) { 270 AR_SREV_9550(ah) || AR_SREV_9561(ah)) {
269 if (spur_fbin_ptr[0] == 0) /* No spur */ 271 if (spur_fbin_ptr[0] == 0) /* No spur */
270 return; 272 return;
271 max_spur_cnts = 5; 273 max_spur_cnts = 5;
@@ -292,7 +294,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
292 294
293 negative = 0; 295 negative = 0;
294 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) || 296 if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) ||
295 AR_SREV_9550(ah)) 297 AR_SREV_9550(ah) || AR_SREV_9561(ah))
296 cur_bb_spur = ath9k_hw_fbin2freq(spur_fbin_ptr[i], 298 cur_bb_spur = ath9k_hw_fbin2freq(spur_fbin_ptr[i],
297 IS_CHAN_2GHZ(chan)); 299 IS_CHAN_2GHZ(chan));
298 else 300 else
@@ -641,8 +643,10 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
641 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO); 643 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO);
642 644
643 /* Enable 11n HT, 20 MHz */ 645 /* Enable 11n HT, 20 MHz */
644 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | 646 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SHORT_GI_40 | enableDacFifo;
645 AR_PHY_GC_SHORT_GI_40 | enableDacFifo; 647
648 if (!AR_SREV_9561(ah))
649 phymode |= AR_PHY_GC_SINGLE_HT_LTF1;
646 650
647 /* Configure baseband for dynamic 20/40 operation */ 651 /* Configure baseband for dynamic 20/40 operation */
648 if (IS_CHAN_HT40(chan)) { 652 if (IS_CHAN_HT40(chan)) {
@@ -745,7 +749,8 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
745 else 749 else
746 ah->enabled_cals &= ~TX_CL_CAL; 750 ah->enabled_cals &= ~TX_CL_CAL;
747 751
748 if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) { 752 if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah) ||
753 AR_SREV_9561(ah)) {
749 if (ah->is_clk_25mhz) { 754 if (ah->is_clk_25mhz) {
750 REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); 755 REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
751 REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); 756 REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
@@ -812,6 +817,19 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah,
812 return ret; 817 return ret;
813} 818}
814 819
820static int ar9561_hw_get_modes_txgain_index(struct ath_hw *ah,
821 struct ath9k_channel *chan)
822{
823 if (IS_CHAN_2GHZ(chan)) {
824 if (IS_CHAN_HT40(chan))
825 return 1;
826 else
827 return 2;
828 }
829
830 return 0;
831}
832
815static void ar9003_doubler_fix(struct ath_hw *ah) 833static void ar9003_doubler_fix(struct ath_hw *ah)
816{ 834{
817 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { 835 if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
@@ -911,21 +929,29 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
911 REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 929 REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
912 modesIndex, regWrites); 930 modesIndex, regWrites);
913 } 931 }
932
933 if (AR_SREV_9561(ah) && (ar9003_hw_get_rx_gain_idx(ah) == 0))
934 REG_WRITE_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
935 modesIndex, regWrites);
914 } 936 }
915 937
916 if (AR_SREV_9550(ah)) 938 if (AR_SREV_9550(ah) || AR_SREV_9561(ah))
917 REG_WRITE_ARRAY(&ah->ini_modes_rx_gain_bounds, modesIndex, 939 REG_WRITE_ARRAY(&ah->ini_modes_rx_gain_bounds, modesIndex,
918 regWrites); 940 regWrites);
919 941
920 /* 942 /*
921 * TXGAIN initvals. 943 * TXGAIN initvals.
922 */ 944 */
923 if (AR_SREV_9550(ah) || AR_SREV_9531(ah)) { 945 if (AR_SREV_9550(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
924 int modes_txgain_index = 1; 946 int modes_txgain_index = 1;
925 947
926 if (AR_SREV_9550(ah)) 948 if (AR_SREV_9550(ah))
927 modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan); 949 modes_txgain_index = ar9550_hw_get_modes_txgain_index(ah, chan);
928 950
951 if (AR_SREV_9561(ah))
952 modes_txgain_index =
953 ar9561_hw_get_modes_txgain_index(ah, chan);
954
929 if (modes_txgain_index < 0) 955 if (modes_txgain_index < 0)
930 return -EINVAL; 956 return -EINVAL;
931 957
@@ -1989,7 +2015,8 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1989 priv_ops->rf_set_freq = ar9003_hw_set_channel; 2015 priv_ops->rf_set_freq = ar9003_hw_set_channel;
1990 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; 2016 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
1991 2017
1992 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) 2018 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
2019 AR_SREV_9561(ah))
1993 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control_soc; 2020 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control_soc;
1994 else 2021 else
1995 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; 2022 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index fd090b1f2d0f..c311b2bfdb00 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -454,7 +454,7 @@
454#define AR_PHY_GEN_CTRL (AR_SM_BASE + 0x4) 454#define AR_PHY_GEN_CTRL (AR_SM_BASE + 0x4)
455#define AR_PHY_MODE (AR_SM_BASE + 0x8) 455#define AR_PHY_MODE (AR_SM_BASE + 0x8)
456#define AR_PHY_ACTIVE (AR_SM_BASE + 0xc) 456#define AR_PHY_ACTIVE (AR_SM_BASE + 0xc)
457#define AR_PHY_SPUR_MASK_A (AR_SM_BASE + 0x20) 457#define AR_PHY_SPUR_MASK_A (AR_SM_BASE + (AR_SREV_9561(ah) ? 0x18 : 0x20))
458#define AR_PHY_SPUR_MASK_B (AR_SM_BASE + 0x24) 458#define AR_PHY_SPUR_MASK_B (AR_SM_BASE + 0x24)
459#define AR_PHY_SPECTRAL_SCAN (AR_SM_BASE + 0x28) 459#define AR_PHY_SPECTRAL_SCAN (AR_SM_BASE + 0x28)
460#define AR_PHY_RADAR_BW_FILTER (AR_SM_BASE + 0x2c) 460#define AR_PHY_RADAR_BW_FILTER (AR_SM_BASE + 0x2c)
@@ -506,7 +506,7 @@
506#define AR_PHY_TEST_CHAIN_SEL 0xC0000000 506#define AR_PHY_TEST_CHAIN_SEL 0xC0000000
507#define AR_PHY_TEST_CHAIN_SEL_S 30 507#define AR_PHY_TEST_CHAIN_SEL_S 30
508 508
509#define AR_PHY_TEST_CTL_STATUS (AR_SM_BASE + 0x164) 509#define AR_PHY_TEST_CTL_STATUS (AR_SM_BASE + (AR_SREV_9561(ah) ? 0x160 : 0x164))
510#define AR_PHY_TEST_CTL_TSTDAC_EN 0x1 510#define AR_PHY_TEST_CTL_TSTDAC_EN 0x1
511#define AR_PHY_TEST_CTL_TSTDAC_EN_S 0 511#define AR_PHY_TEST_CTL_TSTDAC_EN_S 0
512#define AR_PHY_TEST_CTL_TX_OBS_SEL 0x1C 512#define AR_PHY_TEST_CTL_TX_OBS_SEL 0x1C
@@ -525,7 +525,7 @@
525 525
526#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) 526#define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c)
527 527
528#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) 528#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + (AR_SREV_9561(ah) ? 0x16c : 0x170))
529#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008 529#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008
530#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3 530#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3
531 531
@@ -536,7 +536,7 @@
536#define AR_PHY_SCRAMBLER_SEED (AR_SM_BASE + 0x190) 536#define AR_PHY_SCRAMBLER_SEED (AR_SM_BASE + 0x190)
537#define AR_PHY_CCK_TX_CTRL (AR_SM_BASE + 0x194) 537#define AR_PHY_CCK_TX_CTRL (AR_SM_BASE + 0x194)
538 538
539#define AR_PHY_HEAVYCLIP_CTL (AR_SM_BASE + 0x1a4) 539#define AR_PHY_HEAVYCLIP_CTL (AR_SM_BASE + (AR_SREV_9561(ah) ? 0x198 : 0x1a4))
540#define AR_PHY_HEAVYCLIP_20 (AR_SM_BASE + 0x1a8) 540#define AR_PHY_HEAVYCLIP_20 (AR_SM_BASE + 0x1a8)
541#define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac) 541#define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac)
542#define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0) 542#define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0)
@@ -726,21 +726,24 @@
726 726
727#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ 727#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
728 (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) 728 (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
729#define AR_CH0_TOP2_XPABIASLVL 0xf000 729#define AR_CH0_TOP2_XPABIASLVL (AR_SREV_9561(ah) ? 0x1e00 : 0xf000)
730#define AR_CH0_TOP2_XPABIASLVL_S 12 730#define AR_CH0_TOP2_XPABIASLVL_S 12
731 731
732#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ 732#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \
733 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : 0x16290)) 733 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : \
734 (AR_SREV_9561(ah) ? 0x162c0 : 0x16290)))
734#define AR_CH0_XTAL_CAPINDAC 0x7f000000 735#define AR_CH0_XTAL_CAPINDAC 0x7f000000
735#define AR_CH0_XTAL_CAPINDAC_S 24 736#define AR_CH0_XTAL_CAPINDAC_S 24
736#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 737#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
737#define AR_CH0_XTAL_CAPOUTDAC_S 17 738#define AR_CH0_XTAL_CAPOUTDAC_S 17
738 739
739#define AR_PHY_PMU1 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16340 : 0x16c40) 740#define AR_PHY_PMU1 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16340 : \
741 (AR_SREV_9561(ah) ? 0x16cc0 : 0x16c40))
740#define AR_PHY_PMU1_PWD 0x1 742#define AR_PHY_PMU1_PWD 0x1
741#define AR_PHY_PMU1_PWD_S 0 743#define AR_PHY_PMU1_PWD_S 0
742 744
743#define AR_PHY_PMU2 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16344 : 0x16c44) 745#define AR_PHY_PMU2 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16344 : \
746 (AR_SREV_9561(ah) ? 0x16cc4 : 0x16c44))
744#define AR_PHY_PMU2_PGM 0x00200000 747#define AR_PHY_PMU2_PGM 0x00200000
745#define AR_PHY_PMU2_PGM_S 21 748#define AR_PHY_PMU2_PGM_S 21
746 749
diff --git a/drivers/net/wireless/ath/ath9k/ar956x_initvals.h b/drivers/net/wireless/ath/ath9k/ar956x_initvals.h
new file mode 100644
index 000000000000..c3a47eaaf0c0
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar956x_initvals.h
@@ -0,0 +1,1046 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
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 INITVALS_956X_H
19#define INITVALS_956X_H
20
21#define qca956x_1p0_mac_core ar955x_1p0_mac_core
22
23#define qca956x_1p0_mac_postamble ar9331_1p1_mac_postamble
24
25#define qca956x_1p0_soc_preamble ar955x_1p0_soc_preamble
26
27#define qca956x_1p0_soc_postamble ar9300_2p2_soc_postamble
28
29#define qca956x_1p0_common_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
30
31#define qca956x_1p0_baseband_postamble_dfs_channel ar9300_2p2_baseband_postamble_dfs_channel
32
33#define qca956x_1p0_common_wo_xlna_rx_gain_bounds ar955x_1p0_common_wo_xlna_rx_gain_bounds
34
35#define qca956x_1p0_common_rx_gain_bounds ar955x_1p0_common_rx_gain_bounds
36
37#define qca956x_1p0_modes_fast_clock ar9462_2p0_modes_fast_clock
38
39static const u32 qca956x_1p0_baseband_core[][2] = {
40 /* Addr allmodes */
41 {0x00009800, 0xafe68e30},
42 {0x00009804, 0xfd14e000},
43 {0x00009808, 0x9c0a9f6b},
44 {0x0000980c, 0x04900000},
45 {0x00009814, 0x0280c00a},
46 {0x00009818, 0x00000000},
47 {0x0000981c, 0x00020028},
48 {0x00009834, 0x6400a190},
49 {0x00009838, 0x0108ecff},
50 {0x0000983c, 0x14000600},
51 {0x00009880, 0x201fff00},
52 {0x00009884, 0x00001042},
53 {0x000098a4, 0x00200400},
54 {0x000098b0, 0x32840cbf},
55 {0x000098bc, 0x00000002},
56 {0x000098d0, 0x004b6a8e},
57 {0x000098d4, 0x00000820},
58 {0x000098dc, 0x00000000},
59 {0x000098f0, 0x00000000},
60 {0x000098f4, 0x00000000},
61 {0x00009c04, 0xff55ff55},
62 {0x00009c08, 0x0320ff55},
63 {0x00009c0c, 0x00000000},
64 {0x00009c10, 0x00000000},
65 {0x00009c14, 0x00046384},
66 {0x00009c18, 0x05b6b440},
67 {0x00009c1c, 0x00b6b440},
68 {0x00009d00, 0xc080a333},
69 {0x00009d04, 0x40206c10},
70 {0x00009d08, 0x009c4060},
71 {0x00009d0c, 0x9883800a},
72 {0x00009d10, 0x01834061},
73 {0x00009d14, 0x00c0040b},
74 {0x00009d18, 0x00000000},
75 {0x00009e08, 0x0038230c},
76 {0x00009e24, 0x990bb514},
77 {0x00009e28, 0x0c6f0000},
78 {0x00009e30, 0x06336f77},
79 {0x00009e34, 0x6af6532f},
80 {0x00009e38, 0x0cc80c00},
81 {0x00009e40, 0x0d261820},
82 {0x00009e4c, 0x00001004},
83 {0x00009e50, 0x00ff03f1},
84 {0x00009fc0, 0x813e4789},
85 {0x00009fc4, 0x0001efb5},
86 {0x00009fcc, 0x40000014},
87 {0x00009fd0, 0x02993b93},
88 {0x0000a20c, 0x00000000},
89 {0x0000a218, 0x00000000},
90 {0x0000a21c, 0x00000000},
91 {0x0000a228, 0x10002310},
92 {0x0000a23c, 0x00000000},
93 {0x0000a244, 0x0c000000},
94 {0x0000a248, 0x00000140},
95 {0x0000a2a0, 0x00000007},
96 {0x0000a2c0, 0x00000007},
97 {0x0000a2c8, 0x00000000},
98 {0x0000a2d4, 0x00000000},
99 {0x0000a2ec, 0x00000000},
100 {0x0000a2f0, 0x00000000},
101 {0x0000a2f4, 0x00000000},
102 {0x0000a2f8, 0x00000000},
103 {0x0000a344, 0x00000000},
104 {0x0000a34c, 0x00000000},
105 {0x0000a350, 0x0000a000},
106 {0x0000a360, 0x00000000},
107 {0x0000a36c, 0x00000000},
108 {0x0000a384, 0x00000001},
109 {0x0000a388, 0x00000444},
110 {0x0000a38c, 0x00000000},
111 {0x0000a390, 0x210d0401},
112 {0x0000a394, 0xab9a7144},
113 {0x0000a398, 0x00000201},
114 {0x0000a39c, 0x42424848},
115 {0x0000a3a0, 0x3c466478},
116 {0x0000a3a4, 0x3a363600},
117 {0x0000a3a8, 0x0000003a},
118 {0x0000a3ac, 0x00000000},
119 {0x0000a3b0, 0x009011fe},
120 {0x0000a3b4, 0x00000034},
121 {0x0000a3b8, 0x00b3ec0a},
122 {0x0000a3bc, 0x00000036},
123 {0x0000a3c0, 0x20202020},
124 {0x0000a3c4, 0x22222220},
125 {0x0000a3c8, 0x20200020},
126 {0x0000a3cc, 0x20202020},
127 {0x0000a3d0, 0x20202020},
128 {0x0000a3d4, 0x20202020},
129 {0x0000a3d8, 0x20202020},
130 {0x0000a3dc, 0x20202020},
131 {0x0000a3e0, 0x20202020},
132 {0x0000a3e4, 0x20202020},
133 {0x0000a3e8, 0x20202020},
134 {0x0000a3ec, 0x20202020},
135 {0x0000a3f0, 0x00000000},
136 {0x0000a3f4, 0x00000000},
137 {0x0000a3f8, 0x0c9bd380},
138 {0x0000a3fc, 0x000f0f01},
139 {0x0000a400, 0x8fa91f01},
140 {0x0000a404, 0x00000000},
141 {0x0000a408, 0x0e79e5c6},
142 {0x0000a40c, 0x00820820},
143 {0x0000a414, 0x1ce739ce},
144 {0x0000a418, 0x2d0019ce},
145 {0x0000a41c, 0x1ce739ce},
146 {0x0000a420, 0x000001ce},
147 {0x0000a424, 0x1ce739ce},
148 {0x0000a428, 0x000001ce},
149 {0x0000a42c, 0x1ce739ce},
150 {0x0000a430, 0x1ce739ce},
151 {0x0000a434, 0x00000000},
152 {0x0000a438, 0x00001801},
153 {0x0000a43c, 0x00100000},
154 {0x0000a444, 0x00000000},
155 {0x0000a448, 0x05000080},
156 {0x0000a44c, 0x00000001},
157 {0x0000a450, 0x00010000},
158 {0x0000a454, 0x05000000},
159 {0x0000a458, 0x00000000},
160 {0x0000a644, 0xbfad9fee},
161 {0x0000a648, 0x0048660d},
162 {0x0000a64c, 0x00003c37},
163 {0x0000a670, 0x03020100},
164 {0x0000a674, 0x21200504},
165 {0x0000a678, 0x61602322},
166 {0x0000a67c, 0x65646362},
167 {0x0000a680, 0x6b6a6968},
168 {0x0000a684, 0xe2706d6c},
169 {0x0000a688, 0x000000e3},
170 {0x0000a690, 0x00000838},
171 {0x0000a7cc, 0x00000000},
172 {0x0000a7d0, 0x00000000},
173 {0x0000a7d4, 0x00000004},
174 {0x0000a7dc, 0x00000000},
175 {0x0000a8d0, 0x004b6a8e},
176 {0x0000a8d4, 0x00000820},
177 {0x0000a8dc, 0x00000000},
178 {0x0000a8f0, 0x00000000},
179 {0x0000a8f4, 0x00000000},
180 {0x0000b2d0, 0x00000080},
181 {0x0000b2d4, 0x00000000},
182 {0x0000b2ec, 0x00000000},
183 {0x0000b2f0, 0x00000000},
184 {0x0000b2f4, 0x00000000},
185 {0x0000b2f8, 0x00000000},
186 {0x0000b408, 0x0e79e5c0},
187 {0x0000b40c, 0x00820820},
188 {0x0000b420, 0x00000000},
189 {0x0000b8d0, 0x004b6a8e},
190 {0x0000b8d4, 0x00000820},
191 {0x0000b8dc, 0x00000000},
192 {0x0000b8f0, 0x00000000},
193 {0x0000b8f4, 0x00000000},
194 {0x0000c2d0, 0x00000080},
195 {0x0000c2d4, 0x00000000},
196 {0x0000c2ec, 0x00000000},
197 {0x0000c2f0, 0x00000000},
198 {0x0000c2f4, 0x00000000},
199 {0x0000c2f8, 0x00000000},
200 {0x0000c408, 0x0e79e5c0},
201 {0x0000c40c, 0x00820820},
202 {0x0000c420, 0x00000000},
203};
204
205static const u32 qca956x_1p0_baseband_postamble[][5] = {
206 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
207 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
208 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
209 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac621f1, 0x5ac621f1},
210 {0x00009828, 0x06903081, 0x06903081, 0x07d43881, 0x07d43881},
211 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
212 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
213 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
214 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
215 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
216 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000de, 0x6c4000de},
217 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
218 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x337d605e, 0x337d5d5e},
219 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
220 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
221 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003a6, 0x000003a6},
222 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
223 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcf946222, 0xcf946222},
224 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
225 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
226 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
227 {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x045c0cc4, 0x045c0cc0},
228 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
229 {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
230 {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
231 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
232 {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
233 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
234 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
235 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
236 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
237 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
238 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
239 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
240 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
241 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
242 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
243 {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18},
244 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
245 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
246 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
247 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
248 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
249 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
250 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
251 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
252 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001a6, 0x000001a6},
253 {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
254 {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
255 {0x0000be04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
256 {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
257 {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
258 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001a6, 0x000001a6},
259 {0x0000c284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
260};
261
262static const u32 qca956x_1p0_radio_core[][2] = {
263 /* Addr allmodes */
264 {0x00016000, 0x36db6db6},
265 {0x00016004, 0x6db6db40},
266 {0x00016008, 0x73f00000},
267 {0x0001600c, 0x00000000},
268 {0x00016040, 0x3f80fff8},
269 {0x0001604c, 0x000f0278},
270 {0x00016050, 0x8036db6c},
271 {0x00016054, 0x6db60000},
272 {0x00016080, 0x00080000},
273 {0x00016084, 0x0e48048c},
274 {0x00016088, 0x14214514},
275 {0x0001608c, 0x119f080a},
276 {0x00016090, 0x24926490},
277 {0x00016094, 0x00000000},
278 {0x000160a0, 0xc2108ffe},
279 {0x000160a4, 0x812fc370},
280 {0x000160a8, 0x423c8000},
281 {0x000160b4, 0x92480000},
282 {0x000160c0, 0x006db6d8},
283 {0x000160c4, 0x24b6db6c},
284 {0x000160c8, 0x6db6db6c},
285 {0x000160cc, 0x6db6fb7c},
286 {0x000160d0, 0x6db6da44},
287 {0x00016100, 0x07ff8001},
288 {0x00016108, 0x00080010},
289 {0x00016144, 0x01884080},
290 {0x00016148, 0x00008058},
291 {0x00016288, 0x001c6000},
292 {0x0001628c, 0x50000000},
293 {0x000162c0, 0x4b962100},
294 {0x000162c4, 0x00000480},
295 {0x000162c8, 0x04000144},
296 {0x00016380, 0x00000000},
297 {0x00016384, 0x00000000},
298 {0x00016388, 0x00800700},
299 {0x0001638c, 0x00800700},
300 {0x00016390, 0x00800700},
301 {0x00016394, 0x00000000},
302 {0x00016398, 0x00000000},
303 {0x0001639c, 0x00000000},
304 {0x000163a0, 0x00000001},
305 {0x000163a4, 0x00000001},
306 {0x000163a8, 0x00000000},
307 {0x000163ac, 0x00000000},
308 {0x000163b0, 0x00000000},
309 {0x000163b4, 0x00000000},
310 {0x000163b8, 0x00000000},
311 {0x000163bc, 0x00000000},
312 {0x000163c0, 0x000000a0},
313 {0x000163c4, 0x000c0000},
314 {0x000163c8, 0x14021402},
315 {0x000163cc, 0x00001402},
316 {0x000163d0, 0x00000000},
317 {0x000163d4, 0x00000000},
318 {0x00016400, 0x36db6db6},
319 {0x00016404, 0x6db6db40},
320 {0x00016408, 0x73f00000},
321 {0x0001640c, 0x00000000},
322 {0x00016440, 0x3f80fff8},
323 {0x0001644c, 0x000f0278},
324 {0x00016450, 0x8036db6c},
325 {0x00016454, 0x6db60000},
326 {0x00016500, 0x07ff8001},
327 {0x00016508, 0x00080010},
328 {0x00016544, 0x01884080},
329 {0x00016548, 0x00008058},
330 {0x00016780, 0x00000000},
331 {0x00016784, 0x00000000},
332 {0x00016788, 0x00800700},
333 {0x0001678c, 0x00800700},
334 {0x00016790, 0x00800700},
335 {0x00016794, 0x00000000},
336 {0x00016798, 0x00000000},
337 {0x0001679c, 0x00000000},
338 {0x000167a0, 0x00000001},
339 {0x000167a4, 0x00000001},
340 {0x000167a8, 0x00000000},
341 {0x000167ac, 0x00000000},
342 {0x000167b0, 0x00000000},
343 {0x000167b4, 0x00000000},
344 {0x000167b8, 0x00000000},
345 {0x000167bc, 0x00000000},
346 {0x000167c0, 0x000000a0},
347 {0x000167c4, 0x000c0000},
348 {0x000167c8, 0x14021402},
349 {0x000167cc, 0x00001402},
350 {0x000167d0, 0x00000000},
351 {0x000167d4, 0x00000000},
352 {0x00016800, 0x36db6db6},
353 {0x00016804, 0x6db6db40},
354 {0x00016808, 0x73f00000},
355 {0x0001680c, 0x00000000},
356 {0x00016840, 0x3f80fff8},
357 {0x0001684c, 0x000f0278},
358 {0x00016850, 0x8036db6c},
359 {0x00016854, 0x6db60000},
360 {0x00016900, 0x07ff8001},
361 {0x00016908, 0x00080010},
362 {0x00016944, 0x01884080},
363 {0x00016948, 0x00008058},
364 {0x00016b80, 0x00000000},
365 {0x00016b84, 0x00000000},
366 {0x00016b88, 0x00800700},
367 {0x00016b8c, 0x00800700},
368 {0x00016b90, 0x00800700},
369 {0x00016b94, 0x00000000},
370 {0x00016b98, 0x00000000},
371 {0x00016b9c, 0x00000000},
372 {0x00016ba0, 0x00000001},
373 {0x00016ba4, 0x00000001},
374 {0x00016ba8, 0x00000000},
375 {0x00016bac, 0x00000000},
376 {0x00016bb0, 0x00000000},
377 {0x00016bb4, 0x00000000},
378 {0x00016bb8, 0x00000000},
379 {0x00016bbc, 0x00000000},
380 {0x00016bc0, 0x000000a0},
381 {0x00016bc4, 0x000c0000},
382 {0x00016bc8, 0x14021402},
383 {0x00016bcc, 0x00001402},
384 {0x00016bd0, 0x00000000},
385 {0x00016bd4, 0x00000000},
386};
387
388static const u32 qca956x_1p0_radio_postamble[][5] = {
389 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
390 {0x00016098, 0xd2dd5554, 0xd2dd5554, 0xc4128f5c, 0xc4128f5c},
391 {0x0001609c, 0x0a566f3a, 0x0a566f3a, 0x0fd08f25, 0x0fd08f25},
392 {0x000160ac, 0xa4647c00, 0xa4647c00, 0x24646800, 0x24646800},
393 {0x000160b0, 0x01885f52, 0x01885f52, 0x00fe7f46, 0x00fe7f46},
394 {0x00016104, 0xb7a00000, 0xb7a00000, 0xfff80001, 0xfff80001},
395 {0x0001610c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000},
396 {0x00016140, 0x10804008, 0x10804008, 0x50804000, 0x50804000},
397 {0x00016504, 0xb7a00000, 0xb7a00000, 0xfff80001, 0xfff80001},
398 {0x0001650c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000},
399 {0x00016540, 0x10804008, 0x10804008, 0x50804000, 0x50804000},
400 {0x00016904, 0xb7a00000, 0xb7a00000, 0xfff80001, 0xfff80001},
401 {0x0001690c, 0xc0000000, 0xc0000000, 0x00000000, 0x00000000},
402 {0x00016940, 0x10804008, 0x10804008, 0x50804000, 0x50804000},
403};
404
405static const u32 qca956x_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
406 /* Addr allmodes */
407 {0x0000a38c, 0x00000000},
408 {0x0000a390, 0x6f7f0301},
409 {0x0000a394, 0xca9228ee},
410};
411
412static const u32 qca956x_1p0_modes_no_xpa_tx_gain_table[][3] = {
413 /* Addr 5G 2G */
414 {0x0000a2dc, 0xffa9ac94, 0xffa9ac94},
415 {0x0000a2e0, 0xff323118, 0xff323118},
416 {0x0000a2e4, 0xff3ffe00, 0xff3ffe00},
417 {0x0000a2e8, 0xffc00000, 0xffc00000},
418 {0x0000a39c, 0x42424242, 0x42424242},
419 {0x0000a3a4, 0x3a3e3e00, 0x3a3e3e00},
420 {0x0000a3b0, 0x00a01404, 0x00a01404},
421 {0x0000a3b4, 0x00000034, 0x00000034},
422 {0x0000a3b8, 0x00800408, 0x00800408},
423 {0x0000a3bc, 0x00000036, 0x00000036},
424 {0x0000a410, 0x000050dc, 0x000050dc},
425 {0x0000a500, 0x09000040, 0x09000040},
426 {0x0000a504, 0x0b000041, 0x0b000041},
427 {0x0000a508, 0x0d000042, 0x0d000042},
428 {0x0000a50c, 0x11000044, 0x11000044},
429 {0x0000a510, 0x15000046, 0x15000046},
430 {0x0000a514, 0x1d000440, 0x1d000440},
431 {0x0000a518, 0x1f000441, 0x1f000441},
432 {0x0000a51c, 0x23000443, 0x23000443},
433 {0x0000a520, 0x25000444, 0x25000444},
434 {0x0000a524, 0x280004e0, 0x280004e0},
435 {0x0000a528, 0x2c0004e2, 0x2c0004e2},
436 {0x0000a52c, 0x2e0004e3, 0x2e0004e3},
437 {0x0000a530, 0x300004e4, 0x300004e4},
438 {0x0000a534, 0x340004e6, 0x340004e6},
439 {0x0000a538, 0x37000ce0, 0x37000ce0},
440 {0x0000a53c, 0x3b000ce2, 0x3b000ce2},
441 {0x0000a540, 0x3d000ce3, 0x3d000ce3},
442 {0x0000a544, 0x3f000ce4, 0x3f000ce4},
443 {0x0000a548, 0x45001ee0, 0x45001ee0},
444 {0x0000a54c, 0x49001ee2, 0x49001ee2},
445 {0x0000a550, 0x4d001ee4, 0x4d001ee4},
446 {0x0000a554, 0x51001ee6, 0x51001ee6},
447 {0x0000a558, 0x55001eea, 0x55001eea},
448 {0x0000a55c, 0x59001eec, 0x59001eec},
449 {0x0000a560, 0x5d001ef0, 0x5d001ef0},
450 {0x0000a564, 0x5f001ef1, 0x5f001ef1},
451 {0x0000a568, 0x60001ef2, 0x60001ef2},
452 {0x0000a56c, 0x61001ef3, 0x61001ef3},
453 {0x0000a570, 0x62001ef4, 0x62001ef4},
454 {0x0000a574, 0x63001ef5, 0x63001ef5},
455 {0x0000a578, 0x64001ffc, 0x64001ffc},
456 {0x0000a57c, 0x64001ffc, 0x64001ffc},
457 {0x0000a600, 0x00000000, 0x00000000},
458 {0x0000a604, 0x00000000, 0x00000000},
459 {0x0000a608, 0x00000000, 0x00000000},
460 {0x0000a60c, 0x00000000, 0x00000000},
461 {0x0000a610, 0x00804000, 0x00804000},
462 {0x0000a614, 0x00804201, 0x00804201},
463 {0x0000a618, 0x00804201, 0x00804201},
464 {0x0000a61c, 0x00804201, 0x00804201},
465 {0x0000a620, 0x00804201, 0x00804201},
466 {0x0000a624, 0x00804201, 0x00804201},
467 {0x0000a628, 0x00804201, 0x00804201},
468 {0x0000a62c, 0x02808a02, 0x02808a02},
469 {0x0000a630, 0x0340cd03, 0x0340cd03},
470 {0x0000a634, 0x0340cd03, 0x0340cd03},
471 {0x0000a638, 0x0340cd03, 0x0340cd03},
472 {0x0000a63c, 0x05011404, 0x05011404},
473 {0x0000b2dc, 0xffa9ac94, 0xffa9ac94},
474 {0x0000b2e0, 0xff323118, 0xff323118},
475 {0x0000b2e4, 0xff3ffe00, 0xff3ffe00},
476 {0x0000b2e8, 0xffc00000, 0xffc00000},
477 {0x0000c2dc, 0xffa9ac94, 0xffa9ac94},
478 {0x0000c2e0, 0xff323118, 0xff323118},
479 {0x0000c2e4, 0xff3ffe00, 0xff3ffe00},
480 {0x0000c2e8, 0xffc00000, 0xffc00000},
481 {0x00016044, 0x049242db, 0x049242db},
482 {0x00016048, 0x64925a70, 0x64925a70},
483 {0x00016148, 0x00008050, 0x00008050},
484 {0x00016280, 0x41110005, 0x41110005},
485 {0x00016284, 0x453a6000, 0x453a6000},
486 {0x00016444, 0x049242db, 0x049242db},
487 {0x00016448, 0x6c925a70, 0x6c925a70},
488 {0x00016548, 0x00008050, 0x00008050},
489 {0x00016844, 0x049242db, 0x049242db},
490 {0x00016848, 0x6c925a70, 0x6c925a70},
491 {0x00016948, 0x00008050, 0x00008050},
492};
493
494static const u32 qca956x_1p0_modes_xpa_tx_gain_table[][3] = {
495 /* Addr 5G 2G */
496 {0x0000a2dc, 0xcc69ac94, 0xcc69ac94},
497 {0x0000a2e0, 0xf0b23118, 0xf0b23118},
498 {0x0000a2e4, 0xffffc000, 0xffffc000},
499 {0x0000a2e8, 0xc0000000, 0xc0000000},
500 {0x0000a410, 0x000050d2, 0x000050d2},
501 {0x0000a500, 0x0a000040, 0x0a000040},
502 {0x0000a504, 0x0c000041, 0x0c000041},
503 {0x0000a508, 0x0e000042, 0x0e000042},
504 {0x0000a50c, 0x12000044, 0x12000044},
505 {0x0000a510, 0x16000046, 0x16000046},
506 {0x0000a514, 0x1d000440, 0x1d000440},
507 {0x0000a518, 0x1f000441, 0x1f000441},
508 {0x0000a51c, 0x23000443, 0x23000443},
509 {0x0000a520, 0x25000444, 0x25000444},
510 {0x0000a524, 0x29000a40, 0x29000a40},
511 {0x0000a528, 0x2d000a42, 0x2d000a42},
512 {0x0000a52c, 0x2f000a43, 0x2f000a43},
513 {0x0000a530, 0x31000a44, 0x31000a44},
514 {0x0000a534, 0x35000a46, 0x35000a46},
515 {0x0000a538, 0x38000ce0, 0x38000ce0},
516 {0x0000a53c, 0x3c000ce2, 0x3c000ce2},
517 {0x0000a540, 0x3e000ce3, 0x3e000ce3},
518 {0x0000a544, 0x40000ce4, 0x40000ce4},
519 {0x0000a548, 0x46001ee0, 0x46001ee0},
520 {0x0000a54c, 0x4a001ee2, 0x4a001ee2},
521 {0x0000a550, 0x4e001ee4, 0x4e001ee4},
522 {0x0000a554, 0x52001ee6, 0x52001ee6},
523 {0x0000a558, 0x56001eea, 0x56001eea},
524 {0x0000a55c, 0x5a001eec, 0x5a001eec},
525 {0x0000a560, 0x5e001ef0, 0x5e001ef0},
526 {0x0000a564, 0x60001ef1, 0x60001ef1},
527 {0x0000a568, 0x61001ef2, 0x61001ef2},
528 {0x0000a56c, 0x62001ef3, 0x62001ef3},
529 {0x0000a570, 0x63001ef4, 0x63001ef4},
530 {0x0000a574, 0x64001ef5, 0x64001ef5},
531 {0x0000a578, 0x65001ffc, 0x65001ffc},
532 {0x0000a57c, 0x65001ffc, 0x65001ffc},
533 {0x0000a600, 0x00000000, 0x00000000},
534 {0x0000a604, 0x00000000, 0x00000000},
535 {0x0000a608, 0x00000000, 0x00000000},
536 {0x0000a60c, 0x00000000, 0x00000000},
537 {0x0000a610, 0x00000000, 0x00000000},
538 {0x0000a614, 0x00000000, 0x00000000},
539 {0x0000a618, 0x00000000, 0x00000000},
540 {0x0000a61c, 0x00804201, 0x00804201},
541 {0x0000a620, 0x00804201, 0x00804201},
542 {0x0000a624, 0x00804201, 0x00804201},
543 {0x0000a628, 0x00804201, 0x00804201},
544 {0x0000a62c, 0x02808a02, 0x02808a02},
545 {0x0000a630, 0x0340cd03, 0x0340cd03},
546 {0x0000a634, 0x0340cd03, 0x0340cd03},
547 {0x0000a638, 0x0340cd03, 0x0340cd03},
548 {0x0000a63c, 0x05011404, 0x05011404},
549 {0x0000b2dc, 0xcc69ac94, 0xcc69ac94},
550 {0x0000b2e0, 0xf0b23118, 0xf0b23118},
551 {0x0000b2e4, 0xffffc000, 0xffffc000},
552 {0x0000b2e8, 0xc0000000, 0xc0000000},
553 {0x0000c2dc, 0xcc69ac94, 0xcc69ac94},
554 {0x0000c2e0, 0xf0b23118, 0xf0b23118},
555 {0x0000c2e4, 0xffffc000, 0xffffc000},
556 {0x0000c2e8, 0xc0000000, 0xc0000000},
557 {0x00016044, 0x012492db, 0x012492db},
558 {0x00016048, 0x6c927a70, 0x6c927a70},
559 {0x00016050, 0x8036d36c, 0x8036d36c},
560 {0x00016280, 0x41110005, 0x41110005},
561 {0x00016284, 0x453a7e00, 0x453a7e00},
562 {0x00016444, 0x012492db, 0x012492db},
563 {0x00016448, 0x6c927a70, 0x6c927a70},
564 {0x00016450, 0x8036d36c, 0x8036d36c},
565 {0x00016844, 0x012492db, 0x012492db},
566 {0x00016848, 0x6c927a70, 0x6c927a70},
567 {0x00016850, 0x8036d36c, 0x8036d36c},
568};
569
570static const u32 qca956x_1p0_modes_no_xpa_low_ob_db_tx_gain_table[][3] = {
571 /* Addr 5G 2G */
572 {0x0000a2dc, 0xffa9ac94, 0xffa9ac94},
573 {0x0000a2e0, 0xff323118, 0xff323118},
574 {0x0000a2e4, 0xff3ffe00, 0xff3ffe00},
575 {0x0000a2e8, 0xffc00000, 0xffc00000},
576 {0x0000a39c, 0x42424242, 0x42424242},
577 {0x0000a3a4, 0x3a3e3e00, 0x3a3e3e00},
578 {0x0000a3b0, 0x00a01404, 0x00a01404},
579 {0x0000a3b4, 0x00000034, 0x00000034},
580 {0x0000a3b8, 0x00800408, 0x00800408},
581 {0x0000a3bc, 0x00000036, 0x00000036},
582 {0x0000a410, 0x000050dc, 0x000050dc},
583 {0x0000a414, 0x16b739ce, 0x16b739ce},
584 {0x0000a418, 0x2d00198b, 0x2d00198b},
585 {0x0000a41c, 0x16b5adce, 0x16b5adce},
586 {0x0000a420, 0x0000014a, 0x0000014a},
587 {0x0000a424, 0x14a525cc, 0x14a525cc},
588 {0x0000a428, 0x0000012a, 0x0000012a},
589 {0x0000a42c, 0x14a5294a, 0x14a5294a},
590 {0x0000a430, 0x1294a929, 0x1294a929},
591 {0x0000a500, 0x09000040, 0x09000040},
592 {0x0000a504, 0x0b000041, 0x0b000041},
593 {0x0000a508, 0x0d000042, 0x0d000042},
594 {0x0000a50c, 0x11000044, 0x11000044},
595 {0x0000a510, 0x15000046, 0x15000046},
596 {0x0000a514, 0x1d000440, 0x1d000440},
597 {0x0000a518, 0x1f000441, 0x1f000441},
598 {0x0000a51c, 0x23000443, 0x23000443},
599 {0x0000a520, 0x25000444, 0x25000444},
600 {0x0000a524, 0x280004e0, 0x280004e0},
601 {0x0000a528, 0x2c0004e2, 0x2c0004e2},
602 {0x0000a52c, 0x2e0004e3, 0x2e0004e3},
603 {0x0000a530, 0x300004e4, 0x300004e4},
604 {0x0000a534, 0x340004e6, 0x340004e6},
605 {0x0000a538, 0x37000ce0, 0x37000ce0},
606 {0x0000a53c, 0x3b000ce2, 0x3b000ce2},
607 {0x0000a540, 0x3d000ce3, 0x3d000ce3},
608 {0x0000a544, 0x3f000ce4, 0x3f000ce4},
609 {0x0000a548, 0x45001ee0, 0x45001ee0},
610 {0x0000a54c, 0x49001ee2, 0x49001ee2},
611 {0x0000a550, 0x4d001ee4, 0x4d001ee4},
612 {0x0000a554, 0x51001ee6, 0x51001ee6},
613 {0x0000a558, 0x55001eea, 0x55001eea},
614 {0x0000a55c, 0x59001eec, 0x59001eec},
615 {0x0000a560, 0x5d001ef0, 0x5d001ef0},
616 {0x0000a564, 0x5f001ef1, 0x5f001ef1},
617 {0x0000a568, 0x60001ef2, 0x60001ef2},
618 {0x0000a56c, 0x61001ef3, 0x61001ef3},
619 {0x0000a570, 0x62001ef4, 0x62001ef4},
620 {0x0000a574, 0x63001ef5, 0x63001ef5},
621 {0x0000a578, 0x64001ffc, 0x64001ffc},
622 {0x0000a57c, 0x64001ffc, 0x64001ffc},
623 {0x0000a600, 0x00000000, 0x00000000},
624 {0x0000a604, 0x00000000, 0x00000000},
625 {0x0000a608, 0x00000000, 0x00000000},
626 {0x0000a60c, 0x00000000, 0x00000000},
627 {0x0000a610, 0x00804000, 0x00804000},
628 {0x0000a614, 0x00804201, 0x00804201},
629 {0x0000a618, 0x00804201, 0x00804201},
630 {0x0000a61c, 0x00804201, 0x00804201},
631 {0x0000a620, 0x00804201, 0x00804201},
632 {0x0000a624, 0x00804201, 0x00804201},
633 {0x0000a628, 0x00804201, 0x00804201},
634 {0x0000a62c, 0x02808a02, 0x02808a02},
635 {0x0000a630, 0x0340cd03, 0x0340cd03},
636 {0x0000a634, 0x0340cd03, 0x0340cd03},
637 {0x0000a638, 0x0340cd03, 0x0340cd03},
638 {0x0000a63c, 0x05011404, 0x05011404},
639 {0x0000b2dc, 0xffa9ac94, 0xffa9ac94},
640 {0x0000b2e0, 0xff323118, 0xff323118},
641 {0x0000b2e4, 0xff3ffe00, 0xff3ffe00},
642 {0x0000b2e8, 0xffc00000, 0xffc00000},
643 {0x0000c2dc, 0xffa9ac94, 0xffa9ac94},
644 {0x0000c2e0, 0xff323118, 0xff323118},
645 {0x0000c2e4, 0xff3ffe00, 0xff3ffe00},
646 {0x0000c2e8, 0xffc00000, 0xffc00000},
647 {0x00016044, 0x046e42db, 0x046e42db},
648 {0x00016048, 0x64925a70, 0x64925a70},
649 {0x00016148, 0x00008050, 0x00008050},
650 {0x00016280, 0x41110005, 0x41110005},
651 {0x00016284, 0x453a6000, 0x453a6000},
652 {0x00016444, 0x046e42db, 0x046e42db},
653 {0x00016448, 0x6c925a70, 0x6c925a70},
654 {0x00016548, 0x00008050, 0x00008050},
655 {0x00016844, 0x046e42db, 0x046e42db},
656 {0x00016848, 0x6c925a70, 0x6c925a70},
657 {0x00016948, 0x00008050, 0x00008050},
658};
659
660static const u32 qca956x_1p0_modes_no_xpa_green_tx_gain_table[][3] = {
661 /* Addr 5G 2G */
662 {0x000098bc, 0x00000001, 0x00000001},
663 {0x0000a2dc, 0xd3555284, 0xd3555284},
664 {0x0000a2e0, 0x1c666318, 0x1c666318},
665 {0x0000a2e4, 0xe07bbc00, 0xe07bbc00},
666 {0x0000a2e8, 0xff800000, 0xff800000},
667 {0x0000a3a4, 0x3a3e3e00, 0x3a3e3e00},
668 {0x0000a410, 0x000050dc, 0x000050dc},
669 {0x0000a500, 0x02000040, 0x02000040},
670 {0x0000a504, 0x04000041, 0x04000041},
671 {0x0000a508, 0x06000042, 0x06000042},
672 {0x0000a50c, 0x0a000044, 0x0a000044},
673 {0x0000a510, 0x0c000045, 0x0c000045},
674 {0x0000a514, 0x13000440, 0x13000440},
675 {0x0000a518, 0x15000441, 0x15000441},
676 {0x0000a51c, 0x19000443, 0x19000443},
677 {0x0000a520, 0x1b000444, 0x1b000444},
678 {0x0000a524, 0x1e0004e0, 0x1e0004e0},
679 {0x0000a528, 0x220004e2, 0x220004e2},
680 {0x0000a52c, 0x240004e3, 0x240004e3},
681 {0x0000a530, 0x260004e4, 0x260004e4},
682 {0x0000a534, 0x2a0004e6, 0x2a0004e6},
683 {0x0000a538, 0x32000ce0, 0x32000ce0},
684 {0x0000a53c, 0x36000ce2, 0x36000ce2},
685 {0x0000a540, 0x3a000ce4, 0x3a000ce4},
686 {0x0000a544, 0x3e000ce6, 0x3e000ce6},
687 {0x0000a548, 0x45001ee0, 0x45001ee0},
688 {0x0000a54c, 0x49001ee2, 0x49001ee2},
689 {0x0000a550, 0x4d001ee4, 0x4d001ee4},
690 {0x0000a554, 0x51001ee6, 0x51001ee6},
691 {0x0000a558, 0x55001eea, 0x55001eea},
692 {0x0000a55c, 0x59001eec, 0x59001eec},
693 {0x0000a560, 0x5d001ef0, 0x5d001ef0},
694 {0x0000a564, 0x5f001ef1, 0x5f001ef1},
695 {0x0000a568, 0x60001ef2, 0x60001ef2},
696 {0x0000a56c, 0x61001ef3, 0x61001ef3},
697 {0x0000a570, 0x62001ef4, 0x62001ef4},
698 {0x0000a574, 0x63001ff5, 0x63001ff5},
699 {0x0000a578, 0x64001ffc, 0x64001ffc},
700 {0x0000a57c, 0x64001ffc, 0x64001ffc},
701 {0x0000a600, 0x00000000, 0x00000000},
702 {0x0000a604, 0x00000000, 0x00000000},
703 {0x0000a608, 0x00000000, 0x00000000},
704 {0x0000a60c, 0x00000000, 0x00000000},
705 {0x0000a610, 0x00804000, 0x00804000},
706 {0x0000a614, 0x00804201, 0x00804201},
707 {0x0000a618, 0x00804201, 0x00804201},
708 {0x0000a61c, 0x00804201, 0x00804201},
709 {0x0000a620, 0x00804201, 0x00804201},
710 {0x0000a624, 0x00804201, 0x00804201},
711 {0x0000a628, 0x00804201, 0x00804201},
712 {0x0000a62c, 0x02808a02, 0x02808a02},
713 {0x0000a630, 0x0340cd03, 0x0340cd03},
714 {0x0000a634, 0x0340cd03, 0x0340cd03},
715 {0x0000a638, 0x0340cd03, 0x0340cd03},
716 {0x0000a63c, 0x05011404, 0x05011404},
717 {0x0000b2dc, 0xd3555284, 0xd3555284},
718 {0x0000b2e0, 0x1c666318, 0x1c666318},
719 {0x0000b2e4, 0xe07bbc00, 0xe07bbc00},
720 {0x0000b2e8, 0xff800000, 0xff800000},
721 {0x0000c2dc, 0xd3555284, 0xd3555284},
722 {0x0000c2e0, 0x1c666318, 0x1c666318},
723 {0x0000c2e4, 0xe07bbc00, 0xe07bbc00},
724 {0x0000c2e8, 0xff800000, 0xff800000},
725 {0x00016044, 0x849242db, 0x849242db},
726 {0x00016048, 0x64925a70, 0x64925a70},
727 {0x00016280, 0x41110005, 0x41110005},
728 {0x00016284, 0x453a6000, 0x453a6000},
729 {0x00016444, 0x849242db, 0x849242db},
730 {0x00016448, 0x6c925a70, 0x6c925a70},
731 {0x00016844, 0x849242db, 0x849242db},
732 {0x00016848, 0x6c925a70, 0x6c925a70},
733 {0x0000a7f0, 0x800002cc, 0x800002cc},
734 {0x0000a7f4, 0x00000018, 0x00000018},
735 {0x0000a7f4, 0x00000018, 0x00000018},
736 {0x0000a7f4, 0x00000018, 0x00000018},
737 {0x0000a7f4, 0x00000018, 0x00000018},
738 {0x0000a7f4, 0x00000018, 0x00000018},
739 {0x0000a7f4, 0x00000018, 0x00000018},
740 {0x0000a7f4, 0x00000018, 0x00000018},
741 {0x0000a7f4, 0x00000018, 0x00000018},
742 {0x0000a7f4, 0x00000018, 0x00000018},
743 {0x0000a7f4, 0x00000018, 0x00000018},
744 {0x0000a7f4, 0x00000018, 0x00000018},
745 {0x0000a7f4, 0x00000018, 0x00000018},
746 {0x0000a7f4, 0x00000018, 0x00000018},
747 {0x0000a7f4, 0x00000018, 0x00000018},
748 {0x0000a7f4, 0x00000028, 0x00000028},
749 {0x0000a7f4, 0x00000028, 0x00000028},
750 {0x0000a7f4, 0x00000028, 0x00000028},
751 {0x0000a7f4, 0x00000028, 0x00000028},
752 {0x0000a7f4, 0x00000048, 0x00000048},
753 {0x0000a7f4, 0x00000048, 0x00000048},
754 {0x0000a7f4, 0x00000048, 0x00000048},
755 {0x0000a7f4, 0x00000048, 0x00000048},
756 {0x0000a7f4, 0x00000048, 0x00000048},
757 {0x0000a7f4, 0x00000048, 0x00000048},
758 {0x0000a7f4, 0x00000048, 0x00000048},
759 {0x0000a7f4, 0x00000048, 0x00000048},
760 {0x0000a7f4, 0x00000048, 0x00000048},
761 {0x0000a7f4, 0x00000048, 0x00000048},
762 {0x0000a7f4, 0x00000048, 0x00000048},
763 {0x0000a7f4, 0x00000048, 0x00000048},
764 {0x0000a7f4, 0x00000048, 0x00000048},
765 {0x0000a7f4, 0x00000048, 0x00000048},
766};
767
768static const u32 qca956x_1p0_common_rx_gain_table[][2] = {
769 /* Addr allmodes */
770 {0x0000a000, 0x00010000},
771 {0x0000a004, 0x00030002},
772 {0x0000a008, 0x00050004},
773 {0x0000a00c, 0x00810080},
774 {0x0000a010, 0x00830082},
775 {0x0000a014, 0x01810180},
776 {0x0000a018, 0x01830182},
777 {0x0000a01c, 0x01850184},
778 {0x0000a020, 0x01890188},
779 {0x0000a024, 0x018b018a},
780 {0x0000a028, 0x018d018c},
781 {0x0000a02c, 0x01910190},
782 {0x0000a030, 0x01930192},
783 {0x0000a034, 0x01950194},
784 {0x0000a038, 0x038a0196},
785 {0x0000a03c, 0x038c038b},
786 {0x0000a040, 0x0390038d},
787 {0x0000a044, 0x03920391},
788 {0x0000a048, 0x03940393},
789 {0x0000a04c, 0x03960395},
790 {0x0000a050, 0x00000000},
791 {0x0000a054, 0x00000000},
792 {0x0000a058, 0x00000000},
793 {0x0000a05c, 0x00000000},
794 {0x0000a060, 0x00000000},
795 {0x0000a064, 0x00000000},
796 {0x0000a068, 0x00000000},
797 {0x0000a06c, 0x00000000},
798 {0x0000a070, 0x00000000},
799 {0x0000a074, 0x00000000},
800 {0x0000a078, 0x00000000},
801 {0x0000a07c, 0x00000000},
802 {0x0000a080, 0x22222222},
803 {0x0000a084, 0x1d1d1d1d},
804 {0x0000a088, 0x1d1d1d1d},
805 {0x0000a08c, 0x1d1d1d1d},
806 {0x0000a090, 0x17171717},
807 {0x0000a094, 0x11111717},
808 {0x0000a098, 0x00030311},
809 {0x0000a09c, 0x00000000},
810 {0x0000a0a0, 0x00000000},
811 {0x0000a0a4, 0x00000000},
812 {0x0000a0a8, 0x00000000},
813 {0x0000a0ac, 0x00000000},
814 {0x0000a0b0, 0x00000000},
815 {0x0000a0b4, 0x00000000},
816 {0x0000a0b8, 0x00000000},
817 {0x0000a0bc, 0x00000000},
818 {0x0000a0c0, 0x001f0000},
819 {0x0000a0c4, 0x01000101},
820 {0x0000a0c8, 0x011e011f},
821 {0x0000a0cc, 0x011c011d},
822 {0x0000a0d0, 0x02030204},
823 {0x0000a0d4, 0x02010202},
824 {0x0000a0d8, 0x021f0200},
825 {0x0000a0dc, 0x0302021e},
826 {0x0000a0e0, 0x03000301},
827 {0x0000a0e4, 0x031e031f},
828 {0x0000a0e8, 0x0402031d},
829 {0x0000a0ec, 0x04000401},
830 {0x0000a0f0, 0x041e041f},
831 {0x0000a0f4, 0x0502041d},
832 {0x0000a0f8, 0x05000501},
833 {0x0000a0fc, 0x051e051f},
834 {0x0000a100, 0x06010602},
835 {0x0000a104, 0x061f0600},
836 {0x0000a108, 0x061d061e},
837 {0x0000a10c, 0x07020703},
838 {0x0000a110, 0x07000701},
839 {0x0000a114, 0x00000000},
840 {0x0000a118, 0x00000000},
841 {0x0000a11c, 0x00000000},
842 {0x0000a120, 0x00000000},
843 {0x0000a124, 0x00000000},
844 {0x0000a128, 0x00000000},
845 {0x0000a12c, 0x00000000},
846 {0x0000a130, 0x00000000},
847 {0x0000a134, 0x00000000},
848 {0x0000a138, 0x00000000},
849 {0x0000a13c, 0x00000000},
850 {0x0000a140, 0x001f0000},
851 {0x0000a144, 0x01000101},
852 {0x0000a148, 0x011e011f},
853 {0x0000a14c, 0x011c011d},
854 {0x0000a150, 0x02030204},
855 {0x0000a154, 0x02010202},
856 {0x0000a158, 0x021f0200},
857 {0x0000a15c, 0x0302021e},
858 {0x0000a160, 0x03000301},
859 {0x0000a164, 0x031e031f},
860 {0x0000a168, 0x0402031d},
861 {0x0000a16c, 0x04000401},
862 {0x0000a170, 0x041e041f},
863 {0x0000a174, 0x0502041d},
864 {0x0000a178, 0x05000501},
865 {0x0000a17c, 0x051e051f},
866 {0x0000a180, 0x06010602},
867 {0x0000a184, 0x061f0600},
868 {0x0000a188, 0x061d061e},
869 {0x0000a18c, 0x07020703},
870 {0x0000a190, 0x07000701},
871 {0x0000a194, 0x00000000},
872 {0x0000a198, 0x00000000},
873 {0x0000a19c, 0x00000000},
874 {0x0000a1a0, 0x00000000},
875 {0x0000a1a4, 0x00000000},
876 {0x0000a1a8, 0x00000000},
877 {0x0000a1ac, 0x00000000},
878 {0x0000a1b0, 0x00000000},
879 {0x0000a1b4, 0x00000000},
880 {0x0000a1b8, 0x00000000},
881 {0x0000a1bc, 0x00000000},
882 {0x0000a1c0, 0x00000000},
883 {0x0000a1c4, 0x00000000},
884 {0x0000a1c8, 0x00000000},
885 {0x0000a1cc, 0x00000000},
886 {0x0000a1d0, 0x00000000},
887 {0x0000a1d4, 0x00000000},
888 {0x0000a1d8, 0x00000000},
889 {0x0000a1dc, 0x00000000},
890 {0x0000a1e0, 0x00000000},
891 {0x0000a1e4, 0x00000000},
892 {0x0000a1e8, 0x00000000},
893 {0x0000a1ec, 0x00000000},
894 {0x0000a1f0, 0x00000396},
895 {0x0000a1f4, 0x00000396},
896 {0x0000a1f8, 0x00000396},
897 {0x0000a1fc, 0x00000196},
898 {0x0000b000, 0x00010000},
899 {0x0000b004, 0x00030002},
900 {0x0000b008, 0x00050004},
901 {0x0000b00c, 0x00810080},
902 {0x0000b010, 0x00830082},
903 {0x0000b014, 0x01810180},
904 {0x0000b018, 0x01830182},
905 {0x0000b01c, 0x01850184},
906 {0x0000b020, 0x02810280},
907 {0x0000b024, 0x02830282},
908 {0x0000b028, 0x02850284},
909 {0x0000b02c, 0x02890288},
910 {0x0000b030, 0x028b028a},
911 {0x0000b034, 0x0388028c},
912 {0x0000b038, 0x038a0389},
913 {0x0000b03c, 0x038c038b},
914 {0x0000b040, 0x0390038d},
915 {0x0000b044, 0x03920391},
916 {0x0000b048, 0x03940393},
917 {0x0000b04c, 0x03960395},
918 {0x0000b050, 0x00000000},
919 {0x0000b054, 0x00000000},
920 {0x0000b058, 0x00000000},
921 {0x0000b05c, 0x00000000},
922 {0x0000b060, 0x00000000},
923 {0x0000b064, 0x00000000},
924 {0x0000b068, 0x00000000},
925 {0x0000b06c, 0x00000000},
926 {0x0000b070, 0x00000000},
927 {0x0000b074, 0x00000000},
928 {0x0000b078, 0x00000000},
929 {0x0000b07c, 0x00000000},
930 {0x0000b080, 0x23232323},
931 {0x0000b084, 0x21232323},
932 {0x0000b088, 0x19191c1e},
933 {0x0000b08c, 0x12141417},
934 {0x0000b090, 0x07070e0e},
935 {0x0000b094, 0x03030305},
936 {0x0000b098, 0x00000003},
937 {0x0000b09c, 0x00000000},
938 {0x0000b0a0, 0x00000000},
939 {0x0000b0a4, 0x00000000},
940 {0x0000b0a8, 0x00000000},
941 {0x0000b0ac, 0x00000000},
942 {0x0000b0b0, 0x00000000},
943 {0x0000b0b4, 0x00000000},
944 {0x0000b0b8, 0x00000000},
945 {0x0000b0bc, 0x00000000},
946 {0x0000b0c0, 0x003f0020},
947 {0x0000b0c4, 0x00400041},
948 {0x0000b0c8, 0x0140005f},
949 {0x0000b0cc, 0x0160015f},
950 {0x0000b0d0, 0x017e017f},
951 {0x0000b0d4, 0x02410242},
952 {0x0000b0d8, 0x025f0240},
953 {0x0000b0dc, 0x027f0260},
954 {0x0000b0e0, 0x0341027e},
955 {0x0000b0e4, 0x035f0340},
956 {0x0000b0e8, 0x037f0360},
957 {0x0000b0ec, 0x04400441},
958 {0x0000b0f0, 0x0460045f},
959 {0x0000b0f4, 0x0541047f},
960 {0x0000b0f8, 0x055f0540},
961 {0x0000b0fc, 0x057f0560},
962 {0x0000b100, 0x06400641},
963 {0x0000b104, 0x0660065f},
964 {0x0000b108, 0x067e067f},
965 {0x0000b10c, 0x07410742},
966 {0x0000b110, 0x075f0740},
967 {0x0000b114, 0x077f0760},
968 {0x0000b118, 0x07800781},
969 {0x0000b11c, 0x07a0079f},
970 {0x0000b120, 0x07c107bf},
971 {0x0000b124, 0x000007c0},
972 {0x0000b128, 0x00000000},
973 {0x0000b12c, 0x00000000},
974 {0x0000b130, 0x00000000},
975 {0x0000b134, 0x00000000},
976 {0x0000b138, 0x00000000},
977 {0x0000b13c, 0x00000000},
978 {0x0000b140, 0x003f0020},
979 {0x0000b144, 0x00400041},
980 {0x0000b148, 0x0140005f},
981 {0x0000b14c, 0x0160015f},
982 {0x0000b150, 0x017e017f},
983 {0x0000b154, 0x02410242},
984 {0x0000b158, 0x025f0240},
985 {0x0000b15c, 0x027f0260},
986 {0x0000b160, 0x0341027e},
987 {0x0000b164, 0x035f0340},
988 {0x0000b168, 0x037f0360},
989 {0x0000b16c, 0x04400441},
990 {0x0000b170, 0x0460045f},
991 {0x0000b174, 0x0541047f},
992 {0x0000b178, 0x055f0540},
993 {0x0000b17c, 0x057f0560},
994 {0x0000b180, 0x06400641},
995 {0x0000b184, 0x0660065f},
996 {0x0000b188, 0x067e067f},
997 {0x0000b18c, 0x07410742},
998 {0x0000b190, 0x075f0740},
999 {0x0000b194, 0x077f0760},
1000 {0x0000b198, 0x07800781},
1001 {0x0000b19c, 0x07a0079f},
1002 {0x0000b1a0, 0x07c107bf},
1003 {0x0000b1a4, 0x000007c0},
1004 {0x0000b1a8, 0x00000000},
1005 {0x0000b1ac, 0x00000000},
1006 {0x0000b1b0, 0x00000000},
1007 {0x0000b1b4, 0x00000000},
1008 {0x0000b1b8, 0x00000000},
1009 {0x0000b1bc, 0x00000000},
1010 {0x0000b1c0, 0x00000000},
1011 {0x0000b1c4, 0x00000000},
1012 {0x0000b1c8, 0x00000000},
1013 {0x0000b1cc, 0x00000000},
1014 {0x0000b1d0, 0x00000000},
1015 {0x0000b1d4, 0x00000000},
1016 {0x0000b1d8, 0x00000000},
1017 {0x0000b1dc, 0x00000000},
1018 {0x0000b1e0, 0x00000000},
1019 {0x0000b1e4, 0x00000000},
1020 {0x0000b1e8, 0x00000000},
1021 {0x0000b1ec, 0x00000000},
1022 {0x0000b1f0, 0x00000396},
1023 {0x0000b1f4, 0x00000396},
1024 {0x0000b1f8, 0x00000396},
1025 {0x0000b1fc, 0x00000196},
1026};
1027
1028static const u32 qca956x_1p0_xlna_only[][5] = {
1029 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1030 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
1031 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac621f1, 0x5ac621f1},
1032 {0x00009828, 0x06903081, 0x06903081, 0x07d43881, 0x07d43881},
1033 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x03721720},
1034 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000de, 0x6c4000da},
1035 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec8ad2e},
1036 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x317a6062, 0x317a5ae2},
1037 {0x00009e18, 0x00000000, 0x00000000, 0x03c00000, 0x03c00000},
1038 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003b2, 0x000003b2},
1039 {0x00009fc0, 0x813e4788, 0x813e4788, 0x813e4789, 0x813e4789},
1040 {0x0000ae18, 0x00000000, 0x00000000, 0x03c00000, 0x03c00000},
1041 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001b2, 0x000001b2},
1042 {0x0000be18, 0x00000000, 0x00000000, 0x03c00000, 0x03c00000},
1043 {0x0000be20, 0x000001b5, 0x000001b5, 0x000001b2, 0x000001b2},
1044};
1045
1046#endif /* INITVALS_956X_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index c43e2ad36587..dd5d3914799b 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -403,7 +403,8 @@ static const struct file_operations fops_antenna_diversity = {
403 403
404static int read_file_dma(struct seq_file *file, void *data) 404static int read_file_dma(struct seq_file *file, void *data)
405{ 405{
406 struct ath_softc *sc = file->private; 406 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
407 struct ath_softc *sc = hw->priv;
407 struct ath_hw *ah = sc->sc_ah; 408 struct ath_hw *ah = sc->sc_ah;
408 u32 val[ATH9K_NUM_DMA_DEBUG_REGS]; 409 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
409 int i, qcuOffset = 0, dcuOffset = 0; 410 int i, qcuOffset = 0, dcuOffset = 0;
@@ -470,20 +471,6 @@ static int read_file_dma(struct seq_file *file, void *data)
470 return 0; 471 return 0;
471} 472}
472 473
473static int open_file_dma(struct inode *inode, struct file *f)
474{
475 return single_open(f, read_file_dma, inode->i_private);
476}
477
478static const struct file_operations fops_dma = {
479 .open = open_file_dma,
480 .read = seq_read,
481 .owner = THIS_MODULE,
482 .llseek = seq_lseek,
483 .release = single_release,
484};
485
486
487void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) 474void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
488{ 475{
489 if (status) 476 if (status)
@@ -539,7 +526,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
539 526
540static int read_file_interrupt(struct seq_file *file, void *data) 527static int read_file_interrupt(struct seq_file *file, void *data)
541{ 528{
542 struct ath_softc *sc = file->private; 529 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
530 struct ath_softc *sc = hw->priv;
543 531
544#define PR_IS(a, s) \ 532#define PR_IS(a, s) \
545 do { \ 533 do { \
@@ -600,22 +588,10 @@ static int read_file_interrupt(struct seq_file *file, void *data)
600 return 0; 588 return 0;
601} 589}
602 590
603static int open_file_interrupt(struct inode *inode, struct file *f)
604{
605 return single_open(f, read_file_interrupt, inode->i_private);
606}
607
608static const struct file_operations fops_interrupt = {
609 .read = seq_read,
610 .open = open_file_interrupt,
611 .owner = THIS_MODULE,
612 .llseek = seq_lseek,
613 .release = single_release,
614};
615
616static int read_file_xmit(struct seq_file *file, void *data) 591static int read_file_xmit(struct seq_file *file, void *data)
617{ 592{
618 struct ath_softc *sc = file->private; 593 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
594 struct ath_softc *sc = hw->priv;
619 595
620 seq_printf(file, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO"); 596 seq_printf(file, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
621 597
@@ -661,7 +637,8 @@ static void print_queue(struct ath_softc *sc, struct ath_txq *txq,
661 637
662static int read_file_queues(struct seq_file *file, void *data) 638static int read_file_queues(struct seq_file *file, void *data)
663{ 639{
664 struct ath_softc *sc = file->private; 640 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
641 struct ath_softc *sc = hw->priv;
665 struct ath_txq *txq; 642 struct ath_txq *txq;
666 int i; 643 int i;
667 static const char *qname[4] = { 644 static const char *qname[4] = {
@@ -682,7 +659,8 @@ static int read_file_queues(struct seq_file *file, void *data)
682 659
683static int read_file_misc(struct seq_file *file, void *data) 660static int read_file_misc(struct seq_file *file, void *data)
684{ 661{
685 struct ath_softc *sc = file->private; 662 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
663 struct ath_softc *sc = hw->priv;
686 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 664 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
687 struct ath9k_vif_iter_data iter_data; 665 struct ath9k_vif_iter_data iter_data;
688 struct ath_chanctx *ctx; 666 struct ath_chanctx *ctx;
@@ -773,7 +751,8 @@ static int read_file_misc(struct seq_file *file, void *data)
773 751
774static int read_file_reset(struct seq_file *file, void *data) 752static int read_file_reset(struct seq_file *file, void *data)
775{ 753{
776 struct ath_softc *sc = file->private; 754 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
755 struct ath_softc *sc = hw->priv;
777 static const char * const reset_cause[__RESET_TYPE_MAX] = { 756 static const char * const reset_cause[__RESET_TYPE_MAX] = {
778 [RESET_TYPE_BB_HANG] = "Baseband Hang", 757 [RESET_TYPE_BB_HANG] = "Baseband Hang",
779 [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog", 758 [RESET_TYPE_BB_WATCHDOG] = "Baseband Watchdog",
@@ -837,58 +816,6 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
837 TX_STAT_INC(qnum, delim_underrun); 816 TX_STAT_INC(qnum, delim_underrun);
838} 817}
839 818
840static int open_file_xmit(struct inode *inode, struct file *f)
841{
842 return single_open(f, read_file_xmit, inode->i_private);
843}
844
845static const struct file_operations fops_xmit = {
846 .read = seq_read,
847 .open = open_file_xmit,
848 .owner = THIS_MODULE,
849 .llseek = seq_lseek,
850 .release = single_release,
851};
852
853static int open_file_queues(struct inode *inode, struct file *f)
854{
855 return single_open(f, read_file_queues, inode->i_private);
856}
857
858static const struct file_operations fops_queues = {
859 .read = seq_read,
860 .open = open_file_queues,
861 .owner = THIS_MODULE,
862 .llseek = seq_lseek,
863 .release = single_release,
864};
865
866static int open_file_misc(struct inode *inode, struct file *f)
867{
868 return single_open(f, read_file_misc, inode->i_private);
869}
870
871static const struct file_operations fops_misc = {
872 .read = seq_read,
873 .open = open_file_misc,
874 .owner = THIS_MODULE,
875 .llseek = seq_lseek,
876 .release = single_release,
877};
878
879static int open_file_reset(struct inode *inode, struct file *f)
880{
881 return single_open(f, read_file_reset, inode->i_private);
882}
883
884static const struct file_operations fops_reset = {
885 .read = seq_read,
886 .open = open_file_reset,
887 .owner = THIS_MODULE,
888 .llseek = seq_lseek,
889 .release = single_release,
890};
891
892void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 819void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
893{ 820{
894 ath9k_cmn_debug_stat_rx(&sc->debug.stats.rxstats, rs); 821 ath9k_cmn_debug_stat_rx(&sc->debug.stats.rxstats, rs);
@@ -1018,7 +945,8 @@ static const struct file_operations fops_regdump = {
1018 945
1019static int read_file_dump_nfcal(struct seq_file *file, void *data) 946static int read_file_dump_nfcal(struct seq_file *file, void *data)
1020{ 947{
1021 struct ath_softc *sc = file->private; 948 struct ieee80211_hw *hw = dev_get_drvdata(file->private);
949 struct ath_softc *sc = hw->priv;
1022 struct ath_hw *ah = sc->sc_ah; 950 struct ath_hw *ah = sc->sc_ah;
1023 struct ath9k_nfcal_hist *h = sc->cur_chan->caldata.nfCalHist; 951 struct ath9k_nfcal_hist *h = sc->cur_chan->caldata.nfCalHist;
1024 struct ath_common *common = ath9k_hw_common(ah); 952 struct ath_common *common = ath9k_hw_common(ah);
@@ -1150,11 +1078,6 @@ static ssize_t write_file_tpc(struct file *file, const char __user *user_buf,
1150 ssize_t len; 1078 ssize_t len;
1151 bool tpc_enabled; 1079 bool tpc_enabled;
1152 1080
1153 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1154 /* ar9002 does not support TPC for the moment */
1155 return -EOPNOTSUPP;
1156 }
1157
1158 len = min(count, sizeof(buf) - 1); 1081 len = min(count, sizeof(buf) - 1);
1159 if (copy_from_user(buf, user_buf, len)) 1082 if (copy_from_user(buf, user_buf, len))
1160 return -EFAULT; 1083 return -EFAULT;
@@ -1329,14 +1252,14 @@ int ath9k_init_debug(struct ath_hw *ah)
1329 ath9k_tx99_init_debug(sc); 1252 ath9k_tx99_init_debug(sc);
1330 ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); 1253 ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
1331 1254
1332 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1255 debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
1333 &fops_dma); 1256 read_file_dma);
1334 debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, 1257 debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
1335 &fops_interrupt); 1258 read_file_interrupt);
1336 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, 1259 debugfs_create_devm_seqfile(sc->dev, "xmit", sc->debug.debugfs_phy,
1337 &fops_xmit); 1260 read_file_xmit);
1338 debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, 1261 debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy,
1339 &fops_queues); 1262 read_file_queues);
1340 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1263 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1341 &sc->tx.txq_max_pending[IEEE80211_AC_BK]); 1264 &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
1342 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1265 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
@@ -1345,10 +1268,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1345 &sc->tx.txq_max_pending[IEEE80211_AC_VI]); 1268 &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
1346 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1269 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1347 &sc->tx.txq_max_pending[IEEE80211_AC_VO]); 1270 &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
1348 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, 1271 debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
1349 &fops_misc); 1272 read_file_misc);
1350 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, 1273 debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
1351 &fops_reset); 1274 read_file_reset);
1352 1275
1353 ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); 1276 ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
1354 ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); 1277 ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
@@ -1370,8 +1293,9 @@ int ath9k_init_debug(struct ath_hw *ah)
1370 &ah->config.cwm_ignore_extcca); 1293 &ah->config.cwm_ignore_extcca);
1371 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, 1294 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1372 &fops_regdump); 1295 &fops_regdump);
1373 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc, 1296 debugfs_create_devm_seqfile(sc->dev, "dump_nfcal",
1374 &fops_dump_nfcal); 1297 sc->debug.debugfs_phy,
1298 read_file_dump_nfcal);
1375 1299
1376 ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah); 1300 ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
1377 ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah); 1301 ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 07b806c56c56..e5a78d4fd66e 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -748,6 +748,20 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
748 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 748 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
749 } 749 }
750 750
751 /* TPC initializations */
752 if (ah->tpc_enabled) {
753 int ht40_delta;
754
755 ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
756 ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
757 /* Enable TPC */
758 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
759 MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
760 } else {
761 /* Disable TPC */
762 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
763 }
764
751 REGWRITE_BUFFER_FLUSH(ah); 765 REGWRITE_BUFFER_FLUSH(ah);
752} 766}
753 767
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 5ba1385c9838..6ca33dfde1fd 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -886,6 +886,21 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
886 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) 886 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
887 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); 887 | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
888 } 888 }
889
890 /* TPC initializations */
891 if (ah->tpc_enabled) {
892 int ht40_delta;
893
894 ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
895 ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
896 /* Enable TPC */
897 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
898 MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
899 } else {
900 /* Disable TPC */
901 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
902 }
903
889 REGWRITE_BUFFER_FLUSH(ah); 904 REGWRITE_BUFFER_FLUSH(ah);
890} 905}
891 906
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 122b846b8ec0..098059039351 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -1332,6 +1332,20 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1332 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) 1332 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
1333 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)); 1333 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
1334 1334
1335 /* TPC initializations */
1336 if (ah->tpc_enabled) {
1337 int ht40_delta;
1338
1339 ht40_delta = (IS_CHAN_HT40(chan)) ? ht40PowerIncForPdadc : 0;
1340 ar5008_hw_init_rate_txpower(ah, ratesArray, chan, ht40_delta);
1341 /* Enable TPC */
1342 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX,
1343 MAX_RATE_POWER | AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE);
1344 } else {
1345 /* Disable TPC */
1346 REG_WRITE(ah, AR_PHY_POWER_TX_RATE_MAX, MAX_RATE_POWER);
1347 }
1348
1335 REGWRITE_BUFFER_FLUSH(ah); 1349 REGWRITE_BUFFER_FLUSH(ah);
1336} 1350}
1337 1351
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 9dde265d3f84..c43fec51b8ec 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -44,6 +44,9 @@
44 44
45extern struct ieee80211_ops ath9k_htc_ops; 45extern struct ieee80211_ops ath9k_htc_ops;
46extern int htc_modparam_nohwcrypt; 46extern int htc_modparam_nohwcrypt;
47#ifdef CONFIG_MAC80211_LEDS
48extern int led_blink;
49#endif
47 50
48enum htc_phymode { 51enum htc_phymode {
49 HTC_MODE_11NA = 0, 52 HTC_MODE_11NA = 0,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 50f74a2a4cf8..998b558d4126 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -279,6 +279,10 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
279 else 279 else
280 priv->ah->led_pin = ATH_LED_PIN_DEF; 280 priv->ah->led_pin = ATH_LED_PIN_DEF;
281 281
282 if (!led_blink)
283 priv->led_cdev.default_trigger =
284 ieee80211_get_radio_led_name(priv->hw);
285
282 ath9k_configure_leds(priv); 286 ath9k_configure_leds(priv);
283 287
284 snprintf(priv->led_name, sizeof(priv->led_name), 288 snprintf(priv->led_name, sizeof(priv->led_name),
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index e8fa9448da24..947012757f81 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -39,6 +39,10 @@ module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); 39MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
40 40
41#ifdef CONFIG_MAC80211_LEDS 41#ifdef CONFIG_MAC80211_LEDS
42int led_blink = 1;
43module_param_named(blink, led_blink, int, 0444);
44MODULE_PARM_DESC(blink, "Enable LED blink on activity");
45
42static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { 46static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
43 { .throughput = 0 * 1024, .blink_time = 334 }, 47 { .throughput = 0 * 1024, .blink_time = 334 },
44 { .throughput = 1 * 1024, .blink_time = 260 }, 48 { .throughput = 1 * 1024, .blink_time = 260 },
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index a0ff5b637054..d2408da38c1c 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -351,11 +351,7 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
351 351
352 return; 352 return;
353ret: 353ret:
354 /* HTC-generated packets are freed here. */ 354 kfree_skb(skb);
355 if (htc_hdr && htc_hdr->endpoint_id != ENDPOINT0)
356 dev_kfree_skb_any(skb);
357 else
358 kfree_skb(skb);
359} 355}
360 356
361static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle, 357static void ath9k_htc_fw_panic_report(struct htc_target *htc_handle,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 258c4d236cbe..82d8f32a3461 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -246,6 +246,8 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
246 case AR9300_DEVID_AR953X: 246 case AR9300_DEVID_AR953X:
247 ah->hw_version.macVersion = AR_SREV_VERSION_9531; 247 ah->hw_version.macVersion = AR_SREV_VERSION_9531;
248 return; 248 return;
249 case AR9300_DEVID_QCA956X:
250 ah->hw_version.macVersion = AR_SREV_VERSION_9561;
249 } 251 }
250 252
251 val = REG_READ(ah, AR_SREV) & AR_SREV_ID; 253 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
@@ -422,8 +424,7 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
422 ah->power_mode = ATH9K_PM_UNDEFINED; 424 ah->power_mode = ATH9K_PM_UNDEFINED;
423 ah->htc_reset_init = true; 425 ah->htc_reset_init = true;
424 426
425 /* ar9002 does not support TPC for the moment */ 427 ah->tpc_enabled = true;
426 ah->tpc_enabled = !!AR_SREV_9300_20_OR_LATER(ah);
427 428
428 ah->ani_function = ATH9K_ANI_ALL; 429 ah->ani_function = ATH9K_ANI_ALL;
429 if (!AR_SREV_9300_20_OR_LATER(ah)) 430 if (!AR_SREV_9300_20_OR_LATER(ah))
@@ -539,6 +540,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
539 case AR_SREV_VERSION_9550: 540 case AR_SREV_VERSION_9550:
540 case AR_SREV_VERSION_9565: 541 case AR_SREV_VERSION_9565:
541 case AR_SREV_VERSION_9531: 542 case AR_SREV_VERSION_9531:
543 case AR_SREV_VERSION_9561:
542 break; 544 break;
543 default: 545 default:
544 ath_err(common, 546 ath_err(common,
@@ -639,6 +641,7 @@ int ath9k_hw_init(struct ath_hw *ah)
639 case AR9485_DEVID_AR1111: 641 case AR9485_DEVID_AR1111:
640 case AR9300_DEVID_AR9565: 642 case AR9300_DEVID_AR9565:
641 case AR9300_DEVID_AR953X: 643 case AR9300_DEVID_AR953X:
644 case AR9300_DEVID_QCA956X:
642 break; 645 break;
643 default: 646 default:
644 if (common->bus_ops->ath_bus_type == ATH_USB) 647 if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -779,7 +782,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
779 /* program BB PLL phase_shift */ 782 /* program BB PLL phase_shift */
780 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 783 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
781 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); 784 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1);
782 } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) { 785 } else if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
786 AR_SREV_9561(ah)) {
783 u32 regval, pll2_divint, pll2_divfrac, refdiv; 787 u32 regval, pll2_divint, pll2_divfrac, refdiv;
784 788
785 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 789 REG_WRITE(ah, AR_RTC_PLL_CONTROL,
@@ -790,7 +794,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
790 udelay(100); 794 udelay(100);
791 795
792 if (ah->is_clk_25mhz) { 796 if (ah->is_clk_25mhz) {
793 if (AR_SREV_9531(ah)) { 797 if (AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
794 pll2_divint = 0x1c; 798 pll2_divint = 0x1c;
795 pll2_divfrac = 0xa3d2; 799 pll2_divfrac = 0xa3d2;
796 refdiv = 1; 800 refdiv = 1;
@@ -806,14 +810,15 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
806 refdiv = 5; 810 refdiv = 5;
807 } else { 811 } else {
808 pll2_divint = 0x11; 812 pll2_divint = 0x11;
809 pll2_divfrac = 813 pll2_divfrac = (AR_SREV_9531(ah) ||
810 AR_SREV_9531(ah) ? 0x26665 : 0x26666; 814 AR_SREV_9561(ah)) ?
815 0x26665 : 0x26666;
811 refdiv = 1; 816 refdiv = 1;
812 } 817 }
813 } 818 }
814 819
815 regval = REG_READ(ah, AR_PHY_PLL_MODE); 820 regval = REG_READ(ah, AR_PHY_PLL_MODE);
816 if (AR_SREV_9531(ah)) 821 if (AR_SREV_9531(ah) || AR_SREV_9561(ah))
817 regval |= (0x1 << 22); 822 regval |= (0x1 << 22);
818 else 823 else
819 regval |= (0x1 << 16); 824 regval |= (0x1 << 16);
@@ -831,14 +836,16 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
831 (0x1 << 13) | 836 (0x1 << 13) |
832 (0x4 << 26) | 837 (0x4 << 26) |
833 (0x18 << 19); 838 (0x18 << 19);
834 else if (AR_SREV_9531(ah)) 839 else if (AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
835 regval = (regval & 0x01c00fff) | 840 regval = (regval & 0x01c00fff) |
836 (0x1 << 31) | 841 (0x1 << 31) |
837 (0x2 << 29) | 842 (0x2 << 29) |
838 (0xa << 25) | 843 (0xa << 25) |
839 (0x1 << 19) | 844 (0x1 << 19);
840 (0x6 << 12); 845
841 else 846 if (AR_SREV_9531(ah))
847 regval |= (0x6 << 12);
848 } else
842 regval = (regval & 0x80071fff) | 849 regval = (regval & 0x80071fff) |
843 (0x3 << 30) | 850 (0x3 << 30) |
844 (0x1 << 13) | 851 (0x1 << 13) |
@@ -846,7 +853,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
846 (0x60 << 19); 853 (0x60 << 19);
847 REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 854 REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
848 855
849 if (AR_SREV_9531(ah)) 856 if (AR_SREV_9531(ah) || AR_SREV_9561(ah))
850 REG_WRITE(ah, AR_PHY_PLL_MODE, 857 REG_WRITE(ah, AR_PHY_PLL_MODE,
851 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff); 858 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff);
852 else 859 else
@@ -885,7 +892,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
885 AR_IMR_RXORN | 892 AR_IMR_RXORN |
886 AR_IMR_BCNMISC; 893 AR_IMR_BCNMISC;
887 894
888 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) 895 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
896 AR_SREV_9561(ah))
889 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 897 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
890 898
891 if (AR_SREV_9300_20_OR_LATER(ah)) { 899 if (AR_SREV_9300_20_OR_LATER(ah)) {
@@ -1674,7 +1682,8 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
1674 } 1682 }
1675#ifdef __BIG_ENDIAN 1683#ifdef __BIG_ENDIAN
1676 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || 1684 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
1677 AR_SREV_9550(ah) || AR_SREV_9531(ah)) 1685 AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
1686 AR_SREV_9561(ah))
1678 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); 1687 REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
1679 else 1688 else
1680 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 1689 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
@@ -2462,7 +2471,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2462 2471
2463 if (AR_SREV_9300_20_OR_LATER(ah)) { 2472 if (AR_SREV_9300_20_OR_LATER(ah)) {
2464 pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; 2473 pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
2465 if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah) && !AR_SREV_9565(ah)) 2474 if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah) &&
2475 !AR_SREV_9561(ah) && !AR_SREV_9565(ah))
2466 pCap->hw_caps |= ATH9K_HW_CAP_LDPC; 2476 pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
2467 2477
2468 pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; 2478 pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
@@ -2479,7 +2489,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2479 if (AR_SREV_9300_20_OR_LATER(ah)) 2489 if (AR_SREV_9300_20_OR_LATER(ah))
2480 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; 2490 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
2481 2491
2482 if (AR_SREV_9300_20_OR_LATER(ah)) 2492 if (AR_SREV_9561(ah))
2493 ah->ent_mode = 0x3BDA000;
2494 else if (AR_SREV_9300_20_OR_LATER(ah))
2483 ah->ent_mode = REG_READ(ah, AR_ENT_OTP); 2495 ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
2484 2496
2485 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) 2497 if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 1cbd33551513..450704e49f03 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -54,6 +54,7 @@
54#define AR9485_DEVID_AR1111 0x0037 54#define AR9485_DEVID_AR1111 0x0037
55#define AR9300_DEVID_AR9565 0x0036 55#define AR9300_DEVID_AR9565 0x0036
56#define AR9300_DEVID_AR953X 0x003d 56#define AR9300_DEVID_AR953X 0x003d
57#define AR9300_DEVID_QCA956X 0x003f
57 58
58#define AR5416_AR9100_DEVID 0x000b 59#define AR5416_AR9100_DEVID 0x000b
59 60
@@ -1086,6 +1087,8 @@ bool ar9003_is_paprd_enabled(struct ath_hw *ah);
1086void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); 1087void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1087void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array, 1088void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array,
1088 struct ath9k_channel *chan); 1089 struct ath9k_channel *chan);
1090void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
1091 struct ath9k_channel *chan, int ht40_delta);
1089 1092
1090/* Hardware family op attach helpers */ 1093/* Hardware family op attach helpers */
1091int ar5008_hw_attach_phy_ops(struct ath_hw *ah); 1094int ar5008_hw_attach_phy_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 3e58bfa0c1fd..bba85d1a6cd1 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -820,7 +820,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
820 return; 820 return;
821 } 821 }
822 822
823 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) 823 if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
824 AR_SREV_9561(ah))
824 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 825 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
825 826
826 async_mask = AR_INTR_MAC_IRQ; 827 async_mask = AR_INTR_MAC_IRQ;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index f009b5b57e5e..cc5c6810f32e 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -427,6 +427,11 @@ static const struct pci_device_id ath_pci_id_table[] = {
427 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 427 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
428 0x0036, 428 0x0036,
429 0x11AD, /* LITEON */ 429 0x11AD, /* LITEON */
430 0x1842),
431 .driver_data = ATH9K_PCI_AR9565_1ANT },
432 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
433 0x0036,
434 0x11AD, /* LITEON */
430 0x6671), 435 0x6671),
431 .driver_data = ATH9K_PCI_AR9565_1ANT }, 436 .driver_data = ATH9K_PCI_AR9565_1ANT },
432 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 437 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
@@ -446,9 +451,19 @@ static const struct pci_device_id ath_pci_id_table[] = {
446 .driver_data = ATH9K_PCI_AR9565_1ANT }, 451 .driver_data = ATH9K_PCI_AR9565_1ANT },
447 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 452 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
448 0x0036, 453 0x0036,
454 0x1B9A, /* XAVI */
455 0x28A3),
456 .driver_data = ATH9K_PCI_AR9565_1ANT },
457 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
458 0x0036,
449 PCI_VENDOR_ID_AZWAVE, 459 PCI_VENDOR_ID_AZWAVE,
450 0x218A), 460 0x218A),
451 .driver_data = ATH9K_PCI_AR9565_1ANT }, 461 .driver_data = ATH9K_PCI_AR9565_1ANT },
462 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
463 0x0036,
464 PCI_VENDOR_ID_AZWAVE,
465 0x2F8A),
466 .driver_data = ATH9K_PCI_AR9565_1ANT },
452 467
453 /* WB335 1-ANT / Antenna Diversity */ 468 /* WB335 1-ANT / Antenna Diversity */
454 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 469 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
@@ -508,6 +523,11 @@ static const struct pci_device_id ath_pci_id_table[] = {
508 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 523 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
509 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 524 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
510 0x0036, 525 0x0036,
526 PCI_VENDOR_ID_AZWAVE,
527 0x213C),
528 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
529 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
530 0x0036,
511 PCI_VENDOR_ID_HP, 531 PCI_VENDOR_ID_HP,
512 0x18E3), 532 0x18E3),
513 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 533 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -555,6 +575,16 @@ static const struct pci_device_id ath_pci_id_table[] = {
555 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 575 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
556 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 576 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
557 0x0036, 577 0x0036,
578 PCI_VENDOR_ID_SAMSUNG,
579 0x4129),
580 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
581 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
582 0x0036,
583 PCI_VENDOR_ID_SAMSUNG,
584 0x412A),
585 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
586 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
587 0x0036,
558 PCI_VENDOR_ID_ATHEROS, 588 PCI_VENDOR_ID_ATHEROS,
559 0x3027), 589 0x3027),
560 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 590 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -586,10 +616,25 @@ static const struct pci_device_id ath_pci_id_table[] = {
586 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 616 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
587 0x0036, 617 0x0036,
588 0x11AD, /* LITEON */ 618 0x11AD, /* LITEON */
619 0x1832),
620 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
621 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
622 0x0036,
623 0x11AD, /* LITEON */
589 0x0692), 624 0x0692),
590 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 625 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
591 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 626 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
592 0x0036, 627 0x0036,
628 0x11AD, /* LITEON */
629 0x0803),
630 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
631 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
632 0x0036,
633 0x11AD, /* LITEON */
634 0x0813),
635 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
636 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
637 0x0036,
593 PCI_VENDOR_ID_AZWAVE, 638 PCI_VENDOR_ID_AZWAVE,
594 0x2130), 639 0x2130),
595 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 640 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -605,6 +650,21 @@ static const struct pci_device_id ath_pci_id_table[] = {
605 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 650 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
606 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 651 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
607 0x0036, 652 0x0036,
653 PCI_VENDOR_ID_AZWAVE,
654 0x218B),
655 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
656 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
657 0x0036,
658 PCI_VENDOR_ID_AZWAVE,
659 0x218C),
660 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
661 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
662 0x0036,
663 PCI_VENDOR_ID_AZWAVE,
664 0x2F82),
665 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
666 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
667 0x0036,
608 0x144F, /* ASKEY */ 668 0x144F, /* ASKEY */
609 0x7202), 669 0x7202),
610 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 670 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -616,10 +676,20 @@ static const struct pci_device_id ath_pci_id_table[] = {
616 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 676 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
617 0x0036, 677 0x0036,
618 0x1B9A, /* XAVI */ 678 0x1B9A, /* XAVI */
679 0x2813),
680 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
681 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
682 0x0036,
683 0x1B9A, /* XAVI */
619 0x28A2), 684 0x28A2),
620 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 685 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
621 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 686 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
622 0x0036, 687 0x0036,
688 0x1B9A, /* XAVI */
689 0x28A4),
690 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
691 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
692 0x0036,
623 0x185F, /* WNC */ 693 0x185F, /* WNC */
624 0x3027), 694 0x3027),
625 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 695 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -636,10 +706,25 @@ static const struct pci_device_id ath_pci_id_table[] = {
636 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 706 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
637 0x0036, 707 0x0036,
638 PCI_VENDOR_ID_FOXCONN, 708 PCI_VENDOR_ID_FOXCONN,
709 0xE08F),
710 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
711 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
712 0x0036,
713 PCI_VENDOR_ID_FOXCONN,
639 0xE081), 714 0xE081),
640 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 715 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
641 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 716 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
642 0x0036, 717 0x0036,
718 PCI_VENDOR_ID_FOXCONN,
719 0xE091),
720 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
721 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
722 0x0036,
723 PCI_VENDOR_ID_FOXCONN,
724 0xE099),
725 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
726 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
727 0x0036,
643 PCI_VENDOR_ID_LENOVO, 728 PCI_VENDOR_ID_LENOVO,
644 0x3026), 729 0x3026),
645 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 730 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 7395afbc5124..6fb40ef86fd6 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -425,7 +425,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
425 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; 425 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
426 } 426 }
427 427
428 if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah)) 428 if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah) ||
429 AR_SREV_9561(sc->sc_ah))
429 rfilt |= ATH9K_RX_FILTER_4ADDRESS; 430 rfilt |= ATH9K_RX_FILTER_4ADDRESS;
430 431
431 if (ath9k_is_chanctx_enabled() && 432 if (ath9k_is_chanctx_enabled() &&
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index fb11a9172f38..eb2bb0db297f 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -814,6 +814,7 @@
814#define AR_SREV_REVISION_9531_10 0 814#define AR_SREV_REVISION_9531_10 0
815#define AR_SREV_REVISION_9531_11 1 815#define AR_SREV_REVISION_9531_11 1
816#define AR_SREV_REVISION_9531_20 2 816#define AR_SREV_REVISION_9531_20 2
817#define AR_SREV_VERSION_9561 0x600
817 818
818#define AR_SREV_5416(_ah) \ 819#define AR_SREV_5416(_ah) \
819 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 820 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -974,6 +975,9 @@
974 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \ 975 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
975 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20)) 976 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20))
976 977
978#define AR_SREV_9561(_ah) \
979 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9561))
980
977/* NOTE: When adding chips newer than Peacock, add chip check here */ 981/* NOTE: When adding chips newer than Peacock, add chip check here */
978#define AR_SREV_9580_10_OR_LATER(_ah) \ 982#define AR_SREV_9580_10_OR_LATER(_ah) \
979 (AR_SREV_9580(_ah)) 983 (AR_SREV_9580(_ah))
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index cf60cc405d14..1b8e75c4d2c2 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1097,24 +1097,65 @@ void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
1097} 1097}
1098 1098
1099static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf, 1099static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
1100 u8 rateidx) 1100 u8 rateidx, bool is_40, bool is_cck)
1101{ 1101{
1102 u8 max_power; 1102 u8 max_power;
1103 struct sk_buff *skb;
1104 struct ath_frame_info *fi;
1105 struct ieee80211_tx_info *info;
1103 struct ath_hw *ah = sc->sc_ah; 1106 struct ath_hw *ah = sc->sc_ah;
1104 1107
1105 if (sc->tx99_state) 1108 if (sc->tx99_state || !ah->tpc_enabled)
1106 return MAX_RATE_POWER; 1109 return MAX_RATE_POWER;
1107 1110
1111 skb = bf->bf_mpdu;
1112 fi = get_frame_info(skb);
1113 info = IEEE80211_SKB_CB(skb);
1114
1108 if (!AR_SREV_9300_20_OR_LATER(ah)) { 1115 if (!AR_SREV_9300_20_OR_LATER(ah)) {
1109 /* ar9002 does not support TPC for the moment */ 1116 int txpower = fi->tx_power;
1110 return MAX_RATE_POWER;
1111 }
1112 1117
1113 if (!bf->bf_state.bfs_paprd) { 1118 if (is_40) {
1114 struct sk_buff *skb = bf->bf_mpdu; 1119 u8 power_ht40delta;
1115 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1120 struct ar5416_eeprom_def *eep = &ah->eeprom.def;
1116 struct ath_frame_info *fi = get_frame_info(skb); 1121
1122 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
1123 bool is_2ghz;
1124 struct modal_eep_header *pmodal;
1117 1125
1126 is_2ghz = info->band == IEEE80211_BAND_2GHZ;
1127 pmodal = &eep->modalHeader[is_2ghz];
1128 power_ht40delta = pmodal->ht40PowerIncForPdadc;
1129 } else {
1130 power_ht40delta = 2;
1131 }
1132 txpower += power_ht40delta;
1133 }
1134
1135 if (AR_SREV_9287(ah) || AR_SREV_9285(ah) ||
1136 AR_SREV_9271(ah)) {
1137 txpower -= 2 * AR9287_PWR_TABLE_OFFSET_DB;
1138 } else if (AR_SREV_9280_20_OR_LATER(ah)) {
1139 s8 power_offset;
1140
1141 power_offset = ah->eep_ops->get_eeprom(ah,
1142 EEP_PWR_TABLE_OFFSET);
1143 txpower -= 2 * power_offset;
1144 }
1145
1146 if (OLC_FOR_AR9280_20_LATER && is_cck)
1147 txpower -= 2;
1148
1149 txpower = max(txpower, 0);
1150 max_power = min_t(u8, ah->tx_power[rateidx], txpower);
1151
1152 /* XXX: clamp minimum TX power at 1 for AR9160 since if
1153 * max_power is set to 0, frames are transmitted at max
1154 * TX power
1155 */
1156 if (!max_power && !AR_SREV_9280_20_OR_LATER(ah))
1157 max_power = 1;
1158 } else if (!bf->bf_state.bfs_paprd) {
1118 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC)) 1159 if (rateidx < 8 && (info->flags & IEEE80211_TX_CTL_STBC))
1119 max_power = min(ah->tx_power_stbc[rateidx], 1160 max_power = min(ah->tx_power_stbc[rateidx],
1120 fi->tx_power); 1161 fi->tx_power);
@@ -1152,7 +1193,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1152 info->rtscts_rate = fi->rtscts_rate; 1193 info->rtscts_rate = fi->rtscts_rate;
1153 1194
1154 for (i = 0; i < ARRAY_SIZE(bf->rates); i++) { 1195 for (i = 0; i < ARRAY_SIZE(bf->rates); i++) {
1155 bool is_40, is_sgi, is_sp; 1196 bool is_40, is_sgi, is_sp, is_cck;
1156 int phy; 1197 int phy;
1157 1198
1158 if (!rates[i].count || (rates[i].idx < 0)) 1199 if (!rates[i].count || (rates[i].idx < 0))
@@ -1198,7 +1239,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1198 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) 1239 if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
1199 info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC; 1240 info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC;
1200 1241
1201 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); 1242 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix,
1243 is_40, false);
1202 continue; 1244 continue;
1203 } 1245 }
1204 1246
@@ -1227,7 +1269,9 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
1227 info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah, 1269 info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
1228 phy, rate->bitrate * 100, len, rix, is_sp); 1270 phy, rate->bitrate * 100, len, rix, is_sp);
1229 1271
1230 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix); 1272 is_cck = IS_CCK_RATE(info->rates[i].Rate);
1273 info->txpower[i] = ath_get_rate_txpower(sc, bf, rix, false,
1274 is_cck);
1231 } 1275 }
1232 1276
1233 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */ 1277 /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
@@ -2445,9 +2489,12 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2445 if (sc->sc_ah->caldata) 2489 if (sc->sc_ah->caldata)
2446 set_bit(PAPRD_PACKET_SENT, &sc->sc_ah->caldata->cal_flags); 2490 set_bit(PAPRD_PACKET_SENT, &sc->sc_ah->caldata->cal_flags);
2447 2491
2448 if (!(tx_flags & ATH_TX_ERROR)) 2492 if (!(tx_flags & ATH_TX_ERROR)) {
2449 /* Frame was ACKed */ 2493 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
2450 tx_info->flags |= IEEE80211_TX_STAT_ACK; 2494 tx_info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
2495 else
2496 tx_info->flags |= IEEE80211_TX_STAT_ACK;
2497 }
2451 2498
2452 padpos = ieee80211_hdrlen(hdr->frame_control); 2499 padpos = ieee80211_hdrlen(hdr->frame_control);
2453 padsize = padpos & 3; 2500 padsize = padpos & 3;
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index 73f12f196f14..086549b732b9 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -84,6 +84,7 @@ static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch)
84 if (!cur_ctl) 84 if (!cur_ctl)
85 goto out_fail; 85 goto out_fail;
86 86
87 spin_lock_init(&cur_ctl->skb_lock);
87 cur_ctl->ctl_blk_order = i; 88 cur_ctl->ctl_blk_order = i;
88 if (i == 0) { 89 if (i == 0) {
89 ch->head_blk_ctl = cur_ctl; 90 ch->head_blk_ctl = cur_ctl;
@@ -354,6 +355,8 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
354 * and while-do will not make any cycles. 355 * and while-do will not make any cycles.
355 */ 356 */
356 do { 357 do {
358 if (ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)
359 break;
357 if (ctl->skb) { 360 if (ctl->skb) {
358 dma_unmap_single(NULL, ctl->desc->src_addr_l, 361 dma_unmap_single(NULL, ctl->desc->src_addr_l,
359 ctl->skb->len, DMA_TO_DEVICE); 362 ctl->skb->len, DMA_TO_DEVICE);
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 7dd8873f757e..0783d2ed8238 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -298,6 +298,8 @@ static int wcn36xx_start(struct ieee80211_hw *hw)
298 wcn36xx_debugfs_init(wcn); 298 wcn36xx_debugfs_init(wcn);
299 299
300 INIT_LIST_HEAD(&wcn->vif_list); 300 INIT_LIST_HEAD(&wcn->vif_list);
301 spin_lock_init(&wcn->dxe_lock);
302
301 return 0; 303 return 0;
302 304
303out_smd_stop: 305out_smd_stop:
@@ -795,6 +797,7 @@ static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
795 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", 797 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
796 vif, sta->addr); 798 vif, sta->addr);
797 799
800 spin_lock_init(&sta_priv->ampdu_lock);
798 vif_priv->sta = sta_priv; 801 vif_priv->sta = sta_priv;
799 sta_priv->vif = vif_priv; 802 sta_priv->vif = vif_priv;
800 /* 803 /*
@@ -873,21 +876,32 @@ static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
873 get_sta_index(vif, sta_priv)); 876 get_sta_index(vif, sta_priv));
874 wcn36xx_smd_add_ba(wcn); 877 wcn36xx_smd_add_ba(wcn);
875 wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv)); 878 wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv));
876 ieee80211_start_tx_ba_session(sta, tid, 0);
877 break; 879 break;
878 case IEEE80211_AMPDU_RX_STOP: 880 case IEEE80211_AMPDU_RX_STOP:
879 wcn36xx_smd_del_ba(wcn, tid, get_sta_index(vif, sta_priv)); 881 wcn36xx_smd_del_ba(wcn, tid, get_sta_index(vif, sta_priv));
880 break; 882 break;
881 case IEEE80211_AMPDU_TX_START: 883 case IEEE80211_AMPDU_TX_START:
884 spin_lock_bh(&sta_priv->ampdu_lock);
885 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START;
886 spin_unlock_bh(&sta_priv->ampdu_lock);
887
882 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 888 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
883 break; 889 break;
884 case IEEE80211_AMPDU_TX_OPERATIONAL: 890 case IEEE80211_AMPDU_TX_OPERATIONAL:
891 spin_lock_bh(&sta_priv->ampdu_lock);
892 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_OPERATIONAL;
893 spin_unlock_bh(&sta_priv->ampdu_lock);
894
885 wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1, 895 wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1,
886 get_sta_index(vif, sta_priv)); 896 get_sta_index(vif, sta_priv));
887 break; 897 break;
888 case IEEE80211_AMPDU_TX_STOP_FLUSH: 898 case IEEE80211_AMPDU_TX_STOP_FLUSH:
889 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 899 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
890 case IEEE80211_AMPDU_TX_STOP_CONT: 900 case IEEE80211_AMPDU_TX_STOP_CONT:
901 spin_lock_bh(&sta_priv->ampdu_lock);
902 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_NONE;
903 spin_unlock_bh(&sta_priv->ampdu_lock);
904
891 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 905 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
892 break; 906 break;
893 default: 907 default:
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 63986931829e..69ed39731902 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -21,6 +21,61 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include "smd.h" 22#include "smd.h"
23 23
24struct wcn36xx_cfg_val {
25 u32 cfg_id;
26 u32 value;
27};
28
29#define WCN36XX_CFG_VAL(id, val) \
30{ \
31 .cfg_id = WCN36XX_HAL_CFG_ ## id, \
32 .value = val \
33}
34
35static struct wcn36xx_cfg_val wcn36xx_cfg_vals[] = {
36 WCN36XX_CFG_VAL(CURRENT_TX_ANTENNA, 1),
37 WCN36XX_CFG_VAL(CURRENT_RX_ANTENNA, 1),
38 WCN36XX_CFG_VAL(LOW_GAIN_OVERRIDE, 0),
39 WCN36XX_CFG_VAL(POWER_STATE_PER_CHAIN, 785),
40 WCN36XX_CFG_VAL(CAL_PERIOD, 5),
41 WCN36XX_CFG_VAL(CAL_CONTROL, 1),
42 WCN36XX_CFG_VAL(PROXIMITY, 0),
43 WCN36XX_CFG_VAL(NETWORK_DENSITY, 3),
44 WCN36XX_CFG_VAL(MAX_MEDIUM_TIME, 6000),
45 WCN36XX_CFG_VAL(MAX_MPDUS_IN_AMPDU, 64),
46 WCN36XX_CFG_VAL(RTS_THRESHOLD, 2347),
47 WCN36XX_CFG_VAL(SHORT_RETRY_LIMIT, 6),
48 WCN36XX_CFG_VAL(LONG_RETRY_LIMIT, 6),
49 WCN36XX_CFG_VAL(FRAGMENTATION_THRESHOLD, 8000),
50 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ZERO, 5),
51 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_ONE, 10),
52 WCN36XX_CFG_VAL(DYNAMIC_THRESHOLD_TWO, 15),
53 WCN36XX_CFG_VAL(FIXED_RATE, 0),
54 WCN36XX_CFG_VAL(RETRYRATE_POLICY, 4),
55 WCN36XX_CFG_VAL(RETRYRATE_SECONDARY, 0),
56 WCN36XX_CFG_VAL(RETRYRATE_TERTIARY, 0),
57 WCN36XX_CFG_VAL(FORCE_POLICY_PROTECTION, 5),
58 WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_24GHZ, 1),
59 WCN36XX_CFG_VAL(FIXED_RATE_MULTICAST_5GHZ, 5),
60 WCN36XX_CFG_VAL(DEFAULT_RATE_INDEX_5GHZ, 5),
61 WCN36XX_CFG_VAL(MAX_BA_SESSIONS, 40),
62 WCN36XX_CFG_VAL(PS_DATA_INACTIVITY_TIMEOUT, 200),
63 WCN36XX_CFG_VAL(PS_ENABLE_BCN_FILTER, 1),
64 WCN36XX_CFG_VAL(PS_ENABLE_RSSI_MONITOR, 1),
65 WCN36XX_CFG_VAL(NUM_BEACON_PER_RSSI_AVERAGE, 20),
66 WCN36XX_CFG_VAL(STATS_PERIOD, 10),
67 WCN36XX_CFG_VAL(CFP_MAX_DURATION, 30000),
68 WCN36XX_CFG_VAL(FRAME_TRANS_ENABLED, 0),
69 WCN36XX_CFG_VAL(BA_THRESHOLD_HIGH, 128),
70 WCN36XX_CFG_VAL(MAX_BA_BUFFERS, 2560),
71 WCN36XX_CFG_VAL(DYNAMIC_PS_POLL_VALUE, 0),
72 WCN36XX_CFG_VAL(TX_PWR_CTRL_ENABLE, 1),
73 WCN36XX_CFG_VAL(ENABLE_CLOSE_LOOP, 1),
74 WCN36XX_CFG_VAL(ENABLE_LPWR_IMG_TRANSITION, 0),
75 WCN36XX_CFG_VAL(MAX_ASSOC_LIMIT, 10),
76 WCN36XX_CFG_VAL(ENABLE_MCC_ADAPTIVE_SCHEDULER, 0),
77};
78
24static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value) 79static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value)
25{ 80{
26 struct wcn36xx_hal_cfg *entry; 81 struct wcn36xx_hal_cfg *entry;
@@ -357,8 +412,10 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
357 412
358int wcn36xx_smd_start(struct wcn36xx *wcn) 413int wcn36xx_smd_start(struct wcn36xx *wcn)
359{ 414{
360 struct wcn36xx_hal_mac_start_req_msg msg_body; 415 struct wcn36xx_hal_mac_start_req_msg msg_body, *body;
361 int ret = 0; 416 int ret = 0;
417 int i;
418 size_t len;
362 419
363 mutex_lock(&wcn->hal_mutex); 420 mutex_lock(&wcn->hal_mutex);
364 INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_REQ); 421 INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_REQ);
@@ -368,10 +425,22 @@ int wcn36xx_smd_start(struct wcn36xx *wcn)
368 425
369 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 426 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
370 427
428 body = (struct wcn36xx_hal_mac_start_req_msg *)wcn->hal_buf;
429 len = body->header.len;
430
431 for (i = 0; i < ARRAY_SIZE(wcn36xx_cfg_vals); i++) {
432 ret = put_cfg_tlv_u32(wcn, &len, wcn36xx_cfg_vals[i].cfg_id,
433 wcn36xx_cfg_vals[i].value);
434 if (ret)
435 goto out;
436 }
437 body->header.len = len;
438 body->params.len = len - sizeof(*body);
439
371 wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start type %d\n", 440 wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start type %d\n",
372 msg_body.params.type); 441 msg_body.params.type);
373 442
374 ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); 443 ret = wcn36xx_smd_send_and_wait(wcn, body->header.len);
375 if (ret) { 444 if (ret) {
376 wcn36xx_err("Sending hal_start failed\n"); 445 wcn36xx_err("Sending hal_start failed\n");
377 goto out; 446 goto out;
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c
index 32bb26a0db2a..9bec8237231d 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.c
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.c
@@ -93,6 +93,7 @@ static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd,
93 bd->pdu.mpdu_header_off; 93 bd->pdu.mpdu_header_off;
94 bd->pdu.mpdu_len = len; 94 bd->pdu.mpdu_len = len;
95 bd->pdu.tid = tid; 95 bd->pdu.tid = tid;
96 bd->pdu.bd_ssn = WCN36XX_TXBD_SSN_FILL_DPU_QOS;
96} 97}
97 98
98static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, 99static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn,
@@ -110,15 +111,54 @@ static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn,
110 wcn36xx_warn("vif %pM not found\n", addr); 111 wcn36xx_warn("vif %pM not found\n", addr);
111 return NULL; 112 return NULL;
112} 113}
114
115static void wcn36xx_tx_start_ampdu(struct wcn36xx *wcn,
116 struct wcn36xx_sta *sta_priv,
117 struct sk_buff *skb)
118{
119 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
120 struct ieee80211_sta *sta;
121 u8 *qc, tid;
122
123 if (!conf_is_ht(&wcn->hw->conf))
124 return;
125
126 sta = wcn36xx_priv_to_sta(sta_priv);
127
128 if (WARN_ON(!ieee80211_is_data_qos(hdr->frame_control)))
129 return;
130
131 if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
132 return;
133
134 qc = ieee80211_get_qos_ctl(hdr);
135 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
136
137 spin_lock(&sta_priv->ampdu_lock);
138 if (sta_priv->ampdu_state[tid] != WCN36XX_AMPDU_NONE)
139 goto out_unlock;
140
141 if (sta_priv->non_agg_frame_ct++ >= WCN36XX_AMPDU_START_THRESH) {
142 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START;
143 sta_priv->non_agg_frame_ct = 0;
144 ieee80211_start_tx_ba_session(sta, tid, 0);
145 }
146out_unlock:
147 spin_unlock(&sta_priv->ampdu_lock);
148}
149
113static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, 150static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
114 struct wcn36xx *wcn, 151 struct wcn36xx *wcn,
115 struct wcn36xx_vif **vif_priv, 152 struct wcn36xx_vif **vif_priv,
116 struct wcn36xx_sta *sta_priv, 153 struct wcn36xx_sta *sta_priv,
117 struct ieee80211_hdr *hdr, 154 struct sk_buff *skb,
118 bool bcast) 155 bool bcast)
119{ 156{
157 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
120 struct ieee80211_vif *vif = NULL; 158 struct ieee80211_vif *vif = NULL;
121 struct wcn36xx_vif *__vif_priv = NULL; 159 struct wcn36xx_vif *__vif_priv = NULL;
160 bool is_data_qos;
161
122 bd->bd_rate = WCN36XX_BD_RATE_DATA; 162 bd->bd_rate = WCN36XX_BD_RATE_DATA;
123 163
124 /* 164 /*
@@ -157,14 +197,26 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
157 bd->ack_policy = 1; 197 bd->ack_policy = 1;
158 } 198 }
159 *vif_priv = __vif_priv; 199 *vif_priv = __vif_priv;
200
201 is_data_qos = ieee80211_is_data_qos(hdr->frame_control);
202
203 wcn36xx_set_tx_pdu(bd,
204 is_data_qos ?
205 sizeof(struct ieee80211_qos_hdr) :
206 sizeof(struct ieee80211_hdr_3addr),
207 skb->len, sta_priv ? sta_priv->tid : 0);
208
209 if (sta_priv && is_data_qos)
210 wcn36xx_tx_start_ampdu(wcn, sta_priv, skb);
160} 211}
161 212
162static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd, 213static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
163 struct wcn36xx *wcn, 214 struct wcn36xx *wcn,
164 struct wcn36xx_vif **vif_priv, 215 struct wcn36xx_vif **vif_priv,
165 struct ieee80211_hdr *hdr, 216 struct sk_buff *skb,
166 bool bcast) 217 bool bcast)
167{ 218{
219 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
168 struct wcn36xx_vif *__vif_priv = 220 struct wcn36xx_vif *__vif_priv =
169 get_vif_by_addr(wcn, hdr->addr2); 221 get_vif_by_addr(wcn, hdr->addr2);
170 bd->sta_index = __vif_priv->self_sta_index; 222 bd->sta_index = __vif_priv->self_sta_index;
@@ -198,6 +250,12 @@ static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd,
198 } else 250 } else
199 bd->queue_id = WCN36XX_TX_U_WQ_ID; 251 bd->queue_id = WCN36XX_TX_U_WQ_ID;
200 *vif_priv = __vif_priv; 252 *vif_priv = __vif_priv;
253
254 wcn36xx_set_tx_pdu(bd,
255 ieee80211_is_data_qos(hdr->frame_control) ?
256 sizeof(struct ieee80211_qos_hdr) :
257 sizeof(struct ieee80211_hdr_3addr),
258 skb->len, WCN36XX_TID);
201} 259}
202 260
203int wcn36xx_start_tx(struct wcn36xx *wcn, 261int wcn36xx_start_tx(struct wcn36xx *wcn,
@@ -237,7 +295,7 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
237 295
238 bd->dpu_rf = WCN36XX_BMU_WQ_TX; 296 bd->dpu_rf = WCN36XX_BMU_WQ_TX;
239 297
240 bd->tx_comp = info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS; 298 bd->tx_comp = !!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS);
241 if (bd->tx_comp) { 299 if (bd->tx_comp) {
242 wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); 300 wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n");
243 spin_lock_irqsave(&wcn->dxe_lock, flags); 301 spin_lock_irqsave(&wcn->dxe_lock, flags);
@@ -259,22 +317,11 @@ int wcn36xx_start_tx(struct wcn36xx *wcn,
259 } 317 }
260 318
261 /* Data frames served first*/ 319 /* Data frames served first*/
262 if (is_low) { 320 if (is_low)
263 wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, hdr, bcast); 321 wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, skb, bcast);
264 wcn36xx_set_tx_pdu(bd, 322 else
265 ieee80211_is_data_qos(hdr->frame_control) ?
266 sizeof(struct ieee80211_qos_hdr) :
267 sizeof(struct ieee80211_hdr_3addr),
268 skb->len, sta_priv ? sta_priv->tid : 0);
269 } else {
270 /* MGMT and CTRL frames are handeld here*/ 323 /* MGMT and CTRL frames are handeld here*/
271 wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, hdr, bcast); 324 wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, skb, bcast);
272 wcn36xx_set_tx_pdu(bd,
273 ieee80211_is_data_qos(hdr->frame_control) ?
274 sizeof(struct ieee80211_qos_hdr) :
275 sizeof(struct ieee80211_hdr_3addr),
276 skb->len, WCN36XX_TID);
277 }
278 325
279 buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); 326 buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32));
280 bd->tx_bd_sign = 0xbdbdbdbd; 327 bd->tx_bd_sign = 0xbdbdbdbd;
diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h
index bbfbcf808c77..032216e82b2b 100644
--- a/drivers/net/wireless/ath/wcn36xx/txrx.h
+++ b/drivers/net/wireless/ath/wcn36xx/txrx.h
@@ -32,6 +32,12 @@
32#define WCN36XX_BD_RATE_MGMT 2 32#define WCN36XX_BD_RATE_MGMT 2
33#define WCN36XX_BD_RATE_CTRL 3 33#define WCN36XX_BD_RATE_CTRL 3
34 34
35enum wcn36xx_txbd_ssn_type {
36 WCN36XX_TXBD_SSN_FILL_HOST = 0,
37 WCN36XX_TXBD_SSN_FILL_DPU_NON_QOS = 1,
38 WCN36XX_TXBD_SSN_FILL_DPU_QOS = 2,
39};
40
35struct wcn36xx_pdu { 41struct wcn36xx_pdu {
36 u32 dpu_fb:8; 42 u32 dpu_fb:8;
37 u32 adu_fb:8; 43 u32 adu_fb:8;
@@ -50,7 +56,8 @@ struct wcn36xx_pdu {
50 /* 0x0c*/ 56 /* 0x0c*/
51 u32 reserved4:8; 57 u32 reserved4:8;
52 u32 tid:4; 58 u32 tid:4;
53 u32 reserved3:4; 59 u32 bd_ssn:2;
60 u32 reserved3:2;
54 u32 mpdu_len:16; 61 u32 mpdu_len:16;
55}; 62};
56 63
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index f0fb81dfd17b..7b41e833e18c 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -32,6 +32,9 @@
32#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" 32#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin"
33#define WCN36XX_AGGR_BUFFER_SIZE 64 33#define WCN36XX_AGGR_BUFFER_SIZE 64
34 34
35/* How many frames until we start a-mpdu TX session */
36#define WCN36XX_AMPDU_START_THRESH 20
37
35extern unsigned int wcn36xx_dbg_mask; 38extern unsigned int wcn36xx_dbg_mask;
36 39
37enum wcn36xx_debug_mask { 40enum wcn36xx_debug_mask {
@@ -74,6 +77,13 @@ enum wcn36xx_debug_mask {
74 buf, len, false); \ 77 buf, len, false); \
75} while (0) 78} while (0)
76 79
80enum wcn36xx_ampdu_state {
81 WCN36XX_AMPDU_NONE,
82 WCN36XX_AMPDU_INIT,
83 WCN36XX_AMPDU_START,
84 WCN36XX_AMPDU_OPERATIONAL,
85};
86
77#define WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value) 87#define WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value)
78#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) 88#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band)
79#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) 89#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq)
@@ -165,6 +175,10 @@ struct wcn36xx_sta {
165 bool is_data_encrypted; 175 bool is_data_encrypted;
166 /* Rates */ 176 /* Rates */
167 struct wcn36xx_hal_supported_rates supported_rates; 177 struct wcn36xx_hal_supported_rates supported_rates;
178
179 spinlock_t ampdu_lock; /* protects next two fields */
180 enum wcn36xx_ampdu_state ampdu_state[16];
181 int non_agg_frame_ct;
168}; 182};
169struct wcn36xx_dxe_ch; 183struct wcn36xx_dxe_ch;
170struct wcn36xx { 184struct wcn36xx {
@@ -243,4 +257,10 @@ static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn,
243} 257}
244void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); 258void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates);
245 259
260static inline
261struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv)
262{
263 return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv);
264}
265
246#endif /* _WCN36XX_H_ */ 266#endif /* _WCN36XX_H_ */
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index e72a95d1ced6..bd013fdb86dc 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -162,7 +162,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
162 sinfo->tx_packets = stats->tx_packets; 162 sinfo->tx_packets = stats->tx_packets;
163 sinfo->tx_failed = stats->tx_errors; 163 sinfo->tx_failed = stats->tx_errors;
164 164
165 if (test_bit(wil_status_fwconnected, &wil->status)) { 165 if (test_bit(wil_status_fwconnected, wil->status)) {
166 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); 166 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
167 sinfo->signal = reply.evt.sqi; 167 sinfo->signal = reply.evt.sqi;
168 } 168 }
@@ -282,7 +282,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
282 } 282 }
283 283
284 /* FW don't support scan after connection attempt */ 284 /* FW don't support scan after connection attempt */
285 if (test_bit(wil_status_dontscan, &wil->status)) { 285 if (test_bit(wil_status_dontscan, wil->status)) {
286 wil_err(wil, "Can't scan now\n"); 286 wil_err(wil, "Can't scan now\n");
287 return -EBUSY; 287 return -EBUSY;
288 } 288 }
@@ -362,8 +362,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
362 int ch; 362 int ch;
363 int rc = 0; 363 int rc = 0;
364 364
365 if (test_bit(wil_status_fwconnecting, &wil->status) || 365 if (test_bit(wil_status_fwconnecting, wil->status) ||
366 test_bit(wil_status_fwconnected, &wil->status)) 366 test_bit(wil_status_fwconnected, wil->status))
367 return -EALREADY; 367 return -EALREADY;
368 368
369 wil_print_connect_params(wil, sme); 369 wil_print_connect_params(wil, sme);
@@ -450,7 +450,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
450 memcpy(conn.bssid, bss->bssid, ETH_ALEN); 450 memcpy(conn.bssid, bss->bssid, ETH_ALEN);
451 memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); 451 memcpy(conn.dst_mac, bss->bssid, ETH_ALEN);
452 452
453 set_bit(wil_status_fwconnecting, &wil->status); 453 set_bit(wil_status_fwconnecting, wil->status);
454 454
455 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); 455 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
456 if (rc == 0) { 456 if (rc == 0) {
@@ -458,7 +458,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
458 mod_timer(&wil->connect_timer, 458 mod_timer(&wil->connect_timer,
459 jiffies + msecs_to_jiffies(2000)); 459 jiffies + msecs_to_jiffies(2000));
460 } else { 460 } else {
461 clear_bit(wil_status_fwconnecting, &wil->status); 461 clear_bit(wil_status_fwconnecting, wil->status);
462 } 462 }
463 463
464 out: 464 out:
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 4e6e14501c2f..45c3558ec804 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -50,6 +50,7 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
50 char _s, char _h) 50 char _s, char _h)
51{ 51{
52 void __iomem *x = wmi_addr(wil, vring->hwtail); 52 void __iomem *x = wmi_addr(wil, vring->hwtail);
53 u32 v;
53 54
54 seq_printf(s, "VRING %s = {\n", name); 55 seq_printf(s, "VRING %s = {\n", name);
55 seq_printf(s, " pa = %pad\n", &vring->pa); 56 seq_printf(s, " pa = %pad\n", &vring->pa);
@@ -58,10 +59,12 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
58 seq_printf(s, " swtail = %d\n", vring->swtail); 59 seq_printf(s, " swtail = %d\n", vring->swtail);
59 seq_printf(s, " swhead = %d\n", vring->swhead); 60 seq_printf(s, " swhead = %d\n", vring->swhead);
60 seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail); 61 seq_printf(s, " hwtail = [0x%08x] -> ", vring->hwtail);
61 if (x) 62 if (x) {
62 seq_printf(s, "0x%08x\n", ioread32(x)); 63 v = ioread32(x);
63 else 64 seq_printf(s, "0x%08x = %d\n", v, v);
65 } else {
64 seq_puts(s, "???\n"); 66 seq_puts(s, "???\n");
67 }
65 68
66 if (vring->va && (vring->size < 1025)) { 69 if (vring->va && (vring->size < 1025)) {
67 uint i; 70 uint i;
@@ -101,8 +104,8 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
101 char name[10]; 104 char name[10];
102 /* performance monitoring */ 105 /* performance monitoring */
103 cycles_t now = get_cycles(); 106 cycles_t now = get_cycles();
104 cycles_t idle = txdata->idle * 100; 107 uint64_t idle = txdata->idle * 100;
105 cycles_t total = now - txdata->begin; 108 uint64_t total = now - txdata->begin;
106 109
107 do_div(idle, total); 110 do_div(idle, total);
108 txdata->begin = now; 111 txdata->begin = now;
@@ -110,9 +113,12 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
110 113
111 snprintf(name, sizeof(name), "tx_%2d", i); 114 snprintf(name, sizeof(name), "tx_%2d", i);
112 115
113 seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n", 116 seq_printf(s,
114 wil->sta[cid].addr, cid, tid, used, avail, 117 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %3d%%\n",
115 (int)idle); 118 wil->sta[cid].addr, cid, tid,
119 txdata->agg_wsize, txdata->agg_timeout,
120 txdata->agg_amsdu ? "+" : "-",
121 used, avail, (int)idle);
116 122
117 wil_print_vring(s, wil, name, vring, '_', 'H'); 123 wil_print_vring(s, wil, name, vring, '_', 'H');
118 } 124 }
@@ -384,24 +390,67 @@ static int wil6210_debugfs_create_pseudo_ISR(struct wil6210_priv *wil,
384 return 0; 390 return 0;
385} 391}
386 392
387static const struct dbg_off itr_cnt_off[] = { 393static const struct dbg_off lgc_itr_cnt_off[] = {
388 {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32}, 394 {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_TRSH), doff_io32},
389 {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32}, 395 {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_DATA), doff_io32},
390 {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32}, 396 {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_CNT_CRL), doff_io32},
391 {}, 397 {},
392}; 398};
393 399
400static const struct dbg_off tx_itr_cnt_off[] = {
401 {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH),
402 doff_io32},
403 {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_DATA),
404 doff_io32},
405 {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL),
406 doff_io32},
407 {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_TRSH),
408 doff_io32},
409 {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_DATA),
410 doff_io32},
411 {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_TX_IDL_CNT_CTL),
412 doff_io32},
413 {},
414};
415
416static const struct dbg_off rx_itr_cnt_off[] = {
417 {"TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH),
418 doff_io32},
419 {"DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_DATA),
420 doff_io32},
421 {"CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL),
422 doff_io32},
423 {"IDL_TRSH", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_TRSH),
424 doff_io32},
425 {"IDL_DATA", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_DATA),
426 doff_io32},
427 {"IDL_CTL", S_IRUGO | S_IWUSR, HOSTADDR(RGF_DMA_ITR_RX_IDL_CNT_CTL),
428 doff_io32},
429 {},
430};
431
394static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil, 432static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
395 struct dentry *parent) 433 struct dentry *parent)
396{ 434{
397 struct dentry *d = debugfs_create_dir("ITR_CNT", parent); 435 struct dentry *d, *dtx, *drx;
398 436
437 d = debugfs_create_dir("ITR_CNT", parent);
399 if (IS_ERR_OR_NULL(d)) 438 if (IS_ERR_OR_NULL(d))
400 return -ENODEV; 439 return -ENODEV;
401 440
441 dtx = debugfs_create_dir("TX", d);
442 drx = debugfs_create_dir("RX", d);
443 if (IS_ERR_OR_NULL(dtx) || IS_ERR_OR_NULL(drx))
444 return -ENODEV;
445
402 wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr, 446 wil6210_debugfs_init_offset(wil, d, (void * __force)wil->csr,
403 itr_cnt_off); 447 lgc_itr_cnt_off);
448
449 wil6210_debugfs_init_offset(wil, dtx, (void * __force)wil->csr,
450 tx_itr_cnt_off);
404 451
452 wil6210_debugfs_init_offset(wil, drx, (void * __force)wil->csr,
453 rx_itr_cnt_off);
405 return 0; 454 return 0;
406} 455}
407 456
@@ -558,6 +607,87 @@ static const struct file_operations fops_rxon = {
558 .open = simple_open, 607 .open = simple_open,
559}; 608};
560 609
610/* block ack control, write:
611 * - "add <ringid> <agg_size> <timeout>" to trigger ADDBA
612 * - "del_tx <ringid> <reason>" to trigger DELBA for Tx side
613 * - "del_rx <CID> <TID> <reason>" to trigger DELBA for Rx side
614 */
615static ssize_t wil_write_back(struct file *file, const char __user *buf,
616 size_t len, loff_t *ppos)
617{
618 struct wil6210_priv *wil = file->private_data;
619 int rc;
620 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
621 char cmd[8];
622 int p1, p2, p3;
623
624 if (!kbuf)
625 return -ENOMEM;
626
627 rc = simple_write_to_buffer(kbuf, len, ppos, buf, len);
628 if (rc != len) {
629 kfree(kbuf);
630 return rc >= 0 ? -EIO : rc;
631 }
632
633 kbuf[len] = '\0';
634 rc = sscanf(kbuf, "%8s %d %d %d", cmd, &p1, &p2, &p3);
635 kfree(kbuf);
636
637 if (rc < 0)
638 return rc;
639 if (rc < 2)
640 return -EINVAL;
641
642 if (0 == strcmp(cmd, "add")) {
643 if (rc < 3) {
644 wil_err(wil, "BACK: add require at least 2 params\n");
645 return -EINVAL;
646 }
647 if (rc < 4)
648 p3 = 0;
649 wmi_addba(wil, p1, p2, p3);
650 } else if (0 == strcmp(cmd, "del_tx")) {
651 if (rc < 3)
652 p2 = WLAN_REASON_QSTA_LEAVE_QBSS;
653 wmi_delba_tx(wil, p1, p2);
654 } else if (0 == strcmp(cmd, "del_rx")) {
655 if (rc < 3) {
656 wil_err(wil,
657 "BACK: del_rx require at least 2 params\n");
658 return -EINVAL;
659 }
660 if (rc < 4)
661 p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
662 wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3);
663 } else {
664 wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
665 return -EINVAL;
666 }
667
668 return len;
669}
670
671static ssize_t wil_read_back(struct file *file, char __user *user_buf,
672 size_t count, loff_t *ppos)
673{
674 static const char text[] = "block ack control, write:\n"
675 " - \"add <ringid> <agg_size> <timeout>\" to trigger ADDBA\n"
676 "If missing, <timeout> defaults to 0\n"
677 " - \"del_tx <ringid> <reason>\" to trigger DELBA for Tx side\n"
678 " - \"del_rx <CID> <TID> <reason>\" to trigger DELBA for Rx side\n"
679 "If missing, <reason> set to \"STA_LEAVING\" (36)\n";
680
681 return simple_read_from_buffer(user_buf, count, ppos, text,
682 sizeof(text));
683}
684
685static const struct file_operations fops_back = {
686 .read = wil_read_back,
687 .write = wil_write_back,
688 .open = simple_open,
689};
690
561/*---tx_mgmt---*/ 691/*---tx_mgmt---*/
562/* Write mgmt frame to this file to send it */ 692/* Write mgmt frame to this file to send it */
563static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, 693static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
@@ -1116,7 +1246,8 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
1116 int i; 1246 int i;
1117 u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; 1247 u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
1118 1248
1119 seq_printf(s, "0x%03x [", r->head_seq_num); 1249 seq_printf(s, "([%2d] %3d TU) 0x%03x [", r->buf_size, r->timeout,
1250 r->head_seq_num);
1120 for (i = 0; i < r->buf_size; i++) { 1251 for (i = 0; i < r->buf_size; i++) {
1121 if (i == index) 1252 if (i == index)
1122 seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|'); 1253 seq_printf(s, "%c", r->reorder_buf[i] ? 'O' : '|');
@@ -1127,10 +1258,10 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
1127} 1258}
1128 1259
1129static int wil_sta_debugfs_show(struct seq_file *s, void *data) 1260static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1261__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
1130{ 1262{
1131 struct wil6210_priv *wil = s->private; 1263 struct wil6210_priv *wil = s->private;
1132 int i, tid; 1264 int i, tid;
1133 unsigned long flags;
1134 1265
1135 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 1266 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1136 struct wil_sta_info *p = &wil->sta[i]; 1267 struct wil_sta_info *p = &wil->sta[i];
@@ -1151,7 +1282,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1151 (p->data_port_open ? " data_port_open" : "")); 1282 (p->data_port_open ? " data_port_open" : ""));
1152 1283
1153 if (p->status == wil_sta_connected) { 1284 if (p->status == wil_sta_connected) {
1154 spin_lock_irqsave(&p->tid_rx_lock, flags); 1285 spin_lock_bh(&p->tid_rx_lock);
1155 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { 1286 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1156 struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; 1287 struct wil_tid_ampdu_rx *r = p->tid_rx[tid];
1157 1288
@@ -1160,7 +1291,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1160 wil_print_rxtid(s, r); 1291 wil_print_rxtid(s, r);
1161 } 1292 }
1162 } 1293 }
1163 spin_unlock_irqrestore(&p->tid_rx_lock, flags); 1294 spin_unlock_bh(&p->tid_rx_lock);
1164 } 1295 }
1165 } 1296 }
1166 1297
@@ -1217,6 +1348,7 @@ static const struct {
1217 {"rxon", S_IWUSR, &fops_rxon}, 1348 {"rxon", S_IWUSR, &fops_rxon},
1218 {"tx_mgmt", S_IWUSR, &fops_txmgmt}, 1349 {"tx_mgmt", S_IWUSR, &fops_txmgmt},
1219 {"wmi_send", S_IWUSR, &fops_wmi}, 1350 {"wmi_send", S_IWUSR, &fops_wmi},
1351 {"back", S_IRUGO | S_IWUSR, &fops_back},
1220 {"temp", S_IRUGO, &fops_temp}, 1352 {"temp", S_IRUGO, &fops_temp},
1221 {"freq", S_IRUGO, &fops_freq}, 1353 {"freq", S_IRUGO, &fops_freq},
1222 {"link", S_IRUGO, &fops_link}, 1354 {"link", S_IRUGO, &fops_link},
@@ -1261,7 +1393,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
1261/* fields in struct wil6210_priv */ 1393/* fields in struct wil6210_priv */
1262static const struct dbg_off dbg_wil_off[] = { 1394static const struct dbg_off dbg_wil_off[] = {
1263 WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32), 1395 WIL_FIELD(secure_pcp, S_IRUGO | S_IWUSR, doff_u32),
1264 WIL_FIELD(status, S_IRUGO | S_IWUSR, doff_ulong), 1396 WIL_FIELD(status[0], S_IRUGO | S_IWUSR, doff_ulong),
1265 WIL_FIELD(fw_version, S_IRUGO, doff_u32), 1397 WIL_FIELD(fw_version, S_IRUGO, doff_u32),
1266 WIL_FIELD(hw_version, S_IRUGO, doff_x32), 1398 WIL_FIELD(hw_version, S_IRUGO, doff_x32),
1267 WIL_FIELD(recovery_count, S_IRUGO, doff_u32), 1399 WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c
index d686638972be..4c44a82c34d7 100644
--- a/drivers/net/wireless/ath/wil6210/ethtool.c
+++ b/drivers/net/wireless/ath/wil6210/ethtool.c
@@ -45,16 +45,35 @@ static int wil_ethtoolops_get_coalesce(struct net_device *ndev,
45 struct ethtool_coalesce *cp) 45 struct ethtool_coalesce *cp)
46{ 46{
47 struct wil6210_priv *wil = ndev_to_wil(ndev); 47 struct wil6210_priv *wil = ndev_to_wil(ndev);
48 u32 itr_en, itr_val = 0; 48 u32 tx_itr_en, tx_itr_val = 0;
49 u32 rx_itr_en, rx_itr_val = 0;
49 50
50 wil_dbg_misc(wil, "%s()\n", __func__); 51 wil_dbg_misc(wil, "%s()\n", __func__);
51 52
52 itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL)); 53 if (test_bit(hw_capability_advanced_itr_moderation,
53 if (itr_en & BIT_DMA_ITR_CNT_CRL_EN) 54 wil->hw_capabilities)) {
54 itr_val = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); 55 tx_itr_en = ioread32(wil->csr +
55 56 HOSTADDR(RGF_DMA_ITR_TX_CNT_CTL));
56 cp->rx_coalesce_usecs = itr_val; 57 if (tx_itr_en & BIT_DMA_ITR_TX_CNT_CTL_EN)
58 tx_itr_val =
59 ioread32(wil->csr +
60 HOSTADDR(RGF_DMA_ITR_TX_CNT_TRSH));
61
62 rx_itr_en = ioread32(wil->csr +
63 HOSTADDR(RGF_DMA_ITR_RX_CNT_CTL));
64 if (rx_itr_en & BIT_DMA_ITR_RX_CNT_CTL_EN)
65 rx_itr_val =
66 ioread32(wil->csr +
67 HOSTADDR(RGF_DMA_ITR_RX_CNT_TRSH));
68 } else {
69 rx_itr_en = ioread32(wil->csr + HOSTADDR(RGF_DMA_ITR_CNT_CRL));
70 if (rx_itr_en & BIT_DMA_ITR_CNT_CRL_EN)
71 rx_itr_val = ioread32(wil->csr +
72 HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
73 }
57 74
75 cp->tx_coalesce_usecs = tx_itr_val;
76 cp->rx_coalesce_usecs = rx_itr_val;
58 return 0; 77 return 0;
59} 78}
60 79
@@ -63,22 +82,25 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
63{ 82{
64 struct wil6210_priv *wil = ndev_to_wil(ndev); 83 struct wil6210_priv *wil = ndev_to_wil(ndev);
65 84
66 wil_dbg_misc(wil, "%s(%d usec)\n", __func__, cp->rx_coalesce_usecs); 85 wil_dbg_misc(wil, "%s(rx %d usec, tx %d usec)\n", __func__,
86 cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
67 87
68 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 88 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) {
69 wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); 89 wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n");
70 return -EINVAL; 90 return -EINVAL;
71 } 91 }
72 92
73 /* only @rx_coalesce_usecs supported, ignore 93 /* only @rx_coalesce_usecs and @tx_coalesce_usecs supported,
74 * other parameters 94 * ignore other parameters
75 */ 95 */
76 96
77 if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX) 97 if (cp->rx_coalesce_usecs > WIL6210_ITR_TRSH_MAX ||
98 cp->tx_coalesce_usecs > WIL6210_ITR_TRSH_MAX)
78 goto out_bad; 99 goto out_bad;
79 100
80 wil->itr_trsh = cp->rx_coalesce_usecs; 101 wil->tx_max_burst_duration = cp->tx_coalesce_usecs;
81 wil_set_itr_trsh(wil); 102 wil->rx_max_burst_duration = cp->rx_coalesce_usecs;
103 wil_configure_interrupt_moderation(wil);
82 104
83 return 0; 105 return 0;
84 106
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 4bcbd6297b3e..a6f923086f31 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -102,7 +102,7 @@ static void wil6210_mask_irq_pseudo(struct wil6210_priv *wil)
102 iowrite32(WIL6210_IRQ_DISABLE, wil->csr + 102 iowrite32(WIL6210_IRQ_DISABLE, wil->csr +
103 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 103 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
104 104
105 clear_bit(wil_status_irqen, &wil->status); 105 clear_bit(wil_status_irqen, wil->status);
106} 106}
107 107
108void wil6210_unmask_irq_tx(struct wil6210_priv *wil) 108void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
@@ -130,7 +130,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
130{ 130{
131 wil_dbg_irq(wil, "%s()\n", __func__); 131 wil_dbg_irq(wil, "%s()\n", __func__);
132 132
133 set_bit(wil_status_irqen, &wil->status); 133 set_bit(wil_status_irqen, wil->status);
134 134
135 iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr + 135 iowrite32(WIL6210_IRQ_PSEUDO_MASK, wil->csr +
136 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 136 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
@@ -157,15 +157,91 @@ void wil_unmask_irq(struct wil6210_priv *wil)
157 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 157 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
158 offsetof(struct RGF_ICR, ICC)); 158 offsetof(struct RGF_ICR, ICC));
159 159
160 /* interrupt moderation parameters */
161 wil_set_itr_trsh(wil);
162
163 wil6210_unmask_irq_pseudo(wil); 160 wil6210_unmask_irq_pseudo(wil);
164 wil6210_unmask_irq_tx(wil); 161 wil6210_unmask_irq_tx(wil);
165 wil6210_unmask_irq_rx(wil); 162 wil6210_unmask_irq_rx(wil);
166 wil6210_unmask_irq_misc(wil); 163 wil6210_unmask_irq_misc(wil);
167} 164}
168 165
166/* target write operation */
167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
168
169static
170void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
171{
172 /* Disable and clear tx counter before (re)configuration */
173 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR);
174 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration);
175 wil_info(wil, "set ITR_TX_CNT_TRSH = %d usec\n",
176 wil->tx_max_burst_duration);
177 /* Configure TX max burst duration timer to use usec units */
178 W(RGF_DMA_ITR_TX_CNT_CTL,
179 BIT_DMA_ITR_TX_CNT_CTL_EN | BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL);
180
181 /* Disable and clear tx idle counter before (re)configuration */
182 W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR);
183 W(RGF_DMA_ITR_TX_IDL_CNT_TRSH, wil->tx_interframe_timeout);
184 wil_info(wil, "set ITR_TX_IDL_CNT_TRSH = %d usec\n",
185 wil->tx_interframe_timeout);
186 /* Configure TX max burst duration timer to use usec units */
187 W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_EN |
188 BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL);
189
190 /* Disable and clear rx counter before (re)configuration */
191 W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_CLR);
192 W(RGF_DMA_ITR_RX_CNT_TRSH, wil->rx_max_burst_duration);
193 wil_info(wil, "set ITR_RX_CNT_TRSH = %d usec\n",
194 wil->rx_max_burst_duration);
195 /* Configure TX max burst duration timer to use usec units */
196 W(RGF_DMA_ITR_RX_CNT_CTL,
197 BIT_DMA_ITR_RX_CNT_CTL_EN | BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL);
198
199 /* Disable and clear rx idle counter before (re)configuration */
200 W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR);
201 W(RGF_DMA_ITR_RX_IDL_CNT_TRSH, wil->rx_interframe_timeout);
202 wil_info(wil, "set ITR_RX_IDL_CNT_TRSH = %d usec\n",
203 wil->rx_interframe_timeout);
204 /* Configure TX max burst duration timer to use usec units */
205 W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_EN |
206 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL);
207}
208
209static
210void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil)
211{
212 /* disable, use usec resolution */
213 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR);
214
215 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration);
216 W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration);
217 /* start it */
218 W(RGF_DMA_ITR_CNT_CRL,
219 BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK);
220}
221
222#undef W
223
224void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
225{
226 wil_dbg_irq(wil, "%s()\n", __func__);
227
228 /* disable interrupt moderation for monitor
229 * to get better timestamp precision
230 */
231 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
232 return;
233
234 if (test_bit(hw_capability_advanced_itr_moderation,
235 wil->hw_capabilities))
236 wil_configure_interrupt_moderation_new(wil);
237 else {
238 /* Advanced interrupt moderation is not available before
239 * Sparrow v2. Will use legacy interrupt moderation
240 */
241 wil_configure_interrupt_moderation_lgc(wil);
242 }
243}
244
169static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 245static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
170{ 246{
171 struct wil6210_priv *wil = cookie; 247 struct wil6210_priv *wil = cookie;
@@ -194,18 +270,19 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
194 wil_dbg_irq(wil, "RX done\n"); 270 wil_dbg_irq(wil, "RX done\n");
195 271
196 if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH) 272 if (isr & BIT_DMA_EP_RX_ICR_RX_HTRSH)
197 wil_err_ratelimited(wil, "Received \"Rx buffer is in risk " 273 wil_err_ratelimited(wil,
198 "of overflow\" interrupt\n"); 274 "Received \"Rx buffer is in risk of overflow\" interrupt\n");
199 275
200 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE | BIT_DMA_EP_RX_ICR_RX_HTRSH); 276 isr &= ~(BIT_DMA_EP_RX_ICR_RX_DONE |
201 if (test_bit(wil_status_reset_done, &wil->status)) { 277 BIT_DMA_EP_RX_ICR_RX_HTRSH);
202 if (test_bit(wil_status_napi_en, &wil->status)) { 278 if (test_bit(wil_status_reset_done, wil->status)) {
279 if (test_bit(wil_status_napi_en, wil->status)) {
203 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 280 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n");
204 need_unmask = false; 281 need_unmask = false;
205 napi_schedule(&wil->napi_rx); 282 napi_schedule(&wil->napi_rx);
206 } else { 283 } else {
207 wil_err(wil, "Got Rx interrupt while " 284 wil_err(wil,
208 "stopping interface\n"); 285 "Got Rx interrupt while stopping interface\n");
209 } 286 }
210 } else { 287 } else {
211 wil_err(wil, "Got Rx interrupt while in reset\n"); 288 wil_err(wil, "Got Rx interrupt while in reset\n");
@@ -248,7 +325,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
248 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE; 325 isr &= ~BIT_DMA_EP_TX_ICR_TX_DONE;
249 /* clear also all VRING interrupts */ 326 /* clear also all VRING interrupts */
250 isr &= ~(BIT(25) - 1UL); 327 isr &= ~(BIT(25) - 1UL);
251 if (test_bit(wil_status_reset_done, &wil->status)) { 328 if (test_bit(wil_status_reset_done, wil->status)) {
252 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n"); 329 wil_dbg_txrx(wil, "NAPI(Tx) schedule\n");
253 need_unmask = false; 330 need_unmask = false;
254 napi_schedule(&wil->napi_tx); 331 napi_schedule(&wil->napi_tx);
@@ -310,7 +387,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
310 387
311 if (isr & ISR_MISC_FW_ERROR) { 388 if (isr & ISR_MISC_FW_ERROR) {
312 wil_err(wil, "Firmware error detected\n"); 389 wil_err(wil, "Firmware error detected\n");
313 clear_bit(wil_status_fwready, &wil->status); 390 clear_bit(wil_status_fwready, wil->status);
314 /* 391 /*
315 * do not clear @isr here - we do 2-nd part in thread 392 * do not clear @isr here - we do 2-nd part in thread
316 * there, user space get notified, and it should be done 393 * there, user space get notified, and it should be done
@@ -321,7 +398,7 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
321 if (isr & ISR_MISC_FW_READY) { 398 if (isr & ISR_MISC_FW_READY) {
322 wil_dbg_irq(wil, "IRQ: FW ready\n"); 399 wil_dbg_irq(wil, "IRQ: FW ready\n");
323 wil_cache_mbox_regs(wil); 400 wil_cache_mbox_regs(wil);
324 set_bit(wil_status_reset_done, &wil->status); 401 set_bit(wil_status_reset_done, wil->status);
325 /** 402 /**
326 * Actual FW ready indicated by the 403 * Actual FW ready indicated by the
327 * WMI_FW_READY_EVENTID 404 * WMI_FW_READY_EVENTID
@@ -394,7 +471,7 @@ static irqreturn_t wil6210_thread_irq(int irq, void *cookie)
394 */ 471 */
395static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause) 472static int wil6210_debug_irq_mask(struct wil6210_priv *wil, u32 pseudo_cause)
396{ 473{
397 if (!test_bit(wil_status_irqen, &wil->status)) { 474 if (!test_bit(wil_status_irqen, wil->status)) {
398 u32 icm_rx = wil_ioread32_and_clear(wil->csr + 475 u32 icm_rx = wil_ioread32_and_clear(wil->csr +
399 HOSTADDR(RGF_DMA_EP_RX_ICR) + 476 HOSTADDR(RGF_DMA_EP_RX_ICR) +
400 offsetof(struct RGF_ICR, ICM)); 477 offsetof(struct RGF_ICR, ICM));
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 8ff3fe34fe05..62dc24189bd3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -33,15 +33,46 @@ static bool no_fw_load = true;
33module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); 33module_param(no_fw_load, bool, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash."); 34MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash.");
35 35
36static unsigned int itr_trsh = WIL6210_ITR_TRSH_DEFAULT; 36static unsigned int tx_interframe_timeout =
37 WIL6210_ITR_TX_INTERFRAME_TIMEOUT_DEFAULT;
37 38
38module_param(itr_trsh, uint, S_IRUGO); 39module_param(tx_interframe_timeout, uint, S_IRUGO);
39MODULE_PARM_DESC(itr_trsh, " Interrupt moderation threshold, usecs."); 40MODULE_PARM_DESC(tx_interframe_timeout,
41 " Interrupt moderation TX interframe timeout, usecs.");
42
43static unsigned int rx_interframe_timeout =
44 WIL6210_ITR_RX_INTERFRAME_TIMEOUT_DEFAULT;
45
46module_param(rx_interframe_timeout, uint, S_IRUGO);
47MODULE_PARM_DESC(rx_interframe_timeout,
48 " Interrupt moderation RX interframe timeout, usecs.");
49
50static unsigned int tx_max_burst_duration =
51 WIL6210_ITR_TX_MAX_BURST_DURATION_DEFAULT;
52
53module_param(tx_max_burst_duration, uint, S_IRUGO);
54MODULE_PARM_DESC(tx_max_burst_duration,
55 " Interrupt moderation TX max burst duration, usecs.");
56
57static unsigned int rx_max_burst_duration =
58 WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT;
59
60module_param(rx_max_burst_duration, uint, S_IRUGO);
61MODULE_PARM_DESC(rx_max_burst_duration,
62 " Interrupt moderation RX max burst duration, usecs.");
63
64/* if not set via modparam, will be set to default value of 1/8 of
65 * rx ring size during init flow
66 */
67unsigned short rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_INIT;
68module_param(rx_ring_overflow_thrsh, ushort, S_IRUGO);
69MODULE_PARM_DESC(rx_ring_overflow_thrsh,
70 " RX ring overflow threshold in descriptors.");
40 71
41/* We allow allocation of more than 1 page buffers to support large packets. 72/* We allow allocation of more than 1 page buffers to support large packets.
42 * It is suboptimal behavior performance wise in case MTU above page size. 73 * It is suboptimal behavior performance wise in case MTU above page size.
43 */ 74 */
44unsigned int mtu_max = TXRX_BUF_LEN_DEFAULT - ETH_HLEN; 75unsigned int mtu_max = TXRX_BUF_LEN_DEFAULT - WIL_MAX_MPDU_OVERHEAD;
45static int mtu_max_set(const char *val, const struct kernel_param *kp) 76static int mtu_max_set(const char *val, const struct kernel_param *kp)
46{ 77{
47 int ret; 78 int ret;
@@ -53,7 +84,7 @@ static int mtu_max_set(const char *val, const struct kernel_param *kp)
53 if (ret) 84 if (ret)
54 return ret; 85 return ret;
55 86
56 if (mtu_max < 68 || mtu_max > IEEE80211_MAX_DATA_LEN_DMG) 87 if (mtu_max < 68 || mtu_max > WIL_MAX_ETH_MTU)
57 ret = -EINVAL; 88 ret = -EINVAL;
58 89
59 return ret; 90 return ret;
@@ -135,12 +166,14 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
135 166
136static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, 167static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
137 u16 reason_code, bool from_event) 168 u16 reason_code, bool from_event)
169__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
138{ 170{
139 uint i; 171 uint i;
140 struct net_device *ndev = wil_to_ndev(wil); 172 struct net_device *ndev = wil_to_ndev(wil);
141 struct wireless_dev *wdev = wil->wdev; 173 struct wireless_dev *wdev = wil->wdev;
142 struct wil_sta_info *sta = &wil->sta[cid]; 174 struct wil_sta_info *sta = &wil->sta[cid];
143 175
176 might_sleep();
144 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, 177 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
145 sta->status); 178 sta->status);
146 179
@@ -163,15 +196,14 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
163 196
164 for (i = 0; i < WIL_STA_TID_NUM; i++) { 197 for (i = 0; i < WIL_STA_TID_NUM; i++) {
165 struct wil_tid_ampdu_rx *r; 198 struct wil_tid_ampdu_rx *r;
166 unsigned long flags;
167 199
168 spin_lock_irqsave(&sta->tid_rx_lock, flags); 200 spin_lock_bh(&sta->tid_rx_lock);
169 201
170 r = sta->tid_rx[i]; 202 r = sta->tid_rx[i];
171 sta->tid_rx[i] = NULL; 203 sta->tid_rx[i] = NULL;
172 wil_tid_ampdu_rx_free(wil, r); 204 wil_tid_ampdu_rx_free(wil, r);
173 205
174 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 206 spin_unlock_bh(&sta->tid_rx_lock);
175 } 207 }
176 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 208 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
177 if (wil->vring2cid_tid[i][0] == cid) 209 if (wil->vring2cid_tid[i][0] == cid)
@@ -188,34 +220,45 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
188 struct wireless_dev *wdev = wil->wdev; 220 struct wireless_dev *wdev = wil->wdev;
189 221
190 might_sleep(); 222 might_sleep();
191 if (bssid) { 223 wil_dbg_misc(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
224 reason_code, from_event ? "+" : "-");
225
226 /* Cases are:
227 * - disconnect single STA, still connected
228 * - disconnect single STA, already disconnected
229 * - disconnect all
230 *
231 * For "disconnect all", there are 2 options:
232 * - bssid == NULL
233 * - bssid is our MAC address
234 */
235 if (bssid && memcmp(ndev->dev_addr, bssid, ETH_ALEN)) {
192 cid = wil_find_cid(wil, bssid); 236 cid = wil_find_cid(wil, bssid);
193 wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); 237 wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
194 } else { 238 bssid, cid, reason_code);
195 wil_dbg_misc(wil, "%s(all)\n", __func__); 239 if (cid >= 0) /* disconnect 1 peer */
196 } 240 wil_disconnect_cid(wil, cid, reason_code, from_event);
197 241 } else { /* all */
198 if (cid >= 0) /* disconnect 1 peer */ 242 wil_dbg_misc(wil, "Disconnect all\n");
199 wil_disconnect_cid(wil, cid, reason_code, from_event);
200 else /* disconnect all */
201 for (cid = 0; cid < WIL6210_MAX_CID; cid++) 243 for (cid = 0; cid < WIL6210_MAX_CID; cid++)
202 wil_disconnect_cid(wil, cid, reason_code, from_event); 244 wil_disconnect_cid(wil, cid, reason_code, from_event);
245 }
203 246
204 /* link state */ 247 /* link state */
205 switch (wdev->iftype) { 248 switch (wdev->iftype) {
206 case NL80211_IFTYPE_STATION: 249 case NL80211_IFTYPE_STATION:
207 case NL80211_IFTYPE_P2P_CLIENT: 250 case NL80211_IFTYPE_P2P_CLIENT:
208 wil_link_off(wil); 251 wil_link_off(wil);
209 if (test_bit(wil_status_fwconnected, &wil->status)) { 252 if (test_bit(wil_status_fwconnected, wil->status)) {
210 clear_bit(wil_status_fwconnected, &wil->status); 253 clear_bit(wil_status_fwconnected, wil->status);
211 cfg80211_disconnected(ndev, reason_code, 254 cfg80211_disconnected(ndev, reason_code,
212 NULL, 0, GFP_KERNEL); 255 NULL, 0, GFP_KERNEL);
213 } else if (test_bit(wil_status_fwconnecting, &wil->status)) { 256 } else if (test_bit(wil_status_fwconnecting, wil->status)) {
214 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 257 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
215 WLAN_STATUS_UNSPECIFIED_FAILURE, 258 WLAN_STATUS_UNSPECIFIED_FAILURE,
216 GFP_KERNEL); 259 GFP_KERNEL);
217 } 260 }
218 clear_bit(wil_status_fwconnecting, &wil->status); 261 clear_bit(wil_status_fwconnecting, wil->status);
219 break; 262 break;
220 default: 263 default:
221 break; 264 break;
@@ -248,7 +291,7 @@ static void wil_scan_timer_fn(ulong x)
248{ 291{
249 struct wil6210_priv *wil = (void *)x; 292 struct wil6210_priv *wil = (void *)x;
250 293
251 clear_bit(wil_status_fwready, &wil->status); 294 clear_bit(wil_status_fwready, wil->status);
252 wil_err(wil, "Scan timeout detected, start fw error recovery\n"); 295 wil_err(wil, "Scan timeout detected, start fw error recovery\n");
253 wil->recovery_state = fw_recovery_pending; 296 wil->recovery_state = fw_recovery_pending;
254 schedule_work(&wil->fw_error_worker); 297 schedule_work(&wil->fw_error_worker);
@@ -384,6 +427,8 @@ int wil_priv_init(struct wil6210_priv *wil)
384 427
385 mutex_init(&wil->mutex); 428 mutex_init(&wil->mutex);
386 mutex_init(&wil->wmi_mutex); 429 mutex_init(&wil->wmi_mutex);
430 mutex_init(&wil->back_rx_mutex);
431 mutex_init(&wil->back_tx_mutex);
387 432
388 init_completion(&wil->wmi_ready); 433 init_completion(&wil->wmi_ready);
389 init_completion(&wil->wmi_call); 434 init_completion(&wil->wmi_call);
@@ -396,25 +441,37 @@ int wil_priv_init(struct wil6210_priv *wil)
396 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 441 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
397 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 442 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
398 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 443 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
444 INIT_WORK(&wil->back_rx_worker, wil_back_rx_worker);
445 INIT_WORK(&wil->back_tx_worker, wil_back_tx_worker);
399 446
400 INIT_LIST_HEAD(&wil->pending_wmi_ev); 447 INIT_LIST_HEAD(&wil->pending_wmi_ev);
448 INIT_LIST_HEAD(&wil->back_rx_pending);
449 INIT_LIST_HEAD(&wil->back_tx_pending);
401 spin_lock_init(&wil->wmi_ev_lock); 450 spin_lock_init(&wil->wmi_ev_lock);
402 init_waitqueue_head(&wil->wq); 451 init_waitqueue_head(&wil->wq);
403 452
404 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); 453 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
405 if (!wil->wmi_wq) 454 if (!wil->wmi_wq)
406 return -EAGAIN; 455 return -EAGAIN;
407 456
408 wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); 457 wil->wq_service = create_singlethread_workqueue(WIL_NAME "_service");
409 if (!wil->wmi_wq_conn) { 458 if (!wil->wq_service)
410 destroy_workqueue(wil->wmi_wq); 459 goto out_wmi_wq;
411 return -EAGAIN;
412 }
413 460
414 wil->last_fw_recovery = jiffies; 461 wil->last_fw_recovery = jiffies;
415 wil->itr_trsh = itr_trsh; 462 wil->tx_interframe_timeout = tx_interframe_timeout;
463 wil->rx_interframe_timeout = rx_interframe_timeout;
464 wil->tx_max_burst_duration = tx_max_burst_duration;
465 wil->rx_max_burst_duration = rx_max_burst_duration;
416 466
467 if (rx_ring_overflow_thrsh == WIL6210_RX_HIGH_TRSH_INIT)
468 rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_DEFAULT;
417 return 0; 469 return 0;
470
471out_wmi_wq:
472 destroy_workqueue(wil->wmi_wq);
473
474 return -EAGAIN;
418} 475}
419 476
420/** 477/**
@@ -448,7 +505,11 @@ void wil_priv_deinit(struct wil6210_priv *wil)
448 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 505 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
449 mutex_unlock(&wil->mutex); 506 mutex_unlock(&wil->mutex);
450 wmi_event_flush(wil); 507 wmi_event_flush(wil);
451 destroy_workqueue(wil->wmi_wq_conn); 508 wil_back_rx_flush(wil);
509 cancel_work_sync(&wil->back_rx_worker);
510 wil_back_tx_flush(wil);
511 cancel_work_sync(&wil->back_tx_worker);
512 destroy_workqueue(wil->wq_service);
452 destroy_workqueue(wil->wmi_wq); 513 destroy_workqueue(wil->wmi_wq);
453} 514}
454 515
@@ -478,13 +539,10 @@ static int wil_target_reset(struct wil6210_priv *wil)
478{ 539{
479 int delay = 0; 540 int delay = 0;
480 u32 x; 541 u32 x;
481 u32 rev_id; 542 bool is_reset_v2 = test_bit(hw_capability_reset_v2,
482 bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW); 543 wil->hw_capabilities);
483
484 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name);
485 544
486 wil->hw_version = R(RGF_USER_FW_REV_ID); 545 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name);
487 rev_id = wil->hw_version & 0xff;
488 546
489 /* Clear MAC link up */ 547 /* Clear MAC link up */
490 S(RGF_HP_CTRL, BIT(15)); 548 S(RGF_HP_CTRL, BIT(15));
@@ -496,7 +554,7 @@ static int wil_target_reset(struct wil6210_priv *wil)
496 /* Clear Fw Download notification */ 554 /* Clear Fw Download notification */
497 C(RGF_USER_USAGE_6, BIT(0)); 555 C(RGF_USER_USAGE_6, BIT(0));
498 556
499 if (is_sparrow) { 557 if (is_reset_v2) {
500 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); 558 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN);
501 /* XTAL stabilization should take about 3ms */ 559 /* XTAL stabilization should take about 3ms */
502 usleep_range(5000, 7000); 560 usleep_range(5000, 7000);
@@ -517,10 +575,11 @@ static int wil_target_reset(struct wil6210_priv *wil)
517 575
518 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 576 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
519 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 577 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
520 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000f0 : 0x00000170); 578 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3,
579 is_reset_v2 ? 0x000000f0 : 0x00000170);
521 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); 580 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00);
522 581
523 if (is_sparrow) { 582 if (is_reset_v2) {
524 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 583 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
525 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0); 584 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
526 } 585 }
@@ -530,19 +589,14 @@ static int wil_target_reset(struct wil6210_priv *wil)
530 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 589 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
531 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 590 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
532 591
533 if (is_sparrow) { 592 if (is_reset_v2) {
534 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 593 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
535 /* reset A2 PCIE AHB */ 594 /* reset A2 PCIE AHB */
536 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 595 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
537 } else { 596 } else {
538 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 597 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
539 if (rev_id == 1) { 598 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
540 /* reset A1 BOTH PCIE AHB & PCIE RGF */ 599 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
541 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
542 } else {
543 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
544 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
545 }
546 } 600 }
547 601
548 /* TODO: check order here!!! Erez code is different */ 602 /* TODO: check order here!!! Erez code is different */
@@ -559,8 +613,7 @@ static int wil_target_reset(struct wil6210_priv *wil)
559 } 613 }
560 } while (x != HW_MACHINE_BOOT_DONE); 614 } while (x != HW_MACHINE_BOOT_DONE);
561 615
562 /* TODO: Erez check rev_id != 1 */ 616 if (!is_reset_v2)
563 if (!is_sparrow && (rev_id != 1))
564 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 617 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
565 618
566 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 619 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
@@ -569,26 +622,6 @@ static int wil_target_reset(struct wil6210_priv *wil)
569 return 0; 622 return 0;
570} 623}
571 624
572/**
573 * wil_set_itr_trsh: - apply interrupt coalescing params
574 */
575void wil_set_itr_trsh(struct wil6210_priv *wil)
576{
577 /* disable, use usec resolution */
578 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EXT_TICK);
579
580 /* disable interrupt moderation for monitor
581 * to get better timestamp precision
582 */
583 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
584 return;
585
586 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->itr_trsh);
587 W(RGF_DMA_ITR_CNT_TRSH, wil->itr_trsh);
588 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_EN |
589 BIT_DMA_ITR_CNT_CRL_EXT_TICK); /* start it */
590}
591
592#undef R 625#undef R
593#undef W 626#undef W
594#undef S 627#undef S
@@ -629,13 +662,17 @@ int wil_reset(struct wil6210_priv *wil)
629 662
630 wil_dbg_misc(wil, "%s()\n", __func__); 663 wil_dbg_misc(wil, "%s()\n", __func__);
631 664
665 if (wil->hw_version == HW_VER_UNKNOWN)
666 return -ENODEV;
667
632 WARN_ON(!mutex_is_locked(&wil->mutex)); 668 WARN_ON(!mutex_is_locked(&wil->mutex));
633 WARN_ON(test_bit(wil_status_napi_en, &wil->status)); 669 WARN_ON(test_bit(wil_status_napi_en, wil->status));
634 670
635 cancel_work_sync(&wil->disconnect_worker); 671 cancel_work_sync(&wil->disconnect_worker);
636 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 672 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
637 673
638 wil->status = 0; /* prevent NAPI from being scheduled */ 674 /* prevent NAPI from being scheduled */
675 bitmap_zero(wil->status, wil_status_last);
639 676
640 if (wil->scan_request) { 677 if (wil->scan_request) {
641 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 678 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
@@ -649,7 +686,7 @@ int wil_reset(struct wil6210_priv *wil)
649 686
650 wmi_event_flush(wil); 687 wmi_event_flush(wil);
651 688
652 flush_workqueue(wil->wmi_wq_conn); 689 flush_workqueue(wil->wq_service);
653 flush_workqueue(wil->wmi_wq); 690 flush_workqueue(wil->wmi_wq);
654 691
655 rc = wil_target_reset(wil); 692 rc = wil_target_reset(wil);
@@ -688,6 +725,7 @@ int wil_reset(struct wil6210_priv *wil)
688 reinit_completion(&wil->wmi_ready); 725 reinit_completion(&wil->wmi_ready);
689 reinit_completion(&wil->wmi_call); 726 reinit_completion(&wil->wmi_call);
690 727
728 wil_configure_interrupt_moderation(wil);
691 wil_unmask_irq(wil); 729 wil_unmask_irq(wil);
692 730
693 /* we just started MAC, wait for FW ready */ 731 /* we just started MAC, wait for FW ready */
@@ -774,7 +812,7 @@ int __wil_up(struct wil6210_priv *wil)
774 wil_dbg_misc(wil, "NAPI enable\n"); 812 wil_dbg_misc(wil, "NAPI enable\n");
775 napi_enable(&wil->napi_rx); 813 napi_enable(&wil->napi_rx);
776 napi_enable(&wil->napi_tx); 814 napi_enable(&wil->napi_tx);
777 set_bit(wil_status_napi_en, &wil->status); 815 set_bit(wil_status_napi_en, wil->status);
778 816
779 if (wil->platform_ops.bus_request) 817 if (wil->platform_ops.bus_request)
780 wil->platform_ops.bus_request(wil->platform_handle, 818 wil->platform_ops.bus_request(wil->platform_handle,
@@ -807,7 +845,7 @@ int __wil_down(struct wil6210_priv *wil)
807 wil->platform_ops.bus_request(wil->platform_handle, 0); 845 wil->platform_ops.bus_request(wil->platform_handle, 0);
808 846
809 wil_disable_irq(wil); 847 wil_disable_irq(wil);
810 if (test_and_clear_bit(wil_status_napi_en, &wil->status)) { 848 if (test_and_clear_bit(wil_status_napi_en, wil->status)) {
811 napi_disable(&wil->napi_rx); 849 napi_disable(&wil->napi_rx);
812 napi_disable(&wil->napi_tx); 850 napi_disable(&wil->napi_tx);
813 wil_dbg_misc(wil, "NAPI disable\n"); 851 wil_dbg_misc(wil, "NAPI disable\n");
@@ -822,15 +860,15 @@ int __wil_down(struct wil6210_priv *wil)
822 wil->scan_request = NULL; 860 wil->scan_request = NULL;
823 } 861 }
824 862
825 if (test_bit(wil_status_fwconnected, &wil->status) || 863 if (test_bit(wil_status_fwconnected, wil->status) ||
826 test_bit(wil_status_fwconnecting, &wil->status)) 864 test_bit(wil_status_fwconnecting, wil->status))
827 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); 865 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
828 866
829 /* make sure wil is idle (not connected) */ 867 /* make sure wil is idle (not connected) */
830 mutex_unlock(&wil->mutex); 868 mutex_unlock(&wil->mutex);
831 while (iter--) { 869 while (iter--) {
832 int idle = !test_bit(wil_status_fwconnected, &wil->status) && 870 int idle = !test_bit(wil_status_fwconnected, wil->status) &&
833 !test_bit(wil_status_fwconnecting, &wil->status); 871 !test_bit(wil_status_fwconnecting, wil->status);
834 if (idle) 872 if (idle)
835 break; 873 break;
836 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS); 874 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 66626a8ee728..3dd26709ccb2 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -31,6 +31,46 @@ static bool debug_fw; /* = false; */
31module_param(debug_fw, bool, S_IRUGO); 31module_param(debug_fw, bool, S_IRUGO);
32MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug"); 32MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug");
33 33
34static
35void wil_set_capabilities(struct wil6210_priv *wil)
36{
37 u32 rev_id = ioread32(wil->csr + HOSTADDR(RGF_USER_JTAG_DEV_ID));
38
39 bitmap_zero(wil->hw_capabilities, hw_capability_last);
40
41 switch (rev_id) {
42 case JTAG_DEV_ID_MARLON_B0:
43 wil->hw_name = "Marlon B0";
44 wil->hw_version = HW_VER_MARLON_B0;
45 break;
46 case JTAG_DEV_ID_SPARROW_A0:
47 wil->hw_name = "Sparrow A0";
48 wil->hw_version = HW_VER_SPARROW_A0;
49 break;
50 case JTAG_DEV_ID_SPARROW_A1:
51 wil->hw_name = "Sparrow A1";
52 wil->hw_version = HW_VER_SPARROW_A1;
53 break;
54 case JTAG_DEV_ID_SPARROW_B0:
55 wil->hw_name = "Sparrow B0";
56 wil->hw_version = HW_VER_SPARROW_B0;
57 break;
58 default:
59 wil_err(wil, "Unknown board hardware 0x%08x\n", rev_id);
60 wil->hw_name = "Unknown";
61 wil->hw_version = HW_VER_UNKNOWN;
62 }
63
64 wil_info(wil, "Board hardware is %s\n", wil->hw_name);
65
66 if (wil->hw_version >= HW_VER_SPARROW_A0)
67 set_bit(hw_capability_reset_v2, wil->hw_capabilities);
68
69 if (wil->hw_version >= HW_VER_SPARROW_B0)
70 set_bit(hw_capability_advanced_itr_moderation,
71 wil->hw_capabilities);
72}
73
34void wil_disable_irq(struct wil6210_priv *wil) 74void wil_disable_irq(struct wil6210_priv *wil)
35{ 75{
36 int irq = wil->pdev->irq; 76 int irq = wil->pdev->irq;
@@ -149,12 +189,11 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
149 struct wil6210_priv *wil; 189 struct wil6210_priv *wil;
150 struct device *dev = &pdev->dev; 190 struct device *dev = &pdev->dev;
151 void __iomem *csr; 191 void __iomem *csr;
152 struct wil_board *board = (struct wil_board *)id->driver_data;
153 int rc; 192 int rc;
154 193
155 /* check HW */ 194 /* check HW */
156 dev_info(&pdev->dev, WIL_NAME 195 dev_info(&pdev->dev, WIL_NAME
157 " \"%s\" device found [%04x:%04x] (rev %x)\n", board->name, 196 " device found [%04x:%04x] (rev %x)\n",
158 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision); 197 (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
159 198
160 if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) { 199 if (pci_resource_len(pdev, 0) != WIL6210_MEM_SIZE) {
@@ -204,8 +243,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
204 243
205 pci_set_drvdata(pdev, wil); 244 pci_set_drvdata(pdev, wil);
206 wil->pdev = pdev; 245 wil->pdev = pdev;
207 wil->board = board; 246 wil_set_capabilities(wil);
208
209 wil6210_clear_irq(wil); 247 wil6210_clear_irq(wil);
210 248
211 wil->platform_handle = 249 wil->platform_handle =
@@ -266,23 +304,10 @@ static void wil_pcie_remove(struct pci_dev *pdev)
266 pci_disable_device(pdev); 304 pci_disable_device(pdev);
267} 305}
268 306
269static const struct wil_board wil_board_marlon = {
270 .board = WIL_BOARD_MARLON,
271 .name = "marlon",
272};
273
274static const struct wil_board wil_board_sparrow = {
275 .board = WIL_BOARD_SPARROW,
276 .name = "sparrow",
277};
278
279static const struct pci_device_id wil6210_pcie_ids[] = { 307static const struct pci_device_id wil6210_pcie_ids[] = {
280 { PCI_DEVICE(0x1ae9, 0x0301), 308 { PCI_DEVICE(0x1ae9, 0x0301) },
281 .driver_data = (kernel_ulong_t)&wil_board_marlon }, 309 { PCI_DEVICE(0x1ae9, 0x0310) },
282 { PCI_DEVICE(0x1ae9, 0x0310), 310 { PCI_DEVICE(0x1ae9, 0x0302) }, /* same as above, firmware broken */
283 .driver_data = (kernel_ulong_t)&wil_board_sparrow },
284 { PCI_DEVICE(0x1ae9, 0x0302), /* same as above, firmware broken */
285 .driver_data = (kernel_ulong_t)&wil_board_sparrow },
286 { /* end: all zeroes */ }, 311 { /* end: all zeroes */ },
287}; 312};
288MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids); 313MODULE_DEVICE_TABLE(pci, wil6210_pcie_ids);
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 489cb73d139b..552209227de9 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -89,7 +89,9 @@ static void wil_reorder_release(struct wil6210_priv *wil,
89 } 89 }
90} 90}
91 91
92/* called in NAPI context */
92void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) 93void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
94__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
93{ 95{
94 struct net_device *ndev = wil_to_ndev(wil); 96 struct net_device *ndev = wil_to_ndev(wil);
95 struct vring_rx_desc *d = wil_skb_rxdesc(skb); 97 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
@@ -97,22 +99,26 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
97 int cid = wil_rxdesc_cid(d); 99 int cid = wil_rxdesc_cid(d);
98 int mid = wil_rxdesc_mid(d); 100 int mid = wil_rxdesc_mid(d);
99 u16 seq = wil_rxdesc_seq(d); 101 u16 seq = wil_rxdesc_seq(d);
102 int mcast = wil_rxdesc_mcast(d);
100 struct wil_sta_info *sta = &wil->sta[cid]; 103 struct wil_sta_info *sta = &wil->sta[cid];
101 struct wil_tid_ampdu_rx *r; 104 struct wil_tid_ampdu_rx *r;
102 u16 hseq; 105 u16 hseq;
103 int index; 106 int index;
104 unsigned long flags;
105 107
106 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n", 108 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n",
107 mid, cid, tid, seq); 109 mid, cid, tid, seq, mcast);
108 110
109 spin_lock_irqsave(&sta->tid_rx_lock, flags); 111 if (unlikely(mcast)) {
112 wil_netif_rx_any(skb, ndev);
113 return;
114 }
115
116 spin_lock(&sta->tid_rx_lock);
110 117
111 r = sta->tid_rx[tid]; 118 r = sta->tid_rx[tid];
112 if (!r) { 119 if (!r) {
113 spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
114 wil_netif_rx_any(skb, ndev); 120 wil_netif_rx_any(skb, ndev);
115 return; 121 goto out;
116 } 122 }
117 123
118 hseq = r->head_seq_num; 124 hseq = r->head_seq_num;
@@ -121,13 +127,24 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
121 * reported, and data Rx, few packets may be pass up before reorder 127 * reported, and data Rx, few packets may be pass up before reorder
122 * buffer get allocated. Catch up by pretending SSN is what we 128 * buffer get allocated. Catch up by pretending SSN is what we
123 * see in the 1-st Rx packet 129 * see in the 1-st Rx packet
130 *
131 * Another scenario, Rx get delayed and we got packet from before
132 * BACK. Pass it to the stack and wait.
124 */ 133 */
125 if (r->first_time) { 134 if (r->first_time) {
126 r->first_time = false; 135 r->first_time = false;
127 if (seq != r->head_seq_num) { 136 if (seq != r->head_seq_num) {
128 wil_err(wil, "Error: 1-st frame with wrong sequence" 137 if (seq_less(seq, r->head_seq_num)) {
129 " %d, should be %d. Fixing...\n", seq, 138 wil_err(wil,
130 r->head_seq_num); 139 "Error: frame with early sequence 0x%03x, should be 0x%03x. Waiting...\n",
140 seq, r->head_seq_num);
141 r->first_time = true;
142 wil_netif_rx_any(skb, ndev);
143 goto out;
144 }
145 wil_err(wil,
146 "Error: 1-st frame with wrong sequence 0x%03x, should be 0x%03x. Fixing...\n",
147 seq, r->head_seq_num);
131 r->head_seq_num = seq; 148 r->head_seq_num = seq;
132 r->ssn = seq; 149 r->ssn = seq;
133 } 150 }
@@ -179,7 +196,7 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
179 wil_reorder_release(wil, r); 196 wil_reorder_release(wil, r);
180 197
181out: 198out:
182 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 199 spin_unlock(&sta->tid_rx_lock);
183} 200}
184 201
185struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, 202struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
@@ -219,3 +236,241 @@ void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
219 kfree(r->reorder_time); 236 kfree(r->reorder_time);
220 kfree(r); 237 kfree(r);
221} 238}
239
240/* ADDBA processing */
241static u16 wil_agg_size(struct wil6210_priv *wil, u16 req_agg_wsize)
242{
243 u16 max_agg_size = min_t(u16, WIL_MAX_AGG_WSIZE, WIL_MAX_AMPDU_SIZE /
244 (mtu_max + WIL_MAX_MPDU_OVERHEAD));
245
246 if (!req_agg_wsize)
247 return max_agg_size;
248
249 return min(max_agg_size, req_agg_wsize);
250}
251
252/* Block Ack - Rx side (recipient */
253int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
254 u8 dialog_token, __le16 ba_param_set,
255 __le16 ba_timeout, __le16 ba_seq_ctrl)
256{
257 struct wil_back_rx *req = kzalloc(sizeof(*req), GFP_KERNEL);
258
259 if (!req)
260 return -ENOMEM;
261
262 req->cidxtid = cidxtid;
263 req->dialog_token = dialog_token;
264 req->ba_param_set = le16_to_cpu(ba_param_set);
265 req->ba_timeout = le16_to_cpu(ba_timeout);
266 req->ba_seq_ctrl = le16_to_cpu(ba_seq_ctrl);
267
268 mutex_lock(&wil->back_rx_mutex);
269 list_add_tail(&req->list, &wil->back_rx_pending);
270 mutex_unlock(&wil->back_rx_mutex);
271
272 queue_work(wil->wq_service, &wil->back_rx_worker);
273
274 return 0;
275}
276
277static void wil_back_rx_handle(struct wil6210_priv *wil,
278 struct wil_back_rx *req)
279__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
280{
281 struct wil_sta_info *sta;
282 u8 cid, tid;
283 u16 agg_wsize = 0;
284 /* bit 0: A-MSDU supported
285 * bit 1: policy (should be 0 for us)
286 * bits 2..5: TID
287 * bits 6..15: buffer size
288 */
289 u16 req_agg_wsize = WIL_GET_BITS(req->ba_param_set, 6, 15);
290 bool agg_amsdu = !!(req->ba_param_set & BIT(0));
291 int ba_policy = req->ba_param_set & BIT(1);
292 u16 agg_timeout = req->ba_timeout;
293 u16 status = WLAN_STATUS_SUCCESS;
294 u16 ssn = req->ba_seq_ctrl >> 4;
295 int rc;
296
297 might_sleep();
298 parse_cidxtid(req->cidxtid, &cid, &tid);
299
300 /* sanity checks */
301 if (cid >= WIL6210_MAX_CID) {
302 wil_err(wil, "BACK: invalid CID %d\n", cid);
303 return;
304 }
305
306 sta = &wil->sta[cid];
307 if (sta->status != wil_sta_connected) {
308 wil_err(wil, "BACK: CID %d not connected\n", cid);
309 return;
310 }
311
312 wil_dbg_wmi(wil,
313 "ADDBA request for CID %d %pM TID %d size %d timeout %d AMSDU%s policy %d token %d SSN 0x%03x\n",
314 cid, sta->addr, tid, req_agg_wsize, req->ba_timeout,
315 agg_amsdu ? "+" : "-", !!ba_policy, req->dialog_token, ssn);
316
317 /* apply policies */
318 if (ba_policy) {
319 wil_err(wil, "BACK requested unsupported ba_policy == 1\n");
320 status = WLAN_STATUS_INVALID_QOS_PARAM;
321 }
322 if (status == WLAN_STATUS_SUCCESS)
323 agg_wsize = wil_agg_size(wil, req_agg_wsize);
324
325 rc = wmi_addba_rx_resp(wil, cid, tid, req->dialog_token, status,
326 agg_amsdu, agg_wsize, agg_timeout);
327 if (rc || (status != WLAN_STATUS_SUCCESS))
328 return;
329
330 /* apply */
331 spin_lock_bh(&sta->tid_rx_lock);
332
333 wil_tid_ampdu_rx_free(wil, sta->tid_rx[tid]);
334 sta->tid_rx[tid] = wil_tid_ampdu_rx_alloc(wil, agg_wsize, ssn);
335
336 spin_unlock_bh(&sta->tid_rx_lock);
337}
338
339void wil_back_rx_flush(struct wil6210_priv *wil)
340{
341 struct wil_back_rx *evt, *t;
342
343 wil_dbg_misc(wil, "%s()\n", __func__);
344
345 mutex_lock(&wil->back_rx_mutex);
346
347 list_for_each_entry_safe(evt, t, &wil->back_rx_pending, list) {
348 list_del(&evt->list);
349 kfree(evt);
350 }
351
352 mutex_unlock(&wil->back_rx_mutex);
353}
354
355/* Retrieve next ADDBA request from the pending list */
356static struct list_head *next_back_rx(struct wil6210_priv *wil)
357{
358 struct list_head *ret = NULL;
359
360 mutex_lock(&wil->back_rx_mutex);
361
362 if (!list_empty(&wil->back_rx_pending)) {
363 ret = wil->back_rx_pending.next;
364 list_del(ret);
365 }
366
367 mutex_unlock(&wil->back_rx_mutex);
368
369 return ret;
370}
371
372void wil_back_rx_worker(struct work_struct *work)
373{
374 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
375 back_rx_worker);
376 struct wil_back_rx *evt;
377 struct list_head *lh;
378
379 while ((lh = next_back_rx(wil)) != NULL) {
380 evt = list_entry(lh, struct wil_back_rx, list);
381
382 wil_back_rx_handle(wil, evt);
383 kfree(evt);
384 }
385}
386
387/* BACK - Tx (originator) side */
388static void wil_back_tx_handle(struct wil6210_priv *wil,
389 struct wil_back_tx *req)
390{
391 struct vring_tx_data *txdata = &wil->vring_tx_data[req->ringid];
392 int rc;
393
394 if (txdata->addba_in_progress) {
395 wil_dbg_misc(wil, "ADDBA for vring[%d] already in progress\n",
396 req->ringid);
397 return;
398 }
399 if (txdata->agg_wsize) {
400 wil_dbg_misc(wil,
401 "ADDBA for vring[%d] already established wsize %d\n",
402 req->ringid, txdata->agg_wsize);
403 return;
404 }
405 txdata->addba_in_progress = true;
406 rc = wmi_addba(wil, req->ringid, req->agg_wsize, req->agg_timeout);
407 if (rc)
408 txdata->addba_in_progress = false;
409}
410
411static struct list_head *next_back_tx(struct wil6210_priv *wil)
412{
413 struct list_head *ret = NULL;
414
415 mutex_lock(&wil->back_tx_mutex);
416
417 if (!list_empty(&wil->back_tx_pending)) {
418 ret = wil->back_tx_pending.next;
419 list_del(ret);
420 }
421
422 mutex_unlock(&wil->back_tx_mutex);
423
424 return ret;
425}
426
427void wil_back_tx_worker(struct work_struct *work)
428{
429 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
430 back_tx_worker);
431 struct wil_back_tx *evt;
432 struct list_head *lh;
433
434 while ((lh = next_back_tx(wil)) != NULL) {
435 evt = list_entry(lh, struct wil_back_tx, list);
436
437 wil_back_tx_handle(wil, evt);
438 kfree(evt);
439 }
440}
441
442void wil_back_tx_flush(struct wil6210_priv *wil)
443{
444 struct wil_back_tx *evt, *t;
445
446 wil_dbg_misc(wil, "%s()\n", __func__);
447
448 mutex_lock(&wil->back_tx_mutex);
449
450 list_for_each_entry_safe(evt, t, &wil->back_tx_pending, list) {
451 list_del(&evt->list);
452 kfree(evt);
453 }
454
455 mutex_unlock(&wil->back_tx_mutex);
456}
457
458int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
459{
460 struct wil_back_tx *req = kzalloc(sizeof(*req), GFP_KERNEL);
461
462 if (!req)
463 return -ENOMEM;
464
465 req->ringid = ringid;
466 req->agg_wsize = wil_agg_size(wil, wsize);
467 req->agg_timeout = 0;
468
469 mutex_lock(&wil->back_tx_mutex);
470 list_add_tail(&req->list, &wil->back_tx_pending);
471 mutex_unlock(&wil->back_tx_mutex);
472
473 queue_work(wil->wq_service, &wil->back_tx_worker);
474
475 return 0;
476}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index e3f8bdce5abc..b58ee52e1860 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -463,7 +463,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
463 * and in case of error drop the packet 463 * and in case of error drop the packet
464 * higher stack layers will handle retransmission (if required) 464 * higher stack layers will handle retransmission (if required)
465 */ 465 */
466 if (d->dma.status & RX_DMA_STATUS_L4_IDENT) { 466 if (d->dma.status & RX_DMA_STATUS_L4I) {
467 /* L4 protocol identified, csum calculated */ 467 /* L4 protocol identified, csum calculated */
468 if ((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0) 468 if ((d->dma.error & RX_DMA_ERROR_L4_ERR) == 0)
469 skb->ip_summed = CHECKSUM_UNNECESSARY; 469 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -581,14 +581,8 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
581 skb->protocol = htons(ETH_P_802_2); 581 skb->protocol = htons(ETH_P_802_2);
582 wil_netif_rx_any(skb, ndev); 582 wil_netif_rx_any(skb, ndev);
583 } else { 583 } else {
584 struct ethhdr *eth = (void *)skb->data;
585
586 skb->protocol = eth_type_trans(skb, ndev); 584 skb->protocol = eth_type_trans(skb, ndev);
587 585 wil_rx_reorder(wil, skb);
588 if (is_unicast_ether_addr(eth->h_dest))
589 wil_rx_reorder(wil, skb);
590 else
591 wil_netif_rx_any(skb, ndev);
592 } 586 }
593 } 587 }
594 wil_rx_refill(wil, v->size); 588 wil_rx_refill(wil, v->size);
@@ -645,7 +639,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
645 .vring_cfg = { 639 .vring_cfg = {
646 .tx_sw_ring = { 640 .tx_sw_ring = {
647 .max_mpdu_size = 641 .max_mpdu_size =
648 cpu_to_le16(mtu_max + ETH_HLEN), 642 cpu_to_le16(wil_mtu2macbuf(mtu_max)),
649 .ring_size = cpu_to_le16(size), 643 .ring_size = cpu_to_le16(size),
650 }, 644 },
651 .ringid = id, 645 .ringid = id,
@@ -653,7 +647,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
653 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3, 647 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3,
654 .mac_ctrl = 0, 648 .mac_ctrl = 0,
655 .to_resolution = 0, 649 .to_resolution = 0,
656 .agg_max_wsize = 16, 650 .agg_max_wsize = 0,
657 .schd_params = { 651 .schd_params = {
658 .priority = cpu_to_le16(0), 652 .priority = cpu_to_le16(0),
659 .timeslot_us = cpu_to_le16(0xfff), 653 .timeslot_us = cpu_to_le16(0xfff),
@@ -701,6 +695,8 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
701 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); 695 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
702 696
703 txdata->enabled = 1; 697 txdata->enabled = 1;
698 if (wil->sta[cid].data_port_open && (agg_wsize >= 0))
699 wil_addba_tx_request(wil, id, agg_wsize);
704 700
705 return 0; 701 return 0;
706 out_free: 702 out_free:
@@ -713,6 +709,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
713void wil_vring_fini_tx(struct wil6210_priv *wil, int id) 709void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
714{ 710{
715 struct vring *vring = &wil->vring_tx[id]; 711 struct vring *vring = &wil->vring_tx[id];
712 struct vring_tx_data *txdata = &wil->vring_tx_data[id];
716 713
717 WARN_ON(!mutex_is_locked(&wil->mutex)); 714 WARN_ON(!mutex_is_locked(&wil->mutex));
718 715
@@ -723,10 +720,11 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
723 720
724 /* make sure NAPI won't touch this vring */ 721 /* make sure NAPI won't touch this vring */
725 wil->vring_tx_data[id].enabled = 0; 722 wil->vring_tx_data[id].enabled = 0;
726 if (test_bit(wil_status_napi_en, &wil->status)) 723 if (test_bit(wil_status_napi_en, wil->status))
727 napi_synchronize(&wil->napi_tx); 724 napi_synchronize(&wil->napi_tx);
728 725
729 wil_vring_free(wil, vring, 1); 726 wil_vring_free(wil, vring, 1);
727 memset(txdata, 0, sizeof(*txdata));
730} 728}
731 729
732static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, 730static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
@@ -773,6 +771,38 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil,
773 771
774static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 772static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
775 struct sk_buff *skb); 773 struct sk_buff *skb);
774
775static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
776 struct sk_buff *skb)
777{
778 struct vring *v;
779 int i;
780 u8 cid;
781
782 /* In the STA mode, it is expected to have only 1 VRING
783 * for the AP we connected to.
784 * find 1-st vring and see whether it is eligible for data
785 */
786 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
787 v = &wil->vring_tx[i];
788 if (!v->va)
789 continue;
790
791 cid = wil->vring2cid_tid[i][0];
792 if (!wil->sta[cid].data_port_open &&
793 (skb->protocol != cpu_to_be16(ETH_P_PAE)))
794 break;
795
796 wil_dbg_txrx(wil, "Tx -> ring %d\n", i);
797
798 return v;
799 }
800
801 wil_dbg_txrx(wil, "Tx while no vrings active?\n");
802
803 return NULL;
804}
805
776/* 806/*
777 * Find 1-st vring and return it; set dest address for this vring in skb 807 * Find 1-st vring and return it; set dest address for this vring in skb
778 * duplicate skb and send it to other active vrings 808 * duplicate skb and send it to other active vrings
@@ -1034,14 +1064,14 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1034 int rc; 1064 int rc;
1035 1065
1036 wil_dbg_txrx(wil, "%s()\n", __func__); 1066 wil_dbg_txrx(wil, "%s()\n", __func__);
1037 if (!test_bit(wil_status_fwready, &wil->status)) { 1067 if (!test_bit(wil_status_fwready, wil->status)) {
1038 if (!pr_once_fw) { 1068 if (!pr_once_fw) {
1039 wil_err(wil, "FW not ready\n"); 1069 wil_err(wil, "FW not ready\n");
1040 pr_once_fw = true; 1070 pr_once_fw = true;
1041 } 1071 }
1042 goto drop; 1072 goto drop;
1043 } 1073 }
1044 if (!test_bit(wil_status_fwconnected, &wil->status)) { 1074 if (!test_bit(wil_status_fwconnected, wil->status)) {
1045 wil_err(wil, "FW not connected\n"); 1075 wil_err(wil, "FW not connected\n");
1046 goto drop; 1076 goto drop;
1047 } 1077 }
@@ -1052,15 +1082,19 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1052 pr_once_fw = false; 1082 pr_once_fw = false;
1053 1083
1054 /* find vring */ 1084 /* find vring */
1055 if (is_unicast_ether_addr(eth->h_dest)) 1085 if (wil->wdev->iftype == NL80211_IFTYPE_STATION) {
1056 vring = wil_find_tx_vring(wil, skb); 1086 /* in STA mode (ESS), all to same VRING */
1057 else 1087 vring = wil_find_tx_vring_sta(wil, skb);
1058 vring = wil_tx_bcast(wil, skb); 1088 } else { /* direct communication, find matching VRING */
1089 if (is_unicast_ether_addr(eth->h_dest))
1090 vring = wil_find_tx_vring(wil, skb);
1091 else
1092 vring = wil_tx_bcast(wil, skb);
1093 }
1059 if (!vring) { 1094 if (!vring) {
1060 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1095 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1061 goto drop; 1096 goto drop;
1062 } 1097 }
1063
1064 /* set up vring entry */ 1098 /* set up vring entry */
1065 rc = wil_tx_vring(wil, vring, skb); 1099 rc = wil_tx_vring(wil, vring, skb);
1066 1100
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 630aeb5fa7f4..d90c8aa20c15 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -20,17 +20,15 @@
20#define BUF_SW_OWNED (1) 20#define BUF_SW_OWNED (1)
21#define BUF_HW_OWNED (0) 21#define BUF_HW_OWNED (0)
22 22
23/* size of max. Tx/Rx buffers, as supported by FW */ 23/* default size of MAC Tx/Rx buffers */
24#define TXRX_BUF_LEN_DEFAULT (2242) 24#define TXRX_BUF_LEN_DEFAULT (2048)
25 25
26/* how many bytes to reserve for rtap header? */ 26/* how many bytes to reserve for rtap header? */
27#define WIL6210_RTAP_SIZE (128) 27#define WIL6210_RTAP_SIZE (128)
28 28
29/* Tx/Rx path */ 29/* Tx/Rx path */
30 30
31/* 31/* Common representation of physical address in Vring */
32 * Common representation of physical address in Vring
33 */
34struct vring_dma_addr { 32struct vring_dma_addr {
35 __le32 addr_low; 33 __le32 addr_low;
36 __le16 addr_high; 34 __le16 addr_high;
@@ -49,11 +47,10 @@ static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
49 addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa)); 47 addr->addr_high = cpu_to_le16((u16)upper_32_bits(pa));
50} 48}
51 49
52/* 50/* Tx descriptor - MAC part
53 * Tx descriptor - MAC part
54 * [dword 0] 51 * [dword 0]
55 * bit 0.. 9 : lifetime_expiry_value:10 52 * bit 0.. 9 : lifetime_expiry_value:10
56 * bit 10 : interrup_en:1 53 * bit 10 : interrupt_en:1
57 * bit 11 : status_en:1 54 * bit 11 : status_en:1
58 * bit 12..13 : txss_override:2 55 * bit 12..13 : txss_override:2
59 * bit 14 : timestamp_insertion:1 56 * bit 14 : timestamp_insertion:1
@@ -61,15 +58,12 @@ static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
61 * bit 16..21 : reserved0:6 58 * bit 16..21 : reserved0:6
62 * bit 22..26 : mcs_index:5 59 * bit 22..26 : mcs_index:5
63 * bit 27 : mcs_en:1 60 * bit 27 : mcs_en:1
64 * bit 28..29 : reserved1:2 61 * bit 28..30 : reserved1:3
65 * bit 30 : reserved2:1
66 * bit 31 : sn_preserved:1 62 * bit 31 : sn_preserved:1
67 * [dword 1] 63 * [dword 1]
68 * bit 0.. 3 : pkt_mode:4 64 * bit 0.. 3 : pkt_mode:4
69 * bit 4 : pkt_mode_en:1 65 * bit 4 : pkt_mode_en:1
70 * bit 5.. 7 : reserved0:3 66 * bit 5..14 : reserved0:10
71 * bit 8..13 : reserved1:6
72 * bit 14 : reserved2:1
73 * bit 15 : ack_policy_en:1 67 * bit 15 : ack_policy_en:1
74 * bit 16..19 : dst_index:4 68 * bit 16..19 : dst_index:4
75 * bit 20 : dst_index_en:1 69 * bit 20 : dst_index_en:1
@@ -80,7 +74,7 @@ static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
80 * [dword 2] 74 * [dword 2]
81 * bit 0.. 7 : num_of_descriptors:8 75 * bit 0.. 7 : num_of_descriptors:8
82 * bit 8..17 : reserved:10 76 * bit 8..17 : reserved:10
83 * bit 18..19 : l2_translation_type:2 77 * bit 18..19 : l2_translation_type:2 00 - bypass, 01 - 802.3, 10 - 802.11
84 * bit 20 : snap_hdr_insertion_en:1 78 * bit 20 : snap_hdr_insertion_en:1
85 * bit 21 : vlan_removal_en:1 79 * bit 21 : vlan_removal_en:1
86 * bit 22..31 : reserved0:10 80 * bit 22..31 : reserved0:10
@@ -247,6 +241,46 @@ struct vring_tx_mac {
247 241
248#define TX_DMA_STATUS_DU BIT(0) 242#define TX_DMA_STATUS_DU BIT(0)
249 243
244/* Tx descriptor - DMA part
245 * [dword 0]
246 * bit 0.. 7 : l4_length:8 layer 4 length
247 * bit 8 : cmd_eop:1 This descriptor is the last one in the packet
248 * bit 9 : reserved
249 * bit 10 : cmd_dma_it:1 immediate interrupt
250 * bit 11..12 : SBD - Segment Buffer Details
251 * 00 - Header Segment
252 * 01 - First Data Segment
253 * 10 - Medium Data Segment
254 * 11 - Last Data Segment
255 * bit 13 : TSE - TCP Segmentation Enable
256 * bit 14 : IIC - Directs the HW to Insert IPv4 Checksum
257 * bit 15 : ITC - Directs the HW to Insert TCP/UDP Checksum
258 * bit 16..20 : QID - The target QID that the packet should be stored
259 * in the MAC.
260 * bit 21 : PO - Pseudo header Offload:
261 * 0 - Use the pseudo header value from the TCP checksum field
262 * 1- Calculate Pseudo header Checksum
263 * bit 22 : NC - No UDP Checksum
264 * bit 23..29 : reserved
265 * bit 30..31 : L4T - Layer 4 Type: 00 - UDP , 10 - TCP , 10, 11 - Reserved
266 * If L4Len equal 0, no L4 at all
267 * [dword 1]
268 * bit 0..31 : addr_low:32 The payload buffer low address
269 * [dword 2]
270 * bit 0..15 : addr_high:16 The payload buffer high address
271 * bit 16..23 : ip_length:8 The IP header length for the TX IP checksum
272 * offload feature
273 * bit 24..30 : mac_length:7
274 * bit 31 : ip_version:1 1 - IPv4, 0 - IPv6
275 * [dword 3]
276 * [byte 12] error
277 * bit 0 2 : mac_status:3
278 * bit 3 7 : reserved:5
279 * [byte 13] status
280 * bit 0 : DU:1 Descriptor Used
281 * bit 1 7 : reserved:7
282 * [word 7] length
283 */
250struct vring_tx_dma { 284struct vring_tx_dma {
251 u32 d0; 285 u32 d0;
252 struct vring_dma_addr addr; 286 struct vring_dma_addr addr;
@@ -257,45 +291,45 @@ struct vring_tx_dma {
257 __le16 length; 291 __le16 length;
258} __packed; 292} __packed;
259 293
260/* 294/* Rx descriptor - MAC part
261 * Rx descriptor - MAC part
262 * [dword 0] 295 * [dword 0]
263 * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field 296 * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field
264 * bit 4.. 6 : connection_id:3 :The Source index that was found during 297 * bit 4.. 6 : cid:3 The Source index that was found during parsing the TA.
265 * Parsing the TA. This field is used to define the source of the packet 298 * This field is used to define the source of the packet
266 * bit 7 : reserved:1 299 * bit 7 : reserved:1
267 * bit 8.. 9 : mac_id:2 : The MAC virtual Ring number (always zero) 300 * bit 8.. 9 : mid:2 The MAC virtual number
268 * bit 10..11 : frame_type:2 : The FC Control (b3-2) - MPDU Type 301 * bit 10..11 : frame_type:2 : The FC (b3-2) - MPDU Type
269 * (management, data, control and extension) 302 * (management, data, control and extension)
270 * bit 12..15 : frame_subtype:4 : The FC Control (b7-4) - Frame Subtype 303 * bit 12..15 : frame_subtype:4 : The FC (b7-4) - Frame Subtype
271 * bit 16..27 : seq_number:12 The received Sequence number field 304 * bit 16..27 : seq_number:12 The received Sequence number field
272 * bit 28..31 : extended:4 extended subtype 305 * bit 28..31 : extended:4 extended subtype
273 * [dword 1] 306 * [dword 1]
274 * bit 0.. 3 : reserved 307 * bit 0.. 3 : reserved
275 * bit 4.. 5 : key_id:2 308 * bit 4.. 5 : key_id:2
276 * bit 6 : decrypt_bypass:1 309 * bit 6 : decrypt_bypass:1
277 * bit 7 : security:1 310 * bit 7 : security:1 FC (b14)
278 * bit 8.. 9 : ds_bits:2 311 * bit 8.. 9 : ds_bits:2 FC (b9-8)
279 * bit 10 : a_msdu_present:1 from qos header 312 * bit 10 : a_msdu_present:1 QoS (b7)
280 * bit 11 : a_msdu_type:1 from qos header 313 * bit 11 : a_msdu_type:1 QoS (b8)
281 * bit 12 : a_mpdu:1 part of AMPDU aggregation 314 * bit 12 : a_mpdu:1 part of AMPDU aggregation
282 * bit 13 : broadcast:1 315 * bit 13 : broadcast:1
283 * bit 14 : mutlicast:1 316 * bit 14 : mutlicast:1
284 * bit 15 : reserved:1 317 * bit 15 : reserved:1
285 * bit 16..20 : rx_mac_qid:5 The Queue Identifier that the packet 318 * bit 16..20 : rx_mac_qid:5 The Queue Identifier that the packet
286 * is received from 319 * is received from
287 * bit 21..24 : mcs:4 320 * bit 21..24 : mcs:4
288 * bit 25..28 : mic_icr:4 321 * bit 25..28 : mic_icr:4 this signal tells the DMA to assert an interrupt
322 * after it writes the packet
289 * bit 29..31 : reserved:3 323 * bit 29..31 : reserved:3
290 * [dword 2] 324 * [dword 2]
291 * bit 0.. 2 : time_slot:3 The timeslot that the MPDU is received 325 * bit 0.. 2 : time_slot:3 The timeslot that the MPDU is received
292 * bit 3 : fc_protocol_ver:1 The FC Control (b0) - Protocol Version 326 * bit 3.. 4 : fc_protocol_ver:1 The FC (b1-0) - Protocol Version
293 * bit 4 : fc_order:1 The FC Control (b15) -Order 327 * bit 5 : fc_order:1 The FC Control (b15) -Order
294 * bit 5.. 7 : qos_ack_policy:3 The QoS (b6-5) ack policy Field 328 * bit 6.. 7 : qos_ack_policy:2 The QoS (b6-5) ack policy Field
295 * bit 8 : esop:1 The QoS (b4) ESOP field 329 * bit 8 : esop:1 The QoS (b4) ESOP field
296 * bit 9 : qos_rdg_more_ppdu:1 The QoS (b9) RDG field 330 * bit 9 : qos_rdg_more_ppdu:1 The QoS (b9) RDG field
297 * bit 10..14 : qos_reserved:5 The QoS (b14-10) Reserved field 331 * bit 10..14 : qos_reserved:5 The QoS (b14-10) Reserved field
298 * bit 15 : qos_ac_constraint:1 332 * bit 15 : qos_ac_constraint:1 QoS (b15)
299 * bit 16..31 : pn_15_0:16 low 2 bytes of PN 333 * bit 16..31 : pn_15_0:16 low 2 bytes of PN
300 * [dword 3] 334 * [dword 3]
301 * bit 0..31 : pn_47_16:32 high 4 bytes of PN 335 * bit 0..31 : pn_47_16:32 high 4 bytes of PN
@@ -308,35 +342,46 @@ struct vring_rx_mac {
308 u32 pn_47_16; 342 u32 pn_47_16;
309} __packed; 343} __packed;
310 344
311/* 345/* Rx descriptor - DMA part
312 * Rx descriptor - DMA part
313 * [dword 0] 346 * [dword 0]
314 * bit 0.. 7 : l4_length:8 layer 4 length 347 * bit 0.. 7 : l4_length:8 layer 4 length. The field is only valid if
315 * bit 8.. 9 : reserved:2 348 * L4I bit is set
316 * bit 10 : cmd_dma_it:1 349 * bit 8 : cmd_eop:1 set to 1
350 * bit 9 : cmd_rt:1 set to 1
351 * bit 10 : cmd_dma_it:1 immediate interrupt
317 * bit 11..15 : reserved:5 352 * bit 11..15 : reserved:5
318 * bit 16..29 : phy_info_length:14 353 * bit 16..29 : phy_info_length:14 It is valid when the PII is set.
354 * When the FFM bit is set bits 29-27 are used for for
355 * Flex Filter Match. Matching Index to one of the L2
356 * EtherType Flex Filter
319 * bit 30..31 : l4_type:2 valid if the L4I bit is set in the status field 357 * bit 30..31 : l4_type:2 valid if the L4I bit is set in the status field
358 * 00 - UDP, 01 - TCP, 10, 11 - reserved
320 * [dword 1] 359 * [dword 1]
321 * bit 0..31 : addr_low:32 The payload buffer low address 360 * bit 0..31 : addr_low:32 The payload buffer low address
322 * [dword 2] 361 * [dword 2]
323 * bit 0..15 : addr_high:16 The payload buffer high address 362 * bit 0..15 : addr_high:16 The payload buffer high address
324 * bit 16..23 : ip_length:8 363 * bit 16..23 : ip_length:8 The filed is valid only if the L3I bit is set
325 * bit 24..30 : mac_length:7 364 * bit 24..30 : mac_length:7
326 * bit 31 : ip_version:1 365 * bit 31 : ip_version:1 1 - IPv4, 0 - IPv6
327 * [dword 3] 366 * [dword 3]
328 * [byte 12] error 367 * [byte 12] error
368 * bit 0 : FCS:1
369 * bit 1 : MIC:1
370 * bit 2 : Key miss:1
371 * bit 3 : Replay:1
372 * bit 4 : L3:1 IPv4 checksum
373 * bit 5 : L4:1 TCP/UDP checksum
374 * bit 6 7 : reserved:2
329 * [byte 13] status 375 * [byte 13] status
330 * bit 0 : du:1 376 * bit 0 : DU:1 Descriptor Used
331 * bit 1 : eop:1 377 * bit 1 : EOP:1 The descriptor indicates the End of Packet
332 * bit 2 : error:1 378 * bit 2 : error:1
333 * bit 3 : mi:1 379 * bit 3 : MI:1 MAC Interrupt is asserted (according to parser decision)
334 * bit 4 : l3_identified:1 380 * bit 4 : L3I:1 L3 identified and checksum calculated
335 * bit 5 : l4_identified:1 381 * bit 5 : L4I:1 L4 identified and checksum calculated
336 * bit 6 : phy_info_included:1 382 * bit 6 : PII:1 PHY Info Included in the packet
337 * bit 7 : reserved:1 383 * bit 7 : FFM:1 EtherType Flex Filter Match
338 * [word 7] length 384 * [word 7] length
339 *
340 */ 385 */
341 386
342#define RX_DMA_D0_CMD_DMA_IT BIT(10) 387#define RX_DMA_D0_CMD_DMA_IT BIT(10)
@@ -349,9 +394,9 @@ struct vring_rx_mac {
349#define RX_DMA_STATUS_DU BIT(0) 394#define RX_DMA_STATUS_DU BIT(0)
350#define RX_DMA_STATUS_ERROR BIT(2) 395#define RX_DMA_STATUS_ERROR BIT(2)
351 396
352#define RX_DMA_STATUS_L3_IDENT BIT(4) 397#define RX_DMA_STATUS_L3I BIT(4)
353#define RX_DMA_STATUS_L4_IDENT BIT(5) 398#define RX_DMA_STATUS_L4I BIT(5)
354#define RX_DMA_STATUS_PHY_INFO BIT(6) 399#define RX_DMA_STATUS_PHY_INFO BIT(6)
355 400
356struct vring_rx_dma { 401struct vring_rx_dma {
357 u32 d0; 402 u32 d0;
@@ -423,6 +468,11 @@ static inline int wil_rxdesc_mcs(struct vring_rx_desc *d)
423 return WIL_GET_BITS(d->mac.d1, 21, 24); 468 return WIL_GET_BITS(d->mac.d1, 21, 24);
424} 469}
425 470
471static inline int wil_rxdesc_mcast(struct vring_rx_desc *d)
472{
473 return WIL_GET_BITS(d->mac.d1, 13, 14);
474}
475
426static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d) 476static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d)
427{ 477{
428 return WIL_GET_BITS(d->dma.d0, 16, 29); 478 return WIL_GET_BITS(d->dma.d0, 16, 29);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index c6ec5b99ac7d..da3fe7853d63 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -25,19 +25,14 @@
25 25
26extern bool no_fw_recovery; 26extern bool no_fw_recovery;
27extern unsigned int mtu_max; 27extern unsigned int mtu_max;
28extern unsigned short rx_ring_overflow_thrsh;
29extern int agg_wsize;
28 30
29#define WIL_NAME "wil6210" 31#define WIL_NAME "wil6210"
30#define WIL_FW_NAME "wil6210.fw" 32#define WIL_FW_NAME "wil6210.fw"
31 33
32#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ 34#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
33 35
34struct wil_board {
35 int board;
36#define WIL_BOARD_MARLON (1)
37#define WIL_BOARD_SPARROW (2)
38 const char * const name;
39};
40
41/** 36/**
42 * extract bits [@b0:@b1] (inclusive) from the value @x 37 * extract bits [@b0:@b1] (inclusive) from the value @x
43 * it should be @b0 <= @b1, or result is incorrect 38 * it should be @b0 <= @b1, or result is incorrect
@@ -57,13 +52,41 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
57#define WIL6210_MAX_TX_RINGS (24) /* HW limit */ 52#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
58#define WIL6210_MAX_CID (8) /* HW limit */ 53#define WIL6210_MAX_CID (8) /* HW limit */
59#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ 54#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
55#define WIL_MAX_AMPDU_SIZE (64 * 1024) /* FW/HW limit */
56#define WIL_MAX_AGG_WSIZE (32) /* FW/HW limit */
57/* Hardware offload block adds the following:
58 * 26 bytes - 3-address QoS data header
59 * 8 bytes - IV + EIV (for GCMP)
60 * 8 bytes - SNAP
61 * 16 bytes - MIC (for GCMP)
62 * 4 bytes - CRC
63 */
64#define WIL_MAX_MPDU_OVERHEAD (62)
65
66/* Calculate MAC buffer size for the firmware. It includes all overhead,
67 * as it will go over the air, and need to be 8 byte aligned
68 */
69static inline u32 wil_mtu2macbuf(u32 mtu)
70{
71 return ALIGN(mtu + WIL_MAX_MPDU_OVERHEAD, 8);
72}
73
74/* MTU for Ethernet need to take into account 8-byte SNAP header
75 * to be added when encapsulating Ethernet frame into 802.11
76 */
77#define WIL_MAX_ETH_MTU (IEEE80211_MAX_DATA_LEN_DMG - 8)
60/* Max supported by wil6210 value for interrupt threshold is 5sec. */ 78/* Max supported by wil6210 value for interrupt threshold is 5sec. */
61#define WIL6210_ITR_TRSH_MAX (5000000) 79#define WIL6210_ITR_TRSH_MAX (5000000)
62#define WIL6210_ITR_TRSH_DEFAULT (300) /* usec */ 80#define WIL6210_ITR_TX_INTERFRAME_TIMEOUT_DEFAULT (15) /* usec */
81#define WIL6210_ITR_RX_INTERFRAME_TIMEOUT_DEFAULT (15) /* usec */
82#define WIL6210_ITR_TX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
83#define WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
63#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ 84#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */
64#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) 85#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
65#define WIL6210_SCAN_TO msecs_to_jiffies(10000) 86#define WIL6210_SCAN_TO msecs_to_jiffies(10000)
66 87#define WIL6210_RX_HIGH_TRSH_INIT (0)
88#define WIL6210_RX_HIGH_TRSH_DEFAULT \
89 (1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
67/* Hardware definitions begin */ 90/* Hardware definitions begin */
68 91
69/* 92/*
@@ -135,7 +158,7 @@ struct RGF_ICR {
135 #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1) 158 #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1)
136 #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */ 159 #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */
137 160
138/* Interrupt moderation control */ 161/* Legacy interrupt moderation control (before Sparrow v2)*/
139#define RGF_DMA_ITR_CNT_TRSH (0x881c5c) 162#define RGF_DMA_ITR_CNT_TRSH (0x881c5c)
140#define RGF_DMA_ITR_CNT_DATA (0x881c60) 163#define RGF_DMA_ITR_CNT_DATA (0x881c60)
141#define RGF_DMA_ITR_CNT_CRL (0x881c64) 164#define RGF_DMA_ITR_CNT_CRL (0x881c64)
@@ -145,6 +168,46 @@ struct RGF_ICR {
145 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3) 168 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3)
146 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4) 169 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4)
147 170
171/* New (sparrow v2+) interrupt moderation control */
172#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40)
173#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34)
174#define RGF_DMA_ITR_TX_CNT_DATA (0x881d38)
175#define RGF_DMA_ITR_TX_CNT_CTL (0x881d3c)
176 #define BIT_DMA_ITR_TX_CNT_CTL_EN BIT(0)
177 #define BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL BIT(1)
178 #define BIT_DMA_ITR_TX_CNT_CTL_FOREVER BIT(2)
179 #define BIT_DMA_ITR_TX_CNT_CTL_CLR BIT(3)
180 #define BIT_DMA_ITR_TX_CNT_CTL_REACHED_TRESH BIT(4)
181 #define BIT_DMA_ITR_TX_CNT_CTL_CROSS_EN BIT(5)
182 #define BIT_DMA_ITR_TX_CNT_CTL_FREE_RUNNIG BIT(6)
183#define RGF_DMA_ITR_TX_IDL_CNT_TRSH (0x881d60)
184#define RGF_DMA_ITR_TX_IDL_CNT_DATA (0x881d64)
185#define RGF_DMA_ITR_TX_IDL_CNT_CTL (0x881d68)
186 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EN BIT(0)
187 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL BIT(1)
188 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_FOREVER BIT(2)
189 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR BIT(3)
190 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_REACHED_TRESH BIT(4)
191#define RGF_DMA_ITR_RX_DESQ_NO_MOD (0x881d50)
192#define RGF_DMA_ITR_RX_CNT_TRSH (0x881d44)
193#define RGF_DMA_ITR_RX_CNT_DATA (0x881d48)
194#define RGF_DMA_ITR_RX_CNT_CTL (0x881d4c)
195 #define BIT_DMA_ITR_RX_CNT_CTL_EN BIT(0)
196 #define BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL BIT(1)
197 #define BIT_DMA_ITR_RX_CNT_CTL_FOREVER BIT(2)
198 #define BIT_DMA_ITR_RX_CNT_CTL_CLR BIT(3)
199 #define BIT_DMA_ITR_RX_CNT_CTL_REACHED_TRESH BIT(4)
200 #define BIT_DMA_ITR_RX_CNT_CTL_CROSS_EN BIT(5)
201 #define BIT_DMA_ITR_RX_CNT_CTL_FREE_RUNNIG BIT(6)
202#define RGF_DMA_ITR_RX_IDL_CNT_TRSH (0x881d54)
203#define RGF_DMA_ITR_RX_IDL_CNT_DATA (0x881d58)
204#define RGF_DMA_ITR_RX_IDL_CNT_CTL (0x881d5c)
205 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EN BIT(0)
206 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL BIT(1)
207 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_FOREVER BIT(2)
208 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR BIT(3)
209 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_REACHED_TRESH BIT(4)
210
148#define RGF_DMA_PSEUDO_CAUSE (0x881c68) 211#define RGF_DMA_PSEUDO_CAUSE (0x881c68)
149#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c) 212#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c)
150#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70) 213#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70)
@@ -164,6 +227,20 @@ struct RGF_ICR {
164#define RGF_CAF_PLL_LOCK_STATUS (0x88afec) 227#define RGF_CAF_PLL_LOCK_STATUS (0x88afec)
165 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) 228 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
166 229
230#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
231 #define JTAG_DEV_ID_MARLON_B0 (0x0612072f)
232 #define JTAG_DEV_ID_SPARROW_A0 (0x0632072f)
233 #define JTAG_DEV_ID_SPARROW_A1 (0x1632072f)
234 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
235
236enum {
237 HW_VER_UNKNOWN,
238 HW_VER_MARLON_B0, /* JTAG_DEV_ID_MARLON_B0 */
239 HW_VER_SPARROW_A0, /* JTAG_DEV_ID_SPARROW_A0 */
240 HW_VER_SPARROW_A1, /* JTAG_DEV_ID_SPARROW_A1 */
241 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
242};
243
167/* popular locations */ 244/* popular locations */
168#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) 245#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
169#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ 246#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
@@ -303,6 +380,10 @@ struct vring {
303struct vring_tx_data { 380struct vring_tx_data {
304 int enabled; 381 int enabled;
305 cycles_t idle, last_idle, begin; 382 cycles_t idle, last_idle, begin;
383 u8 agg_wsize; /* agreed aggregation window, 0 - no agg */
384 u16 agg_timeout;
385 u8 agg_amsdu;
386 bool addba_in_progress; /* if set, agg_xxx is for request in progress */
306}; 387};
307 388
308enum { /* for wil6210_priv.status */ 389enum { /* for wil6210_priv.status */
@@ -313,6 +394,7 @@ enum { /* for wil6210_priv.status */
313 wil_status_reset_done, 394 wil_status_reset_done,
314 wil_status_irqen, /* FIXME: interrupts enabled - for debug */ 395 wil_status_irqen, /* FIXME: interrupts enabled - for debug */
315 wil_status_napi_en, /* NAPI enabled protected by wil->mutex */ 396 wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
397 wil_status_last /* keep last */
316}; 398};
317 399
318struct pci_dev; 400struct pci_dev;
@@ -397,15 +479,40 @@ enum {
397 fw_recovery_running = 2, 479 fw_recovery_running = 2,
398}; 480};
399 481
482enum {
483 hw_capability_reset_v2 = 0,
484 hw_capability_advanced_itr_moderation = 1,
485 hw_capability_last
486};
487
488struct wil_back_rx {
489 struct list_head list;
490 /* request params, converted to CPU byte order - what we asked for */
491 u8 cidxtid;
492 u8 dialog_token;
493 u16 ba_param_set;
494 u16 ba_timeout;
495 u16 ba_seq_ctrl;
496};
497
498struct wil_back_tx {
499 struct list_head list;
500 /* request params, converted to CPU byte order - what we asked for */
501 u8 ringid;
502 u8 agg_wsize;
503 u16 agg_timeout;
504};
505
400struct wil6210_priv { 506struct wil6210_priv {
401 struct pci_dev *pdev; 507 struct pci_dev *pdev;
402 int n_msi; 508 int n_msi;
403 struct wireless_dev *wdev; 509 struct wireless_dev *wdev;
404 void __iomem *csr; 510 void __iomem *csr;
405 ulong status; 511 DECLARE_BITMAP(status, wil_status_last);
406 u32 fw_version; 512 u32 fw_version;
407 u32 hw_version; 513 u32 hw_version;
408 struct wil_board *board; 514 const char *hw_name;
515 DECLARE_BITMAP(hw_capabilities, hw_capability_last);
409 u8 n_mids; /* number of additional MIDs as reported by FW */ 516 u8 n_mids; /* number of additional MIDs as reported by FW */
410 u32 recovery_count; /* num of FW recovery attempts in a short time */ 517 u32 recovery_count; /* num of FW recovery attempts in a short time */
411 u32 recovery_state; /* FW recovery state machine */ 518 u32 recovery_state; /* FW recovery state machine */
@@ -415,7 +522,11 @@ struct wil6210_priv {
415 u32 monitor_flags; 522 u32 monitor_flags;
416 u32 secure_pcp; /* create secure PCP? */ 523 u32 secure_pcp; /* create secure PCP? */
417 int sinfo_gen; 524 int sinfo_gen;
418 u32 itr_trsh; 525 /* interrupt moderation */
526 u32 tx_max_burst_duration;
527 u32 tx_interframe_timeout;
528 u32 rx_max_burst_duration;
529 u32 rx_interframe_timeout;
419 /* cached ISR registers */ 530 /* cached ISR registers */
420 u32 isr_misc; 531 u32 isr_misc;
421 /* mailbox related */ 532 /* mailbox related */
@@ -429,7 +540,7 @@ struct wil6210_priv {
429 u16 reply_size; 540 u16 reply_size;
430 struct workqueue_struct *wmi_wq; /* for deferred calls */ 541 struct workqueue_struct *wmi_wq; /* for deferred calls */
431 struct work_struct wmi_event_worker; 542 struct work_struct wmi_event_worker;
432 struct workqueue_struct *wmi_wq_conn; /* for connect worker */ 543 struct workqueue_struct *wq_service;
433 struct work_struct connect_worker; 544 struct work_struct connect_worker;
434 struct work_struct disconnect_worker; 545 struct work_struct disconnect_worker;
435 struct work_struct fw_error_worker; /* for FW error recovery */ 546 struct work_struct fw_error_worker; /* for FW error recovery */
@@ -445,6 +556,13 @@ struct wil6210_priv {
445 spinlock_t wmi_ev_lock; 556 spinlock_t wmi_ev_lock;
446 struct napi_struct napi_rx; 557 struct napi_struct napi_rx;
447 struct napi_struct napi_tx; 558 struct napi_struct napi_tx;
559 /* BACK */
560 struct list_head back_rx_pending;
561 struct mutex back_rx_mutex; /* protect @back_rx_pending */
562 struct work_struct back_rx_worker;
563 struct list_head back_tx_pending;
564 struct mutex back_tx_mutex; /* protect @back_tx_pending */
565 struct work_struct back_tx_worker;
448 /* DMA related */ 566 /* DMA related */
449 struct vring vring_rx; 567 struct vring vring_rx;
450 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 568 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -529,7 +647,6 @@ void wil_if_remove(struct wil6210_priv *wil);
529int wil_priv_init(struct wil6210_priv *wil); 647int wil_priv_init(struct wil6210_priv *wil);
530void wil_priv_deinit(struct wil6210_priv *wil); 648void wil_priv_deinit(struct wil6210_priv *wil);
531int wil_reset(struct wil6210_priv *wil); 649int wil_reset(struct wil6210_priv *wil);
532void wil_set_itr_trsh(struct wil6210_priv *wil);
533void wil_fw_error_recovery(struct wil6210_priv *wil); 650void wil_fw_error_recovery(struct wil6210_priv *wil);
534void wil_set_recovery_state(struct wil6210_priv *wil, int state); 651void wil_set_recovery_state(struct wil6210_priv *wil, int state);
535void wil_link_on(struct wil6210_priv *wil); 652void wil_link_on(struct wil6210_priv *wil);
@@ -567,12 +684,26 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
567int wmi_rxon(struct wil6210_priv *wil, bool on); 684int wmi_rxon(struct wil6210_priv *wil, bool on);
568int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 685int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
569int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason); 686int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
687int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
688int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
689int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
690int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
691 u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
692int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
693 u8 dialog_token, __le16 ba_param_set,
694 __le16 ba_timeout, __le16 ba_seq_ctrl);
695void wil_back_rx_worker(struct work_struct *work);
696void wil_back_rx_flush(struct wil6210_priv *wil);
697int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize);
698void wil_back_tx_worker(struct work_struct *work);
699void wil_back_tx_flush(struct wil6210_priv *wil);
570 700
571void wil6210_clear_irq(struct wil6210_priv *wil); 701void wil6210_clear_irq(struct wil6210_priv *wil);
572int wil6210_init_irq(struct wil6210_priv *wil, int irq); 702int wil6210_init_irq(struct wil6210_priv *wil, int irq);
573void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 703void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
574void wil_mask_irq(struct wil6210_priv *wil); 704void wil_mask_irq(struct wil6210_priv *wil);
575void wil_unmask_irq(struct wil6210_priv *wil); 705void wil_unmask_irq(struct wil6210_priv *wil);
706void wil_configure_interrupt_moderation(struct wil6210_priv *wil);
576void wil_disable_irq(struct wil6210_priv *wil); 707void wil_disable_irq(struct wil6210_priv *wil);
577void wil_enable_irq(struct wil6210_priv *wil); 708void wil_enable_irq(struct wil6210_priv *wil);
578int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 709int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 899754920955..b2b0fe1faa96 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -23,10 +23,15 @@
23#include "wmi.h" 23#include "wmi.h"
24#include "trace.h" 24#include "trace.h"
25 25
26static uint max_assoc_sta = 1; 26static uint max_assoc_sta = WIL6210_MAX_CID;
27module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR); 27module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR);
28MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP"); 28MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP");
29 29
30int agg_wsize; /* = 0; */
31module_param(agg_wsize, int, S_IRUGO | S_IWUSR);
32MODULE_PARM_DESC(agg_wsize, " Window size for Tx Block Ack after connect;"
33 " 0 - use default; < 0 - don't auto-establish");
34
30/** 35/**
31 * WMI event receiving - theory of operations 36 * WMI event receiving - theory of operations
32 * 37 *
@@ -197,7 +202,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
197 202
198 might_sleep(); 203 might_sleep();
199 204
200 if (!test_bit(wil_status_fwready, &wil->status)) { 205 if (!test_bit(wil_status_fwready, wil->status)) {
201 wil_err(wil, "WMI: cannot send command while FW not ready\n"); 206 wil_err(wil, "WMI: cannot send command while FW not ready\n");
202 return -EAGAIN; 207 return -EAGAIN;
203 } 208 }
@@ -300,7 +305,7 @@ static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
300 wil_dbg_wmi(wil, "WMI: got FW ready event\n"); 305 wil_dbg_wmi(wil, "WMI: got FW ready event\n");
301 306
302 wil_set_recovery_state(wil, fw_recovery_idle); 307 wil_set_recovery_state(wil, fw_recovery_idle);
303 set_bit(wil_status_fwready, &wil->status); 308 set_bit(wil_status_fwready, wil->status);
304 /* let the reset sequence continue */ 309 /* let the reset sequence continue */
305 complete(&wil->wmi_ready); 310 complete(&wil->wmi_ready);
306} 311}
@@ -438,7 +443,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
438 443
439 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 444 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
440 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 445 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
441 if (!test_bit(wil_status_fwconnecting, &wil->status)) { 446 if (!test_bit(wil_status_fwconnecting, wil->status)) {
442 wil_err(wil, "Not in connecting state\n"); 447 wil_err(wil, "Not in connecting state\n");
443 return; 448 return;
444 } 449 }
@@ -461,8 +466,8 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
461 466
462 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 467 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
463 } 468 }
464 clear_bit(wil_status_fwconnecting, &wil->status); 469 clear_bit(wil_status_fwconnecting, wil->status);
465 set_bit(wil_status_fwconnected, &wil->status); 470 set_bit(wil_status_fwconnected, wil->status);
466 471
467 /* FIXME FW can transmit only ucast frames to peer */ 472 /* FIXME FW can transmit only ucast frames to peer */
468 /* FIXME real ring_id instead of hard coded 0 */ 473 /* FIXME real ring_id instead of hard coded 0 */
@@ -470,7 +475,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
470 wil->sta[evt->cid].status = wil_sta_conn_pending; 475 wil->sta[evt->cid].status = wil_sta_conn_pending;
471 476
472 wil->pending_connect_cid = evt->cid; 477 wil->pending_connect_cid = evt->cid;
473 queue_work(wil->wmi_wq_conn, &wil->connect_worker); 478 queue_work(wil->wq_service, &wil->connect_worker);
474} 479}
475 480
476static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 481static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
@@ -543,6 +548,22 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
543 } 548 }
544} 549}
545 550
551static void wil_addba_tx_cid(struct wil6210_priv *wil, u8 cid, u16 wsize)
552{
553 struct vring_tx_data *t;
554 int i;
555
556 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
557 if (cid != wil->vring2cid_tid[i][0])
558 continue;
559 t = &wil->vring_tx_data[i];
560 if (!t->enabled)
561 continue;
562
563 wil_addba_tx_request(wil, i, wsize);
564 }
565}
566
546static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len) 567static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
547{ 568{
548 struct net_device *ndev = wil_to_ndev(wil); 569 struct net_device *ndev = wil_to_ndev(wil);
@@ -557,6 +578,8 @@ static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
557 } 578 }
558 579
559 wil->sta[cid].data_port_open = true; 580 wil->sta[cid].data_port_open = true;
581 if (agg_wsize >= 0)
582 wil_addba_tx_cid(wil, cid, agg_wsize);
560 netif_carrier_on(ndev); 583 netif_carrier_on(ndev);
561} 584}
562 585
@@ -582,55 +605,89 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
582 int len) 605 int len)
583{ 606{
584 struct wmi_vring_ba_status_event *evt = d; 607 struct wmi_vring_ba_status_event *evt = d;
585 struct wil_sta_info *sta; 608 struct vring_tx_data *txdata;
586 uint i, cid;
587
588 /* TODO: use Rx BA status, not Tx one */
589 609
590 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n", 610 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d AMSDU%s\n",
591 evt->ringid, 611 evt->ringid,
592 evt->status == WMI_BA_AGREED ? "OK" : "N/A", 612 evt->status == WMI_BA_AGREED ? "OK" : "N/A",
593 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout)); 613 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout),
614 evt->amsdu ? "+" : "-");
594 615
595 if (evt->ringid >= WIL6210_MAX_TX_RINGS) { 616 if (evt->ringid >= WIL6210_MAX_TX_RINGS) {
596 wil_err(wil, "invalid ring id %d\n", evt->ringid); 617 wil_err(wil, "invalid ring id %d\n", evt->ringid);
597 return; 618 return;
598 } 619 }
599 620
600 mutex_lock(&wil->mutex); 621 if (evt->status != WMI_BA_AGREED) {
601 622 evt->ba_timeout = 0;
602 cid = wil->vring2cid_tid[evt->ringid][0]; 623 evt->agg_wsize = 0;
603 if (cid >= WIL6210_MAX_CID) { 624 evt->amsdu = 0;
604 wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
605 goto out;
606 } 625 }
607 626
608 sta = &wil->sta[cid]; 627 txdata = &wil->vring_tx_data[evt->ringid];
609 if (sta->status == wil_sta_unused) {
610 wil_err(wil, "CID %d unused\n", cid);
611 goto out;
612 }
613 628
614 wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); 629 txdata->agg_timeout = le16_to_cpu(evt->ba_timeout);
615 for (i = 0; i < WIL_STA_TID_NUM; i++) { 630 txdata->agg_wsize = evt->agg_wsize;
616 struct wil_tid_ampdu_rx *r; 631 txdata->agg_amsdu = evt->amsdu;
617 unsigned long flags; 632 txdata->addba_in_progress = false;
633}
618 634
619 spin_lock_irqsave(&sta->tid_rx_lock, flags); 635static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d,
636 int len)
637{
638 struct wmi_rcp_addba_req_event *evt = d;
620 639
621 r = sta->tid_rx[i]; 640 wil_addba_rx_request(wil, evt->cidxtid, evt->dialog_token,
622 sta->tid_rx[i] = NULL; 641 evt->ba_param_set, evt->ba_timeout,
623 wil_tid_ampdu_rx_free(wil, r); 642 evt->ba_seq_ctrl);
643}
624 644
625 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 645static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len)
646__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
647{
648 struct wmi_delba_event *evt = d;
649 u8 cid, tid;
650 u16 reason = __le16_to_cpu(evt->reason);
651 struct wil_sta_info *sta;
652 struct wil_tid_ampdu_rx *r;
626 653
627 if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) 654 might_sleep();
628 sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, 655 parse_cidxtid(evt->cidxtid, &cid, &tid);
629 evt->agg_wsize, 0); 656 wil_dbg_wmi(wil, "DELBA CID %d TID %d from %s reason %d\n",
657 cid, tid,
658 evt->from_initiator ? "originator" : "recipient",
659 reason);
660 if (!evt->from_initiator) {
661 int i;
662 /* find Tx vring it belongs to */
663 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) {
664 if ((wil->vring2cid_tid[i][0] == cid) &&
665 (wil->vring2cid_tid[i][1] == tid)) {
666 struct vring_tx_data *txdata =
667 &wil->vring_tx_data[i];
668
669 wil_dbg_wmi(wil, "DELBA Tx vring %d\n", i);
670 txdata->agg_timeout = 0;
671 txdata->agg_wsize = 0;
672 txdata->addba_in_progress = false;
673
674 break; /* max. 1 matching ring */
675 }
676 }
677 if (i >= ARRAY_SIZE(wil->vring2cid_tid))
678 wil_err(wil, "DELBA: unable to find Tx vring\n");
679 return;
630 } 680 }
631 681
632out: 682 sta = &wil->sta[cid];
633 mutex_unlock(&wil->mutex); 683
684 spin_lock_bh(&sta->tid_rx_lock);
685
686 r = sta->tid_rx[tid];
687 sta->tid_rx[tid] = NULL;
688 wil_tid_ampdu_rx_free(wil, r);
689
690 spin_unlock_bh(&sta->tid_rx_lock);
634} 691}
635 692
636static const struct { 693static const struct {
@@ -648,6 +705,8 @@ static const struct {
648 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, 705 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup},
649 {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, 706 {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown},
650 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 707 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status},
708 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req},
709 {WMI_DELBA_EVENTID, wmi_evt_delba},
651}; 710};
652 711
653/* 712/*
@@ -667,7 +726,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
667 ulong flags; 726 ulong flags;
668 unsigned n; 727 unsigned n;
669 728
670 if (!test_bit(wil_status_reset_done, &wil->status)) { 729 if (!test_bit(wil_status_reset_done, wil->status)) {
671 wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); 730 wil_err(wil, "Reset in progress. Cannot handle WMI event\n");
672 return; 731 return;
673 } 732 }
@@ -1024,13 +1083,14 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1024 struct wmi_cfg_rx_chain_cmd cmd = { 1083 struct wmi_cfg_rx_chain_cmd cmd = {
1025 .action = WMI_RX_CHAIN_ADD, 1084 .action = WMI_RX_CHAIN_ADD,
1026 .rx_sw_ring = { 1085 .rx_sw_ring = {
1027 .max_mpdu_size = cpu_to_le16(mtu_max + ETH_HLEN), 1086 .max_mpdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)),
1028 .ring_mem_base = cpu_to_le64(vring->pa), 1087 .ring_mem_base = cpu_to_le64(vring->pa),
1029 .ring_size = cpu_to_le16(vring->size), 1088 .ring_size = cpu_to_le16(vring->size),
1030 }, 1089 },
1031 .mid = 0, /* TODO - what is it? */ 1090 .mid = 0, /* TODO - what is it? */
1032 .decap_trans_type = WMI_DECAP_TYPE_802_3, 1091 .decap_trans_type = WMI_DECAP_TYPE_802_3,
1033 .reorder_type = WMI_RX_SW_REORDER, 1092 .reorder_type = WMI_RX_SW_REORDER,
1093 .host_thrsh = cpu_to_le16(rx_ring_overflow_thrsh),
1034 }; 1094 };
1035 struct { 1095 struct {
1036 struct wil6210_mbox_hdr_wmi wmi; 1096 struct wil6210_mbox_hdr_wmi wmi;
@@ -1110,6 +1170,87 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1110 return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd)); 1170 return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd));
1111} 1171}
1112 1172
1173int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout)
1174{
1175 struct wmi_vring_ba_en_cmd cmd = {
1176 .ringid = ringid,
1177 .agg_max_wsize = size,
1178 .ba_timeout = cpu_to_le16(timeout),
1179 .amsdu = 0,
1180 };
1181
1182 wil_dbg_wmi(wil, "%s(ring %d size %d timeout %d)\n", __func__,
1183 ringid, size, timeout);
1184
1185 return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd));
1186}
1187
1188int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason)
1189{
1190 struct wmi_vring_ba_dis_cmd cmd = {
1191 .ringid = ringid,
1192 .reason = cpu_to_le16(reason),
1193 };
1194
1195 wil_dbg_wmi(wil, "%s(ring %d reason %d)\n", __func__,
1196 ringid, reason);
1197
1198 return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd));
1199}
1200
1201int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason)
1202{
1203 struct wmi_rcp_delba_cmd cmd = {
1204 .cidxtid = cidxtid,
1205 .reason = cpu_to_le16(reason),
1206 };
1207
1208 wil_dbg_wmi(wil, "%s(CID %d TID %d reason %d)\n", __func__,
1209 cidxtid & 0xf, (cidxtid >> 4) & 0xf, reason);
1210
1211 return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd));
1212}
1213
1214int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
1215 u16 status, bool amsdu, u16 agg_wsize, u16 timeout)
1216{
1217 int rc;
1218 struct wmi_rcp_addba_resp_cmd cmd = {
1219 .cidxtid = mk_cidxtid(cid, tid),
1220 .dialog_token = token,
1221 .status_code = cpu_to_le16(status),
1222 /* bit 0: A-MSDU supported
1223 * bit 1: policy (should be 0 for us)
1224 * bits 2..5: TID
1225 * bits 6..15: buffer size
1226 */
1227 .ba_param_set = cpu_to_le16((amsdu ? 1 : 0) | (tid << 2) |
1228 (agg_wsize << 6)),
1229 .ba_timeout = cpu_to_le16(timeout),
1230 };
1231 struct {
1232 struct wil6210_mbox_hdr_wmi wmi;
1233 struct wmi_rcp_addba_resp_sent_event evt;
1234 } __packed reply;
1235
1236 wil_dbg_wmi(wil,
1237 "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s\n",
1238 cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-");
1239
1240 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, &cmd, sizeof(cmd),
1241 WMI_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), 100);
1242 if (rc)
1243 return rc;
1244
1245 if (reply.evt.status) {
1246 wil_err(wil, "ADDBA response failed with status %d\n",
1247 le16_to_cpu(reply.evt.status));
1248 rc = -EINVAL;
1249 }
1250
1251 return rc;
1252}
1253
1113void wmi_event_flush(struct wil6210_priv *wil) 1254void wmi_event_flush(struct wil6210_priv *wil)
1114{ 1255{
1115 struct pending_wmi_event *evt, *t; 1256 struct pending_wmi_event *evt, *t;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 27b97432d1c2..b5102f0b97f4 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -586,6 +586,7 @@ struct wmi_vring_ba_en_cmd {
586 u8 ringid; 586 u8 ringid;
587 u8 agg_max_wsize; 587 u8 agg_max_wsize;
588 __le16 ba_timeout; 588 __le16 ba_timeout;
589 u8 amsdu;
589} __packed; 590} __packed;
590 591
591/* 592/*
@@ -1052,14 +1053,23 @@ struct wmi_scan_complete_event {
1052enum wmi_vring_ba_status { 1053enum wmi_vring_ba_status {
1053 WMI_BA_AGREED = 0, 1054 WMI_BA_AGREED = 0,
1054 WMI_BA_NON_AGREED = 1, 1055 WMI_BA_NON_AGREED = 1,
1056 /* BA_EN in middle of teardown flow */
1057 WMI_BA_TD_WIP = 2,
1058 /* BA_DIS or BA_EN in middle of BA SETUP flow */
1059 WMI_BA_SETUP_WIP = 3,
1060 /* BA_EN when the BA session is already active */
1061 WMI_BA_SESSION_ACTIVE = 4,
1062 /* BA_DIS when the BA session is not active */
1063 WMI_BA_SESSION_NOT_ACTIVE = 5,
1055}; 1064};
1056 1065
1057struct wmi_vring_ba_status_event { 1066struct wmi_vring_ba_status_event {
1058 __le16 status; 1067 __le16 status; /* enum wmi_vring_ba_status */
1059 u8 reserved[2]; 1068 u8 reserved[2];
1060 u8 ringid; 1069 u8 ringid;
1061 u8 agg_wsize; 1070 u8 agg_wsize;
1062 __le16 ba_timeout; 1071 __le16 ba_timeout;
1072 u8 amsdu;
1063} __packed; 1073} __packed;
1064 1074
1065/* 1075/*
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 9183f1cf89a7..55db9f03eb2a 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -45,7 +45,6 @@
45#include <linux/ptrace.h> 45#include <linux/ptrace.h>
46#include <linux/slab.h> 46#include <linux/slab.h>
47#include <linux/string.h> 47#include <linux/string.h>
48#include <linux/ctype.h>
49#include <linux/timer.h> 48#include <linux/timer.h>
50#include <asm/byteorder.h> 49#include <asm/byteorder.h>
51#include <asm/io.h> 50#include <asm/io.h>
@@ -2699,16 +2698,7 @@ static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2699 domain[REGDOMAINSZ] = 0; 2698 domain[REGDOMAINSZ] = 0;
2700 rc = -EINVAL; 2699 rc = -EINVAL;
2701 for (i = 0; i < ARRAY_SIZE(channel_table); i++) { 2700 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2702 /* strcasecmp doesn't exist in the library */ 2701 if (!strcasecmp(channel_table[i].name, domain)) {
2703 char *a = channel_table[i].name;
2704 char *b = domain;
2705 while (*a) {
2706 char c1 = *a++;
2707 char c2 = *b++;
2708 if (tolower(c1) != tolower(c2))
2709 break;
2710 }
2711 if (!*a && !*b) {
2712 priv->config_reg_domain = channel_table[i].reg_domain; 2702 priv->config_reg_domain = channel_table[i].reg_domain;
2713 rc = 0; 2703 rc = 0;
2714 } 2704 }
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 47731cb0d815..58a2e88631fb 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4318,6 +4318,7 @@ redo:
4318 mutex_unlock(&wl->mutex); 4318 mutex_unlock(&wl->mutex);
4319 cancel_delayed_work_sync(&dev->periodic_work); 4319 cancel_delayed_work_sync(&dev->periodic_work);
4320 cancel_work_sync(&wl->tx_work); 4320 cancel_work_sync(&wl->tx_work);
4321 b43_leds_stop(dev);
4321 mutex_lock(&wl->mutex); 4322 mutex_lock(&wl->mutex);
4322 dev = wl->current_dev; 4323 dev = wl->current_dev;
4323 if (!dev || b43_status(dev) < B43_STAT_STARTED) { 4324 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
diff --git a/drivers/net/wireless/b43legacy/radio.c b/drivers/net/wireless/b43legacy/radio.c
index 896177690394..9501420340a9 100644
--- a/drivers/net/wireless/b43legacy/radio.c
+++ b/drivers/net/wireless/b43legacy/radio.c
@@ -1743,25 +1743,6 @@ u16 freq_r3A_value(u16 frequency)
1743 return value; 1743 return value;
1744} 1744}
1745 1745
1746void b43legacy_radio_set_tx_iq(struct b43legacy_wldev *dev)
1747{
1748 static const u8 data_high[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
1749 static const u8 data_low[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
1750 u16 tmp = b43legacy_radio_read16(dev, 0x001E);
1751 int i;
1752 int j;
1753
1754 for (i = 0; i < 5; i++) {
1755 for (j = 0; j < 5; j++) {
1756 if (tmp == (data_high[i] | data_low[j])) {
1757 b43legacy_phy_write(dev, 0x0069, (i - j) << 8 |
1758 0x00C0);
1759 return;
1760 }
1761 }
1762 }
1763}
1764
1765int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev, 1746int b43legacy_radio_selectchannel(struct b43legacy_wldev *dev,
1766 u8 channel, 1747 u8 channel,
1767 int synthetic_pu_workaround) 1748 int synthetic_pu_workaround)
diff --git a/drivers/net/wireless/b43legacy/radio.h b/drivers/net/wireless/b43legacy/radio.h
index bccb3d7da682..dd2976d1d561 100644
--- a/drivers/net/wireless/b43legacy/radio.h
+++ b/drivers/net/wireless/b43legacy/radio.h
@@ -92,7 +92,6 @@ void b43legacy_nrssi_hw_write(struct b43legacy_wldev *dev, u16 offset, s16 val);
92void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val); 92void b43legacy_nrssi_hw_update(struct b43legacy_wldev *dev, u16 val);
93void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev); 93void b43legacy_nrssi_mem_update(struct b43legacy_wldev *dev);
94 94
95void b43legacy_radio_set_tx_iq(struct b43legacy_wldev *dev);
96u16 b43legacy_radio_calibrationvalue(struct b43legacy_wldev *dev); 95u16 b43legacy_radio_calibrationvalue(struct b43legacy_wldev *dev);
97 96
98#endif /* B43legacy_RADIO_H_ */ 97#endif /* B43legacy_RADIO_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 9880dae2a569..00ba90b89455 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -996,18 +996,20 @@ out:
996} 996}
997 997
998#define BRCMF_SDIO_DEVICE(dev_id) \ 998#define BRCMF_SDIO_DEVICE(dev_id) \
999 {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)} 999 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, dev_id)}
1000 1000
1001/* devices we support, null terminated */ 1001/* devices we support, null terminated */
1002static const struct sdio_device_id brcmf_sdmmc_ids[] = { 1002static const struct sdio_device_id brcmf_sdmmc_ids[] = {
1003 BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID), 1003 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143),
1004 BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID), 1004 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43241),
1005 BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID), 1005 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4329),
1006 BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID), 1006 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4330),
1007 BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID), 1007 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4334),
1008 BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID), 1008 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
1009 BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID), 1009 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
1010 BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID), 1010 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
1011 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
1012 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
1011 { /* end: all zeroes */ } 1013 { /* end: all zeroes */ }
1012}; 1014};
1013MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 1015MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 4a88b2381a68..5eba81bfc6ed 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -38,6 +38,7 @@
38#include "proto.h" 38#include "proto.h"
39#include "vendor.h" 39#include "vendor.h"
40#include "bus.h" 40#include "bus.h"
41#include "common.h"
41 42
42#define BRCMF_SCAN_IE_LEN_MAX 2048 43#define BRCMF_SCAN_IE_LEN_MAX 2048
43#define BRCMF_PNO_VERSION 2 44#define BRCMF_PNO_VERSION 2
@@ -452,16 +453,16 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
452} 453}
453 454
454static int 455static int
455send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key) 456send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
456{ 457{
457 int err; 458 int err;
458 struct brcmf_wsec_key_le key_le; 459 struct brcmf_wsec_key_le key_le;
459 460
460 convert_key_from_CPU(key, &key_le); 461 convert_key_from_CPU(key, &key_le);
461 462
462 brcmf_netdev_wait_pend8021x(ndev); 463 brcmf_netdev_wait_pend8021x(ifp);
463 464
464 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le, 465 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
465 sizeof(key_le)); 466 sizeof(key_le));
466 467
467 if (err) 468 if (err)
@@ -1670,7 +1671,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
1670 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n", 1671 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1671 key.len, key.index, key.algo); 1672 key.len, key.index, key.algo);
1672 brcmf_dbg(CONN, "key \"%s\"\n", key.data); 1673 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1673 err = send_key_to_dongle(ndev, &key); 1674 err = send_key_to_dongle(netdev_priv(ndev), &key);
1674 if (err) 1675 if (err)
1675 return err; 1676 return err;
1676 1677
@@ -2052,7 +2053,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2052 /* check for key index change */ 2053 /* check for key index change */
2053 if (key.len == 0) { 2054 if (key.len == 0) {
2054 /* key delete */ 2055 /* key delete */
2055 err = send_key_to_dongle(ndev, &key); 2056 err = send_key_to_dongle(ifp, &key);
2056 if (err) 2057 if (err)
2057 brcmf_err("key delete error (%d)\n", err); 2058 brcmf_err("key delete error (%d)\n", err);
2058 } else { 2059 } else {
@@ -2108,7 +2109,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2108 brcmf_err("Invalid cipher (0x%x)\n", params->cipher); 2109 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2109 return -EINVAL; 2110 return -EINVAL;
2110 } 2111 }
2111 err = send_key_to_dongle(ndev, &key); 2112 err = send_key_to_dongle(ifp, &key);
2112 if (err) 2113 if (err)
2113 brcmf_err("wsec_key error (%d)\n", err); 2114 brcmf_err("wsec_key error (%d)\n", err);
2114 } 2115 }
@@ -2121,7 +2122,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2121 struct key_params *params) 2122 struct key_params *params)
2122{ 2123{
2123 struct brcmf_if *ifp = netdev_priv(ndev); 2124 struct brcmf_if *ifp = netdev_priv(ndev);
2124 struct brcmf_wsec_key key; 2125 struct brcmf_wsec_key *key;
2125 s32 val; 2126 s32 val;
2126 s32 wsec; 2127 s32 wsec;
2127 s32 err = 0; 2128 s32 err = 0;
@@ -2132,54 +2133,62 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2132 if (!check_vif_up(ifp->vif)) 2133 if (!check_vif_up(ifp->vif))
2133 return -EIO; 2134 return -EIO;
2134 2135
2136 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2137 /* we ignore this key index in this case */
2138 brcmf_err("invalid key index (%d)\n", key_idx);
2139 return -EINVAL;
2140 }
2141
2135 if (mac_addr && 2142 if (mac_addr &&
2136 (params->cipher != WLAN_CIPHER_SUITE_WEP40) && 2143 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2137 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { 2144 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2138 brcmf_dbg(TRACE, "Exit"); 2145 brcmf_dbg(TRACE, "Exit");
2139 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params); 2146 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2140 } 2147 }
2141 memset(&key, 0, sizeof(key));
2142 2148
2143 key.len = (u32) params->key_len; 2149 key = &ifp->vif->profile.key[key_idx];
2144 key.index = (u32) key_idx; 2150 memset(key, 0, sizeof(*key));
2145 2151
2146 if (key.len > sizeof(key.data)) { 2152 if (params->key_len > sizeof(key->data)) {
2147 brcmf_err("Too long key length (%u)\n", key.len); 2153 brcmf_err("Too long key length (%u)\n", params->key_len);
2148 err = -EINVAL; 2154 err = -EINVAL;
2149 goto done; 2155 goto done;
2150 } 2156 }
2151 memcpy(key.data, params->key, key.len); 2157 key->len = params->key_len;
2158 key->index = key_idx;
2152 2159
2153 key.flags = BRCMF_PRIMARY_KEY; 2160 memcpy(key->data, params->key, key->len);
2161
2162 key->flags = BRCMF_PRIMARY_KEY;
2154 switch (params->cipher) { 2163 switch (params->cipher) {
2155 case WLAN_CIPHER_SUITE_WEP40: 2164 case WLAN_CIPHER_SUITE_WEP40:
2156 key.algo = CRYPTO_ALGO_WEP1; 2165 key->algo = CRYPTO_ALGO_WEP1;
2157 val = WEP_ENABLED; 2166 val = WEP_ENABLED;
2158 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n"); 2167 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2159 break; 2168 break;
2160 case WLAN_CIPHER_SUITE_WEP104: 2169 case WLAN_CIPHER_SUITE_WEP104:
2161 key.algo = CRYPTO_ALGO_WEP128; 2170 key->algo = CRYPTO_ALGO_WEP128;
2162 val = WEP_ENABLED; 2171 val = WEP_ENABLED;
2163 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); 2172 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2164 break; 2173 break;
2165 case WLAN_CIPHER_SUITE_TKIP: 2174 case WLAN_CIPHER_SUITE_TKIP:
2166 if (!brcmf_is_apmode(ifp->vif)) { 2175 if (!brcmf_is_apmode(ifp->vif)) {
2167 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); 2176 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2168 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2177 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2169 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2178 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2170 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 2179 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2171 } 2180 }
2172 key.algo = CRYPTO_ALGO_TKIP; 2181 key->algo = CRYPTO_ALGO_TKIP;
2173 val = TKIP_ENABLED; 2182 val = TKIP_ENABLED;
2174 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); 2183 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2175 break; 2184 break;
2176 case WLAN_CIPHER_SUITE_AES_CMAC: 2185 case WLAN_CIPHER_SUITE_AES_CMAC:
2177 key.algo = CRYPTO_ALGO_AES_CCM; 2186 key->algo = CRYPTO_ALGO_AES_CCM;
2178 val = AES_ENABLED; 2187 val = AES_ENABLED;
2179 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); 2188 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2180 break; 2189 break;
2181 case WLAN_CIPHER_SUITE_CCMP: 2190 case WLAN_CIPHER_SUITE_CCMP:
2182 key.algo = CRYPTO_ALGO_AES_CCM; 2191 key->algo = CRYPTO_ALGO_AES_CCM;
2183 val = AES_ENABLED; 2192 val = AES_ENABLED;
2184 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); 2193 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2185 break; 2194 break;
@@ -2189,7 +2198,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2189 goto done; 2198 goto done;
2190 } 2199 }
2191 2200
2192 err = send_key_to_dongle(ndev, &key); 2201 err = send_key_to_dongle(ifp, key);
2193 if (err) 2202 if (err)
2194 goto done; 2203 goto done;
2195 2204
@@ -2222,7 +2231,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2222 if (!check_vif_up(ifp->vif)) 2231 if (!check_vif_up(ifp->vif))
2223 return -EIO; 2232 return -EIO;
2224 2233
2225 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { 2234 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2226 /* we ignore this key index in this case */ 2235 /* we ignore this key index in this case */
2227 brcmf_err("invalid key index (%d)\n", key_idx); 2236 brcmf_err("invalid key index (%d)\n", key_idx);
2228 return -EINVAL; 2237 return -EINVAL;
@@ -2237,7 +2246,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2237 brcmf_dbg(CONN, "key index (%d)\n", key_idx); 2246 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2238 2247
2239 /* Set the new key/index */ 2248 /* Set the new key/index */
2240 err = send_key_to_dongle(ndev, &key); 2249 err = send_key_to_dongle(ifp, &key);
2241 2250
2242 brcmf_dbg(TRACE, "Exit\n"); 2251 brcmf_dbg(TRACE, "Exit\n");
2243 return err; 2252 return err;
@@ -2305,6 +2314,39 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2305 return -EOPNOTSUPP; 2314 return -EOPNOTSUPP;
2306} 2315}
2307 2316
2317static void
2318brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2319{
2320 s32 err;
2321 u8 key_idx;
2322 struct brcmf_wsec_key *key;
2323 s32 wsec;
2324
2325 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2326 key = &ifp->vif->profile.key[key_idx];
2327 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2328 (key->algo == CRYPTO_ALGO_WEP128))
2329 break;
2330 }
2331 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2332 return;
2333
2334 err = send_key_to_dongle(ifp, key);
2335 if (err) {
2336 brcmf_err("Setting WEP key failed (%d)\n", err);
2337 return;
2338 }
2339 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2340 if (err) {
2341 brcmf_err("get wsec error (%d)\n", err);
2342 return;
2343 }
2344 wsec |= WEP_ENABLED;
2345 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2346 if (err)
2347 brcmf_err("set wsec error (%d)\n", err);
2348}
2349
2308static s32 2350static s32
2309brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2351brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2310 const u8 *mac, struct station_info *sinfo) 2352 const u8 *mac, struct station_info *sinfo)
@@ -3695,17 +3737,12 @@ static u32
3695brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) 3737brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3696{ 3738{
3697 3739
3698 __le32 iecount_le;
3699 __le32 pktflag_le;
3700
3701 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); 3740 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3702 iebuf[VNDR_IE_CMD_LEN - 1] = '\0'; 3741 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3703 3742
3704 iecount_le = cpu_to_le32(1); 3743 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3705 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3706 3744
3707 pktflag_le = cpu_to_le32(pktflag); 3745 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3708 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3709 3746
3710 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len); 3747 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3711 3748
@@ -3924,6 +3961,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3924 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3961 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3925 struct brcmf_if *ifp = netdev_priv(ndev); 3962 struct brcmf_if *ifp = netdev_priv(ndev);
3926 const struct brcmf_tlv *ssid_ie; 3963 const struct brcmf_tlv *ssid_ie;
3964 const struct brcmf_tlv *country_ie;
3927 struct brcmf_ssid_le ssid_le; 3965 struct brcmf_ssid_le ssid_le;
3928 s32 err = -EPERM; 3966 s32 err = -EPERM;
3929 const struct brcmf_tlv *rsn_ie; 3967 const struct brcmf_tlv *rsn_ie;
@@ -3933,6 +3971,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3933 struct brcmf_fil_bss_enable_le bss_enable; 3971 struct brcmf_fil_bss_enable_le bss_enable;
3934 u16 chanspec; 3972 u16 chanspec;
3935 bool mbss; 3973 bool mbss;
3974 int is_11d;
3936 3975
3937 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", 3976 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3938 settings->chandef.chan->hw_value, 3977 settings->chandef.chan->hw_value,
@@ -3941,10 +3980,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3941 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", 3980 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3942 settings->ssid, settings->ssid_len, settings->auth_type, 3981 settings->ssid, settings->ssid_len, settings->auth_type,
3943 settings->inactivity_timeout); 3982 settings->inactivity_timeout);
3944
3945 dev_role = ifp->vif->wdev.iftype; 3983 dev_role = ifp->vif->wdev.iftype;
3946 mbss = ifp->vif->mbss; 3984 mbss = ifp->vif->mbss;
3947 3985
3986 /* store current 11d setting */
3987 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
3988 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3989 settings->beacon.tail_len,
3990 WLAN_EID_COUNTRY);
3991 is_11d = country_ie ? 1 : 0;
3992
3948 memset(&ssid_le, 0, sizeof(ssid_le)); 3993 memset(&ssid_le, 0, sizeof(ssid_le));
3949 if (settings->ssid == NULL || settings->ssid_len == 0) { 3994 if (settings->ssid == NULL || settings->ssid_len == 0) {
3950 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; 3995 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
@@ -4010,6 +4055,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4010 goto exit; 4055 goto exit;
4011 } 4056 }
4012 4057
4058 if (is_11d != ifp->vif->is_11d) {
4059 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4060 is_11d);
4061 if (err < 0) {
4062 brcmf_err("Regulatory Set Error, %d\n", err);
4063 goto exit;
4064 }
4065 }
4013 if (settings->beacon_interval) { 4066 if (settings->beacon_interval) {
4014 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, 4067 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4015 settings->beacon_interval); 4068 settings->beacon_interval);
@@ -4042,6 +4095,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4042 brcmf_err("SET INFRA error %d\n", err); 4095 brcmf_err("SET INFRA error %d\n", err);
4043 goto exit; 4096 goto exit;
4044 } 4097 }
4098 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4099 /* Multiple-BSS should use same 11d configuration */
4100 err = -EINVAL;
4101 goto exit;
4045 } 4102 }
4046 if (dev_role == NL80211_IFTYPE_AP) { 4103 if (dev_role == NL80211_IFTYPE_AP) {
4047 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) 4104 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
@@ -4057,6 +4114,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4057 brcmf_err("BRCMF_C_UP error (%d)\n", err); 4114 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4058 goto exit; 4115 goto exit;
4059 } 4116 }
4117 /* On DOWN the firmware removes the WEP keys, reconfigure
4118 * them if they were set.
4119 */
4120 brcmf_cfg80211_reconfigure_wep(ifp);
4060 4121
4061 memset(&join_params, 0, sizeof(join_params)); 4122 memset(&join_params, 0, sizeof(join_params));
4062 /* join parameters starts with ssid */ 4123 /* join parameters starts with ssid */
@@ -4133,6 +4194,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4133 brcmf_err("setting INFRA mode failed %d\n", err); 4194 brcmf_err("setting INFRA mode failed %d\n", err);
4134 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) 4195 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4135 brcmf_fil_iovar_int_set(ifp, "mbss", 0); 4196 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4197 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4198 ifp->vif->is_11d);
4199 if (err < 0)
4200 brcmf_err("restoring REGULATORY setting failed %d\n",
4201 err);
4136 /* Bring device back up so it can be used again */ 4202 /* Bring device back up so it can be used again */
4137 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); 4203 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4138 if (err < 0) 4204 if (err < 0)
@@ -4197,6 +4263,34 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4197 return err; 4263 return err;
4198} 4264}
4199 4265
4266static int
4267brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4268 const u8 *mac, struct station_parameters *params)
4269{
4270 struct brcmf_if *ifp = netdev_priv(ndev);
4271 s32 err;
4272
4273 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4274 params->sta_flags_mask, params->sta_flags_set);
4275
4276 /* Ignore all 00 MAC */
4277 if (is_zero_ether_addr(mac))
4278 return 0;
4279
4280 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4281 return 0;
4282
4283 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4284 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4285 (void *)mac, ETH_ALEN);
4286 else
4287 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4288 (void *)mac, ETH_ALEN);
4289 if (err < 0)
4290 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4291
4292 return err;
4293}
4200 4294
4201static void 4295static void
4202brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy, 4296brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
@@ -4471,6 +4565,7 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4471 .stop_ap = brcmf_cfg80211_stop_ap, 4565 .stop_ap = brcmf_cfg80211_stop_ap,
4472 .change_beacon = brcmf_cfg80211_change_beacon, 4566 .change_beacon = brcmf_cfg80211_change_beacon,
4473 .del_station = brcmf_cfg80211_del_station, 4567 .del_station = brcmf_cfg80211_del_station,
4568 .change_station = brcmf_cfg80211_change_station,
4474 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 4569 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4475 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 4570 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4476 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register, 4571 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
@@ -5875,6 +5970,29 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5875 vif_event_equals(event, action), timeout); 5970 vif_event_equals(event, action), timeout);
5876} 5971}
5877 5972
5973static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
5974 struct regulatory_request *req)
5975{
5976 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5977 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5978 struct brcmf_fil_country_le ccreq;
5979 int i;
5980
5981 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
5982 req->alpha2[0], req->alpha2[1]);
5983
5984 /* ignore non-ISO3166 country codes */
5985 for (i = 0; i < sizeof(req->alpha2); i++)
5986 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
5987 brcmf_err("not a ISO3166 code\n");
5988 return;
5989 }
5990 memset(&ccreq, 0, sizeof(ccreq));
5991 ccreq.rev = cpu_to_le32(-1);
5992 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
5993 brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
5994}
5995
5878static void brcmf_free_wiphy(struct wiphy *wiphy) 5996static void brcmf_free_wiphy(struct wiphy *wiphy)
5879{ 5997{
5880 kfree(wiphy->iface_combinations); 5998 kfree(wiphy->iface_combinations);
@@ -5951,6 +6069,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5951 goto priv_out; 6069 goto priv_out;
5952 6070
5953 brcmf_dbg(INFO, "Registering custom regulatory\n"); 6071 brcmf_dbg(INFO, "Registering custom regulatory\n");
6072 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
5954 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 6073 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
5955 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 6074 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5956 6075
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
index 9e98b8d52757..d9e6d01b2b69 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
@@ -75,6 +75,8 @@
75 75
76#define BRCMF_VNDR_IE_P2PAF_SHIFT 12 76#define BRCMF_VNDR_IE_P2PAF_SHIFT 12
77 77
78#define BRCMF_MAX_DEFAULT_KEYS 4
79
78 80
79/** 81/**
80 * enum brcmf_scan_status - scan engine status 82 * enum brcmf_scan_status - scan engine status
@@ -125,11 +127,13 @@ struct brcmf_cfg80211_security {
125 * @ssid: ssid of associated/associating ap. 127 * @ssid: ssid of associated/associating ap.
126 * @bssid: bssid of joined/joining ibss. 128 * @bssid: bssid of joined/joining ibss.
127 * @sec: security information. 129 * @sec: security information.
130 * @key: key information
128 */ 131 */
129struct brcmf_cfg80211_profile { 132struct brcmf_cfg80211_profile {
130 struct brcmf_ssid ssid; 133 struct brcmf_ssid ssid;
131 u8 bssid[ETH_ALEN]; 134 u8 bssid[ETH_ALEN];
132 struct brcmf_cfg80211_security sec; 135 struct brcmf_cfg80211_security sec;
136 struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS];
133}; 137};
134 138
135/** 139/**
@@ -196,6 +200,7 @@ struct brcmf_cfg80211_vif {
196 struct list_head list; 200 struct list_head list;
197 u16 mgmt_rx_reg; 201 u16 mgmt_rx_reg;
198 bool mbss; 202 bool mbss;
203 int is_11d;
199}; 204};
200 205
201/* association inform */ 206/* association inform */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index ddae0b5e56ec..04d2ca0d87d6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -101,14 +101,7 @@
101/* ARM Cortex M3 core, ID 0x82a */ 101/* ARM Cortex M3 core, ID 0x82a */
102#define BCM4329_CORE_ARM_BASE 0x18002000 102#define BCM4329_CORE_ARM_BASE 0x18002000
103#define BCM4329_RAMSIZE 0x48000 103#define BCM4329_RAMSIZE 0x48000
104
105/* bcm43143 */ 104/* bcm43143 */
106/* SDIO device core */
107#define BCM43143_CORE_BUS_BASE 0x18002000
108/* internal memory core */
109#define BCM43143_CORE_SOCRAM_BASE 0x18004000
110/* ARM Cortex M3 core, ID 0x82a */
111#define BCM43143_CORE_ARM_BASE 0x18003000
112#define BCM43143_RAMSIZE 0x70000 105#define BCM43143_RAMSIZE 0x70000
113 106
114#define CORE_SB(base, field) \ 107#define CORE_SB(base, field) \
@@ -164,13 +157,6 @@ struct brcmf_core_priv {
164 struct brcmf_chip_priv *chip; 157 struct brcmf_chip_priv *chip;
165}; 158};
166 159
167/* ARM CR4 core specific control flag bits */
168#define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
169
170/* D11 core specific control flag bits */
171#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004
172#define D11_BCMA_IOCTL_PHYRESET 0x0008
173
174struct brcmf_chip_priv { 160struct brcmf_chip_priv {
175 struct brcmf_chip pub; 161 struct brcmf_chip pub;
176 const struct brcmf_buscore_ops *ops; 162 const struct brcmf_buscore_ops *ops;
@@ -495,6 +481,7 @@ static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
495 ci->pub.ramsize = 0x48000; 481 ci->pub.ramsize = 0x48000;
496 break; 482 break;
497 case BRCM_CC_4334_CHIP_ID: 483 case BRCM_CC_4334_CHIP_ID:
484 case BRCM_CC_43340_CHIP_ID:
498 ci->pub.ramsize = 0x80000; 485 ci->pub.ramsize = 0x80000;
499 break; 486 break;
500 case BRCM_CC_4335_CHIP_ID: 487 case BRCM_CC_4335_CHIP_ID:
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.c b/drivers/net/wireless/brcm80211/brcmfmac/common.c
index 1861a13e8d03..ddf05af13d44 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.c
@@ -25,6 +25,9 @@
25#include "fwil.h" 25#include "fwil.h"
26#include "fwil_types.h" 26#include "fwil_types.h"
27#include "tracepoint.h" 27#include "tracepoint.h"
28#include "common.h"
29
30const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
28 31
29#define BRCMF_DEFAULT_BCN_TIMEOUT 3 32#define BRCMF_DEFAULT_BCN_TIMEOUT 3
30#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 33#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/common.h b/drivers/net/wireless/brcm80211/brcmfmac/common.h
new file mode 100644
index 000000000000..0d39d80cee28
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.h
@@ -0,0 +1,20 @@
1/* Copyright (c) 2014 Broadcom Corporation
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 */
15#ifndef BRCMFMAC_COMMON_H
16#define BRCMFMAC_COMMON_H
17
18extern const u8 ALLFFMAC[ETH_ALEN];
19
20#endif /* BRCMFMAC_COMMON_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index effe6d7831d9..e2a9e33f71ab 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -1093,9 +1093,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1093 return atomic_read(&ifp->pend_8021x_cnt); 1093 return atomic_read(&ifp->pend_8021x_cnt);
1094} 1094}
1095 1095
1096int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 1096int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
1097{ 1097{
1098 struct brcmf_if *ifp = netdev_priv(ndev);
1099 int err; 1098 int err;
1100 1099
1101 err = wait_event_timeout(ifp->pend_8021x_wait, 1100 err = wait_event_timeout(ifp->pend_8021x_wait,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h
index 23f74b139cc8..f2f7d3d1a8ef 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -29,8 +29,6 @@
29/* For supporting multiple interfaces */ 29/* For supporting multiple interfaces */
30#define BRCMF_MAX_IFS 16 30#define BRCMF_MAX_IFS 16
31 31
32#define DOT11_MAX_DEFAULT_KEYS 4
33
34/* Small, medium and maximum buffer size for dcmd 32/* Small, medium and maximum buffer size for dcmd
35 */ 33 */
36#define BRCMF_DCMD_SMLEN 256 34#define BRCMF_DCMD_SMLEN 256
@@ -167,7 +165,7 @@ struct brcmf_skb_reorder_data {
167 u8 *reorder; 165 u8 *reorder;
168}; 166};
169 167
170int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 168int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
171 169
172/* Return pointer to interface name */ 170/* Return pointer to interface name */
173char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 171char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
index 44f3a84d1999..910fbb561469 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -25,6 +25,7 @@
25#include "proto.h" 25#include "proto.h"
26#include "flowring.h" 26#include "flowring.h"
27#include "msgbuf.h" 27#include "msgbuf.h"
28#include "common.h"
28 29
29 30
30#define BRCMF_FLOWRING_HIGH 1024 31#define BRCMF_FLOWRING_HIGH 1024
@@ -34,9 +35,6 @@
34#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] + fifo + ifidx * 16) 35#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] + fifo + ifidx * 16)
35#define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16) 36#define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16)
36 37
37static const u8 ALLZEROMAC[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
38static const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
39
40static const u8 brcmf_flowring_prio2fifo[] = { 38static const u8 brcmf_flowring_prio2fifo[] = {
41 1, 39 1,
42 0, 40 0,
@@ -137,7 +135,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN],
137 hash = flow->hash; 135 hash = flow->hash;
138 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { 136 for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) {
139 if ((hash[hash_idx].ifidx == BRCMF_FLOWRING_INVALID_IFIDX) && 137 if ((hash[hash_idx].ifidx == BRCMF_FLOWRING_INVALID_IFIDX) &&
140 (memcmp(hash[hash_idx].mac, ALLZEROMAC, ETH_ALEN) == 0)) { 138 (is_zero_ether_addr(hash[hash_idx].mac))) {
141 found = true; 139 found = true;
142 break; 140 break;
143 } 141 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index a30be683f4a1..37345e7b873d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -43,6 +43,8 @@
43#define BRCMF_C_SET_RADIO 38 43#define BRCMF_C_SET_RADIO 38
44#define BRCMF_C_GET_PHYTYPE 39 44#define BRCMF_C_GET_PHYTYPE 39
45#define BRCMF_C_SET_KEY 45 45#define BRCMF_C_SET_KEY 45
46#define BRCMF_C_GET_REGULATORY 46
47#define BRCMF_C_SET_REGULATORY 47
46#define BRCMF_C_SET_PASSIVE_SCAN 49 48#define BRCMF_C_SET_PASSIVE_SCAN 49
47#define BRCMF_C_SCAN 50 49#define BRCMF_C_SCAN 50
48#define BRCMF_C_SCAN_RESULTS 51 50#define BRCMF_C_SCAN_RESULTS 51
@@ -60,6 +62,8 @@
60#define BRCMF_C_GET_CURR_RATESET 114 62#define BRCMF_C_GET_CURR_RATESET 114
61#define BRCMF_C_GET_AP 117 63#define BRCMF_C_GET_AP 117
62#define BRCMF_C_SET_AP 118 64#define BRCMF_C_SET_AP 118
65#define BRCMF_C_SET_SCB_AUTHORIZE 121
66#define BRCMF_C_SET_SCB_DEAUTHORIZE 122
63#define BRCMF_C_GET_RSSI 127 67#define BRCMF_C_GET_RSSI 127
64#define BRCMF_C_GET_WSEC 133 68#define BRCMF_C_GET_WSEC 133
65#define BRCMF_C_SET_WSEC 134 69#define BRCMF_C_SET_WSEC 134
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 50891c02c4c1..619669bbdb83 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -112,6 +112,7 @@
112#define BRCMF_WOWL_MAXPATTERNS 8 112#define BRCMF_WOWL_MAXPATTERNS 8
113#define BRCMF_WOWL_MAXPATTERNSIZE 128 113#define BRCMF_WOWL_MAXPATTERNSIZE 128
114 114
115#define BRCMF_COUNTRY_BUF_SZ 4
115 116
116/* join preference types for join_pref iovar */ 117/* join preference types for join_pref iovar */
117enum brcmf_join_pref_types { 118enum brcmf_join_pref_types {
@@ -525,4 +526,17 @@ struct brcmf_mbss_ssid_le {
525 unsigned char SSID[32]; 526 unsigned char SSID[32];
526}; 527};
527 528
529/**
530 * struct brcmf_fil_country_le - country configuration structure.
531 *
532 * @country_abbrev: null-terminated country code used in the country IE.
533 * @rev: revision specifier for ccode. on set, -1 indicates unspecified.
534 * @ccode: null-terminated built-in country code.
535 */
536struct brcmf_fil_country_le {
537 char country_abbrev[BRCMF_COUNTRY_BUF_SZ];
538 __le32 rev;
539 char ccode[BRCMF_COUNTRY_BUF_SZ];
540};
541
528#endif /* FWIL_TYPES_H_ */ 542#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 456944a6a2db..ee147f5c706a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -583,7 +583,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
583 u32 flowid; 583 u32 flowid;
584 void *dma_buf; 584 void *dma_buf;
585 u32 dma_sz; 585 u32 dma_sz;
586 long long address; 586 u64 address;
587 int err; 587 int err;
588 588
589 flowid = work->flowid; 589 flowid = work->flowid;
@@ -620,7 +620,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
620 BRCMF_NROF_H2D_COMMON_MSGRINGS); 620 BRCMF_NROF_H2D_COMMON_MSGRINGS);
621 memcpy(create->sa, work->sa, ETH_ALEN); 621 memcpy(create->sa, work->sa, ETH_ALEN);
622 memcpy(create->da, work->da, ETH_ALEN); 622 memcpy(create->da, work->da, ETH_ALEN);
623 address = (long long)(long)msgbuf->flowring_dma_handle[flowid]; 623 address = (u64)msgbuf->flowring_dma_handle[flowid];
624 create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32); 624 create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32);
625 create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff); 625 create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff);
626 create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM); 626 create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM);
@@ -698,7 +698,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid)
698 dma_addr_t physaddr; 698 dma_addr_t physaddr;
699 u32 pktid; 699 u32 pktid;
700 struct msgbuf_tx_msghdr *tx_msghdr; 700 struct msgbuf_tx_msghdr *tx_msghdr;
701 long long address; 701 u64 address;
702 702
703 commonring = msgbuf->flowrings[flowid]; 703 commonring = msgbuf->flowrings[flowid];
704 if (!brcmf_commonring_write_available(commonring)) 704 if (!brcmf_commonring_write_available(commonring))
@@ -742,7 +742,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid)
742 tx_msghdr->seg_cnt = 1; 742 tx_msghdr->seg_cnt = 1;
743 memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN); 743 memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN);
744 tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN); 744 tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN);
745 address = (long long)(long)physaddr; 745 address = (u64)physaddr;
746 tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32); 746 tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32);
747 tx_msghdr->data_buf_addr.low_addr = 747 tx_msghdr->data_buf_addr.low_addr =
748 cpu_to_le32(address & 0xffffffff); 748 cpu_to_le32(address & 0xffffffff);
@@ -885,7 +885,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
885 u32 pktlen; 885 u32 pktlen;
886 dma_addr_t physaddr; 886 dma_addr_t physaddr;
887 struct msgbuf_rx_bufpost *rx_bufpost; 887 struct msgbuf_rx_bufpost *rx_bufpost;
888 long long address; 888 u64 address;
889 u32 pktid; 889 u32 pktid;
890 u32 i; 890 u32 i;
891 891
@@ -894,7 +894,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
894 count, 894 count,
895 &alloced); 895 &alloced);
896 if (!ret_ptr) { 896 if (!ret_ptr) {
897 brcmf_err("Failed to reserve space in commonring\n"); 897 brcmf_dbg(MSGBUF, "Failed to reserve space in commonring\n");
898 return 0; 898 return 0;
899 } 899 }
900 900
@@ -921,7 +921,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
921 } 921 }
922 922
923 if (msgbuf->rx_metadata_offset) { 923 if (msgbuf->rx_metadata_offset) {
924 address = (long long)(long)physaddr; 924 address = (u64)physaddr;
925 rx_bufpost->metadata_buf_len = 925 rx_bufpost->metadata_buf_len =
926 cpu_to_le16(msgbuf->rx_metadata_offset); 926 cpu_to_le16(msgbuf->rx_metadata_offset);
927 rx_bufpost->metadata_buf_addr.high_addr = 927 rx_bufpost->metadata_buf_addr.high_addr =
@@ -936,7 +936,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
936 rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST; 936 rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST;
937 rx_bufpost->msg.request_id = cpu_to_le32(pktid); 937 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
938 938
939 address = (long long)(long)physaddr; 939 address = (u64)physaddr;
940 rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen); 940 rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen);
941 rx_bufpost->data_buf_addr.high_addr = 941 rx_bufpost->data_buf_addr.high_addr =
942 cpu_to_le32(address >> 32); 942 cpu_to_le32(address >> 32);
@@ -992,7 +992,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
992 u32 pktlen; 992 u32 pktlen;
993 dma_addr_t physaddr; 993 dma_addr_t physaddr;
994 struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost; 994 struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost;
995 long long address; 995 u64 address;
996 u32 pktid; 996 u32 pktid;
997 u32 i; 997 u32 i;
998 998
@@ -1035,7 +1035,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
1035 MSGBUF_TYPE_IOCTLRESP_BUF_POST; 1035 MSGBUF_TYPE_IOCTLRESP_BUF_POST;
1036 rx_bufpost->msg.request_id = cpu_to_le32(pktid); 1036 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
1037 1037
1038 address = (long long)(long)physaddr; 1038 address = (u64)physaddr;
1039 rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen); 1039 rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen);
1040 rx_bufpost->host_buf_addr.high_addr = 1040 rx_bufpost->host_buf_addr.high_addr =
1041 cpu_to_le32(address >> 32); 1041 cpu_to_le32(address >> 32);
@@ -1348,7 +1348,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1348{ 1348{
1349 struct brcmf_bus_msgbuf *if_msgbuf; 1349 struct brcmf_bus_msgbuf *if_msgbuf;
1350 struct brcmf_msgbuf *msgbuf; 1350 struct brcmf_msgbuf *msgbuf;
1351 long long address; 1351 u64 address;
1352 u32 count; 1352 u32 count;
1353 1353
1354 if_msgbuf = drvr->bus_if->msgbuf; 1354 if_msgbuf = drvr->bus_if->msgbuf;
@@ -1379,7 +1379,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1379 GFP_KERNEL); 1379 GFP_KERNEL);
1380 if (!msgbuf->ioctbuf) 1380 if (!msgbuf->ioctbuf)
1381 goto fail; 1381 goto fail;
1382 address = (long long)(long)msgbuf->ioctbuf_handle; 1382 address = (u64)msgbuf->ioctbuf_handle;
1383 msgbuf->ioctbuf_phys_hi = address >> 32; 1383 msgbuf->ioctbuf_phys_hi = address >> 32;
1384 msgbuf->ioctbuf_phys_lo = address & 0xffffffff; 1384 msgbuf->ioctbuf_phys_lo = address & 0xffffffff;
1385 1385
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 905991fdb7b1..e91fa9a2c885 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -959,14 +959,14 @@ brcmf_pcie_init_dmabuffer_for_device(struct brcmf_pciedev_info *devinfo,
959 dma_addr_t *dma_handle) 959 dma_addr_t *dma_handle)
960{ 960{
961 void *ring; 961 void *ring;
962 long long address; 962 u64 address;
963 963
964 ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle, 964 ring = dma_alloc_coherent(&devinfo->pdev->dev, size, dma_handle,
965 GFP_KERNEL); 965 GFP_KERNEL);
966 if (!ring) 966 if (!ring)
967 return NULL; 967 return NULL;
968 968
969 address = (long long)(long)*dma_handle; 969 address = (u64)*dma_handle;
970 brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr, 970 brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr,
971 address & 0xffffffff); 971 address & 0xffffffff);
972 brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr + 4, address >> 32); 972 brcmf_pcie_write_tcm32(devinfo, tcm_dma_phys_addr + 4, address >> 32);
@@ -1166,7 +1166,7 @@ brcmf_pcie_release_scratchbuffers(struct brcmf_pciedev_info *devinfo)
1166 1166
1167static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo) 1167static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
1168{ 1168{
1169 long long address; 1169 u64 address;
1170 u32 addr; 1170 u32 addr;
1171 1171
1172 devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev, 1172 devinfo->shared.scratch = dma_alloc_coherent(&devinfo->pdev->dev,
@@ -1180,7 +1180,7 @@ static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
1180 1180
1181 addr = devinfo->shared.tcm_base_address + 1181 addr = devinfo->shared.tcm_base_address +
1182 BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET; 1182 BRCMF_SHARED_DMA_SCRATCH_ADDR_OFFSET;
1183 address = (long long)(long)devinfo->shared.scratch_dmahandle; 1183 address = (u64)devinfo->shared.scratch_dmahandle;
1184 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1184 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1185 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1185 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1186 addr = devinfo->shared.tcm_base_address + 1186 addr = devinfo->shared.tcm_base_address +
@@ -1198,7 +1198,7 @@ static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
1198 1198
1199 addr = devinfo->shared.tcm_base_address + 1199 addr = devinfo->shared.tcm_base_address +
1200 BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET; 1200 BRCMF_SHARED_DMA_RINGUPD_ADDR_OFFSET;
1201 address = (long long)(long)devinfo->shared.ringupd_dmahandle; 1201 address = (u64)devinfo->shared.ringupd_dmahandle;
1202 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff); 1202 brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
1203 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32); 1203 brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
1204 addr = devinfo->shared.tcm_base_address + 1204 addr = devinfo->shared.tcm_base_address +
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index 0b0d51a61060..99a37765888d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -608,6 +608,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
608#define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt" 608#define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt"
609#define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin" 609#define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin"
610#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" 610#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
611#define BCM43340_FIRMWARE_NAME "brcm/brcmfmac43340-sdio.bin"
612#define BCM43340_NVRAM_NAME "brcm/brcmfmac43340-sdio.txt"
611#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" 613#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
612#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" 614#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
613#define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" 615#define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin"
@@ -629,6 +631,8 @@ MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME);
629MODULE_FIRMWARE(BCM4330_NVRAM_NAME); 631MODULE_FIRMWARE(BCM4330_NVRAM_NAME);
630MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); 632MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
631MODULE_FIRMWARE(BCM4334_NVRAM_NAME); 633MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
634MODULE_FIRMWARE(BCM43340_FIRMWARE_NAME);
635MODULE_FIRMWARE(BCM43340_NVRAM_NAME);
632MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); 636MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
633MODULE_FIRMWARE(BCM4335_NVRAM_NAME); 637MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
634MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); 638MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
@@ -660,6 +664,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
660 { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, 664 { BRCM_CC_4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
661 { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, 665 { BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
662 { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 666 { BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
667 { BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43340) },
663 { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, 668 { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
664 { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, 669 { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
665 { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, 670 { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
@@ -3811,7 +3816,7 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
3811 u32 val, rev; 3816 u32 val, rev;
3812 3817
3813 val = brcmf_sdiod_regrl(sdiodev, addr, NULL); 3818 val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
3814 if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID && 3819 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
3815 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { 3820 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
3816 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; 3821 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
3817 if (rev >= 2) { 3822 if (rev >= 2) {
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index 6996fcc144cf..2124a17d0bfd 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -22,7 +22,6 @@
22 22
23#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c 23#define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
24#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM 24#define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
25#define BRCM_SDIO_VENDOR_ID_BROADCOM SDIO_VENDOR_ID_BROADCOM
26 25
27/* Chipcommon Core Chip IDs */ 26/* Chipcommon Core Chip IDs */
28#define BRCM_CC_43143_CHIP_ID 43143 27#define BRCM_CC_43143_CHIP_ID 43143
@@ -34,6 +33,7 @@
34#define BRCM_CC_4329_CHIP_ID 0x4329 33#define BRCM_CC_4329_CHIP_ID 0x4329
35#define BRCM_CC_4330_CHIP_ID 0x4330 34#define BRCM_CC_4330_CHIP_ID 0x4330
36#define BRCM_CC_4334_CHIP_ID 0x4334 35#define BRCM_CC_4334_CHIP_ID 0x4334
36#define BRCM_CC_43340_CHIP_ID 43340
37#define BRCM_CC_43362_CHIP_ID 43362 37#define BRCM_CC_43362_CHIP_ID 43362
38#define BRCM_CC_4335_CHIP_ID 0x4335 38#define BRCM_CC_4335_CHIP_ID 0x4335
39#define BRCM_CC_4339_CHIP_ID 0x4339 39#define BRCM_CC_4339_CHIP_ID 0x4339
@@ -45,16 +45,6 @@
45#define BRCM_CC_43570_CHIP_ID 43570 45#define BRCM_CC_43570_CHIP_ID 43570
46#define BRCM_CC_43602_CHIP_ID 43602 46#define BRCM_CC_43602_CHIP_ID 43602
47 47
48/* SDIO Device IDs */
49#define BRCM_SDIO_43143_DEVICE_ID BRCM_CC_43143_CHIP_ID
50#define BRCM_SDIO_43241_DEVICE_ID BRCM_CC_43241_CHIP_ID
51#define BRCM_SDIO_4329_DEVICE_ID BRCM_CC_4329_CHIP_ID
52#define BRCM_SDIO_4330_DEVICE_ID BRCM_CC_4330_CHIP_ID
53#define BRCM_SDIO_4334_DEVICE_ID BRCM_CC_4334_CHIP_ID
54#define BRCM_SDIO_43362_DEVICE_ID BRCM_CC_43362_CHIP_ID
55#define BRCM_SDIO_4335_4339_DEVICE_ID BRCM_CC_4335_CHIP_ID
56#define BRCM_SDIO_4354_DEVICE_ID BRCM_CC_4354_CHIP_ID
57
58/* USB Device IDs */ 48/* USB Device IDs */
59#define BRCM_USB_43143_DEVICE_ID 0xbd1e 49#define BRCM_USB_43143_DEVICE_ID 0xbd1e
60#define BRCM_USB_43236_DEVICE_ID 0xbd17 50#define BRCM_USB_43236_DEVICE_ID 0xbd17
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index 0da6e423da63..3689dbbd10bd 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -373,9 +373,8 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
373 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work); 373 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
374 INIT_WORK(&priv->set_beacon_wakeup_period_work, 374 INIT_WORK(&priv->set_beacon_wakeup_period_work,
375 cw1200_set_beacon_wakeup_period_work); 375 cw1200_set_beacon_wakeup_period_work);
376 init_timer(&priv->mcast_timeout); 376 setup_timer(&priv->mcast_timeout, cw1200_mcast_timeout,
377 priv->mcast_timeout.data = (unsigned long)priv; 377 (unsigned long)priv);
378 priv->mcast_timeout.function = cw1200_mcast_timeout;
379 378
380 if (cw1200_queue_stats_init(&priv->tx_queue_stats, 379 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
381 CW1200_LINK_ID_MAX, 380 CW1200_LINK_ID_MAX,
diff --git a/drivers/net/wireless/cw1200/pm.c b/drivers/net/wireless/cw1200/pm.c
index 6907c8fd4578..d2202ae92bdd 100644
--- a/drivers/net/wireless/cw1200/pm.c
+++ b/drivers/net/wireless/cw1200/pm.c
@@ -101,9 +101,8 @@ int cw1200_pm_init(struct cw1200_pm_state *pm,
101{ 101{
102 spin_lock_init(&pm->lock); 102 spin_lock_init(&pm->lock);
103 103
104 init_timer(&pm->stay_awake); 104 setup_timer(&pm->stay_awake, cw1200_pm_stay_awake_tmo,
105 pm->stay_awake.data = (unsigned long)pm; 105 (unsigned long)pm);
106 pm->stay_awake.function = cw1200_pm_stay_awake_tmo;
107 106
108 return 0; 107 return 0;
109} 108}
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
index 9c3925f58d79..0ba5ef9b3e7b 100644
--- a/drivers/net/wireless/cw1200/queue.c
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -179,9 +179,7 @@ int cw1200_queue_init(struct cw1200_queue *queue,
179 INIT_LIST_HEAD(&queue->pending); 179 INIT_LIST_HEAD(&queue->pending);
180 INIT_LIST_HEAD(&queue->free_pool); 180 INIT_LIST_HEAD(&queue->free_pool);
181 spin_lock_init(&queue->lock); 181 spin_lock_init(&queue->lock);
182 init_timer(&queue->gc); 182 setup_timer(&queue->gc, cw1200_queue_gc, (unsigned long)queue);
183 queue->gc.data = (unsigned long)queue;
184 queue->gc.function = cw1200_queue_gc;
185 183
186 queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity, 184 queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
187 GFP_KERNEL); 185 GFP_KERNEL);
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index dc1d20cf64ee..e5665804d986 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3429,9 +3429,7 @@ il3945_setup_deferred_work(struct il_priv *il)
3429 3429
3430 il3945_hw_setup_deferred_work(il); 3430 il3945_hw_setup_deferred_work(il);
3431 3431
3432 init_timer(&il->watchdog); 3432 setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il);
3433 il->watchdog.data = (unsigned long)il;
3434 il->watchdog.function = il_bg_watchdog;
3435 3433
3436 tasklet_init(&il->irq_tasklet, 3434 tasklet_init(&il->irq_tasklet,
3437 (void (*)(unsigned long))il3945_irq_tasklet, 3435 (void (*)(unsigned long))il3945_irq_tasklet,
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 2748fde4b90c..976f65fe9c38 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -6247,13 +6247,10 @@ il4965_setup_deferred_work(struct il_priv *il)
6247 6247
6248 INIT_WORK(&il->txpower_work, il4965_bg_txpower_work); 6248 INIT_WORK(&il->txpower_work, il4965_bg_txpower_work);
6249 6249
6250 init_timer(&il->stats_periodic); 6250 setup_timer(&il->stats_periodic, il4965_bg_stats_periodic,
6251 il->stats_periodic.data = (unsigned long)il; 6251 (unsigned long)il);
6252 il->stats_periodic.function = il4965_bg_stats_periodic;
6253 6252
6254 init_timer(&il->watchdog); 6253 setup_timer(&il->watchdog, il_bg_watchdog, (unsigned long)il);
6255 il->watchdog.data = (unsigned long)il;
6256 il->watchdog.function = il_bg_watchdog;
6257 6254
6258 tasklet_init(&il->irq_tasklet, 6255 tasklet_init(&il->irq_tasklet,
6259 (void (*)(unsigned long))il4965_irq_tasklet, 6256 (void (*)(unsigned long))il4965_irq_tasklet,
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 0b7f46f0b079..de43dd7e170a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -64,22 +64,8 @@
64 * 64 *
65 ******************************************************************************/ 65 ******************************************************************************/
66 66
67/*
68 * module name, copyright, version, etc.
69 */
70#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux" 67#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
71
72#ifdef CONFIG_IWLWIFI_DEBUG
73#define VD "d"
74#else
75#define VD
76#endif
77
78#define DRV_VERSION IWLWIFI_VERSION VD
79
80
81MODULE_DESCRIPTION(DRV_DESCRIPTION); 68MODULE_DESCRIPTION(DRV_DESCRIPTION);
82MODULE_VERSION(DRV_VERSION);
83MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 69MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
84MODULE_LICENSE("GPL"); 70MODULE_LICENSE("GPL");
85 71
@@ -1011,13 +997,11 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
1011 if (priv->lib->bt_params) 997 if (priv->lib->bt_params)
1012 iwlagn_bt_setup_deferred_work(priv); 998 iwlagn_bt_setup_deferred_work(priv);
1013 999
1014 init_timer(&priv->statistics_periodic); 1000 setup_timer(&priv->statistics_periodic, iwl_bg_statistics_periodic,
1015 priv->statistics_periodic.data = (unsigned long)priv; 1001 (unsigned long)priv);
1016 priv->statistics_periodic.function = iwl_bg_statistics_periodic;
1017 1002
1018 init_timer(&priv->ucode_trace); 1003 setup_timer(&priv->ucode_trace, iwl_bg_ucode_trace,
1019 priv->ucode_trace.data = (unsigned long)priv; 1004 (unsigned long)priv);
1020 priv->ucode_trace.function = iwl_bg_ucode_trace;
1021} 1005}
1022 1006
1023void iwl_cancel_deferred_work(struct iwl_priv *priv) 1007void iwl_cancel_deferred_work(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/dvm/tt.c b/drivers/net/wireless/iwlwifi/dvm/tt.c
index acb981a0a0aa..c4736c8834c5 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tt.c
@@ -612,15 +612,10 @@ void iwl_tt_initialize(struct iwl_priv *priv)
612 memset(tt, 0, sizeof(struct iwl_tt_mgmt)); 612 memset(tt, 0, sizeof(struct iwl_tt_mgmt));
613 613
614 tt->state = IWL_TI_0; 614 tt->state = IWL_TI_0;
615 init_timer(&priv->thermal_throttle.ct_kill_exit_tm); 615 setup_timer(&priv->thermal_throttle.ct_kill_exit_tm,
616 priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; 616 iwl_tt_check_exit_ct_kill, (unsigned long)priv);
617 priv->thermal_throttle.ct_kill_exit_tm.function = 617 setup_timer(&priv->thermal_throttle.ct_kill_waiting_tm,
618 iwl_tt_check_exit_ct_kill; 618 iwl_tt_ready_for_ct_kill, (unsigned long)priv);
619 init_timer(&priv->thermal_throttle.ct_kill_waiting_tm);
620 priv->thermal_throttle.ct_kill_waiting_tm.data =
621 (unsigned long)priv;
622 priv->thermal_throttle.ct_kill_waiting_tm.function =
623 iwl_tt_ready_for_ct_kill;
624 /* setup deferred ct kill work */ 619 /* setup deferred ct kill work */
625 INIT_WORK(&priv->tt_work, iwl_bg_tt_work); 620 INIT_WORK(&priv->tt_work, iwl_bg_tt_work);
626 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); 621 INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index a5f9198d5747..97e38d2e2983 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -92,6 +92,12 @@
92#define IWL7265D_NVM_VERSION 0x0c11 92#define IWL7265D_NVM_VERSION 0x0c11
93#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */ 93#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */
94 94
95/* DCCM offsets and lengths */
96#define IWL7000_DCCM_OFFSET 0x800000
97#define IWL7260_DCCM_LEN 0x14000
98#define IWL3160_DCCM_LEN 0x10000
99#define IWL7265_DCCM_LEN 0x17A00
100
95#define IWL7260_FW_PRE "iwlwifi-7260-" 101#define IWL7260_FW_PRE "iwlwifi-7260-"
96#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" 102#define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode"
97 103
@@ -138,7 +144,8 @@ static const struct iwl_ht_params iwl7000_ht_params = {
138 .led_mode = IWL_LED_RF_STATE, \ 144 .led_mode = IWL_LED_RF_STATE, \
139 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \ 145 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
140 .non_shared_ant = ANT_A, \ 146 .non_shared_ant = ANT_A, \
141 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K 147 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, \
148 .dccm_offset = IWL7000_DCCM_OFFSET
142 149
143const struct iwl_cfg iwl7260_2ac_cfg = { 150const struct iwl_cfg iwl7260_2ac_cfg = {
144 .name = "Intel(R) Dual Band Wireless AC 7260", 151 .name = "Intel(R) Dual Band Wireless AC 7260",
@@ -149,6 +156,7 @@ const struct iwl_cfg iwl7260_2ac_cfg = {
149 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 156 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
150 .host_interrupt_operation_mode = true, 157 .host_interrupt_operation_mode = true,
151 .lp_xtal_workaround = true, 158 .lp_xtal_workaround = true,
159 .dccm_len = IWL7260_DCCM_LEN,
152}; 160};
153 161
154const struct iwl_cfg iwl7260_2ac_cfg_high_temp = { 162const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
@@ -161,6 +169,7 @@ const struct iwl_cfg iwl7260_2ac_cfg_high_temp = {
161 .high_temp = true, 169 .high_temp = true,
162 .host_interrupt_operation_mode = true, 170 .host_interrupt_operation_mode = true,
163 .lp_xtal_workaround = true, 171 .lp_xtal_workaround = true,
172 .dccm_len = IWL7260_DCCM_LEN,
164}; 173};
165 174
166const struct iwl_cfg iwl7260_2n_cfg = { 175const struct iwl_cfg iwl7260_2n_cfg = {
@@ -172,6 +181,7 @@ const struct iwl_cfg iwl7260_2n_cfg = {
172 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 181 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
173 .host_interrupt_operation_mode = true, 182 .host_interrupt_operation_mode = true,
174 .lp_xtal_workaround = true, 183 .lp_xtal_workaround = true,
184 .dccm_len = IWL7260_DCCM_LEN,
175}; 185};
176 186
177const struct iwl_cfg iwl7260_n_cfg = { 187const struct iwl_cfg iwl7260_n_cfg = {
@@ -183,6 +193,7 @@ const struct iwl_cfg iwl7260_n_cfg = {
183 .nvm_calib_ver = IWL7260_TX_POWER_VERSION, 193 .nvm_calib_ver = IWL7260_TX_POWER_VERSION,
184 .host_interrupt_operation_mode = true, 194 .host_interrupt_operation_mode = true,
185 .lp_xtal_workaround = true, 195 .lp_xtal_workaround = true,
196 .dccm_len = IWL7260_DCCM_LEN,
186}; 197};
187 198
188const struct iwl_cfg iwl3160_2ac_cfg = { 199const struct iwl_cfg iwl3160_2ac_cfg = {
@@ -193,6 +204,7 @@ const struct iwl_cfg iwl3160_2ac_cfg = {
193 .nvm_ver = IWL3160_NVM_VERSION, 204 .nvm_ver = IWL3160_NVM_VERSION,
194 .nvm_calib_ver = IWL3160_TX_POWER_VERSION, 205 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
195 .host_interrupt_operation_mode = true, 206 .host_interrupt_operation_mode = true,
207 .dccm_len = IWL3160_DCCM_LEN,
196}; 208};
197 209
198const struct iwl_cfg iwl3160_2n_cfg = { 210const struct iwl_cfg iwl3160_2n_cfg = {
@@ -203,6 +215,7 @@ const struct iwl_cfg iwl3160_2n_cfg = {
203 .nvm_ver = IWL3160_NVM_VERSION, 215 .nvm_ver = IWL3160_NVM_VERSION,
204 .nvm_calib_ver = IWL3160_TX_POWER_VERSION, 216 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
205 .host_interrupt_operation_mode = true, 217 .host_interrupt_operation_mode = true,
218 .dccm_len = IWL3160_DCCM_LEN,
206}; 219};
207 220
208const struct iwl_cfg iwl3160_n_cfg = { 221const struct iwl_cfg iwl3160_n_cfg = {
@@ -213,6 +226,7 @@ const struct iwl_cfg iwl3160_n_cfg = {
213 .nvm_ver = IWL3160_NVM_VERSION, 226 .nvm_ver = IWL3160_NVM_VERSION,
214 .nvm_calib_ver = IWL3160_TX_POWER_VERSION, 227 .nvm_calib_ver = IWL3160_TX_POWER_VERSION,
215 .host_interrupt_operation_mode = true, 228 .host_interrupt_operation_mode = true,
229 .dccm_len = IWL3160_DCCM_LEN,
216}; 230};
217 231
218static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = { 232static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = {
@@ -240,6 +254,7 @@ const struct iwl_cfg iwl3165_2ac_cfg = {
240 .nvm_ver = IWL3165_NVM_VERSION, 254 .nvm_ver = IWL3165_NVM_VERSION,
241 .nvm_calib_ver = IWL3165_TX_POWER_VERSION, 255 .nvm_calib_ver = IWL3165_TX_POWER_VERSION,
242 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 256 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
257 .dccm_len = IWL7265_DCCM_LEN,
243}; 258};
244 259
245const struct iwl_cfg iwl7265_2ac_cfg = { 260const struct iwl_cfg iwl7265_2ac_cfg = {
@@ -250,6 +265,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
250 .nvm_ver = IWL7265_NVM_VERSION, 265 .nvm_ver = IWL7265_NVM_VERSION,
251 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 266 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
252 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 267 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
268 .dccm_len = IWL7265_DCCM_LEN,
253}; 269};
254 270
255const struct iwl_cfg iwl7265_2n_cfg = { 271const struct iwl_cfg iwl7265_2n_cfg = {
@@ -260,6 +276,7 @@ const struct iwl_cfg iwl7265_2n_cfg = {
260 .nvm_ver = IWL7265_NVM_VERSION, 276 .nvm_ver = IWL7265_NVM_VERSION,
261 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 277 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
262 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 278 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
279 .dccm_len = IWL7265_DCCM_LEN,
263}; 280};
264 281
265const struct iwl_cfg iwl7265_n_cfg = { 282const struct iwl_cfg iwl7265_n_cfg = {
@@ -270,6 +287,7 @@ const struct iwl_cfg iwl7265_n_cfg = {
270 .nvm_ver = IWL7265_NVM_VERSION, 287 .nvm_ver = IWL7265_NVM_VERSION,
271 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 288 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
272 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 289 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
290 .dccm_len = IWL7265_DCCM_LEN,
273}; 291};
274 292
275const struct iwl_cfg iwl7265d_2ac_cfg = { 293const struct iwl_cfg iwl7265d_2ac_cfg = {
@@ -280,6 +298,7 @@ const struct iwl_cfg iwl7265d_2ac_cfg = {
280 .nvm_ver = IWL7265D_NVM_VERSION, 298 .nvm_ver = IWL7265D_NVM_VERSION,
281 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 299 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
282 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 300 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
301 .dccm_len = IWL7265_DCCM_LEN,
283}; 302};
284 303
285const struct iwl_cfg iwl7265d_2n_cfg = { 304const struct iwl_cfg iwl7265d_2n_cfg = {
@@ -290,6 +309,7 @@ const struct iwl_cfg iwl7265d_2n_cfg = {
290 .nvm_ver = IWL7265D_NVM_VERSION, 309 .nvm_ver = IWL7265D_NVM_VERSION,
291 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 310 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
292 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 311 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
312 .dccm_len = IWL7265_DCCM_LEN,
293}; 313};
294 314
295const struct iwl_cfg iwl7265d_n_cfg = { 315const struct iwl_cfg iwl7265d_n_cfg = {
@@ -300,6 +320,7 @@ const struct iwl_cfg iwl7265d_n_cfg = {
300 .nvm_ver = IWL7265D_NVM_VERSION, 320 .nvm_ver = IWL7265D_NVM_VERSION,
301 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 321 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
302 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 322 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
323 .dccm_len = IWL7265_DCCM_LEN,
303}; 324};
304 325
305MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); 326MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 3668fc57e770..2f7fe8167dc9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -81,12 +81,21 @@
81#define IWL8000_NVM_VERSION 0x0a1d 81#define IWL8000_NVM_VERSION 0x0a1d
82#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */ 82#define IWL8000_TX_POWER_VERSION 0xffff /* meaningless */
83 83
84/* Memory offsets and lengths */
85#define IWL8260_DCCM_OFFSET 0x800000
86#define IWL8260_DCCM_LEN 0x18000
87#define IWL8260_DCCM2_OFFSET 0x880000
88#define IWL8260_DCCM2_LEN 0x8000
89#define IWL8260_SMEM_OFFSET 0x400000
90#define IWL8260_SMEM_LEN 0x68000
91
84#define IWL8000_FW_PRE "iwlwifi-8000" 92#define IWL8000_FW_PRE "iwlwifi-8000"
85#define IWL8000_MODULE_FIRMWARE(api) \ 93#define IWL8000_MODULE_FIRMWARE(api) \
86 IWL8000_FW_PRE "-" __stringify(api) ".ucode" 94 IWL8000_FW_PRE "-" __stringify(api) ".ucode"
87 95
88#define NVM_HW_SECTION_NUM_FAMILY_8000 10 96#define NVM_HW_SECTION_NUM_FAMILY_8000 10
89#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000.bin" 97#define DEFAULT_NVM_FILE_FAMILY_8000A "iwl_nvm_8000.bin"
98#define DEFAULT_NVM_FILE_FAMILY_8000 "iwl_nvm_8000B.bin"
90 99
91/* Max SDIO RX aggregation size of the ADDBA request/response */ 100/* Max SDIO RX aggregation size of the ADDBA request/response */
92#define MAX_RX_AGG_SIZE_8260_SDIO 28 101#define MAX_RX_AGG_SIZE_8260_SDIO 28
@@ -124,7 +133,13 @@ static const struct iwl_ht_params iwl8000_ht_params = {
124 .led_mode = IWL_LED_RF_STATE, \ 133 .led_mode = IWL_LED_RF_STATE, \
125 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \ 134 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
126 .d0i3 = true, \ 135 .d0i3 = true, \
127 .non_shared_ant = ANT_A 136 .non_shared_ant = ANT_A, \
137 .dccm_offset = IWL8260_DCCM_OFFSET, \
138 .dccm_len = IWL8260_DCCM_LEN, \
139 .dccm2_offset = IWL8260_DCCM2_OFFSET, \
140 .dccm2_len = IWL8260_DCCM2_LEN, \
141 .smem_offset = IWL8260_SMEM_OFFSET, \
142 .smem_len = IWL8260_SMEM_LEN
128 143
129const struct iwl_cfg iwl8260_2n_cfg = { 144const struct iwl_cfg iwl8260_2n_cfg = {
130 .name = "Intel(R) Dual Band Wireless N 8260", 145 .name = "Intel(R) Dual Band Wireless N 8260",
@@ -145,6 +160,16 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
145 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K, 160 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
146}; 161};
147 162
163const struct iwl_cfg iwl4165_2ac_cfg = {
164 .name = "Intel(R) Dual Band Wireless AC 4165",
165 .fw_name_pre = IWL8000_FW_PRE,
166 IWL_DEVICE_8000,
167 .ht_params = &iwl8000_ht_params,
168 .nvm_ver = IWL8000_NVM_VERSION,
169 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
170 .max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
171};
172
148const struct iwl_cfg iwl8260_2ac_sdio_cfg = { 173const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
149 .name = "Intel(R) Dual Band Wireless-AC 8260", 174 .name = "Intel(R) Dual Band Wireless-AC 8260",
150 .fw_name_pre = IWL8000_FW_PRE, 175 .fw_name_pre = IWL8000_FW_PRE,
@@ -153,6 +178,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
153 .nvm_ver = IWL8000_NVM_VERSION, 178 .nvm_ver = IWL8000_NVM_VERSION,
154 .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 179 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
155 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, 180 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
181 .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A,
156 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, 182 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
157 .disable_dummy_notification = true, 183 .disable_dummy_notification = true,
158 .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO, 184 .max_ht_ampdu_exponent = MAX_HT_AMPDU_EXPONENT_8260_SDIO,
@@ -167,6 +193,7 @@ const struct iwl_cfg iwl4165_2ac_sdio_cfg = {
167 .nvm_ver = IWL8000_NVM_VERSION, 193 .nvm_ver = IWL8000_NVM_VERSION,
168 .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 194 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
169 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, 195 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
196 .default_nvm_file_8000A = DEFAULT_NVM_FILE_FAMILY_8000A,
170 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, 197 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
171 .bt_shared_single_ant = true, 198 .bt_shared_single_ant = true,
172 .disable_dummy_notification = true, 199 .disable_dummy_notification = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 3a4b9c7fc083..445bff690a63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -261,6 +261,12 @@ struct iwl_pwr_tx_backoff {
261 * station can receive in HT 261 * station can receive in HT
262 * @max_vht_ampdu_exponent: the exponent of the max length of A-MPDU that the 262 * @max_vht_ampdu_exponent: the exponent of the max length of A-MPDU that the
263 * station can receive in VHT 263 * station can receive in VHT
264 * @dccm_offset: offset from which DCCM begins
265 * @dccm_len: length of DCCM (including runtime stack CCM)
266 * @dccm2_offset: offset from which the second DCCM begins
267 * @dccm2_len: length of the second DCCM
268 * @smem_offset: offset from which the SMEM begins
269 * @smem_len: the length of SMEM
264 * 270 *
265 * We enable the driver to be backward compatible wrt. hardware features. 271 * We enable the driver to be backward compatible wrt. hardware features.
266 * API differences in uCode shouldn't be handled here but through TLVs 272 * API differences in uCode shouldn't be handled here but through TLVs
@@ -298,11 +304,18 @@ struct iwl_cfg {
298 const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; 304 const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
299 bool no_power_up_nic_in_init; 305 bool no_power_up_nic_in_init;
300 const char *default_nvm_file; 306 const char *default_nvm_file;
307 const char *default_nvm_file_8000A;
301 unsigned int max_rx_agg_size; 308 unsigned int max_rx_agg_size;
302 bool disable_dummy_notification; 309 bool disable_dummy_notification;
303 unsigned int max_tx_agg_size; 310 unsigned int max_tx_agg_size;
304 unsigned int max_ht_ampdu_exponent; 311 unsigned int max_ht_ampdu_exponent;
305 unsigned int max_vht_ampdu_exponent; 312 unsigned int max_vht_ampdu_exponent;
313 const u32 dccm_offset;
314 const u32 dccm_len;
315 const u32 dccm2_offset;
316 const u32 dccm2_len;
317 const u32 smem_offset;
318 const u32 smem_len;
306}; 319};
307 320
308/* 321/*
@@ -369,8 +382,8 @@ extern const struct iwl_cfg iwl7265d_2n_cfg;
369extern const struct iwl_cfg iwl7265d_n_cfg; 382extern const struct iwl_cfg iwl7265d_n_cfg;
370extern const struct iwl_cfg iwl8260_2n_cfg; 383extern const struct iwl_cfg iwl8260_2n_cfg;
371extern const struct iwl_cfg iwl8260_2ac_cfg; 384extern const struct iwl_cfg iwl8260_2ac_cfg;
385extern const struct iwl_cfg iwl4165_2ac_cfg;
372extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; 386extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
373extern const struct iwl_cfg iwl4265_2ac_sdio_cfg;
374extern const struct iwl_cfg iwl4165_2ac_sdio_cfg; 387extern const struct iwl_cfg iwl4165_2ac_sdio_cfg;
375#endif /* CONFIG_IWLMVM */ 388#endif /* CONFIG_IWLMVM */
376 389
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index aff63c3f5bf8..faa17f2e352a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -184,6 +184,7 @@
184#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */ 184#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY (0x00400000) /* PCI_OWN_SEM */
185#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */ 185#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE (0x02000000) /* ME_OWN */
186#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */ 186#define CSR_HW_IF_CONFIG_REG_PREPARE (0x08000000) /* WAKE_ME */
187#define CSR_HW_IF_CONFIG_REG_ENABLE_PME (0x10000000)
187#define CSR_HW_IF_CONFIG_REG_PERSIST_MODE (0x40000000) /* PERSISTENCE */ 188#define CSR_HW_IF_CONFIG_REG_PERSIST_MODE (0x40000000) /* PERSISTENCE */
188 189
189#define CSR_MBOX_SET_REG_OS_ALIVE BIT(5) 190#define CSR_MBOX_SET_REG_OS_ALIVE BIT(5)
@@ -306,6 +307,7 @@
306enum { 307enum {
307 SILICON_A_STEP = 0, 308 SILICON_A_STEP = 0,
308 SILICON_B_STEP, 309 SILICON_B_STEP,
310 SILICON_C_STEP,
309}; 311};
310 312
311 313
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 850b85a47806..e7c0df6db6ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -84,21 +84,8 @@
84 * 84 *
85 ******************************************************************************/ 85 ******************************************************************************/
86 86
87/*
88 * module name, copyright, version, etc.
89 */
90#define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux" 87#define DRV_DESCRIPTION "Intel(R) Wireless WiFi driver for Linux"
91
92#ifdef CONFIG_IWLWIFI_DEBUG
93#define VD "d"
94#else
95#define VD
96#endif
97
98#define DRV_VERSION IWLWIFI_VERSION VD
99
100MODULE_DESCRIPTION(DRV_DESCRIPTION); 88MODULE_DESCRIPTION(DRV_DESCRIPTION);
101MODULE_VERSION(DRV_VERSION);
102MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 89MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
103MODULE_LICENSE("GPL"); 90MODULE_LICENSE("GPL");
104 91
@@ -250,9 +237,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
250 /* 237 /*
251 * Starting 8000B - FW name format has changed. This overwrites the 238 * Starting 8000B - FW name format has changed. This overwrites the
252 * previous name and uses the new format. 239 * previous name and uses the new format.
253 *
254 * TODO:
255 * Once there is only one supported step for 8000 family - delete this!
256 */ 240 */
257 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) { 241 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
258 char rev_step[2] = { 242 char rev_step[2] = {
@@ -263,13 +247,6 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
263 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP) 247 if (CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP)
264 rev_step[0] = 0; 248 rev_step[0] = 0;
265 249
266 /*
267 * If hw_rev wasn't set yet - default as B-step. If it IS A-step
268 * we'll reload that FW later instead.
269 */
270 if (drv->trans->hw_rev == 0)
271 rev_step[0] = 'B';
272
273 snprintf(drv->firmware_name, sizeof(drv->firmware_name), 250 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
274 "%s%s-%s.ucode", name_pre, rev_step, tag); 251 "%s%s-%s.ucode", name_pre, rev_step, tag);
275 } 252 }
@@ -926,6 +903,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
926 IWL_UCODE_REGULAR_USNIFFER, 903 IWL_UCODE_REGULAR_USNIFFER,
927 tlv_len); 904 tlv_len);
928 break; 905 break;
906 case IWL_UCODE_TLV_SDIO_ADMA_ADDR:
907 if (tlv_len != sizeof(u32))
908 goto invalid_tlv_len;
909 drv->fw.sdio_adma_addr =
910 le32_to_cpup((__le32 *)tlv_data);
911 break;
929 default: 912 default:
930 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); 913 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
931 break; 914 break;
@@ -1082,7 +1065,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1082 u32 api_ver; 1065 u32 api_ver;
1083 int i; 1066 int i;
1084 bool load_module = false; 1067 bool load_module = false;
1085 u32 hw_rev = drv->trans->hw_rev;
1086 1068
1087 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; 1069 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
1088 fw->ucode_capa.standard_phy_calibration_size = 1070 fw->ucode_capa.standard_phy_calibration_size =
@@ -1275,50 +1257,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
1275 op->name, err); 1257 op->name, err);
1276#endif 1258#endif
1277 } 1259 }
1278
1279 /*
1280 * We may have loaded the wrong FW file in 8000 HW family if it is an
1281 * A-step card, and if drv->trans->hw_rev wasn't properly read when
1282 * the FW file had been loaded. (This might happen in SDIO.) In such a
1283 * case - unload and reload the correct file.
1284 *
1285 * TODO:
1286 * Once there is only one supported step for 8000 family - delete this!
1287 */
1288 if (drv->trans->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
1289 CSR_HW_REV_STEP(drv->trans->hw_rev) == SILICON_A_STEP &&
1290 drv->trans->hw_rev != hw_rev) {
1291 char firmware_name[32];
1292
1293 /* Free previous FW resources */
1294 if (drv->op_mode)
1295 _iwl_op_mode_stop(drv);
1296 iwl_dealloc_ucode(drv);
1297
1298 /* Build name of correct-step FW */
1299 snprintf(firmware_name, sizeof(firmware_name),
1300 strrchr(drv->firmware_name, '-'));
1301 snprintf(drv->firmware_name, sizeof(drv->firmware_name),
1302 "%s%s", drv->cfg->fw_name_pre, firmware_name);
1303
1304 /* Clear data before loading correct FW */
1305 list_del(&drv->list);
1306
1307 /* Request correct FW file this time */
1308 IWL_DEBUG_INFO(drv, "attempting to load A-step FW %s\n",
1309 drv->firmware_name);
1310 err = request_firmware(&ucode_raw, drv->firmware_name,
1311 drv->trans->dev);
1312 if (err) {
1313 IWL_ERR(drv, "Failed swapping FW!\n");
1314 goto out_unbind;
1315 }
1316
1317 /* Redo callback function - this time with right FW */
1318 iwl_req_fw_callback(ucode_raw, context);
1319 }
1320
1321 kfree(pieces);
1322 return; 1260 return;
1323 1261
1324 try_again: 1262 try_again:
@@ -1430,6 +1368,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
1430 .bt_coex_active = true, 1368 .bt_coex_active = true,
1431 .power_level = IWL_POWER_INDEX_1, 1369 .power_level = IWL_POWER_INDEX_1,
1432 .wd_disable = true, 1370 .wd_disable = true,
1371 .d0i3_disable = true,
1433#ifndef CONFIG_IWLWIFI_UAPSD 1372#ifndef CONFIG_IWLWIFI_UAPSD
1434 .uapsd_disable = true, 1373 .uapsd_disable = true,
1435#endif /* CONFIG_IWLWIFI_UAPSD */ 1374#endif /* CONFIG_IWLWIFI_UAPSD */
@@ -1492,7 +1431,7 @@ static int __init iwl_drv_init(void)
1492 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) 1431 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++)
1493 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); 1432 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv);
1494 1433
1495 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); 1434 pr_info(DRV_DESCRIPTION "\n");
1496 pr_info(DRV_COPYRIGHT "\n"); 1435 pr_info(DRV_COPYRIGHT "\n");
1497 1436
1498#ifdef CONFIG_IWLWIFI_DEBUGFS 1437#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -1546,8 +1485,12 @@ MODULE_PARM_DESC(wd_disable,
1546module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); 1485module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1547MODULE_PARM_DESC(nvm_file, "NVM file name"); 1486MODULE_PARM_DESC(nvm_file, "NVM file name");
1548 1487
1549module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1488module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable,
1550 bool, S_IRUGO); 1489 bool, S_IRUGO);
1490MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
1491
1492module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
1493 bool, S_IRUGO | S_IWUSR);
1551#ifdef CONFIG_IWLWIFI_UAPSD 1494#ifdef CONFIG_IWLWIFI_UAPSD
1552MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); 1495MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)");
1553#else 1496#else
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index be4f8972241a..adf522c756e6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -68,7 +68,6 @@
68 68
69/* for all modules */ 69/* for all modules */
70#define DRV_NAME "iwlwifi" 70#define DRV_NAME "iwlwifi"
71#define IWLWIFI_VERSION "in-tree:"
72#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation" 71#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation"
73#define DRV_AUTHOR "<ilw@linux.intel.com>" 72#define DRV_AUTHOR "<ilw@linux.intel.com>"
74 73
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 20a8a64c9fe3..919a2548a92c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -71,7 +71,6 @@
71 71
72/** 72/**
73 * enum iwl_fw_error_dump_type - types of data in the dump file 73 * enum iwl_fw_error_dump_type - types of data in the dump file
74 * @IWL_FW_ERROR_DUMP_SRAM:
75 * @IWL_FW_ERROR_DUMP_CSR: Control Status Registers - from offset 0 74 * @IWL_FW_ERROR_DUMP_CSR: Control Status Registers - from offset 0
76 * @IWL_FW_ERROR_DUMP_RXF: 75 * @IWL_FW_ERROR_DUMP_RXF:
77 * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as 76 * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
@@ -82,9 +81,10 @@
82 * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several 81 * @IWL_FW_ERROR_DUMP_PRPH: range of periphery registers - there can be several
83 * sections like this in a single file. 82 * sections like this in a single file.
84 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers 83 * @IWL_FW_ERROR_DUMP_FH_REGS: range of FH registers
84 * @IWL_FW_ERROR_DUMP_MEM: chunk of memory
85 */ 85 */
86enum iwl_fw_error_dump_type { 86enum iwl_fw_error_dump_type {
87 IWL_FW_ERROR_DUMP_SRAM = 0, 87 /* 0 is deprecated */
88 IWL_FW_ERROR_DUMP_CSR = 1, 88 IWL_FW_ERROR_DUMP_CSR = 1,
89 IWL_FW_ERROR_DUMP_RXF = 2, 89 IWL_FW_ERROR_DUMP_RXF = 2,
90 IWL_FW_ERROR_DUMP_TXCMD = 3, 90 IWL_FW_ERROR_DUMP_TXCMD = 3,
@@ -93,6 +93,7 @@ enum iwl_fw_error_dump_type {
93 IWL_FW_ERROR_DUMP_PRPH = 6, 93 IWL_FW_ERROR_DUMP_PRPH = 6,
94 IWL_FW_ERROR_DUMP_TXF = 7, 94 IWL_FW_ERROR_DUMP_TXF = 7,
95 IWL_FW_ERROR_DUMP_FH_REGS = 8, 95 IWL_FW_ERROR_DUMP_FH_REGS = 8,
96 IWL_FW_ERROR_DUMP_MEM = 9,
96 97
97 IWL_FW_ERROR_DUMP_MAX, 98 IWL_FW_ERROR_DUMP_MAX,
98}; 99};
@@ -133,6 +134,27 @@ struct iwl_fw_error_dump_txcmd {
133 u8 data[]; 134 u8 data[];
134} __packed; 135} __packed;
135 136
137/**
138 * struct iwl_fw_error_dump_fifo - RX/TX FIFO data
139 * @fifo_num: number of FIFO (starting from 0)
140 * @available_bytes: num of bytes available in FIFO (may be less than FIFO size)
141 * @wr_ptr: position of write pointer
142 * @rd_ptr: position of read pointer
143 * @fence_ptr: position of fence pointer
144 * @fence_mode: the current mode of the fence (before locking) -
145 * 0=follow RD pointer ; 1 = freeze
146 * @data: all of the FIFO's data
147 */
148struct iwl_fw_error_dump_fifo {
149 __le32 fifo_num;
150 __le32 available_bytes;
151 __le32 wr_ptr;
152 __le32 rd_ptr;
153 __le32 fence_ptr;
154 __le32 fence_mode;
155 u8 data[];
156} __packed;
157
136enum iwl_fw_error_dump_family { 158enum iwl_fw_error_dump_family {
137 IWL_FW_ERROR_DUMP_FAMILY_7 = 7, 159 IWL_FW_ERROR_DUMP_FAMILY_7 = 7,
138 IWL_FW_ERROR_DUMP_FAMILY_8 = 8, 160 IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
@@ -180,6 +202,23 @@ struct iwl_fw_error_dump_prph {
180 __le32 data[]; 202 __le32 data[];
181}; 203};
182 204
205enum iwl_fw_error_dump_mem_type {
206 IWL_FW_ERROR_DUMP_MEM_SRAM,
207 IWL_FW_ERROR_DUMP_MEM_SMEM,
208};
209
210/**
211 * struct iwl_fw_error_dump_mem - chunk of memory
212 * @type: %enum iwl_fw_error_dump_mem_type
213 * @offset: the offset from which the memory was read
214 * @data: the content of the memory
215 */
216struct iwl_fw_error_dump_mem {
217 __le32 type;
218 __le32 offset;
219 u8 data[];
220};
221
183/** 222/**
184 * iwl_fw_error_next_data - advance fw error dump data pointer 223 * iwl_fw_error_next_data - advance fw error dump data pointer
185 * @data: previous data block 224 * @data: previous data block
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 1bbe4fc47b97..e4f589898eda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -132,6 +132,7 @@ enum iwl_ucode_tlv_type {
132 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30, 132 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 133 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, 134 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
135 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35,
135 IWL_UCODE_TLV_FW_DBG_DEST = 38, 136 IWL_UCODE_TLV_FW_DBG_DEST = 38,
136 IWL_UCODE_TLV_FW_DBG_CONF = 39, 137 IWL_UCODE_TLV_FW_DBG_CONF = 39,
137}; 138};
@@ -234,29 +235,34 @@ enum iwl_ucode_tlv_flag {
234 235
235/** 236/**
236 * enum iwl_ucode_tlv_api - ucode api 237 * enum iwl_ucode_tlv_api - ucode api
237 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
238 * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
239 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 238 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
240 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
241 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 239 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
242 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. 240 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
243 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. 241 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
244 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 242 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
245 * longer than the passive one, which is essential for fragmented scan. 243 * longer than the passive one, which is essential for fragmented scan.
244 * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
246 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, 245 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
247 * regardless of the band or the number of the probes. FW will calculate 246 * regardless of the band or the number of the probes. FW will calculate
248 * the actual dwell time. 247 * the actual dwell time.
248 * @IWL_UCODE_TLV_API_SCD_CFG: This firmware can configure the scheduler
249 * through the dedicated host command.
250 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too.
251 * @IWL_UCODE_TLV_API_ASYNC_DTM: Async temperature notifications are supported.
252 * @IWL_UCODE_TLV_API_LQ_SS_PARAMS: Configure STBC/BFER via LQ CMD ss_params
249 */ 253 */
250enum iwl_ucode_tlv_api { 254enum iwl_ucode_tlv_api {
251 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
252 IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
253 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
254 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
255 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
256 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), 257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
257 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
258 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 259 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
260 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
259 IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), 261 IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13),
262 IWL_UCODE_TLV_API_SCD_CFG = BIT(15),
263 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16),
264 IWL_UCODE_TLV_API_ASYNC_DTM = BIT(17),
265 IWL_UCODE_TLV_API_LQ_SS_PARAMS = BIT(18),
260}; 266};
261 267
262/** 268/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index e6dc3b870949..ffd785cc67d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -152,6 +152,8 @@ struct iwl_fw_cscheme_list {
152 * @mvm_fw: indicates this is MVM firmware 152 * @mvm_fw: indicates this is MVM firmware
153 * @cipher_scheme: optional external cipher scheme. 153 * @cipher_scheme: optional external cipher scheme.
154 * @human_readable: human readable version 154 * @human_readable: human readable version
155 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
156 * we get the ALIVE from the uCode
155 * @dbg_dest_tlv: points to the destination TLV for debug 157 * @dbg_dest_tlv: points to the destination TLV for debug
156 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 158 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
157 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries 159 * @dbg_conf_tlv_len: lengths of the @dbg_conf_tlv entries
@@ -181,6 +183,8 @@ struct iwl_fw {
181 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 183 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
182 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 184 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
183 185
186 u32 sdio_adma_addr;
187
184 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 188 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
185 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 189 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
186 size_t dbg_conf_tlv_len[FW_DBG_MAX]; 190 size_t dbg_conf_tlv_len[FW_DBG_MAX];
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 7a2cbf6f90db..03250a45272e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -193,11 +193,15 @@ void iwl_force_nmi(struct iwl_trans *trans)
193 * DEVICE_SET_NMI_8000B_REG - is used. 193 * DEVICE_SET_NMI_8000B_REG - is used.
194 */ 194 */
195 if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || 195 if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) ||
196 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) 196 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) {
197 iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL); 197 iwl_write_prph(trans, DEVICE_SET_NMI_REG,
198 else 198 DEVICE_SET_NMI_VAL_DRV);
199 iwl_write_prph(trans, DEVICE_SET_NMI_REG,
200 DEVICE_SET_NMI_VAL_HW);
201 } else {
199 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, 202 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG,
200 DEVICE_SET_NMI_8000B_VAL); 203 DEVICE_SET_NMI_8000B_VAL);
204 }
201} 205}
202IWL_EXPORT_SYMBOL(iwl_force_nmi); 206IWL_EXPORT_SYMBOL(iwl_force_nmi);
203 207
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index 71507cf490e6..2a8cf4b2445c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
103 * @power_level: power level, default = 1 103 * @power_level: power level, default = 1
104 * @debug_level: levels are IWL_DL_* 104 * @debug_level: levels are IWL_DL_*
105 * @ant_coupling: antenna coupling in dB, default = 0 105 * @ant_coupling: antenna coupling in dB, default = 0
106 * @d0i3_disable: disable d0i3, default = 1,
106 * @fw_monitor: allow to use firmware monitor 107 * @fw_monitor: allow to use firmware monitor
107 */ 108 */
108struct iwl_mod_params { 109struct iwl_mod_params {
@@ -121,6 +122,7 @@ struct iwl_mod_params {
121 int ant_coupling; 122 int ant_coupling;
122 char *nvm_file; 123 char *nvm_file;
123 bool uapsd_disable; 124 bool uapsd_disable;
125 bool d0i3_disable;
124 bool fw_monitor; 126 bool fw_monitor;
125}; 127};
126 128
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 06e02fcd6f7b..c74f1a4edf23 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -468,6 +468,8 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
468 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg); 468 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
469 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg); 469 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
470 data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg); 470 data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
471 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(radio_cfg);
472 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
471} 473}
472 474
473static void iwl_set_hw_address(const struct iwl_cfg *cfg, 475static void iwl_set_hw_address(const struct iwl_cfg *cfg,
@@ -592,6 +594,10 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
592 594
593 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw); 595 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
594 iwl_set_radio_cfg(cfg, data, radio_cfg); 596 iwl_set_radio_cfg(cfg, data, radio_cfg);
597 if (data->valid_tx_ant)
598 tx_chains &= data->valid_tx_ant;
599 if (data->valid_rx_ant)
600 rx_chains &= data->valid_rx_ant;
595 601
596 sku = iwl_get_sku(cfg, nvm_sw); 602 sku = iwl_get_sku(cfg, nvm_sw);
597 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; 603 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 2df51eab1348..b21fcf042b77 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -99,6 +99,7 @@
99 99
100#define APMG_PCIDEV_STT_VAL_PERSIST_DIS (0x00000200) 100#define APMG_PCIDEV_STT_VAL_PERSIST_DIS (0x00000200)
101#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) 101#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
102#define APMG_PCIDEV_STT_VAL_WAKE_ME (0x00004000)
102 103
103#define APMG_RTC_INT_STT_RFKILL (0x10000000) 104#define APMG_RTC_INT_STT_RFKILL (0x10000000)
104 105
@@ -107,7 +108,8 @@
107 108
108/* Device NMI register */ 109/* Device NMI register */
109#define DEVICE_SET_NMI_REG 0x00a01c30 110#define DEVICE_SET_NMI_REG 0x00a01c30
110#define DEVICE_SET_NMI_VAL 0x1 111#define DEVICE_SET_NMI_VAL_HW BIT(0)
112#define DEVICE_SET_NMI_VAL_DRV BIT(7)
111#define DEVICE_SET_NMI_8000B_REG 0x00a01c24 113#define DEVICE_SET_NMI_8000B_REG 0x00a01c24
112#define DEVICE_SET_NMI_8000B_VAL 0x1000000 114#define DEVICE_SET_NMI_8000B_VAL 0x1000000
113 115
@@ -358,18 +360,40 @@ enum secure_load_status_reg {
358 360
359/* Rx FIFO */ 361/* Rx FIFO */
360#define RXF_SIZE_ADDR (0xa00c88) 362#define RXF_SIZE_ADDR (0xa00c88)
363#define RXF_RD_D_SPACE (0xa00c40)
364#define RXF_RD_WR_PTR (0xa00c50)
365#define RXF_RD_RD_PTR (0xa00c54)
366#define RXF_RD_FENCE_PTR (0xa00c4c)
367#define RXF_SET_FENCE_MODE (0xa00c14)
368#define RXF_LD_WR2FENCE (0xa00c1c)
369#define RXF_FIFO_RD_FENCE_INC (0xa00c68)
361#define RXF_SIZE_BYTE_CND_POS (7) 370#define RXF_SIZE_BYTE_CND_POS (7)
362#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS) 371#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS)
372#define RXF_DIFF_FROM_PREV (0x200)
363 373
364#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10) 374#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
365#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c) 375#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
366 376
377/* Tx FIFO */
378#define TXF_FIFO_ITEM_CNT (0xa00438)
379#define TXF_WR_PTR (0xa00414)
380#define TXF_RD_PTR (0xa00410)
381#define TXF_FENCE_PTR (0xa00418)
382#define TXF_LOCK_FENCE (0xa00424)
383#define TXF_LARC_NUM (0xa0043c)
384#define TXF_READ_MODIFY_DATA (0xa00448)
385#define TXF_READ_MODIFY_ADDR (0xa0044c)
386
367/* FW monitor */ 387/* FW monitor */
388#define MON_BUFF_SAMPLE_CTL (0xa03c00)
368#define MON_BUFF_BASE_ADDR (0xa03c3c) 389#define MON_BUFF_BASE_ADDR (0xa03c3c)
369#define MON_BUFF_END_ADDR (0xa03c40) 390#define MON_BUFF_END_ADDR (0xa03c40)
370#define MON_BUFF_WRPTR (0xa03c44) 391#define MON_BUFF_WRPTR (0xa03c44)
371#define MON_BUFF_CYCLE_CNT (0xa03c48) 392#define MON_BUFF_CYCLE_CNT (0xa03c48)
372 393
394#define DBGC_IN_SAMPLE (0xa03c00)
395#define DBGC_OUT_CTRL (0xa03c0c)
396
373/* FW chicken bits */ 397/* FW chicken bits */
374#define LMPM_CHICK 0xA01FF8 398#define LMPM_CHICK 0xA01FF8
375enum { 399enum {
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 028408a6ecba..84d8477432a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -382,6 +382,8 @@ enum iwl_trans_status {
382 * are considered stuck and will trigger device restart 382 * are considered stuck and will trigger device restart
383 * @command_names: array of command names, must be 256 entries 383 * @command_names: array of command names, must be 256 entries
384 * (one for each command); for debugging only 384 * (one for each command); for debugging only
385 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
386 * we get the ALIVE from the uCode
385 */ 387 */
386struct iwl_trans_config { 388struct iwl_trans_config {
387 struct iwl_op_mode *op_mode; 389 struct iwl_op_mode *op_mode;
@@ -396,6 +398,8 @@ struct iwl_trans_config {
396 bool scd_set_active; 398 bool scd_set_active;
397 unsigned int queue_watchdog_timeout; 399 unsigned int queue_watchdog_timeout;
398 const char *const *command_names; 400 const char *const *command_names;
401
402 u32 sdio_adma_addr;
399}; 403};
400 404
401struct iwl_trans_dump_data { 405struct iwl_trans_dump_data {
@@ -552,6 +556,21 @@ enum iwl_trans_state {
552}; 556};
553 557
554/** 558/**
559 * enum iwl_d0i3_mode - d0i3 mode
560 *
561 * @IWL_D0I3_MODE_OFF - d0i3 is disabled
562 * @IWL_D0I3_MODE_ON_IDLE - enter d0i3 when device is idle
563 * (e.g. no active references)
564 * @IWL_D0I3_MODE_ON_SUSPEND - enter d0i3 only on suspend
565 * (in case of 'any' trigger)
566 */
567enum iwl_d0i3_mode {
568 IWL_D0I3_MODE_OFF = 0,
569 IWL_D0I3_MODE_ON_IDLE,
570 IWL_D0I3_MODE_ON_SUSPEND,
571};
572
573/**
555 * struct iwl_trans - transport common data 574 * struct iwl_trans - transport common data
556 * 575 *
557 * @ops - pointer to iwl_trans_ops 576 * @ops - pointer to iwl_trans_ops
@@ -612,6 +631,8 @@ struct iwl_trans {
612 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX]; 631 const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_MAX];
613 u8 dbg_dest_reg_num; 632 u8 dbg_dest_reg_num;
614 633
634 enum iwl_d0i3_mode d0i3_mode;
635
615 /* pointer to trans specific struct */ 636 /* pointer to trans specific struct */
616 /*Ensure that this pointer will always be aligned to sizeof pointer */ 637 /*Ensure that this pointer will always be aligned to sizeof pointer */
617 char trans_specific[0] __aligned(sizeof(void *)); 638 char trans_specific[0] __aligned(sizeof(void *));
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index a3bfda45d9e6..1ec4d55155f7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -342,7 +342,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
342 { 342 {
343 .range = 12, 343 .range = 12,
344 .lut20 = { 344 .lut20 = {
345 cpu_to_le32(0x00000001), cpu_to_le32(0x00000000), 345 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
346 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 346 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
347 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 347 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
348 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 348 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -363,7 +363,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
363 { 363 {
364 .range = 20, 364 .range = 20,
365 .lut20 = { 365 .lut20 = {
366 cpu_to_le32(0x00000002), cpu_to_le32(0x00000000), 366 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
367 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 367 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
368 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 368 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
369 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 369 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -384,7 +384,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
384 { 384 {
385 .range = 21, 385 .range = 21,
386 .lut20 = { 386 .lut20 = {
387 cpu_to_le32(0x00000003), cpu_to_le32(0x00000000), 387 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
388 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 388 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
389 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 389 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
390 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 390 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -405,7 +405,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
405 { 405 {
406 .range = 23, 406 .range = 23,
407 .lut20 = { 407 .lut20 = {
408 cpu_to_le32(0x00000004), cpu_to_le32(0x00000000), 408 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
409 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 409 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
410 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 410 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
411 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 411 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -426,7 +426,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
426 { 426 {
427 .range = 27, 427 .range = 27,
428 .lut20 = { 428 .lut20 = {
429 cpu_to_le32(0x00000005), cpu_to_le32(0x00000000), 429 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
430 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 430 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
431 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 431 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
432 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 432 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -447,7 +447,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
447 { 447 {
448 .range = 30, 448 .range = 30,
449 .lut20 = { 449 .lut20 = {
450 cpu_to_le32(0x00000006), cpu_to_le32(0x00000000), 450 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
451 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 451 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
452 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 452 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
453 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 453 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -468,7 +468,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
468 { 468 {
469 .range = 32, 469 .range = 32,
470 .lut20 = { 470 .lut20 = {
471 cpu_to_le32(0x00000007), cpu_to_le32(0x00000000), 471 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
472 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 472 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
473 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 473 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
474 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 474 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -489,7 +489,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
489 { 489 {
490 .range = 33, 490 .range = 33,
491 .lut20 = { 491 .lut20 = {
492 cpu_to_le32(0x00000008), cpu_to_le32(0x00000000), 492 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
493 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 493 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
494 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 494 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
495 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 495 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -989,7 +989,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
989static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, 989static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
990 struct ieee80211_vif *vif) 990 struct ieee80211_vif *vif)
991{ 991{
992 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 992 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
993 struct iwl_bt_iterator_data *data = _data; 993 struct iwl_bt_iterator_data *data = _data;
994 struct iwl_mvm *mvm = data->mvm; 994 struct iwl_mvm *mvm = data->mvm;
995 995
@@ -1025,7 +1025,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
1025void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1025void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1026 enum ieee80211_rssi_event rssi_event) 1026 enum ieee80211_rssi_event rssi_event)
1027{ 1027{
1028 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1028 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1029 struct iwl_bt_iterator_data data = { 1029 struct iwl_bt_iterator_data data = {
1030 .mvm = mvm, 1030 .mvm = mvm,
1031 }; 1031 };
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index b3210cfbecc8..d530ef3da107 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -330,7 +330,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
330 { 330 {
331 .range = 12, 331 .range = 12,
332 .lut20 = { 332 .lut20 = {
333 cpu_to_le32(0x00000001), cpu_to_le32(0x00000000), 333 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
334 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 334 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
335 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 335 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
336 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 336 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -351,7 +351,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
351 { 351 {
352 .range = 20, 352 .range = 20,
353 .lut20 = { 353 .lut20 = {
354 cpu_to_le32(0x00000002), cpu_to_le32(0x00000000), 354 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
355 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 355 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
356 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 356 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
357 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 357 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -372,7 +372,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
372 { 372 {
373 .range = 21, 373 .range = 21,
374 .lut20 = { 374 .lut20 = {
375 cpu_to_le32(0x00000003), cpu_to_le32(0x00000000), 375 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
376 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 376 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
377 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 377 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
378 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 378 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -393,7 +393,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
393 { 393 {
394 .range = 23, 394 .range = 23,
395 .lut20 = { 395 .lut20 = {
396 cpu_to_le32(0x00000004), cpu_to_le32(0x00000000), 396 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
397 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 397 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
398 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 398 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
399 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 399 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -414,7 +414,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
414 { 414 {
415 .range = 27, 415 .range = 27,
416 .lut20 = { 416 .lut20 = {
417 cpu_to_le32(0x00000005), cpu_to_le32(0x00000000), 417 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
418 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 418 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
419 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 419 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
420 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 420 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -435,7 +435,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
435 { 435 {
436 .range = 30, 436 .range = 30,
437 .lut20 = { 437 .lut20 = {
438 cpu_to_le32(0x00000006), cpu_to_le32(0x00000000), 438 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
439 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 439 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
440 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 440 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
441 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 441 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -456,7 +456,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
456 { 456 {
457 .range = 32, 457 .range = 32,
458 .lut20 = { 458 .lut20 = {
459 cpu_to_le32(0x00000007), cpu_to_le32(0x00000000), 459 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
460 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 460 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
461 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 461 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
462 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 462 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -477,7 +477,7 @@ static const struct corunning_block_luts antenna_coupling_ranges[] = {
477 { 477 {
478 .range = 33, 478 .range = 33,
479 .lut20 = { 479 .lut20 = {
480 cpu_to_le32(0x00000008), cpu_to_le32(0x00000000), 480 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
481 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 481 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
482 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 482 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
483 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000), 483 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
@@ -1034,7 +1034,7 @@ int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
1034static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, 1034static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
1035 struct ieee80211_vif *vif) 1035 struct ieee80211_vif *vif)
1036{ 1036{
1037 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1037 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1038 struct iwl_bt_iterator_data *data = _data; 1038 struct iwl_bt_iterator_data *data = _data;
1039 struct iwl_mvm *mvm = data->mvm; 1039 struct iwl_mvm *mvm = data->mvm;
1040 1040
@@ -1070,7 +1070,7 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
1070void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1070void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1071 enum ieee80211_rssi_event rssi_event) 1071 enum ieee80211_rssi_event rssi_event)
1072{ 1072{
1073 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1073 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1074 struct iwl_bt_iterator_data data = { 1074 struct iwl_bt_iterator_data data = {
1075 .mvm = mvm, 1075 .mvm = mvm,
1076 }; 1076 };
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 3bd93476ec1c..d91c46b0f888 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -94,13 +94,42 @@
94#define IWL_MVM_BT_COEX_MPLUT 1 94#define IWL_MVM_BT_COEX_MPLUT 1
95#define IWL_MVM_BT_COEX_RRC 1 95#define IWL_MVM_BT_COEX_RRC 1
96#define IWL_MVM_BT_COEX_TTC 1 96#define IWL_MVM_BT_COEX_TTC 1
97#define IWL_MVM_BT_COEX_MPLUT_REG0 0x28412201 97#define IWL_MVM_BT_COEX_MPLUT_REG0 0x22002200
98#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451 98#define IWL_MVM_BT_COEX_MPLUT_REG1 0x11118451
99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30 99#define IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS 30
100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 100#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0 101#define IWL_MVM_FW_BCAST_FILTER_PASS_ALL 0
102#define IWL_MVM_QUOTA_THRESHOLD 8 102#define IWL_MVM_QUOTA_THRESHOLD 8
103#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0 103#define IWL_MVM_RS_RSSI_BASED_INIT_RATE 0
104#define IWL_MVM_RS_DISABLE_MIMO 0 104#define IWL_MVM_RS_DISABLE_P2P_MIMO 0
105#define IWL_MVM_RS_NUM_TRY_BEFORE_ANT_TOGGLE 1
106#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE 2
107#define IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE_TW 1
108#define IWL_MVM_RS_INITIAL_MIMO_NUM_RATES 3
109#define IWL_MVM_RS_INITIAL_SISO_NUM_RATES 3
110#define IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES 2
111#define IWL_MVM_RS_INITIAL_LEGACY_RETRIES 2
112#define IWL_MVM_RS_SECONDARY_LEGACY_RETRIES 1
113#define IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES 16
114#define IWL_MVM_RS_SECONDARY_SISO_NUM_RATES 3
115#define IWL_MVM_RS_SECONDARY_SISO_RETRIES 1
116#define IWL_MVM_RS_RATE_MIN_FAILURE_TH 3
117#define IWL_MVM_RS_RATE_MIN_SUCCESS_TH 8
118#define IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT 5 /* Seconds */
119#define IWL_MVM_RS_IDLE_TIMEOUT 5 /* Seconds */
120#define IWL_MVM_RS_MISSED_RATE_MAX 15
121#define IWL_MVM_RS_LEGACY_FAILURE_LIMIT 160
122#define IWL_MVM_RS_LEGACY_SUCCESS_LIMIT 480
123#define IWL_MVM_RS_LEGACY_TABLE_COUNT 160
124#define IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT 400
125#define IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT 4500
126#define IWL_MVM_RS_NON_LEGACY_TABLE_COUNT 1500
127#define IWL_MVM_RS_SR_FORCE_DECREASE 15 /* percent */
128#define IWL_MVM_RS_SR_NO_DECREASE 85 /* percent */
129#define IWL_MVM_RS_AGG_TIME_LIMIT 4000 /* 4 msecs. valid 100-8000 */
130#define IWL_MVM_RS_AGG_DISABLE_START 3
131#define IWL_MVM_RS_TPC_SR_FORCE_INCREASE 75 /* percent */
132#define IWL_MVM_RS_TPC_SR_NO_INCREASE 85 /* percent */
133#define IWL_MVM_RS_TPC_TX_POWER_STEP 3
105 134
106#endif /* __MVM_CONSTANTS_H */ 135#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 744de262373e..14e8fd661889 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -793,7 +793,7 @@ iwl_mvm_get_wowlan_config(struct iwl_mvm *mvm,
793 struct ieee80211_sta *ap_sta) 793 struct ieee80211_sta *ap_sta)
794{ 794{
795 int ret; 795 int ret;
796 struct iwl_mvm_sta *mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; 796 struct iwl_mvm_sta *mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
797 797
798 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */ 798 /* TODO: wowlan_config_cmd->wowlan_ba_teardown_tids */
799 799
@@ -1137,12 +1137,43 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1137 return ret; 1137 return ret;
1138} 1138}
1139 1139
1140static int iwl_mvm_enter_d0i3_sync(struct iwl_mvm *mvm)
1141{
1142 struct iwl_notification_wait wait_d3;
1143 static const u8 d3_notif[] = { D3_CONFIG_CMD };
1144 int ret;
1145
1146 iwl_init_notification_wait(&mvm->notif_wait, &wait_d3,
1147 d3_notif, ARRAY_SIZE(d3_notif),
1148 NULL, NULL);
1149
1150 ret = iwl_mvm_enter_d0i3(mvm->hw->priv);
1151 if (ret)
1152 goto remove_notif;
1153
1154 ret = iwl_wait_notification(&mvm->notif_wait, &wait_d3, HZ);
1155 WARN_ON_ONCE(ret);
1156 return ret;
1157
1158remove_notif:
1159 iwl_remove_notification(&mvm->notif_wait, &wait_d3);
1160 return ret;
1161}
1162
1140int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) 1163int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
1141{ 1164{
1142 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1165 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1143 1166
1144 iwl_trans_suspend(mvm->trans); 1167 iwl_trans_suspend(mvm->trans);
1145 if (iwl_mvm_is_d0i3_supported(mvm)) { 1168 if (wowlan->any) {
1169 /* 'any' trigger means d0i3 usage */
1170 if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
1171 int ret = iwl_mvm_enter_d0i3_sync(mvm);
1172
1173 if (ret)
1174 return ret;
1175 }
1176
1146 mutex_lock(&mvm->d0i3_suspend_mutex); 1177 mutex_lock(&mvm->d0i3_suspend_mutex);
1147 __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags); 1178 __set_bit(D0I3_DEFER_WAKEUP, &mvm->d0i3_suspend_flags);
1148 mutex_unlock(&mvm->d0i3_suspend_mutex); 1179 mutex_unlock(&mvm->d0i3_suspend_mutex);
@@ -1626,7 +1657,7 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm,
1626 if (IS_ERR_OR_NULL(ap_sta)) 1657 if (IS_ERR_OR_NULL(ap_sta))
1627 goto out_free; 1658 goto out_free;
1628 1659
1629 mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; 1660 mvm_ap_sta = iwl_mvm_sta_from_mac80211(ap_sta);
1630 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1661 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1631 u16 seq = status.qos_seq_ctr[i]; 1662 u16 seq = status.qos_seq_ctr[i];
1632 /* firmware stores last-used value, we store next value */ 1663 /* firmware stores last-used value, we store next value */
@@ -1876,8 +1907,20 @@ int iwl_mvm_resume(struct ieee80211_hw *hw)
1876 1907
1877 iwl_trans_resume(mvm->trans); 1908 iwl_trans_resume(mvm->trans);
1878 1909
1879 if (iwl_mvm_is_d0i3_supported(mvm)) 1910 if (mvm->hw->wiphy->wowlan_config->any) {
1911 /* 'any' trigger means d0i3 usage */
1912 if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND) {
1913 int ret = iwl_mvm_exit_d0i3(hw->priv);
1914
1915 if (ret)
1916 return ret;
1917 /*
1918 * d0i3 exit will be deferred until reconfig_complete.
1919 * make sure there we are out of d0i3.
1920 */
1921 }
1880 return 0; 1922 return 0;
1923 }
1881 1924
1882 return __iwl_mvm_resume(mvm, false); 1925 return __iwl_mvm_resume(mvm, false);
1883} 1926}
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
index 9aa2311a776c..5fe14591e1c4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs-vif.c
@@ -268,7 +268,7 @@ static ssize_t iwl_dbgfs_mac_params_read(struct file *file,
268 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id], 268 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[ap_sta_id],
269 lockdep_is_held(&mvm->mutex)); 269 lockdep_is_held(&mvm->mutex));
270 if (!IS_ERR_OR_NULL(sta)) { 270 if (!IS_ERR_OR_NULL(sta)) {
271 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 271 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
272 272
273 pos += scnprintf(buf+pos, bufsz-pos, 273 pos += scnprintf(buf+pos, bufsz-pos,
274 "ap_sta_id %d - reduced Tx power %d\n", 274 "ap_sta_id %d - reduced Tx power %d\n",
@@ -517,6 +517,34 @@ static ssize_t iwl_dbgfs_low_latency_read(struct file *file,
517 return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf)); 517 return simple_read_from_buffer(user_buf, count, ppos, buf, sizeof(buf));
518} 518}
519 519
520static ssize_t iwl_dbgfs_uapsd_misbehaving_read(struct file *file,
521 char __user *user_buf,
522 size_t count, loff_t *ppos)
523{
524 struct ieee80211_vif *vif = file->private_data;
525 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
526 char buf[20];
527 int len;
528
529 len = sprintf(buf, "%pM\n", mvmvif->uapsd_misbehaving_bssid);
530 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
531}
532
533static ssize_t iwl_dbgfs_uapsd_misbehaving_write(struct ieee80211_vif *vif,
534 char *buf, size_t count,
535 loff_t *ppos)
536{
537 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
538 struct iwl_mvm *mvm = mvmvif->mvm;
539 bool ret;
540
541 mutex_lock(&mvm->mutex);
542 ret = mac_pton(buf, mvmvif->uapsd_misbehaving_bssid);
543 mutex_unlock(&mvm->mutex);
544
545 return ret ? count : -EINVAL;
546}
547
520#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 548#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
521 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif) 549 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
522#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ 550#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
@@ -531,6 +559,7 @@ MVM_DEBUGFS_READ_FILE_OPS(mac_params);
531MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32); 559MVM_DEBUGFS_READ_WRITE_FILE_OPS(pm_params, 32);
532MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256); 560MVM_DEBUGFS_READ_WRITE_FILE_OPS(bf_params, 256);
533MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10); 561MVM_DEBUGFS_READ_WRITE_FILE_OPS(low_latency, 10);
562MVM_DEBUGFS_READ_WRITE_FILE_OPS(uapsd_misbehaving, 20);
534 563
535void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 564void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
536{ 565{
@@ -564,6 +593,8 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
564 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR); 593 MVM_DEBUGFS_ADD_FILE_VIF(mac_params, mvmvif->dbgfs_dir, S_IRUSR);
565 MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir, 594 MVM_DEBUGFS_ADD_FILE_VIF(low_latency, mvmvif->dbgfs_dir,
566 S_IRUSR | S_IWUSR); 595 S_IRUSR | S_IWUSR);
596 MVM_DEBUGFS_ADD_FILE_VIF(uapsd_misbehaving, mvmvif->dbgfs_dir,
597 S_IRUSR | S_IWUSR);
567 598
568 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p && 599 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p &&
569 mvmvif == mvm->bf_allowed_vif) 600 mvmvif == mvm->bf_allowed_vif)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 33bf915cd7ea..82c09d86af8c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -654,10 +654,10 @@ out:
654 return ret ?: count; 654 return ret ?: count;
655} 655}
656 656
657#define PRINT_STATS_LE32(_str, _val) \ 657#define PRINT_STATS_LE32(_struct, _memb) \
658 pos += scnprintf(buf + pos, bufsz - pos, \ 658 pos += scnprintf(buf + pos, bufsz - pos, \
659 fmt_table, _str, \ 659 fmt_table, #_memb, \
660 le32_to_cpu(_val)) 660 le32_to_cpu(_struct->_memb))
661 661
662static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, 662static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
663 char __user *user_buf, size_t count, 663 char __user *user_buf, size_t count,
@@ -692,97 +692,89 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file,
692 692
693 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 693 pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
694 "Statistics_Rx - OFDM"); 694 "Statistics_Rx - OFDM");
695 PRINT_STATS_LE32("ina_cnt", ofdm->ina_cnt); 695 PRINT_STATS_LE32(ofdm, ina_cnt);
696 PRINT_STATS_LE32("fina_cnt", ofdm->fina_cnt); 696 PRINT_STATS_LE32(ofdm, fina_cnt);
697 PRINT_STATS_LE32("plcp_err", ofdm->plcp_err); 697 PRINT_STATS_LE32(ofdm, plcp_err);
698 PRINT_STATS_LE32("crc32_err", ofdm->crc32_err); 698 PRINT_STATS_LE32(ofdm, crc32_err);
699 PRINT_STATS_LE32("overrun_err", ofdm->overrun_err); 699 PRINT_STATS_LE32(ofdm, overrun_err);
700 PRINT_STATS_LE32("early_overrun_err", ofdm->early_overrun_err); 700 PRINT_STATS_LE32(ofdm, early_overrun_err);
701 PRINT_STATS_LE32("crc32_good", ofdm->crc32_good); 701 PRINT_STATS_LE32(ofdm, crc32_good);
702 PRINT_STATS_LE32("false_alarm_cnt", ofdm->false_alarm_cnt); 702 PRINT_STATS_LE32(ofdm, false_alarm_cnt);
703 PRINT_STATS_LE32("fina_sync_err_cnt", ofdm->fina_sync_err_cnt); 703 PRINT_STATS_LE32(ofdm, fina_sync_err_cnt);
704 PRINT_STATS_LE32("sfd_timeout", ofdm->sfd_timeout); 704 PRINT_STATS_LE32(ofdm, sfd_timeout);
705 PRINT_STATS_LE32("fina_timeout", ofdm->fina_timeout); 705 PRINT_STATS_LE32(ofdm, fina_timeout);
706 PRINT_STATS_LE32("unresponded_rts", ofdm->unresponded_rts); 706 PRINT_STATS_LE32(ofdm, unresponded_rts);
707 PRINT_STATS_LE32("rxe_frame_lmt_overrun", 707 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun);
708 ofdm->rxe_frame_limit_overrun); 708 PRINT_STATS_LE32(ofdm, sent_ack_cnt);
709 PRINT_STATS_LE32("sent_ack_cnt", ofdm->sent_ack_cnt); 709 PRINT_STATS_LE32(ofdm, sent_cts_cnt);
710 PRINT_STATS_LE32("sent_cts_cnt", ofdm->sent_cts_cnt); 710 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt);
711 PRINT_STATS_LE32("sent_ba_rsp_cnt", ofdm->sent_ba_rsp_cnt); 711 PRINT_STATS_LE32(ofdm, dsp_self_kill);
712 PRINT_STATS_LE32("dsp_self_kill", ofdm->dsp_self_kill); 712 PRINT_STATS_LE32(ofdm, mh_format_err);
713 PRINT_STATS_LE32("mh_format_err", ofdm->mh_format_err); 713 PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum);
714 PRINT_STATS_LE32("re_acq_main_rssi_sum", ofdm->re_acq_main_rssi_sum); 714 PRINT_STATS_LE32(ofdm, reserved);
715 PRINT_STATS_LE32("reserved", ofdm->reserved);
716 715
717 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 716 pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
718 "Statistics_Rx - CCK"); 717 "Statistics_Rx - CCK");
719 PRINT_STATS_LE32("ina_cnt", cck->ina_cnt); 718 PRINT_STATS_LE32(cck, ina_cnt);
720 PRINT_STATS_LE32("fina_cnt", cck->fina_cnt); 719 PRINT_STATS_LE32(cck, fina_cnt);
721 PRINT_STATS_LE32("plcp_err", cck->plcp_err); 720 PRINT_STATS_LE32(cck, plcp_err);
722 PRINT_STATS_LE32("crc32_err", cck->crc32_err); 721 PRINT_STATS_LE32(cck, crc32_err);
723 PRINT_STATS_LE32("overrun_err", cck->overrun_err); 722 PRINT_STATS_LE32(cck, overrun_err);
724 PRINT_STATS_LE32("early_overrun_err", cck->early_overrun_err); 723 PRINT_STATS_LE32(cck, early_overrun_err);
725 PRINT_STATS_LE32("crc32_good", cck->crc32_good); 724 PRINT_STATS_LE32(cck, crc32_good);
726 PRINT_STATS_LE32("false_alarm_cnt", cck->false_alarm_cnt); 725 PRINT_STATS_LE32(cck, false_alarm_cnt);
727 PRINT_STATS_LE32("fina_sync_err_cnt", cck->fina_sync_err_cnt); 726 PRINT_STATS_LE32(cck, fina_sync_err_cnt);
728 PRINT_STATS_LE32("sfd_timeout", cck->sfd_timeout); 727 PRINT_STATS_LE32(cck, sfd_timeout);
729 PRINT_STATS_LE32("fina_timeout", cck->fina_timeout); 728 PRINT_STATS_LE32(cck, fina_timeout);
730 PRINT_STATS_LE32("unresponded_rts", cck->unresponded_rts); 729 PRINT_STATS_LE32(cck, unresponded_rts);
731 PRINT_STATS_LE32("rxe_frame_lmt_overrun", 730 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun);
732 cck->rxe_frame_limit_overrun); 731 PRINT_STATS_LE32(cck, sent_ack_cnt);
733 PRINT_STATS_LE32("sent_ack_cnt", cck->sent_ack_cnt); 732 PRINT_STATS_LE32(cck, sent_cts_cnt);
734 PRINT_STATS_LE32("sent_cts_cnt", cck->sent_cts_cnt); 733 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt);
735 PRINT_STATS_LE32("sent_ba_rsp_cnt", cck->sent_ba_rsp_cnt); 734 PRINT_STATS_LE32(cck, dsp_self_kill);
736 PRINT_STATS_LE32("dsp_self_kill", cck->dsp_self_kill); 735 PRINT_STATS_LE32(cck, mh_format_err);
737 PRINT_STATS_LE32("mh_format_err", cck->mh_format_err); 736 PRINT_STATS_LE32(cck, re_acq_main_rssi_sum);
738 PRINT_STATS_LE32("re_acq_main_rssi_sum", cck->re_acq_main_rssi_sum); 737 PRINT_STATS_LE32(cck, reserved);
739 PRINT_STATS_LE32("reserved", cck->reserved);
740 738
741 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 739 pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
742 "Statistics_Rx - GENERAL"); 740 "Statistics_Rx - GENERAL");
743 PRINT_STATS_LE32("bogus_cts", general->bogus_cts); 741 PRINT_STATS_LE32(general, bogus_cts);
744 PRINT_STATS_LE32("bogus_ack", general->bogus_ack); 742 PRINT_STATS_LE32(general, bogus_ack);
745 PRINT_STATS_LE32("non_bssid_frames", general->non_bssid_frames); 743 PRINT_STATS_LE32(general, non_bssid_frames);
746 PRINT_STATS_LE32("filtered_frames", general->filtered_frames); 744 PRINT_STATS_LE32(general, filtered_frames);
747 PRINT_STATS_LE32("non_channel_beacons", general->non_channel_beacons); 745 PRINT_STATS_LE32(general, non_channel_beacons);
748 PRINT_STATS_LE32("channel_beacons", general->channel_beacons); 746 PRINT_STATS_LE32(general, channel_beacons);
749 PRINT_STATS_LE32("num_missed_bcon", general->num_missed_bcon); 747 PRINT_STATS_LE32(general, num_missed_bcon);
750 PRINT_STATS_LE32("adc_rx_saturation_time", 748 PRINT_STATS_LE32(general, adc_rx_saturation_time);
751 general->adc_rx_saturation_time); 749 PRINT_STATS_LE32(general, ina_detection_search_time);
752 PRINT_STATS_LE32("ina_detection_search_time", 750 PRINT_STATS_LE32(general, beacon_silence_rssi_a);
753 general->ina_detection_search_time); 751 PRINT_STATS_LE32(general, beacon_silence_rssi_b);
754 PRINT_STATS_LE32("beacon_silence_rssi_a", 752 PRINT_STATS_LE32(general, beacon_silence_rssi_c);
755 general->beacon_silence_rssi_a); 753 PRINT_STATS_LE32(general, interference_data_flag);
756 PRINT_STATS_LE32("beacon_silence_rssi_b", 754 PRINT_STATS_LE32(general, channel_load);
757 general->beacon_silence_rssi_b); 755 PRINT_STATS_LE32(general, dsp_false_alarms);
758 PRINT_STATS_LE32("beacon_silence_rssi_c", 756 PRINT_STATS_LE32(general, beacon_rssi_a);
759 general->beacon_silence_rssi_c); 757 PRINT_STATS_LE32(general, beacon_rssi_b);
760 PRINT_STATS_LE32("interference_data_flag", 758 PRINT_STATS_LE32(general, beacon_rssi_c);
761 general->interference_data_flag); 759 PRINT_STATS_LE32(general, beacon_energy_a);
762 PRINT_STATS_LE32("channel_load", general->channel_load); 760 PRINT_STATS_LE32(general, beacon_energy_b);
763 PRINT_STATS_LE32("dsp_false_alarms", general->dsp_false_alarms); 761 PRINT_STATS_LE32(general, beacon_energy_c);
764 PRINT_STATS_LE32("beacon_rssi_a", general->beacon_rssi_a); 762 PRINT_STATS_LE32(general, num_bt_kills);
765 PRINT_STATS_LE32("beacon_rssi_b", general->beacon_rssi_b); 763 PRINT_STATS_LE32(general, mac_id);
766 PRINT_STATS_LE32("beacon_rssi_c", general->beacon_rssi_c); 764 PRINT_STATS_LE32(general, directed_data_mpdu);
767 PRINT_STATS_LE32("beacon_energy_a", general->beacon_energy_a);
768 PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b);
769 PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c);
770 PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills);
771 PRINT_STATS_LE32("mac_id", general->mac_id);
772 PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu);
773 765
774 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 766 pos += scnprintf(buf + pos, bufsz - pos, fmt_header,
775 "Statistics_Rx - HT"); 767 "Statistics_Rx - HT");
776 PRINT_STATS_LE32("plcp_err", ht->plcp_err); 768 PRINT_STATS_LE32(ht, plcp_err);
777 PRINT_STATS_LE32("overrun_err", ht->overrun_err); 769 PRINT_STATS_LE32(ht, overrun_err);
778 PRINT_STATS_LE32("early_overrun_err", ht->early_overrun_err); 770 PRINT_STATS_LE32(ht, early_overrun_err);
779 PRINT_STATS_LE32("crc32_good", ht->crc32_good); 771 PRINT_STATS_LE32(ht, crc32_good);
780 PRINT_STATS_LE32("crc32_err", ht->crc32_err); 772 PRINT_STATS_LE32(ht, crc32_err);
781 PRINT_STATS_LE32("mh_format_err", ht->mh_format_err); 773 PRINT_STATS_LE32(ht, mh_format_err);
782 PRINT_STATS_LE32("agg_crc32_good", ht->agg_crc32_good); 774 PRINT_STATS_LE32(ht, agg_crc32_good);
783 PRINT_STATS_LE32("agg_mpdu_cnt", ht->agg_mpdu_cnt); 775 PRINT_STATS_LE32(ht, agg_mpdu_cnt);
784 PRINT_STATS_LE32("agg_cnt", ht->agg_cnt); 776 PRINT_STATS_LE32(ht, agg_cnt);
785 PRINT_STATS_LE32("unsupport_mcs", ht->unsupport_mcs); 777 PRINT_STATS_LE32(ht, unsupport_mcs);
786 778
787 mutex_unlock(&mvm->mutex); 779 mutex_unlock(&mvm->mutex);
788 780
@@ -933,7 +925,7 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
933 return -EINVAL; 925 return -EINVAL;
934 if (scan_rx_ant > ANT_ABC) 926 if (scan_rx_ant > ANT_ABC)
935 return -EINVAL; 927 return -EINVAL;
936 if (scan_rx_ant & ~mvm->fw->valid_rx_ant) 928 if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm)))
937 return -EINVAL; 929 return -EINVAL;
938 930
939 if (mvm->scan_rx_ant != scan_rx_ant) { 931 if (mvm->scan_rx_ant != scan_rx_ant) {
@@ -945,6 +937,61 @@ iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf,
945 return count; 937 return count;
946} 938}
947 939
940static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file,
941 char __user *user_buf,
942 size_t count, loff_t *ppos)
943{
944 struct iwl_mvm *mvm = file->private_data;
945 enum iwl_fw_dbg_conf conf;
946 char buf[8];
947 const size_t bufsz = sizeof(buf);
948 int pos = 0;
949
950 mutex_lock(&mvm->mutex);
951 conf = mvm->fw_dbg_conf;
952 mutex_unlock(&mvm->mutex);
953
954 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf);
955
956 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
957}
958
959static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm,
960 char *buf, size_t count,
961 loff_t *ppos)
962{
963 int ret, conf_id;
964
965 ret = kstrtoint(buf, 0, &conf_id);
966 if (ret)
967 return ret;
968
969 if (WARN_ON(conf_id >= FW_DBG_MAX))
970 return -EINVAL;
971
972 mutex_lock(&mvm->mutex);
973 ret = iwl_mvm_start_fw_dbg_conf(mvm, conf_id);
974 mutex_unlock(&mvm->mutex);
975
976 return ret ?: count;
977}
978
979static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm,
980 char *buf, size_t count,
981 loff_t *ppos)
982{
983 int ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PRPH_WRITE);
984
985 if (ret)
986 return ret;
987
988 iwl_mvm_fw_dbg_collect(mvm);
989
990 iwl_mvm_unref(mvm, IWL_MVM_REF_PRPH_WRITE);
991
992 return count;
993}
994
948#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__) 995#define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__)
949#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 996#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
950static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file, 997static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file,
@@ -1340,6 +1387,7 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
1340 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD); 1387 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
1341 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); 1388 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1342 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA); 1389 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_CSA);
1390 PRINT_MVM_REF(IWL_MVM_REF_FW_DBG_COLLECT);
1343 1391
1344 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1392 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1345} 1393}
@@ -1439,6 +1487,26 @@ out:
1439 return count; 1487 return count;
1440} 1488}
1441 1489
1490static ssize_t iwl_dbgfs_enable_scan_iteration_notif_write(struct iwl_mvm *mvm,
1491 char *buf,
1492 size_t count,
1493 loff_t *ppos)
1494{
1495 int val;
1496
1497 mutex_lock(&mvm->mutex);
1498
1499 if (kstrtoint(buf, 10, &val)) {
1500 mutex_unlock(&mvm->mutex);
1501 return -EINVAL;
1502 }
1503
1504 mvm->scan_iter_notif_enabled = val;
1505 mutex_unlock(&mvm->mutex);
1506
1507 return count;
1508}
1509
1442MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); 1510MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64);
1443 1511
1444/* Device wide debugfs entries */ 1512/* Device wide debugfs entries */
@@ -1459,6 +1527,9 @@ MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1459MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10); 1527MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
1460MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1528MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1461MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); 1529MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1530MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8);
1531MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 8);
1532MVM_DEBUGFS_WRITE_FILE_OPS(enable_scan_iteration_notif, 8);
1462 1533
1463#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1534#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1464MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); 1535MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
@@ -1500,6 +1571,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1500 S_IWUSR | S_IRUSR); 1571 S_IWUSR | S_IRUSR);
1501 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1572 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
1502 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 1573 MVM_DEBUGFS_ADD_FILE(d0i3_refs, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
1574 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
1575 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, S_IWUSR);
1576 MVM_DEBUGFS_ADD_FILE(enable_scan_iteration_notif, mvm->debugfs_dir,
1577 S_IWUSR);
1503 1578
1504#ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1579#ifdef CONFIG_IWLWIFI_BCAST_FILTERING
1505 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) { 1580 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index 430020047b77..4fc0938b3fb6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -92,14 +92,32 @@ enum iwl_ltr_config_flags {
92}; 92};
93 93
94/** 94/**
95 * struct iwl_ltr_config_cmd_v1 - configures the LTR
96 * @flags: See %enum iwl_ltr_config_flags
97 */
98struct iwl_ltr_config_cmd_v1 {
99 __le32 flags;
100 __le32 static_long;
101 __le32 static_short;
102} __packed; /* LTR_CAPABLE_API_S_VER_1 */
103
104#define LTR_VALID_STATES_NUM 4
105
106/**
95 * struct iwl_ltr_config_cmd - configures the LTR 107 * struct iwl_ltr_config_cmd - configures the LTR
96 * @flags: See %enum iwl_ltr_config_flags 108 * @flags: See %enum iwl_ltr_config_flags
109 * @static_long:
110 * @static_short:
111 * @ltr_cfg_values:
112 * @ltr_short_idle_timeout:
97 */ 113 */
98struct iwl_ltr_config_cmd { 114struct iwl_ltr_config_cmd {
99 __le32 flags; 115 __le32 flags;
100 __le32 static_long; 116 __le32 static_long;
101 __le32 static_short; 117 __le32 static_short;
102} __packed; 118 __le32 ltr_cfg_values[LTR_VALID_STATES_NUM];
119 __le32 ltr_short_idle_timeout;
120} __packed; /* LTR_CAPABLE_API_S_VER_2 */
103 121
104/* Radio LP RX Energy Threshold measured in dBm */ 122/* Radio LP RX Energy Threshold measured in dBm */
105#define POWER_LPRX_RSSI_THRESHOLD 75 123#define POWER_LPRX_RSSI_THRESHOLD 75
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
index 8bb5b94bf963..6a2a6b0ab91b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -308,6 +308,17 @@ enum {
308#define LQ_FLAG_DYNAMIC_BW_POS 6 308#define LQ_FLAG_DYNAMIC_BW_POS 6
309#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS) 309#define LQ_FLAG_DYNAMIC_BW_MSK (1 << LQ_FLAG_DYNAMIC_BW_POS)
310 310
311/* Single Stream Parameters
312 * SS_STBC/BFER_ALLOWED - Controls whether STBC or Beamformer (BFER) is allowed
313 * ucode will make a smart decision between SISO/STBC/BFER
314 * SS_PARAMS_VALID - if not set ignore the ss_params field.
315 */
316enum {
317 RS_SS_STBC_ALLOWED = BIT(0),
318 RS_SS_BFER_ALLOWED = BIT(1),
319 RS_SS_PARAMS_VALID = BIT(31),
320};
321
311/** 322/**
312 * struct iwl_lq_cmd - link quality command 323 * struct iwl_lq_cmd - link quality command
313 * @sta_id: station to update 324 * @sta_id: station to update
@@ -330,7 +341,7 @@ enum {
330 * 2 - 0x3f: maximal number of frames (up to 3f == 63) 341 * 2 - 0x3f: maximal number of frames (up to 3f == 63)
331 * @rs_table: array of rates for each TX try, each is rate_n_flags, 342 * @rs_table: array of rates for each TX try, each is rate_n_flags,
332 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP 343 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP
333 * @bf_params: beam forming params, currently not used 344 * @ss_params: single stream features. declare whether STBC or BFER are allowed.
334 */ 345 */
335struct iwl_lq_cmd { 346struct iwl_lq_cmd {
336 u8 sta_id; 347 u8 sta_id;
@@ -348,6 +359,6 @@ struct iwl_lq_cmd {
348 u8 agg_frame_cnt_limit; 359 u8 agg_frame_cnt_limit;
349 __le32 reserved2; 360 __le32 reserved2;
350 __le32 rs_table[LQ_MAX_RETRY_NUM]; 361 __le32 rs_table[LQ_MAX_RETRY_NUM];
351 __le32 bf_params; 362 __le32 ss_params;
352}; /* LINK_QUALITY_CMD_API_S_VER_1 */ 363}; /* LINK_QUALITY_CMD_API_S_VER_1 */
353#endif /* __fw_api_rs_h__ */ 364#endif /* __fw_api_rs_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 201846de94e7..cfc0e65b34a5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -653,8 +653,11 @@ enum iwl_scan_channel_flags {
653}; 653};
654 654
655/* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S 655/* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
656 * @flags: enum iwl_scan_channel_flgs 656 * @flags: enum iwl_scan_channel_flags
657 * @non_ebs_ratio: how many regular scan iteration before EBS 657 * @non_ebs_ratio: defines the ratio of number of scan iterations where EBS is
658 * involved.
659 * 1 - EBS is disabled.
660 * 2 - every second scan will be full scan(and so on).
658 */ 661 */
659struct iwl_scan_channel_opt { 662struct iwl_scan_channel_opt {
660 __le16 flags; 663 __le16 flags;
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
new file mode 100644
index 000000000000..928168b18346
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-stats.h
@@ -0,0 +1,277 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
10 *
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
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
23 * USA
24 *
25 * The full GNU General Public License is included in this distribution
26 * in the file called COPYING.
27 *
28 * Contact Information:
29 * Intel Linux Wireless <ilw@linux.intel.com>
30 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
31 *
32 * BSD LICENSE
33 *
34 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
35 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 *
42 * * Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * * Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in
46 * the documentation and/or other materials provided with the
47 * distribution.
48 * * Neither the name Intel Corporation nor the names of its
49 * contributors may be used to endorse or promote products derived
50 * from this software without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
53 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
54 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
55 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
56 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
57 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
58 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
59 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
60 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
61 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
62 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
63 *
64 *****************************************************************************/
65
66#ifndef __fw_api_stats_h__
67#define __fw_api_stats_h__
68
69struct mvm_statistics_dbg {
70 __le32 burst_check;
71 __le32 burst_count;
72 __le32 wait_for_silence_timeout_cnt;
73 __le32 reserved[3];
74} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
75
76struct mvm_statistics_div {
77 __le32 tx_on_a;
78 __le32 tx_on_b;
79 __le32 exec_time;
80 __le32 probe_time;
81 __le32 rssi_ant;
82 __le32 reserved2;
83} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
84
85struct mvm_statistics_rx_non_phy {
86 __le32 bogus_cts; /* CTS received when not expecting CTS */
87 __le32 bogus_ack; /* ACK received when not expecting ACK */
88 __le32 non_bssid_frames; /* number of frames with BSSID that
89 * doesn't belong to the STA BSSID */
90 __le32 filtered_frames; /* count frames that were dumped in the
91 * filtering process */
92 __le32 non_channel_beacons; /* beacons with our bss id but not on
93 * our serving channel */
94 __le32 channel_beacons; /* beacons with our bss id and in our
95 * serving channel */
96 __le32 num_missed_bcon; /* number of missed beacons */
97 __le32 adc_rx_saturation_time; /* count in 0.8us units the time the
98 * ADC was in saturation */
99 __le32 ina_detection_search_time;/* total time (in 0.8us) searched
100 * for INA */
101 __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */
102 __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */
103 __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */
104 __le32 interference_data_flag; /* flag for interference data
105 * availability. 1 when data is
106 * available. */
107 __le32 channel_load; /* counts RX Enable time in uSec */
108 __le32 dsp_false_alarms; /* DSP false alarm (both OFDM
109 * and CCK) counter */
110 __le32 beacon_rssi_a;
111 __le32 beacon_rssi_b;
112 __le32 beacon_rssi_c;
113 __le32 beacon_energy_a;
114 __le32 beacon_energy_b;
115 __le32 beacon_energy_c;
116 __le32 num_bt_kills;
117 __le32 mac_id;
118 __le32 directed_data_mpdu;
119} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
120
121struct mvm_statistics_rx_phy {
122 __le32 ina_cnt;
123 __le32 fina_cnt;
124 __le32 plcp_err;
125 __le32 crc32_err;
126 __le32 overrun_err;
127 __le32 early_overrun_err;
128 __le32 crc32_good;
129 __le32 false_alarm_cnt;
130 __le32 fina_sync_err_cnt;
131 __le32 sfd_timeout;
132 __le32 fina_timeout;
133 __le32 unresponded_rts;
134 __le32 rxe_frame_lmt_overrun;
135 __le32 sent_ack_cnt;
136 __le32 sent_cts_cnt;
137 __le32 sent_ba_rsp_cnt;
138 __le32 dsp_self_kill;
139 __le32 mh_format_err;
140 __le32 re_acq_main_rssi_sum;
141 __le32 reserved;
142} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
143
144struct mvm_statistics_rx_ht_phy {
145 __le32 plcp_err;
146 __le32 overrun_err;
147 __le32 early_overrun_err;
148 __le32 crc32_good;
149 __le32 crc32_err;
150 __le32 mh_format_err;
151 __le32 agg_crc32_good;
152 __le32 agg_mpdu_cnt;
153 __le32 agg_cnt;
154 __le32 unsupport_mcs;
155} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
156
157struct mvm_statistics_tx_non_phy {
158 __le32 preamble_cnt;
159 __le32 rx_detected_cnt;
160 __le32 bt_prio_defer_cnt;
161 __le32 bt_prio_kill_cnt;
162 __le32 few_bytes_cnt;
163 __le32 cts_timeout;
164 __le32 ack_timeout;
165 __le32 expected_ack_cnt;
166 __le32 actual_ack_cnt;
167 __le32 dump_msdu_cnt;
168 __le32 burst_abort_next_frame_mismatch_cnt;
169 __le32 burst_abort_missing_next_frame_cnt;
170 __le32 cts_timeout_collision;
171 __le32 ack_or_ba_timeout_collision;
172} __packed; /* STATISTICS_TX_NON_PHY_API_S_VER_3 */
173
174#define MAX_CHAINS 3
175
176struct mvm_statistics_tx_non_phy_agg {
177 __le32 ba_timeout;
178 __le32 ba_reschedule_frames;
179 __le32 scd_query_agg_frame_cnt;
180 __le32 scd_query_no_agg;
181 __le32 scd_query_agg;
182 __le32 scd_query_mismatch;
183 __le32 frame_not_ready;
184 __le32 underrun;
185 __le32 bt_prio_kill;
186 __le32 rx_ba_rsp_cnt;
187 __s8 txpower[MAX_CHAINS];
188 __s8 reserved;
189 __le32 reserved2;
190} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
191
192struct mvm_statistics_tx_channel_width {
193 __le32 ext_cca_narrow_ch20[1];
194 __le32 ext_cca_narrow_ch40[2];
195 __le32 ext_cca_narrow_ch80[3];
196 __le32 ext_cca_narrow_ch160[4];
197 __le32 last_tx_ch_width_indx;
198 __le32 rx_detected_per_ch_width[4];
199 __le32 success_per_ch_width[4];
200 __le32 fail_per_ch_width[4];
201}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
202
203struct mvm_statistics_tx {
204 struct mvm_statistics_tx_non_phy general;
205 struct mvm_statistics_tx_non_phy_agg agg;
206 struct mvm_statistics_tx_channel_width channel_width;
207} __packed; /* STATISTICS_TX_API_S_VER_4 */
208
209
210struct mvm_statistics_bt_activity {
211 __le32 hi_priority_tx_req_cnt;
212 __le32 hi_priority_tx_denied_cnt;
213 __le32 lo_priority_tx_req_cnt;
214 __le32 lo_priority_tx_denied_cnt;
215 __le32 hi_priority_rx_req_cnt;
216 __le32 hi_priority_rx_denied_cnt;
217 __le32 lo_priority_rx_req_cnt;
218 __le32 lo_priority_rx_denied_cnt;
219} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
220
221struct mvm_statistics_general {
222 __le32 radio_temperature;
223 __le32 radio_voltage;
224 struct mvm_statistics_dbg dbg;
225 __le32 sleep_time;
226 __le32 slots_out;
227 __le32 slots_idle;
228 __le32 ttl_timestamp;
229 struct mvm_statistics_div slow_div;
230 __le32 rx_enable_counter;
231 /*
232 * num_of_sos_states:
233 * count the number of times we have to re-tune
234 * in order to get out of bad PHY status
235 */
236 __le32 num_of_sos_states;
237 __le32 beacon_filtered;
238 __le32 missed_beacons;
239 __s8 beacon_filter_average_energy;
240 __s8 beacon_filter_reason;
241 __s8 beacon_filter_current_energy;
242 __s8 beacon_filter_reserved;
243 __le32 beacon_filter_delta_time;
244 struct mvm_statistics_bt_activity bt_activity;
245} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
246
247struct mvm_statistics_rx {
248 struct mvm_statistics_rx_phy ofdm;
249 struct mvm_statistics_rx_phy cck;
250 struct mvm_statistics_rx_non_phy general;
251 struct mvm_statistics_rx_ht_phy ofdm_ht;
252} __packed; /* STATISTICS_RX_API_S_VER_3 */
253
254/*
255 * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
256 *
257 * By default, uCode issues this notification after receiving a beacon
258 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
259 * REPLY_STATISTICS_CMD 0x9c, above.
260 *
261 * Statistics counters continue to increment beacon after beacon, but are
262 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
263 * 0x9c with CLEAR_STATS bit set (see above).
264 *
265 * uCode also issues this notification during scans. uCode clears statistics
266 * appropriately so that each notification contains statistics for only the
267 * one channel that has just been scanned.
268 */
269
270struct iwl_notif_statistics {
271 __le32 flag;
272 struct mvm_statistics_rx rx;
273 struct mvm_statistics_tx tx;
274 struct mvm_statistics_general general;
275} __packed; /* STATISTICS_NTFY_API_S_VER_8 */
276
277#endif /* __fw_api_stats_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 5bca1f8bfebf..81c4ea3c6958 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -592,4 +592,43 @@ static inline u32 iwl_mvm_get_scd_ssn(struct iwl_mvm_tx_resp *tx_resp)
592 tx_resp->frame_count) & 0xfff; 592 tx_resp->frame_count) & 0xfff;
593} 593}
594 594
595/**
596 * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
597 * @token:
598 * @sta_id: station id
599 * @tid:
600 * @scd_queue: scheduler queue to confiug
601 * @enable: 1 queue enable, 0 queue disable
602 * @aggregate: 1 aggregated queue, 0 otherwise
603 * @tx_fifo: %enum iwl_mvm_tx_fifo
604 * @window: BA window size
605 * @ssn: SSN for the BA agreement
606 */
607struct iwl_scd_txq_cfg_cmd {
608 u8 token;
609 u8 sta_id;
610 u8 tid;
611 u8 scd_queue;
612 u8 enable;
613 u8 aggregate;
614 u8 tx_fifo;
615 u8 window;
616 __le16 ssn;
617 __le16 reserved;
618} __packed; /* SCD_QUEUE_CFG_CMD_API_S_VER_1 */
619
620/**
621 * struct iwl_scd_txq_cfg_rsp
622 * @token: taken from the command
623 * @sta_id: station id from the command
624 * @tid: tid from the command
625 * @scd_queue: scd_queue from the command
626 */
627struct iwl_scd_txq_cfg_rsp {
628 u8 token;
629 u8 sta_id;
630 u8 tid;
631 u8 scd_queue;
632} __packed; /* SCD_QUEUE_CFG_RSP_API_S_VER_1 */
633
595#endif /* __fw_api_tx_h__ */ 634#endif /* __fw_api_tx_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 88af6dd2ceaa..b56154fe8ec5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -74,6 +74,7 @@
74#include "fw-api-d3.h" 74#include "fw-api-d3.h"
75#include "fw-api-coex.h" 75#include "fw-api-coex.h"
76#include "fw-api-scan.h" 76#include "fw-api-scan.h"
77#include "fw-api-stats.h"
77 78
78/* Tx queue numbers */ 79/* Tx queue numbers */
79enum { 80enum {
@@ -128,6 +129,9 @@ enum {
128 /* global key */ 129 /* global key */
129 WEP_KEY = 0x20, 130 WEP_KEY = 0x20,
130 131
132 /* Memory */
133 SHARED_MEM_CFG = 0x25,
134
131 /* TDLS */ 135 /* TDLS */
132 TDLS_CHANNEL_SWITCH_CMD = 0x27, 136 TDLS_CHANNEL_SWITCH_CMD = 0x27,
133 TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa, 137 TDLS_CHANNEL_SWITCH_NOTIFICATION = 0xaa,
@@ -1381,214 +1385,6 @@ struct iwl_mvm_marker {
1381 __le32 metadata[0]; 1385 __le32 metadata[0];
1382} __packed; /* MARKER_API_S_VER_1 */ 1386} __packed; /* MARKER_API_S_VER_1 */
1383 1387
1384struct mvm_statistics_dbg {
1385 __le32 burst_check;
1386 __le32 burst_count;
1387 __le32 wait_for_silence_timeout_cnt;
1388 __le32 reserved[3];
1389} __packed; /* STATISTICS_DEBUG_API_S_VER_2 */
1390
1391struct mvm_statistics_div {
1392 __le32 tx_on_a;
1393 __le32 tx_on_b;
1394 __le32 exec_time;
1395 __le32 probe_time;
1396 __le32 rssi_ant;
1397 __le32 reserved2;
1398} __packed; /* STATISTICS_SLOW_DIV_API_S_VER_2 */
1399
1400struct mvm_statistics_general_common {
1401 __le32 temperature; /* radio temperature */
1402 __le32 temperature_m; /* radio voltage */
1403 struct mvm_statistics_dbg dbg;
1404 __le32 sleep_time;
1405 __le32 slots_out;
1406 __le32 slots_idle;
1407 __le32 ttl_timestamp;
1408 struct mvm_statistics_div div;
1409 __le32 rx_enable_counter;
1410 /*
1411 * num_of_sos_states:
1412 * count the number of times we have to re-tune
1413 * in order to get out of bad PHY status
1414 */
1415 __le32 num_of_sos_states;
1416} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1417
1418struct mvm_statistics_rx_non_phy {
1419 __le32 bogus_cts; /* CTS received when not expecting CTS */
1420 __le32 bogus_ack; /* ACK received when not expecting ACK */
1421 __le32 non_bssid_frames; /* number of frames with BSSID that
1422 * doesn't belong to the STA BSSID */
1423 __le32 filtered_frames; /* count frames that were dumped in the
1424 * filtering process */
1425 __le32 non_channel_beacons; /* beacons with our bss id but not on
1426 * our serving channel */
1427 __le32 channel_beacons; /* beacons with our bss id and in our
1428 * serving channel */
1429 __le32 num_missed_bcon; /* number of missed beacons */
1430 __le32 adc_rx_saturation_time; /* count in 0.8us units the time the
1431 * ADC was in saturation */
1432 __le32 ina_detection_search_time;/* total time (in 0.8us) searched
1433 * for INA */
1434 __le32 beacon_silence_rssi_a; /* RSSI silence after beacon frame */
1435 __le32 beacon_silence_rssi_b; /* RSSI silence after beacon frame */
1436 __le32 beacon_silence_rssi_c; /* RSSI silence after beacon frame */
1437 __le32 interference_data_flag; /* flag for interference data
1438 * availability. 1 when data is
1439 * available. */
1440 __le32 channel_load; /* counts RX Enable time in uSec */
1441 __le32 dsp_false_alarms; /* DSP false alarm (both OFDM
1442 * and CCK) counter */
1443 __le32 beacon_rssi_a;
1444 __le32 beacon_rssi_b;
1445 __le32 beacon_rssi_c;
1446 __le32 beacon_energy_a;
1447 __le32 beacon_energy_b;
1448 __le32 beacon_energy_c;
1449 __le32 num_bt_kills;
1450 __le32 mac_id;
1451 __le32 directed_data_mpdu;
1452} __packed; /* STATISTICS_RX_NON_PHY_API_S_VER_3 */
1453
1454struct mvm_statistics_rx_phy {
1455 __le32 ina_cnt;
1456 __le32 fina_cnt;
1457 __le32 plcp_err;
1458 __le32 crc32_err;
1459 __le32 overrun_err;
1460 __le32 early_overrun_err;
1461 __le32 crc32_good;
1462 __le32 false_alarm_cnt;
1463 __le32 fina_sync_err_cnt;
1464 __le32 sfd_timeout;
1465 __le32 fina_timeout;
1466 __le32 unresponded_rts;
1467 __le32 rxe_frame_limit_overrun;
1468 __le32 sent_ack_cnt;
1469 __le32 sent_cts_cnt;
1470 __le32 sent_ba_rsp_cnt;
1471 __le32 dsp_self_kill;
1472 __le32 mh_format_err;
1473 __le32 re_acq_main_rssi_sum;
1474 __le32 reserved;
1475} __packed; /* STATISTICS_RX_PHY_API_S_VER_2 */
1476
1477struct mvm_statistics_rx_ht_phy {
1478 __le32 plcp_err;
1479 __le32 overrun_err;
1480 __le32 early_overrun_err;
1481 __le32 crc32_good;
1482 __le32 crc32_err;
1483 __le32 mh_format_err;
1484 __le32 agg_crc32_good;
1485 __le32 agg_mpdu_cnt;
1486 __le32 agg_cnt;
1487 __le32 unsupport_mcs;
1488} __packed; /* STATISTICS_HT_RX_PHY_API_S_VER_1 */
1489
1490#define MAX_CHAINS 3
1491
1492struct mvm_statistics_tx_non_phy_agg {
1493 __le32 ba_timeout;
1494 __le32 ba_reschedule_frames;
1495 __le32 scd_query_agg_frame_cnt;
1496 __le32 scd_query_no_agg;
1497 __le32 scd_query_agg;
1498 __le32 scd_query_mismatch;
1499 __le32 frame_not_ready;
1500 __le32 underrun;
1501 __le32 bt_prio_kill;
1502 __le32 rx_ba_rsp_cnt;
1503 __s8 txpower[MAX_CHAINS];
1504 __s8 reserved;
1505 __le32 reserved2;
1506} __packed; /* STATISTICS_TX_NON_PHY_AGG_API_S_VER_1 */
1507
1508struct mvm_statistics_tx_channel_width {
1509 __le32 ext_cca_narrow_ch20[1];
1510 __le32 ext_cca_narrow_ch40[2];
1511 __le32 ext_cca_narrow_ch80[3];
1512 __le32 ext_cca_narrow_ch160[4];
1513 __le32 last_tx_ch_width_indx;
1514 __le32 rx_detected_per_ch_width[4];
1515 __le32 success_per_ch_width[4];
1516 __le32 fail_per_ch_width[4];
1517}; /* STATISTICS_TX_CHANNEL_WIDTH_API_S_VER_1 */
1518
1519struct mvm_statistics_tx {
1520 __le32 preamble_cnt;
1521 __le32 rx_detected_cnt;
1522 __le32 bt_prio_defer_cnt;
1523 __le32 bt_prio_kill_cnt;
1524 __le32 few_bytes_cnt;
1525 __le32 cts_timeout;
1526 __le32 ack_timeout;
1527 __le32 expected_ack_cnt;
1528 __le32 actual_ack_cnt;
1529 __le32 dump_msdu_cnt;
1530 __le32 burst_abort_next_frame_mismatch_cnt;
1531 __le32 burst_abort_missing_next_frame_cnt;
1532 __le32 cts_timeout_collision;
1533 __le32 ack_or_ba_timeout_collision;
1534 struct mvm_statistics_tx_non_phy_agg agg;
1535 struct mvm_statistics_tx_channel_width channel_width;
1536} __packed; /* STATISTICS_TX_API_S_VER_4 */
1537
1538
1539struct mvm_statistics_bt_activity {
1540 __le32 hi_priority_tx_req_cnt;
1541 __le32 hi_priority_tx_denied_cnt;
1542 __le32 lo_priority_tx_req_cnt;
1543 __le32 lo_priority_tx_denied_cnt;
1544 __le32 hi_priority_rx_req_cnt;
1545 __le32 hi_priority_rx_denied_cnt;
1546 __le32 lo_priority_rx_req_cnt;
1547 __le32 lo_priority_rx_denied_cnt;
1548} __packed; /* STATISTICS_BT_ACTIVITY_API_S_VER_1 */
1549
1550struct mvm_statistics_general {
1551 struct mvm_statistics_general_common common;
1552 __le32 beacon_filtered;
1553 __le32 missed_beacons;
1554 __s8 beacon_filter_average_energy;
1555 __s8 beacon_filter_reason;
1556 __s8 beacon_filter_current_energy;
1557 __s8 beacon_filter_reserved;
1558 __le32 beacon_filter_delta_time;
1559 struct mvm_statistics_bt_activity bt_activity;
1560} __packed; /* STATISTICS_GENERAL_API_S_VER_5 */
1561
1562struct mvm_statistics_rx {
1563 struct mvm_statistics_rx_phy ofdm;
1564 struct mvm_statistics_rx_phy cck;
1565 struct mvm_statistics_rx_non_phy general;
1566 struct mvm_statistics_rx_ht_phy ofdm_ht;
1567} __packed; /* STATISTICS_RX_API_S_VER_3 */
1568
1569/*
1570 * STATISTICS_NOTIFICATION = 0x9d (notification only, not a command)
1571 *
1572 * By default, uCode issues this notification after receiving a beacon
1573 * while associated. To disable this behavior, set DISABLE_NOTIF flag in the
1574 * REPLY_STATISTICS_CMD 0x9c, above.
1575 *
1576 * Statistics counters continue to increment beacon after beacon, but are
1577 * cleared when changing channels or when driver issues REPLY_STATISTICS_CMD
1578 * 0x9c with CLEAR_STATS bit set (see above).
1579 *
1580 * uCode also issues this notification during scans. uCode clears statistics
1581 * appropriately so that each notification contains statistics for only the
1582 * one channel that has just been scanned.
1583 */
1584
1585struct iwl_notif_statistics { /* STATISTICS_NTFY_API_S_VER_8 */
1586 __le32 flag;
1587 struct mvm_statistics_rx rx;
1588 struct mvm_statistics_tx tx;
1589 struct mvm_statistics_general general;
1590} __packed;
1591
1592/*********************************** 1388/***********************************
1593 * Smart Fifo API 1389 * Smart Fifo API
1594 ***********************************/ 1390 ***********************************/
@@ -1680,63 +1476,6 @@ struct iwl_dts_measurement_notif {
1680 __le32 voltage; 1476 __le32 voltage;
1681} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ 1477} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
1682 1478
1683/**
1684 * enum iwl_scd_control - scheduler config command control flags
1685 * @IWL_SCD_CONTROL_RM_TID: remove TID from this queue
1686 * @IWL_SCD_CONTROL_SET_SSN: use the SSN and program it into HW
1687 */
1688enum iwl_scd_control {
1689 IWL_SCD_CONTROL_RM_TID = BIT(4),
1690 IWL_SCD_CONTROL_SET_SSN = BIT(5),
1691};
1692
1693/**
1694 * enum iwl_scd_flags - scheduler config command flags
1695 * @IWL_SCD_FLAGS_SHARE_TID: multiple TIDs map to this queue
1696 * @IWL_SCD_FLAGS_SHARE_RA: multiple RAs map to this queue
1697 * @IWL_SCD_FLAGS_DQA_ENABLED: DQA is enabled
1698 */
1699enum iwl_scd_flags {
1700 IWL_SCD_FLAGS_SHARE_TID = BIT(0),
1701 IWL_SCD_FLAGS_SHARE_RA = BIT(1),
1702 IWL_SCD_FLAGS_DQA_ENABLED = BIT(2),
1703};
1704
1705#define IWL_SCDQ_INVALID_STA 0xff
1706
1707/**
1708 * struct iwl_scd_txq_cfg_cmd - New txq hw scheduler config command
1709 * @token: dialog token addba - unused legacy
1710 * @sta_id: station id 4-bit
1711 * @tid: TID 0..7
1712 * @scd_queue: TFD queue num 0 .. 31
1713 * @enable: 1 queue enable, 0 queue disable
1714 * @aggregate: 1 aggregated queue, 0 otherwise
1715 * @tx_fifo: tx fifo num 0..7
1716 * @window: up to 64
1717 * @ssn: starting seq num 12-bit
1718 * @control: command control flags
1719 * @flags: flags - see &enum iwl_scd_flags
1720 *
1721 * Note that every time the command is sent, all parameters must
1722 * be filled with the exception of
1723 * - the SSN, which is only used with @IWL_SCD_CONTROL_SET_SSN
1724 * - the window, which is only relevant when starting aggregation
1725 */
1726struct iwl_scd_txq_cfg_cmd {
1727 u8 token;
1728 u8 sta_id;
1729 u8 tid;
1730 u8 scd_queue;
1731 u8 enable;
1732 u8 aggregate;
1733 u8 tx_fifo;
1734 u8 window;
1735 __le16 ssn;
1736 u8 control;
1737 u8 flags;
1738} __packed;
1739
1740/*********************************** 1479/***********************************
1741 * TDLS API 1480 * TDLS API
1742 ***********************************/ 1481 ***********************************/
@@ -1878,4 +1617,36 @@ struct iwl_tdls_config_res {
1878 struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT]; 1617 struct iwl_tdls_config_sta_info_res sta_info[IWL_MVM_TDLS_STA_COUNT];
1879} __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */ 1618} __packed; /* TDLS_CONFIG_RSP_API_S_VER_1 */
1880 1619
1620#define TX_FIFO_MAX_NUM 8
1621#define RX_FIFO_MAX_NUM 2
1622
1623/**
1624 * Shared memory configuration information from the FW
1625 *
1626 * @shared_mem_addr: shared memory addr (pre 8000 HW set to 0x0 as MARBH is not
1627 * accessible)
1628 * @shared_mem_size: shared memory size
1629 * @sample_buff_addr: internal sample (mon/adc) buff addr (pre 8000 HW set to
1630 * 0x0 as accessible only via DBGM RDAT)
1631 * @sample_buff_size: internal sample buff size
1632 * @txfifo_addr: start addr of TXF0 (excluding the context table 0.5KB), (pre
1633 * 8000 HW set to 0x0 as not accessible)
1634 * @txfifo_size: size of TXF0 ... TXF7
1635 * @rxfifo_size: RXF1, RXF2 sizes. If there is no RXF2, it'll have a value of 0
1636 * @page_buff_addr: used by UMAC and performance debug (page miss analysis),
1637 * when paging is not supported this should be 0
1638 * @page_buff_size: size of %page_buff_addr
1639 */
1640struct iwl_shared_mem_cfg {
1641 __le32 shared_mem_addr;
1642 __le32 shared_mem_size;
1643 __le32 sample_buff_addr;
1644 __le32 sample_buff_size;
1645 __le32 txfifo_addr;
1646 __le32 txfifo_size[TX_FIFO_MAX_NUM];
1647 __le32 rxfifo_size[RX_FIFO_MAX_NUM];
1648 __le32 page_buff_addr;
1649 __le32 page_buff_size;
1650} __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
1651
1881#endif /* __fw_api_h__ */ 1652#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index d0fa6e9ed590..a322a5e3d31b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -70,6 +70,7 @@
70#include "iwl-debug.h" 70#include "iwl-debug.h"
71#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */ 71#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */
72#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */ 72#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
73#include "iwl-prph.h"
73#include "iwl-eeprom-parse.h" 74#include "iwl-eeprom-parse.h"
74 75
75#include "mvm.h" 76#include "mvm.h"
@@ -269,7 +270,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm)
269 enum iwl_ucode_type ucode_type = mvm->cur_ucode; 270 enum iwl_ucode_type ucode_type = mvm->cur_ucode;
270 271
271 /* Set parameters */ 272 /* Set parameters */
272 phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); 273 phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_get_phy_config(mvm));
273 phy_cfg_cmd.calib_control.event_trigger = 274 phy_cfg_cmd.calib_control.event_trigger =
274 mvm->fw->default_calib[ucode_type].event_trigger; 275 mvm->fw->default_calib[ucode_type].event_trigger;
275 phy_cfg_cmd.calib_control.flow_trigger = 276 phy_cfg_cmd.calib_control.flow_trigger =
@@ -346,7 +347,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
346 mvm->calibrating = true; 347 mvm->calibrating = true;
347 348
348 /* Send TX valid antennas before triggering calibrations */ 349 /* Send TX valid antennas before triggering calibrations */
349 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 350 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
350 if (ret) 351 if (ret)
351 goto error; 352 goto error;
352 353
@@ -399,8 +400,71 @@ out:
399 return ret; 400 return ret;
400} 401}
401 402
402static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, 403static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)
403 enum iwl_fw_dbg_conf conf_id) 404{
405 struct iwl_host_cmd cmd = {
406 .id = SHARED_MEM_CFG,
407 .flags = CMD_WANT_SKB,
408 .data = { NULL, },
409 .len = { 0, },
410 };
411 struct iwl_rx_packet *pkt;
412 struct iwl_shared_mem_cfg *mem_cfg;
413 u32 i;
414
415 lockdep_assert_held(&mvm->mutex);
416
417 if (WARN_ON(iwl_mvm_send_cmd(mvm, &cmd)))
418 return;
419
420 pkt = cmd.resp_pkt;
421 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
422 IWL_ERR(mvm, "Bad return from SHARED_MEM_CFG (0x%08X)\n",
423 pkt->hdr.flags);
424 goto exit;
425 }
426
427 mem_cfg = (void *)pkt->data;
428
429 mvm->shared_mem_cfg.shared_mem_addr =
430 le32_to_cpu(mem_cfg->shared_mem_addr);
431 mvm->shared_mem_cfg.shared_mem_size =
432 le32_to_cpu(mem_cfg->shared_mem_size);
433 mvm->shared_mem_cfg.sample_buff_addr =
434 le32_to_cpu(mem_cfg->sample_buff_addr);
435 mvm->shared_mem_cfg.sample_buff_size =
436 le32_to_cpu(mem_cfg->sample_buff_size);
437 mvm->shared_mem_cfg.txfifo_addr = le32_to_cpu(mem_cfg->txfifo_addr);
438 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++)
439 mvm->shared_mem_cfg.txfifo_size[i] =
440 le32_to_cpu(mem_cfg->txfifo_size[i]);
441 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++)
442 mvm->shared_mem_cfg.rxfifo_size[i] =
443 le32_to_cpu(mem_cfg->rxfifo_size[i]);
444 mvm->shared_mem_cfg.page_buff_addr =
445 le32_to_cpu(mem_cfg->page_buff_addr);
446 mvm->shared_mem_cfg.page_buff_size =
447 le32_to_cpu(mem_cfg->page_buff_size);
448 IWL_DEBUG_INFO(mvm, "SHARED MEM CFG: got memory offsets/sizes\n");
449
450exit:
451 iwl_free_resp(&cmd);
452}
453
454void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm)
455{
456 /* stop recording */
457 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
458 iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
459 } else {
460 iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
461 iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
462 }
463
464 schedule_work(&mvm->fw_error_dump_wk);
465}
466
467int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf conf_id)
404{ 468{
405 u8 *ptr; 469 u8 *ptr;
406 int ret; 470 int ret;
@@ -435,6 +499,35 @@ static int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm,
435 return ret; 499 return ret;
436} 500}
437 501
502static int iwl_mvm_config_ltr_v1(struct iwl_mvm *mvm)
503{
504 struct iwl_ltr_config_cmd_v1 cmd_v1 = {
505 .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
506 };
507
508 if (!mvm->trans->ltr_enabled)
509 return 0;
510
511 return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
512 sizeof(cmd_v1), &cmd_v1);
513}
514
515static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
516{
517 struct iwl_ltr_config_cmd cmd = {
518 .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
519 };
520
521 if (!mvm->trans->ltr_enabled)
522 return 0;
523
524 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_HDC_PHASE_0))
525 return iwl_mvm_config_ltr_v1(mvm);
526
527 return iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
528 sizeof(cmd), &cmd);
529}
530
438int iwl_mvm_up(struct iwl_mvm *mvm) 531int iwl_mvm_up(struct iwl_mvm *mvm)
439{ 532{
440 int ret, i; 533 int ret, i;
@@ -482,6 +575,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
482 goto error; 575 goto error;
483 } 576 }
484 577
578 iwl_mvm_get_shared_mem_conf(mvm);
579
485 ret = iwl_mvm_sf_update(mvm, NULL, false); 580 ret = iwl_mvm_sf_update(mvm, NULL, false);
486 if (ret) 581 if (ret)
487 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 582 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
@@ -489,7 +584,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
489 mvm->fw_dbg_conf = FW_DBG_INVALID; 584 mvm->fw_dbg_conf = FW_DBG_INVALID;
490 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM); 585 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
491 586
492 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 587 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
493 if (ret) 588 if (ret)
494 goto error; 589 goto error;
495 590
@@ -538,14 +633,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
538 /* Initialize tx backoffs to the minimal possible */ 633 /* Initialize tx backoffs to the minimal possible */
539 iwl_mvm_tt_tx_backoff(mvm, 0); 634 iwl_mvm_tt_tx_backoff(mvm, 0);
540 635
541 if (mvm->trans->ltr_enabled) { 636 WARN_ON(iwl_mvm_config_ltr(mvm));
542 struct iwl_ltr_config_cmd cmd = {
543 .flags = cpu_to_le32(LTR_CFG_FLAG_FEATURE_ENABLE),
544 };
545
546 WARN_ON(iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0,
547 sizeof(cmd), &cmd));
548 }
549 637
550 ret = iwl_mvm_power_update_device(mvm); 638 ret = iwl_mvm_power_update_device(mvm);
551 if (ret) 639 if (ret)
@@ -584,7 +672,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
584 goto error; 672 goto error;
585 } 673 }
586 674
587 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 675 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
588 if (ret) 676 if (ret)
589 goto error; 677 goto error;
590 678
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index f6d86ccce6a8..8bf78fa8ace0 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -208,8 +208,10 @@ u32 iwl_mvm_mac_get_queues_mask(struct ieee80211_vif *vif)
208 if (vif->type == NL80211_IFTYPE_P2P_DEVICE) 208 if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
209 return BIT(IWL_MVM_OFFCHANNEL_QUEUE); 209 return BIT(IWL_MVM_OFFCHANNEL_QUEUE);
210 210
211 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 211 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
212 qmask |= BIT(vif->hw_queue[ac]); 212 if (vif->hw_queue[ac] != IEEE80211_INVAL_HW_QUEUE)
213 qmask |= BIT(vif->hw_queue[ac]);
214 }
213 215
214 if (vif->type == NL80211_IFTYPE_AP) 216 if (vif->type == NL80211_IFTYPE_AP)
215 qmask |= BIT(vif->cab_queue); 217 qmask |= BIT(vif->cab_queue);
@@ -496,14 +498,14 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
496 498
497 switch (vif->type) { 499 switch (vif->type) {
498 case NL80211_IFTYPE_P2P_DEVICE: 500 case NL80211_IFTYPE_P2P_DEVICE:
499 iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE); 501 iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 0);
500 break; 502 break;
501 case NL80211_IFTYPE_AP: 503 case NL80211_IFTYPE_AP:
502 iwl_mvm_disable_txq(mvm, vif->cab_queue); 504 iwl_mvm_disable_txq(mvm, vif->cab_queue, 0);
503 /* fall through */ 505 /* fall through */
504 default: 506 default:
505 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 507 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
506 iwl_mvm_disable_txq(mvm, vif->hw_queue[ac]); 508 iwl_mvm_disable_txq(mvm, vif->hw_queue[ac], 0);
507 } 509 }
508} 510}
509 511
@@ -975,7 +977,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
975 beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags); 977 beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags);
976 978
977 mvm->mgmt_last_antenna_idx = 979 mvm->mgmt_last_antenna_idx =
978 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 980 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
979 mvm->mgmt_last_antenna_idx); 981 mvm->mgmt_last_antenna_idx);
980 982
981 beacon_cmd.tx.rate_n_flags = 983 beacon_cmd.tx.rate_n_flags =
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 17358a88e26d..cef6f3373542 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -85,6 +85,7 @@
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"
88 89
89static const struct ieee80211_iface_limit iwl_mvm_limits[] = { 90static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
90 { 91 {
@@ -105,7 +106,7 @@ static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
105 106
106static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = { 107static const struct ieee80211_iface_combination iwl_mvm_iface_combinations[] = {
107 { 108 {
108 .num_different_channels = 1, 109 .num_different_channels = 2,
109 .max_interfaces = 3, 110 .max_interfaces = 3,
110 .limits = iwl_mvm_limits, 111 .limits = iwl_mvm_limits,
111 .n_limits = ARRAY_SIZE(iwl_mvm_limits), 112 .n_limits = ARRAY_SIZE(iwl_mvm_limits),
@@ -372,6 +373,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
372 373
373 hw->wiphy->max_remain_on_channel_duration = 10000; 374 hw->wiphy->max_remain_on_channel_duration = 10000;
374 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; 375 hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
376 /* we can compensate an offset of up to 3 channels = 15 MHz */
377 hw->wiphy->max_adj_channel_rssi_comp = 3 * 5;
375 378
376 /* Extract MAC address */ 379 /* Extract MAC address */
377 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); 380 memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
@@ -454,15 +457,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
454 device_can_wakeup(mvm->trans->dev)) { 457 device_can_wakeup(mvm->trans->dev)) {
455 mvm->wowlan.flags = WIPHY_WOWLAN_ANY; 458 mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
456 hw->wiphy->wowlan = &mvm->wowlan; 459 hw->wiphy->wowlan = &mvm->wowlan;
457 } else if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 460 }
461
462 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
458 mvm->trans->ops->d3_suspend && 463 mvm->trans->ops->d3_suspend &&
459 mvm->trans->ops->d3_resume && 464 mvm->trans->ops->d3_resume &&
460 device_can_wakeup(mvm->trans->dev)) { 465 device_can_wakeup(mvm->trans->dev)) {
461 mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 466 mvm->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT |
462 WIPHY_WOWLAN_DISCONNECT | 467 WIPHY_WOWLAN_DISCONNECT |
463 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 468 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
464 WIPHY_WOWLAN_RFKILL_RELEASE | 469 WIPHY_WOWLAN_RFKILL_RELEASE |
465 WIPHY_WOWLAN_NET_DETECT; 470 WIPHY_WOWLAN_NET_DETECT;
466 if (!iwlwifi_mod_params.sw_crypto) 471 if (!iwlwifi_mod_params.sw_crypto)
467 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 472 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
468 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 473 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
@@ -756,41 +761,215 @@ static void iwl_mvm_free_coredump(const void *data)
756 kfree(fw_error_dump); 761 kfree(fw_error_dump);
757} 762}
758 763
764static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
765 struct iwl_fw_error_dump_data **dump_data)
766{
767 struct iwl_fw_error_dump_fifo *fifo_hdr;
768 u32 *fifo_data;
769 u32 fifo_len;
770 unsigned long flags;
771 int i, j;
772
773 if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags))
774 return;
775
776 /* Pull RXF data from all RXFs */
777 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++) {
778 /*
779 * Keep aside the additional offset that might be needed for
780 * next RXF
781 */
782 u32 offset_diff = RXF_DIFF_FROM_PREV * i;
783
784 fifo_hdr = (void *)(*dump_data)->data;
785 fifo_data = (void *)fifo_hdr->data;
786 fifo_len = mvm->shared_mem_cfg.rxfifo_size[i];
787
788 /* No need to try to read the data if the length is 0 */
789 if (fifo_len == 0)
790 continue;
791
792 /* Add a TLV for the RXF */
793 (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
794 (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
795
796 fifo_hdr->fifo_num = cpu_to_le32(i);
797 fifo_hdr->available_bytes =
798 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
799 RXF_RD_D_SPACE +
800 offset_diff));
801 fifo_hdr->wr_ptr =
802 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
803 RXF_RD_WR_PTR +
804 offset_diff));
805 fifo_hdr->rd_ptr =
806 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
807 RXF_RD_RD_PTR +
808 offset_diff));
809 fifo_hdr->fence_ptr =
810 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
811 RXF_RD_FENCE_PTR +
812 offset_diff));
813 fifo_hdr->fence_mode =
814 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
815 RXF_SET_FENCE_MODE +
816 offset_diff));
817
818 /* Lock fence */
819 iwl_trans_write_prph(mvm->trans,
820 RXF_SET_FENCE_MODE + offset_diff, 0x1);
821 /* Set fence pointer to the same place like WR pointer */
822 iwl_trans_write_prph(mvm->trans,
823 RXF_LD_WR2FENCE + offset_diff, 0x1);
824 /* Set fence offset */
825 iwl_trans_write_prph(mvm->trans,
826 RXF_LD_FENCE_OFFSET_ADDR + offset_diff,
827 0x0);
828
829 /* Read FIFO */
830 fifo_len /= sizeof(u32); /* Size in DWORDS */
831 for (j = 0; j < fifo_len; j++)
832 fifo_data[j] = iwl_trans_read_prph(mvm->trans,
833 RXF_FIFO_RD_FENCE_INC +
834 offset_diff);
835 *dump_data = iwl_fw_error_next_data(*dump_data);
836 }
837
838 /* Pull TXF data from all TXFs */
839 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++) {
840 /* Mark the number of TXF we're pulling now */
841 iwl_trans_write_prph(mvm->trans, TXF_LARC_NUM, i);
842
843 fifo_hdr = (void *)(*dump_data)->data;
844 fifo_data = (void *)fifo_hdr->data;
845 fifo_len = mvm->shared_mem_cfg.txfifo_size[i];
846
847 /* No need to try to read the data if the length is 0 */
848 if (fifo_len == 0)
849 continue;
850
851 /* Add a TLV for the FIFO */
852 (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXF);
853 (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
854
855 fifo_hdr->fifo_num = cpu_to_le32(i);
856 fifo_hdr->available_bytes =
857 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
858 TXF_FIFO_ITEM_CNT));
859 fifo_hdr->wr_ptr =
860 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
861 TXF_WR_PTR));
862 fifo_hdr->rd_ptr =
863 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
864 TXF_RD_PTR));
865 fifo_hdr->fence_ptr =
866 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
867 TXF_FENCE_PTR));
868 fifo_hdr->fence_mode =
869 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
870 TXF_LOCK_FENCE));
871
872 /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */
873 iwl_trans_write_prph(mvm->trans, TXF_READ_MODIFY_ADDR,
874 TXF_WR_PTR);
875
876 /* Dummy-read to advance the read pointer to the head */
877 iwl_trans_read_prph(mvm->trans, TXF_READ_MODIFY_DATA);
878
879 /* Read FIFO */
880 fifo_len /= sizeof(u32); /* Size in DWORDS */
881 for (j = 0; j < fifo_len; j++)
882 fifo_data[j] = iwl_trans_read_prph(mvm->trans,
883 TXF_READ_MODIFY_DATA);
884 *dump_data = iwl_fw_error_next_data(*dump_data);
885 }
886
887 iwl_trans_release_nic_access(mvm->trans, &flags);
888}
889
759void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 890void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
760{ 891{
761 struct iwl_fw_error_dump_file *dump_file; 892 struct iwl_fw_error_dump_file *dump_file;
762 struct iwl_fw_error_dump_data *dump_data; 893 struct iwl_fw_error_dump_data *dump_data;
763 struct iwl_fw_error_dump_info *dump_info; 894 struct iwl_fw_error_dump_info *dump_info;
895 struct iwl_fw_error_dump_mem *dump_mem;
764 struct iwl_mvm_dump_ptrs *fw_error_dump; 896 struct iwl_mvm_dump_ptrs *fw_error_dump;
765 const struct fw_img *img;
766 u32 sram_len, sram_ofs; 897 u32 sram_len, sram_ofs;
767 u32 file_len, rxf_len; 898 u32 file_len, fifo_data_len = 0;
768 unsigned long flags; 899 u32 smem_len = mvm->cfg->smem_len;
769 int reg_val; 900 u32 sram2_len = mvm->cfg->dccm2_len;
770 901
771 lockdep_assert_held(&mvm->mutex); 902 lockdep_assert_held(&mvm->mutex);
772 903
904 /* W/A for 8000 HW family A-step */
905 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
906 CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) {
907 if (smem_len)
908 smem_len = 0x38000;
909
910 if (sram2_len)
911 sram2_len = 0x10000;
912 }
913
773 fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); 914 fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
774 if (!fw_error_dump) 915 if (!fw_error_dump)
775 return; 916 return;
776 917
777 img = &mvm->fw->img[mvm->cur_ucode]; 918 /* SRAM - include stack CCM if driver knows the values for it */
778 sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 919 if (!mvm->cfg->dccm_offset || !mvm->cfg->dccm_len) {
779 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 920 const struct fw_img *img;
921
922 img = &mvm->fw->img[mvm->cur_ucode];
923 sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
924 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
925 } else {
926 sram_ofs = mvm->cfg->dccm_offset;
927 sram_len = mvm->cfg->dccm_len;
928 }
929
930 /* reading RXF/TXF sizes */
931 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) {
932 struct iwl_mvm_shared_mem_cfg *mem_cfg = &mvm->shared_mem_cfg;
933 int i;
934
935 fifo_data_len = 0;
936
937 /* Count RXF size */
938 for (i = 0; i < ARRAY_SIZE(mem_cfg->rxfifo_size); i++) {
939 if (!mem_cfg->rxfifo_size[i])
940 continue;
941
942 /* Add header info */
943 fifo_data_len += mem_cfg->rxfifo_size[i] +
944 sizeof(*dump_data) +
945 sizeof(struct iwl_fw_error_dump_fifo);
946 }
780 947
781 /* reading buffer size */ 948 for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++) {
782 reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR); 949 if (!mem_cfg->txfifo_size[i])
783 rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS; 950 continue;
784 951
785 /* the register holds the value divided by 128 */ 952 /* Add header info */
786 rxf_len = rxf_len << 7; 953 fifo_data_len += mem_cfg->txfifo_size[i] +
954 sizeof(*dump_data) +
955 sizeof(struct iwl_fw_error_dump_fifo);
956 }
957 }
787 958
788 file_len = sizeof(*dump_file) + 959 file_len = sizeof(*dump_file) +
789 sizeof(*dump_data) * 3 + 960 sizeof(*dump_data) * 2 +
790 sram_len + 961 sram_len + sizeof(*dump_mem) +
791 rxf_len + 962 fifo_data_len +
792 sizeof(*dump_info); 963 sizeof(*dump_info);
793 964
965 /* Make room for the SMEM, if it exists */
966 if (smem_len)
967 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
968
969 /* Make room for the secondary SRAM, if it exists */
970 if (sram2_len)
971 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
972
794 dump_file = vzalloc(file_len); 973 dump_file = vzalloc(file_len);
795 if (!dump_file) { 974 if (!dump_file) {
796 kfree(fw_error_dump); 975 kfree(fw_error_dump);
@@ -809,6 +988,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
809 mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ? 988 mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
810 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) : 989 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
811 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8); 990 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
991 dump_info->hw_step = cpu_to_le32(CSR_HW_REV_STEP(mvm->trans->hw_rev));
812 memcpy(dump_info->fw_human_readable, mvm->fw->human_readable, 992 memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
813 sizeof(dump_info->fw_human_readable)); 993 sizeof(dump_info->fw_human_readable));
814 strncpy(dump_info->dev_human_readable, mvm->cfg->name, 994 strncpy(dump_info->dev_human_readable, mvm->cfg->name,
@@ -817,28 +997,39 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
817 sizeof(dump_info->bus_human_readable)); 997 sizeof(dump_info->bus_human_readable));
818 998
819 dump_data = iwl_fw_error_next_data(dump_data); 999 dump_data = iwl_fw_error_next_data(dump_data);
820 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF); 1000 /* We only dump the FIFOs if the FW is in error state */
821 dump_data->len = cpu_to_le32(rxf_len); 1001 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status))
822 1002 iwl_mvm_dump_fifos(mvm, &dump_data);
823 if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) { 1003
824 u32 *rxf = (void *)dump_data->data; 1004 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
825 int i; 1005 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
1006 dump_mem = (void *)dump_data->data;
1007 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
1008 dump_mem->offset = cpu_to_le32(sram_ofs);
1009 iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_mem->data,
1010 sram_len);
826 1011
827 for (i = 0; i < (rxf_len / sizeof(u32)); i++) { 1012 if (smem_len) {
828 iwl_trans_write_prph(mvm->trans, 1013 dump_data = iwl_fw_error_next_data(dump_data);
829 RXF_LD_FENCE_OFFSET_ADDR, 1014 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
830 i * sizeof(u32)); 1015 dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem));
831 rxf[i] = iwl_trans_read_prph(mvm->trans, 1016 dump_mem = (void *)dump_data->data;
832 RXF_FIFO_RD_FENCE_ADDR); 1017 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SMEM);
833 } 1018 dump_mem->offset = cpu_to_le32(mvm->cfg->smem_offset);
834 iwl_trans_release_nic_access(mvm->trans, &flags); 1019 iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->smem_offset,
1020 dump_mem->data, smem_len);
835 } 1021 }
836 1022
837 dump_data = iwl_fw_error_next_data(dump_data); 1023 if (sram2_len) {
838 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM); 1024 dump_data = iwl_fw_error_next_data(dump_data);
839 dump_data->len = cpu_to_le32(sram_len); 1025 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
840 iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data, 1026 dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem));
841 sram_len); 1027 dump_mem = (void *)dump_data->data;
1028 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
1029 dump_mem->offset = cpu_to_le32(mvm->cfg->dccm2_offset);
1030 iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->dccm2_offset,
1031 dump_mem->data, sram2_len);
1032 }
842 1033
843 fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); 1034 fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
844 fw_error_dump->op_mode_len = file_len; 1035 fw_error_dump->op_mode_len = file_len;
@@ -859,6 +1050,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
859 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) 1050 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status))
860 iwl_mvm_fw_error_dump(mvm); 1051 iwl_mvm_fw_error_dump(mvm);
861 1052
1053 /* cleanup all stale references (scan, roc), but keep the
1054 * ucode_down ref until reconfig is complete
1055 */
1056 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
1057
862 iwl_trans_stop_device(mvm->trans); 1058 iwl_trans_stop_device(mvm->trans);
863 1059
864 mvm->scan_status = IWL_MVM_SCAN_NONE; 1060 mvm->scan_status = IWL_MVM_SCAN_NONE;
@@ -888,10 +1084,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
888 1084
889 ieee80211_wake_queues(mvm->hw); 1085 ieee80211_wake_queues(mvm->hw);
890 1086
891 /* cleanup all stale references (scan, roc), but keep the
892 * ucode_down ref until reconfig is complete */
893 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
894
895 /* clear any stale d0i3 state */ 1087 /* clear any stale d0i3 state */
896 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); 1088 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
897 1089
@@ -928,6 +1120,19 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
928 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1120 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
929 int ret; 1121 int ret;
930 1122
1123 /* Some hw restart cleanups must not hold the mutex */
1124 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1125 /*
1126 * Make sure we are out of d0i3. This is needed
1127 * to make sure the reference accounting is correct
1128 * (and there is no stale d0i3_exit_work).
1129 */
1130 wait_event_timeout(mvm->d0i3_exit_waitq,
1131 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1132 &mvm->status),
1133 HZ);
1134 }
1135
931 mutex_lock(&mvm->mutex); 1136 mutex_lock(&mvm->mutex);
932 ret = __iwl_mvm_mac_start(mvm); 1137 ret = __iwl_mvm_mac_start(mvm);
933 mutex_unlock(&mvm->mutex); 1138 mutex_unlock(&mvm->mutex);
@@ -977,6 +1182,13 @@ static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
977 IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n"); 1182 IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
978 _iwl_mvm_exit_d0i3(mvm); 1183 _iwl_mvm_exit_d0i3(mvm);
979 } 1184 }
1185
1186 if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND)
1187 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
1188 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1189 &mvm->status),
1190 HZ))
1191 WARN_ONCE(1, "D0i3 exit on resume timed out\n");
980} 1192}
981 1193
982static void 1194static void
@@ -1153,10 +1365,6 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1153 mvm->bf_allowed_vif = mvmvif; 1365 mvm->bf_allowed_vif = mvmvif;
1154 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 1366 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
1155 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 1367 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
1156 if (mvm->fw->ucode_capa.flags &
1157 IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
1158 !iwlwifi_mod_params.uapsd_disable)
1159 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
1160 } 1368 }
1161 1369
1162 /* 1370 /*
@@ -2087,7 +2295,7 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
2087 struct ieee80211_sta *sta) 2295 struct ieee80211_sta *sta)
2088{ 2296{
2089 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2297 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2090 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 2298 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
2091 2299
2092 /* 2300 /*
2093 * This is called before mac80211 does RCU synchronisation, 2301 * This is called before mac80211 does RCU synchronisation,
@@ -2104,6 +2312,20 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
2104 mutex_unlock(&mvm->mutex); 2312 mutex_unlock(&mvm->mutex);
2105} 2313}
2106 2314
2315static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2316 const u8 *bssid)
2317{
2318 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
2319 return;
2320
2321 if (iwlwifi_mod_params.uapsd_disable) {
2322 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2323 return;
2324 }
2325
2326 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
2327}
2328
2107static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 2329static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2108 struct ieee80211_vif *vif, 2330 struct ieee80211_vif *vif,
2109 struct ieee80211_sta *sta, 2331 struct ieee80211_sta *sta,
@@ -2163,6 +2385,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2163 * Reset EBS status here assuming environment has been changed. 2385 * Reset EBS status here assuming environment has been changed.
2164 */ 2386 */
2165 mvm->last_ebs_successful = true; 2387 mvm->last_ebs_successful = true;
2388 iwl_mvm_check_uapsd(mvm, vif, sta->addr);
2166 ret = 0; 2389 ret = 0;
2167 } else if (old_state == IEEE80211_STA_AUTH && 2390 } else if (old_state == IEEE80211_STA_AUTH &&
2168 new_state == IEEE80211_STA_ASSOC) { 2391 new_state == IEEE80211_STA_ASSOC) {
@@ -3102,7 +3325,7 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
3102 bool set) 3325 bool set)
3103{ 3326{
3104 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 3327 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3105 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 3328 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
3106 3329
3107 if (!mvm_sta || !mvm_sta->vif) { 3330 if (!mvm_sta || !mvm_sta->vif) {
3108 IWL_ERR(mvm, "Station is not associated to a vif\n"); 3331 IWL_ERR(mvm, "Station is not associated to a vif\n");
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index d24660fb4ef2..979ac23522f2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -276,6 +276,7 @@ enum iwl_mvm_ref_type {
276 IWL_MVM_REF_TM_CMD, 276 IWL_MVM_REF_TM_CMD,
277 IWL_MVM_REF_EXIT_WORK, 277 IWL_MVM_REF_EXIT_WORK,
278 IWL_MVM_REF_PROTECT_CSA, 278 IWL_MVM_REF_PROTECT_CSA,
279 IWL_MVM_REF_FW_DBG_COLLECT,
279 280
280 /* update debugfs.c when changing this */ 281 /* update debugfs.c when changing this */
281 282
@@ -535,6 +536,18 @@ enum iwl_mvm_tdls_cs_state {
535 IWL_MVM_TDLS_SW_ACTIVE, 536 IWL_MVM_TDLS_SW_ACTIVE,
536}; 537};
537 538
539struct iwl_mvm_shared_mem_cfg {
540 u32 shared_mem_addr;
541 u32 shared_mem_size;
542 u32 sample_buff_addr;
543 u32 sample_buff_size;
544 u32 txfifo_addr;
545 u32 txfifo_size[TX_FIFO_MAX_NUM];
546 u32 rxfifo_size[RX_FIFO_MAX_NUM];
547 u32 page_buff_addr;
548 u32 page_buff_size;
549};
550
538struct iwl_mvm { 551struct iwl_mvm {
539 /* for logger access */ 552 /* for logger access */
540 struct device *dev; 553 struct device *dev;
@@ -641,6 +654,8 @@ struct iwl_mvm {
641 bool disable_power_off; 654 bool disable_power_off;
642 bool disable_power_off_d3; 655 bool disable_power_off_d3;
643 656
657 bool scan_iter_notif_enabled;
658
644 struct debugfs_blob_wrapper nvm_hw_blob; 659 struct debugfs_blob_wrapper nvm_hw_blob;
645 struct debugfs_blob_wrapper nvm_sw_blob; 660 struct debugfs_blob_wrapper nvm_sw_blob;
646 struct debugfs_blob_wrapper nvm_calib_blob; 661 struct debugfs_blob_wrapper nvm_calib_blob;
@@ -784,6 +799,8 @@ struct iwl_mvm {
784 u32 ch_sw_tm_ie; 799 u32 ch_sw_tm_ie;
785 } peer; 800 } peer;
786 } tdls_cs; 801 } tdls_cs;
802
803 struct iwl_mvm_shared_mem_cfg shared_mem_cfg;
787}; 804};
788 805
789/* Extract MVM priv from op_mode and _hw */ 806/* Extract MVM priv from op_mode and _hw */
@@ -850,12 +867,14 @@ iwl_mvm_sta_from_staid_protected(struct iwl_mvm *mvm, u8 sta_id)
850static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm) 867static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
851{ 868{
852 return mvm->trans->cfg->d0i3 && 869 return mvm->trans->cfg->d0i3 &&
870 mvm->trans->d0i3_mode != IWL_D0I3_MODE_OFF &&
871 !iwlwifi_mod_params.d0i3_disable &&
853 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT); 872 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
854} 873}
855 874
856static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm) 875static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
857{ 876{
858 return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_DQA_SUPPORT; 877 return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_API_SCD_CFG;
859} 878}
860 879
861extern const u8 iwl_mvm_ac_to_tx_fifo[]; 880extern const u8 iwl_mvm_ac_to_tx_fifo[];
@@ -937,6 +956,33 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
937int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); 956int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
938int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm); 957int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
939 958
959static inline u8 iwl_mvm_get_valid_tx_ant(struct iwl_mvm *mvm)
960{
961 return mvm->nvm_data && mvm->nvm_data->valid_tx_ant ?
962 mvm->fw->valid_tx_ant & mvm->nvm_data->valid_tx_ant :
963 mvm->fw->valid_tx_ant;
964}
965
966static inline u8 iwl_mvm_get_valid_rx_ant(struct iwl_mvm *mvm)
967{
968 return mvm->nvm_data && mvm->nvm_data->valid_rx_ant ?
969 mvm->fw->valid_rx_ant & mvm->nvm_data->valid_rx_ant :
970 mvm->fw->valid_rx_ant;
971}
972
973static inline u32 iwl_mvm_get_phy_config(struct iwl_mvm *mvm)
974{
975 u32 phy_config = ~(FW_PHY_CFG_TX_CHAIN |
976 FW_PHY_CFG_RX_CHAIN);
977 u32 valid_rx_ant = iwl_mvm_get_valid_rx_ant(mvm);
978 u32 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
979
980 phy_config |= valid_tx_ant << FW_PHY_CFG_TX_CHAIN_POS |
981 valid_rx_ant << FW_PHY_CFG_RX_CHAIN_POS;
982
983 return mvm->fw->phy_config & phy_config;
984}
985
940int iwl_mvm_up(struct iwl_mvm *mvm); 986int iwl_mvm_up(struct iwl_mvm *mvm);
941int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm); 987int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
942 988
@@ -970,6 +1016,9 @@ int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
970 struct iwl_device_cmd *cmd); 1016 struct iwl_device_cmd *cmd);
971int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 1017int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
972 struct iwl_device_cmd *cmd); 1018 struct iwl_device_cmd *cmd);
1019int iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
1020 struct iwl_rx_cmd_buffer *rxb,
1021 struct iwl_device_cmd *cmd);
973 1022
974/* MVM PHY */ 1023/* MVM PHY */
975int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 1024int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
@@ -1031,6 +1080,9 @@ int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm, bool is_sched_scan);
1031int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, 1080int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
1032 struct iwl_rx_cmd_buffer *rxb, 1081 struct iwl_rx_cmd_buffer *rxb,
1033 struct iwl_device_cmd *cmd); 1082 struct iwl_device_cmd *cmd);
1083int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
1084 struct iwl_rx_cmd_buffer *rxb,
1085 struct iwl_device_cmd *cmd);
1034int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 1086int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
1035 struct ieee80211_vif *vif, 1087 struct ieee80211_vif *vif,
1036 struct cfg80211_sched_scan_request *req, 1088 struct cfg80211_sched_scan_request *req,
@@ -1091,9 +1143,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1091 1143
1092/* rate scaling */ 1144/* rate scaling */
1093int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); 1145int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
1094void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, 1146void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
1095 struct iwl_mvm_frame_stats *stats,
1096 u32 rate, bool agg);
1097int rs_pretty_print_rate(char *buf, const u32 rate); 1147int rs_pretty_print_rate(char *buf, const u32 rate);
1098void rs_update_last_rssi(struct iwl_mvm *mvm, 1148void rs_update_last_rssi(struct iwl_mvm *mvm,
1099 struct iwl_lq_sta *lq_sta, 1149 struct iwl_lq_sta *lq_sta,
@@ -1159,6 +1209,8 @@ void iwl_mvm_unref(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
1159int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type); 1209int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
1160bool iwl_mvm_ref_taken(struct iwl_mvm *mvm); 1210bool iwl_mvm_ref_taken(struct iwl_mvm *mvm);
1161void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); 1211void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
1212int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode);
1213int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode);
1162int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); 1214int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
1163 1215
1164/* BT Coex */ 1216/* BT Coex */
@@ -1261,7 +1313,7 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
1261/* hw scheduler queue config */ 1313/* hw scheduler queue config */
1262void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 1314void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
1263 const struct iwl_trans_txq_scd_cfg *cfg); 1315 const struct iwl_trans_txq_scd_cfg *cfg);
1264void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue); 1316void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags);
1265 1317
1266static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, 1318static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1267 u8 fifo) 1319 u8 fifo)
@@ -1344,4 +1396,7 @@ struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
1344void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); 1396void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1345void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); 1397void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
1346 1398
1399int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id);
1400void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm);
1401
1347#endif /* __IWL_MVM_H__ */ 1402#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index d55fd8e3654c..5383429d96c1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -356,7 +356,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
356 max_section_size = IWL_MAX_NVM_SECTION_SIZE; 356 max_section_size = IWL_MAX_NVM_SECTION_SIZE;
357 else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) 357 else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
358 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; 358 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE;
359 else /* Family 8000 B-step */ 359 else /* Family 8000 B-step or C-step */
360 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; 360 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE;
361 361
362 /* 362 /*
@@ -565,6 +565,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
565 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 565 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
566 if (!mvm->nvm_data) 566 if (!mvm->nvm_data)
567 return -ENODATA; 567 return -ENODATA;
568 IWL_DEBUG_EEPROM(mvm->trans->dev, "nvm version = %x\n",
569 mvm->nvm_data->nvm_version);
568 570
569 return 0; 571 return 0;
570} 572}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 97dfba50c682..8bf8c2a29e5e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -84,15 +84,8 @@
84#include "time-event.h" 84#include "time-event.h"
85#include "iwl-fw-error-dump.h" 85#include "iwl-fw-error-dump.h"
86 86
87/*
88 * module name, copyright, version, etc.
89 */
90#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" 87#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
91
92#define DRV_VERSION IWLWIFI_VERSION
93
94MODULE_DESCRIPTION(DRV_DESCRIPTION); 88MODULE_DESCRIPTION(DRV_DESCRIPTION);
95MODULE_VERSION(DRV_VERSION);
96MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); 89MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
97MODULE_LICENSE("GPL"); 90MODULE_LICENSE("GPL");
98 91
@@ -146,13 +139,14 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
146 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 139 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
147 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 140 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
148 u32 reg_val = 0; 141 u32 reg_val = 0;
142 u32 phy_config = iwl_mvm_get_phy_config(mvm);
149 143
150 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >> 144 radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
151 FW_PHY_CFG_RADIO_TYPE_POS; 145 FW_PHY_CFG_RADIO_TYPE_POS;
152 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >> 146 radio_cfg_step = (phy_config & FW_PHY_CFG_RADIO_STEP) >>
153 FW_PHY_CFG_RADIO_STEP_POS; 147 FW_PHY_CFG_RADIO_STEP_POS;
154 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >> 148 radio_cfg_dash = (phy_config & FW_PHY_CFG_RADIO_DASH) >>
155 FW_PHY_CFG_RADIO_DASH_POS; 149 FW_PHY_CFG_RADIO_DASH_POS;
156 150
157 /* SKU control */ 151 /* SKU control */
158 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 152 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -240,6 +234,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
240 234
241 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 235 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
242 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), 236 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
237 RX_HANDLER(SCAN_ITERATION_COMPLETE,
238 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
243 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 239 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
244 iwl_mvm_rx_scan_offload_complete_notif, true), 240 iwl_mvm_rx_scan_offload_complete_notif, true),
245 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results, 241 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
@@ -274,6 +270,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
274 CMD(MGMT_MCAST_KEY), 270 CMD(MGMT_MCAST_KEY),
275 CMD(TX_CMD), 271 CMD(TX_CMD),
276 CMD(TXPATH_FLUSH), 272 CMD(TXPATH_FLUSH),
273 CMD(SHARED_MEM_CFG),
277 CMD(MAC_CONTEXT_CMD), 274 CMD(MAC_CONTEXT_CMD),
278 CMD(TIME_EVENT_CMD), 275 CMD(TIME_EVENT_CMD),
279 CMD(TIME_EVENT_NOTIFICATION), 276 CMD(TIME_EVENT_NOTIFICATION),
@@ -487,6 +484,8 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
487 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; 484 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
488 trans_cfg.scd_set_active = true; 485 trans_cfg.scd_set_active = true;
489 486
487 trans_cfg.sdio_adma_addr = fw->sdio_adma_addr;
488
490 snprintf(mvm->hw->wiphy->fw_version, 489 snprintf(mvm->hw->wiphy->fw_version,
491 sizeof(mvm->hw->wiphy->fw_version), 490 sizeof(mvm->hw->wiphy->fw_version),
492 "%s", fw->fw_version); 491 "%s", fw->fw_version);
@@ -517,10 +516,15 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
517 min_backoff = calc_min_backoff(trans, cfg); 516 min_backoff = calc_min_backoff(trans, cfg);
518 iwl_mvm_tt_initialize(mvm, min_backoff); 517 iwl_mvm_tt_initialize(mvm, min_backoff);
519 /* set the nvm_file_name according to priority */ 518 /* set the nvm_file_name according to priority */
520 if (iwlwifi_mod_params.nvm_file) 519 if (iwlwifi_mod_params.nvm_file) {
521 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; 520 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
522 else 521 } else {
523 mvm->nvm_file_name = mvm->cfg->default_nvm_file; 522 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
523 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
524 mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A;
525 else
526 mvm->nvm_file_name = mvm->cfg->default_nvm_file;
527 }
524 528
525 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, 529 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name,
526 "not allowing power-up and not having nvm_file\n")) 530 "not allowing power-up and not having nvm_file\n"))
@@ -817,9 +821,20 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
817 struct iwl_mvm *mvm = 821 struct iwl_mvm *mvm =
818 container_of(work, struct iwl_mvm, fw_error_dump_wk); 822 container_of(work, struct iwl_mvm, fw_error_dump_wk);
819 823
824 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
825 return;
826
820 mutex_lock(&mvm->mutex); 827 mutex_lock(&mvm->mutex);
821 iwl_mvm_fw_error_dump(mvm); 828 iwl_mvm_fw_error_dump(mvm);
829
830 /* start recording again if the firmware is not crashed */
831 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
832 mvm->fw->dbg_dest_tlv &&
833 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
834
822 mutex_unlock(&mvm->mutex); 835 mutex_unlock(&mvm->mutex);
836
837 iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
823} 838}
824 839
825void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) 840void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
@@ -1031,7 +1046,8 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1031out: 1046out:
1032 rcu_read_unlock(); 1047 rcu_read_unlock();
1033} 1048}
1034static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) 1049
1050int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1035{ 1051{
1036 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1052 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1037 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE; 1053 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
@@ -1047,6 +1063,7 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1047 }; 1063 };
1048 struct iwl_d3_manager_config d3_cfg_cmd = { 1064 struct iwl_d3_manager_config d3_cfg_cmd = {
1049 .min_sleep_time = cpu_to_le32(1000), 1065 .min_sleep_time = cpu_to_le32(1000),
1066 .wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
1050 }; 1067 };
1051 1068
1052 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n"); 1069 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
@@ -1146,7 +1163,7 @@ void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
1146 1163
1147 if (mvm->d0i3_offloading && qos_seq) { 1164 if (mvm->d0i3_offloading && qos_seq) {
1148 /* update qos seq numbers if offloading was enabled */ 1165 /* update qos seq numbers if offloading was enabled */
1149 mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv; 1166 mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
1150 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1167 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1151 u16 seq = le16_to_cpu(qos_seq[i]); 1168 u16 seq = le16_to_cpu(qos_seq[i]);
1152 /* firmware stores last-used one, we store next one */ 1169 /* firmware stores last-used one, we store next one */
@@ -1245,7 +1262,7 @@ out:
1245 return ret; 1262 return ret;
1246} 1263}
1247 1264
1248static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) 1265int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
1249{ 1266{
1250 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1267 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1251 1268
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 1c0d4a45c1a8..5b43616eeb06 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -170,13 +170,13 @@ static void iwl_mvm_phy_ctxt_cmd_data(struct iwl_mvm *mvm,
170 active_cnt = 2; 170 active_cnt = 2;
171 } 171 }
172 172
173 cmd->rxchain_info = cpu_to_le32(mvm->fw->valid_rx_ant << 173 cmd->rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) <<
174 PHY_RX_CHAIN_VALID_POS); 174 PHY_RX_CHAIN_VALID_POS);
175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); 175 cmd->rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS);
176 cmd->rxchain_info |= cpu_to_le32(active_cnt << 176 cmd->rxchain_info |= cpu_to_le32(active_cnt <<
177 PHY_RX_CHAIN_MIMO_CNT_POS); 177 PHY_RX_CHAIN_MIMO_CNT_POS);
178 178
179 cmd->txchain_info = cpu_to_le32(mvm->fw->valid_tx_ant); 179 cmd->txchain_info = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
180} 180}
181 181
182/* 182/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 30ceb67ed7a7..9f32f2db95bd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -42,25 +42,12 @@
42 42
43#define RS_NAME "iwl-mvm-rs" 43#define RS_NAME "iwl-mvm-rs"
44 44
45#define NUM_TRY_BEFORE_ANT_TOGGLE 1
46#define RS_LEGACY_RETRIES_PER_RATE 1
47#define RS_HT_VHT_RETRIES_PER_RATE 2
48#define RS_HT_VHT_RETRIES_PER_RATE_TW 1
49#define RS_INITIAL_MIMO_NUM_RATES 3
50#define RS_INITIAL_SISO_NUM_RATES 3
51#define RS_INITIAL_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
52#define RS_SECONDARY_LEGACY_NUM_RATES LINK_QUAL_MAX_RETRY_NUM
53#define RS_SECONDARY_SISO_NUM_RATES 3
54#define RS_SECONDARY_SISO_RETRIES 1
55
56#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */ 45#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
57#define IWL_RATE_MIN_FAILURE_TH 3 /* min failures to calc tpt */
58#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
59 46
60/* max allowed rate miss before sync LQ cmd */ 47/* Calculations of success ratio are done in fixed point where 12800 is 100%.
61#define IWL_MISSED_RATE_MAX 15 48 * Use this macro when dealing with thresholds consts set as a percentage
62#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ) 49 */
63#define RS_IDLE_TIMEOUT (5*HZ) 50#define RS_PERCENT(x) (128 * x)
64 51
65static u8 rs_ht_to_legacy[] = { 52static u8 rs_ht_to_legacy[] = {
66 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, 53 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
@@ -173,7 +160,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
173 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 160 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
174 return false; 161 return false;
175 162
176 if (num_of_ant(mvm->fw->valid_tx_ant) < 2) 163 if (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) < 2)
177 return false; 164 return false;
178 165
179 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 166 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
@@ -613,7 +600,8 @@ static s32 get_expected_tpt(struct iwl_scale_tbl_info *tbl, int rs_index)
613 * at this rate. window->data contains the bitmask of successful 600 * at this rate. window->data contains the bitmask of successful
614 * packets. 601 * packets.
615 */ 602 */
616static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, 603static int _rs_collect_tx_data(struct iwl_mvm *mvm,
604 struct iwl_scale_tbl_info *tbl,
617 int scale_index, int attempts, int successes, 605 int scale_index, int attempts, int successes,
618 struct iwl_rate_scale_data *window) 606 struct iwl_rate_scale_data *window)
619{ 607{
@@ -668,8 +656,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
668 fail_count = window->counter - window->success_counter; 656 fail_count = window->counter - window->success_counter;
669 657
670 /* Calculate average throughput, if we have enough history. */ 658 /* Calculate average throughput, if we have enough history. */
671 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || 659 if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) ||
672 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) 660 (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH))
673 window->average_tpt = (window->success_ratio * tpt + 64) / 128; 661 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
674 else 662 else
675 window->average_tpt = IWL_INVALID_VALUE; 663 window->average_tpt = IWL_INVALID_VALUE;
@@ -677,7 +665,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
677 return 0; 665 return 0;
678} 666}
679 667
680static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta, 668static int rs_collect_tx_data(struct iwl_mvm *mvm,
669 struct iwl_lq_sta *lq_sta,
681 struct iwl_scale_tbl_info *tbl, 670 struct iwl_scale_tbl_info *tbl,
682 int scale_index, int attempts, int successes, 671 int scale_index, int attempts, int successes,
683 u8 reduced_txp) 672 u8 reduced_txp)
@@ -698,7 +687,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
698 /* Select window for current tx bit rate */ 687 /* Select window for current tx bit rate */
699 window = &(tbl->win[scale_index]); 688 window = &(tbl->win[scale_index]);
700 689
701 ret = _rs_collect_tx_data(tbl, scale_index, attempts, successes, 690 ret = _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
702 window); 691 window);
703 if (ret) 692 if (ret)
704 return ret; 693 return ret;
@@ -707,7 +696,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
707 return -EINVAL; 696 return -EINVAL;
708 697
709 window = &tbl->tpc_win[reduced_txp]; 698 window = &tbl->tpc_win[reduced_txp];
710 return _rs_collect_tx_data(tbl, scale_index, attempts, successes, 699 return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
711 window); 700 window);
712} 701}
713 702
@@ -928,7 +917,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
928 break; 917 break;
929 if (rate_mask & (1 << low)) 918 if (rate_mask & (1 << low))
930 break; 919 break;
931 IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low);
932 } 920 }
933 921
934 high = index; 922 high = index;
@@ -938,7 +926,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
938 break; 926 break;
939 if (rate_mask & (1 << high)) 927 if (rate_mask & (1 << high))
940 break; 928 break;
941 IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high);
942 } 929 }
943 930
944 return (high << 8) | low; 931 return (high << 8) | low;
@@ -1004,7 +991,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
1004 } 991 }
1005 992
1006 if (num_of_ant(rate->ant) > 1) 993 if (num_of_ant(rate->ant) > 1)
1007 rate->ant = first_antenna(mvm->fw->valid_tx_ant); 994 rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
1008 995
1009 /* Relevant in both switching to SISO or Legacy */ 996 /* Relevant in both switching to SISO or Legacy */
1010 rate->sgi = false; 997 rate->sgi = false;
@@ -1125,7 +1112,8 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1125 } 1112 }
1126 1113
1127 if (time_after(jiffies, 1114 if (time_after(jiffies,
1128 (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) { 1115 (unsigned long)(lq_sta->last_tx +
1116 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
1129 int t; 1117 int t;
1130 1118
1131 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); 1119 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
@@ -1158,7 +1146,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1158 * ... driver. 1146 * ... driver.
1159 */ 1147 */
1160 lq_sta->missed_rate_counter++; 1148 lq_sta->missed_rate_counter++;
1161 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 1149 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
1162 lq_sta->missed_rate_counter = 0; 1150 lq_sta->missed_rate_counter = 0;
1163 IWL_DEBUG_RATE(mvm, 1151 IWL_DEBUG_RATE(mvm,
1164 "Too many rates mismatch. Send sync LQ. rs_state %d\n", 1152 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
@@ -1213,7 +1201,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1213 1201
1214 ucode_rate = le32_to_cpu(table->rs_table[0]); 1202 ucode_rate = le32_to_cpu(table->rs_table[0]);
1215 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate); 1203 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1216 rs_collect_tx_data(lq_sta, curr_tbl, rate.index, 1204 rs_collect_tx_data(mvm, lq_sta, curr_tbl, rate.index,
1217 info->status.ampdu_len, 1205 info->status.ampdu_len,
1218 info->status.ampdu_ack_len, 1206 info->status.ampdu_ack_len,
1219 reduced_txp); 1207 reduced_txp);
@@ -1249,7 +1237,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1249 else 1237 else
1250 continue; 1238 continue;
1251 1239
1252 rs_collect_tx_data(lq_sta, tmp_tbl, rate.index, 1, 1240 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, rate.index, 1,
1253 i < retries ? 0 : legacy_success, 1241 i < retries ? 0 : legacy_success,
1254 reduced_txp); 1242 reduced_txp);
1255 } 1243 }
@@ -1303,13 +1291,13 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1303 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n"); 1291 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
1304 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; 1292 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
1305 if (is_legacy) { 1293 if (is_legacy) {
1306 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; 1294 lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT;
1307 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 1295 lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT;
1308 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT; 1296 lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT;
1309 } else { 1297 } else {
1310 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT; 1298 lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT;
1311 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT; 1299 lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT;
1312 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT; 1300 lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT;
1313 } 1301 }
1314 lq_sta->table_count = 0; 1302 lq_sta->table_count = 0;
1315 lq_sta->total_failed = 0; 1303 lq_sta->total_failed = 0;
@@ -1318,6 +1306,13 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1318 lq_sta->visited_columns = 0; 1306 lq_sta->visited_columns = 0;
1319} 1307}
1320 1308
1309static inline int rs_get_max_rate_from_mask(unsigned long rate_mask)
1310{
1311 if (rate_mask)
1312 return find_last_bit(&rate_mask, BITS_PER_LONG);
1313 return IWL_RATE_INVALID;
1314}
1315
1321static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta, 1316static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
1322 const struct rs_tx_column *column) 1317 const struct rs_tx_column *column)
1323{ 1318{
@@ -1420,7 +1415,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1420 u32 target_tpt; 1415 u32 target_tpt;
1421 int rate_idx; 1416 int rate_idx;
1422 1417
1423 if (success_ratio > RS_SR_NO_DECREASE) { 1418 if (success_ratio > IWL_MVM_RS_SR_NO_DECREASE) {
1424 target_tpt = 100 * expected_current_tpt; 1419 target_tpt = 100 * expected_current_tpt;
1425 IWL_DEBUG_RATE(mvm, 1420 IWL_DEBUG_RATE(mvm,
1426 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n", 1421 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n",
@@ -1488,7 +1483,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1488 flush_interval_passed = 1483 flush_interval_passed =
1489 time_after(jiffies, 1484 time_after(jiffies,
1490 (unsigned long)(lq_sta->flush_timer + 1485 (unsigned long)(lq_sta->flush_timer +
1491 RS_STAY_IN_COLUMN_TIMEOUT)); 1486 (IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * HZ)));
1492 1487
1493 /* 1488 /*
1494 * Check if we should allow search for new modulation mode. 1489 * Check if we should allow search for new modulation mode.
@@ -1567,7 +1562,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1567 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; 1562 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1568 const struct rs_tx_column *next_col; 1563 const struct rs_tx_column *next_col;
1569 allow_column_func_t allow_func; 1564 allow_column_func_t allow_func;
1570 u8 valid_ants = mvm->fw->valid_tx_ant; 1565 u8 valid_ants = iwl_mvm_get_valid_tx_ant(mvm);
1571 const u16 *expected_tpt_tbl; 1566 const u16 *expected_tpt_tbl;
1572 u16 tpt, max_expected_tpt; 1567 u16 tpt, max_expected_tpt;
1573 1568
@@ -1613,8 +1608,12 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1613 continue; 1608 continue;
1614 1609
1615 max_rate = rs_get_max_allowed_rate(lq_sta, next_col); 1610 max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
1616 if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID)) 1611 if (max_rate == IWL_RATE_INVALID) {
1612 IWL_DEBUG_RATE(mvm,
1613 "Skip column %d: no rate is allowed in this column\n",
1614 next_col_id);
1617 continue; 1615 continue;
1616 }
1618 1617
1619 max_expected_tpt = expected_tpt_tbl[max_rate]; 1618 max_expected_tpt = expected_tpt_tbl[max_rate];
1620 if (tpt >= max_expected_tpt) { 1619 if (tpt >= max_expected_tpt) {
@@ -1724,7 +1723,8 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1724{ 1723{
1725 enum rs_action action = RS_ACTION_STAY; 1724 enum rs_action action = RS_ACTION_STAY;
1726 1725
1727 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { 1726 if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) ||
1727 (current_tpt == 0)) {
1728 IWL_DEBUG_RATE(mvm, 1728 IWL_DEBUG_RATE(mvm,
1729 "Decrease rate because of low SR\n"); 1729 "Decrease rate because of low SR\n");
1730 return RS_ACTION_DOWNSCALE; 1730 return RS_ACTION_DOWNSCALE;
@@ -1783,7 +1783,7 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1783 1783
1784out: 1784out:
1785 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { 1785 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
1786 if (sr >= RS_SR_NO_DECREASE) { 1786 if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) {
1787 IWL_DEBUG_RATE(mvm, 1787 IWL_DEBUG_RATE(mvm,
1788 "SR is above NO DECREASE. Avoid downscale\n"); 1788 "SR is above NO DECREASE. Avoid downscale\n");
1789 action = RS_ACTION_STAY; 1789 action = RS_ACTION_STAY;
@@ -1802,20 +1802,12 @@ out:
1802static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 1802static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1803 struct iwl_lq_sta *lq_sta) 1803 struct iwl_lq_sta *lq_sta)
1804{ 1804{
1805 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1806 struct ieee80211_vif *vif = mvmsta->vif;
1807 bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION &&
1808 !vif->bss_conf.ps);
1809
1810 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which 1805 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which
1811 * supports STBC of at least 1*SS 1806 * supports STBC of at least 1*SS
1812 */ 1807 */
1813 if (!lq_sta->stbc) 1808 if (!lq_sta->stbc)
1814 return false; 1809 return false;
1815 1810
1816 if (!mvm->ps_disabled && !sta_ps_disabled)
1817 return false;
1818
1819 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 1811 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
1820 return false; 1812 return false;
1821 1813
@@ -1825,11 +1817,11 @@ static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1825static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index, 1817static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,
1826 int *weaker, int *stronger) 1818 int *weaker, int *stronger)
1827{ 1819{
1828 *weaker = index + TPC_TX_POWER_STEP; 1820 *weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP;
1829 if (*weaker > TPC_MAX_REDUCTION) 1821 if (*weaker > TPC_MAX_REDUCTION)
1830 *weaker = TPC_INVALID; 1822 *weaker = TPC_INVALID;
1831 1823
1832 *stronger = index - TPC_TX_POWER_STEP; 1824 *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP;
1833 if (*stronger < 0) 1825 if (*stronger < 0)
1834 *stronger = TPC_INVALID; 1826 *stronger = TPC_INVALID;
1835} 1827}
@@ -1885,7 +1877,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
1885 } 1877 }
1886 1878
1887 /* Too many failures, increase txp */ 1879 /* Too many failures, increase txp */
1888 if (sr <= TPC_SR_FORCE_INCREASE || current_tpt == 0) { 1880 if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) ||
1881 current_tpt == 0) {
1889 IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n"); 1882 IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n");
1890 return TPC_ACTION_NO_RESTIRCTION; 1883 return TPC_ACTION_NO_RESTIRCTION;
1891 } 1884 }
@@ -1908,7 +1901,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
1908 } 1901 }
1909 1902
1910 /* next, increase if needed */ 1903 /* next, increase if needed */
1911 if (sr < TPC_SR_NO_INCREASE && strong != TPC_INVALID) { 1904 if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) &&
1905 strong != TPC_INVALID) {
1912 if (weak_tpt == IWL_INVALID_VALUE && 1906 if (weak_tpt == IWL_INVALID_VALUE &&
1913 strong_tpt != IWL_INVALID_VALUE && 1907 strong_tpt != IWL_INVALID_VALUE &&
1914 current_tpt < strong_tpt) { 1908 current_tpt < strong_tpt) {
@@ -1935,7 +1929,7 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
1935 struct iwl_lq_sta *lq_sta, 1929 struct iwl_lq_sta *lq_sta,
1936 struct iwl_scale_tbl_info *tbl) 1930 struct iwl_scale_tbl_info *tbl)
1937{ 1931{
1938 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1932 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1939 struct ieee80211_vif *vif = mvm_sta->vif; 1933 struct ieee80211_vif *vif = mvm_sta->vif;
1940 struct ieee80211_chanctx_conf *chanctx_conf; 1934 struct ieee80211_chanctx_conf *chanctx_conf;
1941 enum ieee80211_band band; 1935 enum ieee80211_band band;
@@ -2044,7 +2038,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2044 u16 high_low; 2038 u16 high_low;
2045 s32 sr; 2039 s32 sr;
2046 u8 prev_agg = lq_sta->is_agg; 2040 u8 prev_agg = lq_sta->is_agg;
2047 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 2041 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
2048 struct iwl_mvm_tid_data *tid_data; 2042 struct iwl_mvm_tid_data *tid_data;
2049 struct rs_rate *rate; 2043 struct rs_rate *rate;
2050 2044
@@ -2106,8 +2100,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2106 * in current association (use new rate found above). 2100 * in current association (use new rate found above).
2107 */ 2101 */
2108 fail_count = window->counter - window->success_counter; 2102 fail_count = window->counter - window->success_counter;
2109 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && 2103 if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) &&
2110 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 2104 (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) {
2111 IWL_DEBUG_RATE(mvm, 2105 IWL_DEBUG_RATE(mvm,
2112 "(%s: %d): Test Window: succ %d total %d\n", 2106 "(%s: %d): Test Window: succ %d total %d\n",
2113 rs_pretty_lq_type(rate->type), 2107 rs_pretty_lq_type(rate->type),
@@ -2385,7 +2379,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
2385 int i, nentries; 2379 int i, nentries;
2386 s8 best_rssi = S8_MIN; 2380 s8 best_rssi = S8_MIN;
2387 u8 best_ant = ANT_NONE; 2381 u8 best_ant = ANT_NONE;
2388 u8 valid_tx_ant = mvm->fw->valid_tx_ant; 2382 u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
2389 const struct rs_init_rate_info *initial_rates; 2383 const struct rs_init_rate_info *initial_rates;
2390 2384
2391 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { 2385 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {
@@ -2530,7 +2524,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2530static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, 2524static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2531 gfp_t gfp) 2525 gfp_t gfp)
2532{ 2526{
2533 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2527 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
2534 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate; 2528 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
2535 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 2529 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2536 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta; 2530 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
@@ -2606,68 +2600,116 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2606 } 2600 }
2607} 2601}
2608 2602
2603static void rs_ht_init(struct iwl_mvm *mvm,
2604 struct ieee80211_sta *sta,
2605 struct iwl_lq_sta *lq_sta,
2606 struct ieee80211_sta_ht_cap *ht_cap)
2607{
2608 /* active_siso_rate mask includes 9 MBits (bit 5),
2609 * and CCK (bits 0-3), supp_rates[] does not;
2610 * shift to convert format, force 9 MBits off.
2611 */
2612 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2613 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2614 lq_sta->active_siso_rate &= ~((u16)0x2);
2615 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2616
2617 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2618 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2619 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2620 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2621
2622 if (mvm->cfg->ht_params->ldpc &&
2623 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
2624 lq_sta->ldpc = true;
2625
2626 if (mvm->cfg->ht_params->stbc &&
2627 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2628 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
2629 lq_sta->stbc = true;
2630
2631 lq_sta->is_vht = false;
2632}
2633
2634static void rs_vht_init(struct iwl_mvm *mvm,
2635 struct ieee80211_sta *sta,
2636 struct iwl_lq_sta *lq_sta,
2637 struct ieee80211_sta_vht_cap *vht_cap)
2638{
2639 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2640
2641 if (mvm->cfg->ht_params->ldpc &&
2642 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
2643 lq_sta->ldpc = true;
2644
2645 if (mvm->cfg->ht_params->stbc &&
2646 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2647 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
2648 lq_sta->stbc = true;
2649
2650 lq_sta->is_vht = true;
2651}
2652
2609#ifdef CONFIG_IWLWIFI_DEBUGFS 2653#ifdef CONFIG_IWLWIFI_DEBUGFS
2610static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm, 2654static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
2611 struct iwl_mvm_frame_stats *stats)
2612{ 2655{
2613 spin_lock_bh(&mvm->drv_stats_lock); 2656 spin_lock_bh(&mvm->drv_stats_lock);
2614 memset(stats, 0, sizeof(*stats)); 2657 memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats));
2615 spin_unlock_bh(&mvm->drv_stats_lock); 2658 spin_unlock_bh(&mvm->drv_stats_lock);
2616} 2659}
2617 2660
2618void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, 2661void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg)
2619 struct iwl_mvm_frame_stats *stats,
2620 u32 rate, bool agg)
2621{ 2662{
2622 u8 nss = 0, mcs = 0; 2663 u8 nss = 0, mcs = 0;
2623 2664
2624 spin_lock(&mvm->drv_stats_lock); 2665 spin_lock(&mvm->drv_stats_lock);
2625 2666
2626 if (agg) 2667 if (agg)
2627 stats->agg_frames++; 2668 mvm->drv_rx_stats.agg_frames++;
2628 2669
2629 stats->success_frames++; 2670 mvm->drv_rx_stats.success_frames++;
2630 2671
2631 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { 2672 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2632 case RATE_MCS_CHAN_WIDTH_20: 2673 case RATE_MCS_CHAN_WIDTH_20:
2633 stats->bw_20_frames++; 2674 mvm->drv_rx_stats.bw_20_frames++;
2634 break; 2675 break;
2635 case RATE_MCS_CHAN_WIDTH_40: 2676 case RATE_MCS_CHAN_WIDTH_40:
2636 stats->bw_40_frames++; 2677 mvm->drv_rx_stats.bw_40_frames++;
2637 break; 2678 break;
2638 case RATE_MCS_CHAN_WIDTH_80: 2679 case RATE_MCS_CHAN_WIDTH_80:
2639 stats->bw_80_frames++; 2680 mvm->drv_rx_stats.bw_80_frames++;
2640 break; 2681 break;
2641 default: 2682 default:
2642 WARN_ONCE(1, "bad BW. rate 0x%x", rate); 2683 WARN_ONCE(1, "bad BW. rate 0x%x", rate);
2643 } 2684 }
2644 2685
2645 if (rate & RATE_MCS_HT_MSK) { 2686 if (rate & RATE_MCS_HT_MSK) {
2646 stats->ht_frames++; 2687 mvm->drv_rx_stats.ht_frames++;
2647 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK; 2688 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
2648 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1; 2689 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
2649 } else if (rate & RATE_MCS_VHT_MSK) { 2690 } else if (rate & RATE_MCS_VHT_MSK) {
2650 stats->vht_frames++; 2691 mvm->drv_rx_stats.vht_frames++;
2651 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; 2692 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2652 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> 2693 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
2653 RATE_VHT_MCS_NSS_POS) + 1; 2694 RATE_VHT_MCS_NSS_POS) + 1;
2654 } else { 2695 } else {
2655 stats->legacy_frames++; 2696 mvm->drv_rx_stats.legacy_frames++;
2656 } 2697 }
2657 2698
2658 if (nss == 1) 2699 if (nss == 1)
2659 stats->siso_frames++; 2700 mvm->drv_rx_stats.siso_frames++;
2660 else if (nss == 2) 2701 else if (nss == 2)
2661 stats->mimo2_frames++; 2702 mvm->drv_rx_stats.mimo2_frames++;
2662 2703
2663 if (rate & RATE_MCS_SGI_MSK) 2704 if (rate & RATE_MCS_SGI_MSK)
2664 stats->sgi_frames++; 2705 mvm->drv_rx_stats.sgi_frames++;
2665 else 2706 else
2666 stats->ngi_frames++; 2707 mvm->drv_rx_stats.ngi_frames++;
2667 2708
2668 stats->last_rates[stats->last_frame_idx] = rate; 2709 mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate;
2669 stats->last_frame_idx = (stats->last_frame_idx + 1) % 2710 mvm->drv_rx_stats.last_frame_idx =
2670 ARRAY_SIZE(stats->last_rates); 2711 (mvm->drv_rx_stats.last_frame_idx + 1) %
2712 ARRAY_SIZE(mvm->drv_rx_stats.last_rates);
2671 2713
2672 spin_unlock(&mvm->drv_stats_lock); 2714 spin_unlock(&mvm->drv_stats_lock);
2673} 2715}
@@ -2683,14 +2725,11 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2683 struct ieee80211_hw *hw = mvm->hw; 2725 struct ieee80211_hw *hw = mvm->hw;
2684 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2726 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2685 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 2727 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
2686 struct iwl_mvm_sta *sta_priv; 2728 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
2687 struct iwl_lq_sta *lq_sta; 2729 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
2688 struct ieee80211_supported_band *sband; 2730 struct ieee80211_supported_band *sband;
2689 unsigned long supp; /* must be unsigned long for for_each_set_bit */ 2731 unsigned long supp; /* must be unsigned long for for_each_set_bit */
2690 2732
2691 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2692 lq_sta = &sta_priv->lq_sta;
2693
2694 /* clear all non-persistent lq data */ 2733 /* clear all non-persistent lq data */
2695 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); 2734 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
2696 2735
@@ -2712,7 +2751,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2712 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2751 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2713 * after assoc.. */ 2752 * after assoc.. */
2714 2753
2715 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2754 lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX;
2716 lq_sta->band = sband->band; 2755 lq_sta->band = sband->band;
2717 /* 2756 /*
2718 * active legacy rates as per supported rates bitmap 2757 * active legacy rates as per supported rates bitmap
@@ -2723,57 +2762,23 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2723 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); 2762 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2724 2763
2725 /* TODO: should probably account for rx_highest for both HT/VHT */ 2764 /* TODO: should probably account for rx_highest for both HT/VHT */
2726 if (!vht_cap || !vht_cap->vht_supported) { 2765 if (!vht_cap || !vht_cap->vht_supported)
2727 /* active_siso_rate mask includes 9 MBits (bit 5), 2766 rs_ht_init(mvm, sta, lq_sta, ht_cap);
2728 * and CCK (bits 0-3), supp_rates[] does not; 2767 else
2729 * shift to convert format, force 9 MBits off. 2768 rs_vht_init(mvm, sta, lq_sta, vht_cap);
2730 */
2731 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2732 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2733 lq_sta->active_siso_rate &= ~((u16)0x2);
2734 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2735
2736 /* Same here */
2737 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2738 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2739 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2740 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2741
2742 lq_sta->is_vht = false;
2743 if (mvm->cfg->ht_params->ldpc &&
2744 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
2745 lq_sta->ldpc = true;
2746
2747 if (mvm->cfg->ht_params->stbc &&
2748 (num_of_ant(mvm->fw->valid_tx_ant) > 1) &&
2749 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
2750 lq_sta->stbc = true;
2751 } else {
2752 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2753 lq_sta->is_vht = true;
2754
2755 if (mvm->cfg->ht_params->ldpc &&
2756 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
2757 lq_sta->ldpc = true;
2758
2759 if (mvm->cfg->ht_params->stbc &&
2760 (num_of_ant(mvm->fw->valid_tx_ant) > 1) &&
2761 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
2762 lq_sta->stbc = true;
2763 }
2764 2769
2765 if (IWL_MVM_RS_DISABLE_MIMO) 2770 if (IWL_MVM_RS_DISABLE_P2P_MIMO && sta_priv->vif->p2p)
2766 lq_sta->active_mimo2_rate = 0; 2771 lq_sta->active_mimo2_rate = 0;
2767 2772
2768 lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, 2773 lq_sta->max_legacy_rate_idx =
2769 BITS_PER_LONG); 2774 rs_get_max_rate_from_mask(lq_sta->active_legacy_rate);
2770 lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate, 2775 lq_sta->max_siso_rate_idx =
2771 BITS_PER_LONG); 2776 rs_get_max_rate_from_mask(lq_sta->active_siso_rate);
2772 lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, 2777 lq_sta->max_mimo2_rate_idx =
2773 BITS_PER_LONG); 2778 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);
2774 2779
2775 IWL_DEBUG_RATE(mvm, 2780 IWL_DEBUG_RATE(mvm,
2776 "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n", 2781 "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d\n",
2777 lq_sta->active_legacy_rate, 2782 lq_sta->active_legacy_rate,
2778 lq_sta->active_siso_rate, 2783 lq_sta->active_siso_rate,
2779 lq_sta->active_mimo2_rate, 2784 lq_sta->active_mimo2_rate,
@@ -2785,14 +2790,14 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2785 2790
2786 /* These values will be overridden later */ 2791 /* These values will be overridden later */
2787 lq_sta->lq.single_stream_ant_msk = 2792 lq_sta->lq.single_stream_ant_msk =
2788 first_antenna(mvm->fw->valid_tx_ant); 2793 first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
2789 lq_sta->lq.dual_stream_ant_msk = ANT_AB; 2794 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2790 2795
2791 /* as default allow aggregation for all tids */ 2796 /* as default allow aggregation for all tids */
2792 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2797 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2793 lq_sta->is_agg = 0; 2798 lq_sta->is_agg = 0;
2794#ifdef CONFIG_IWLWIFI_DEBUGFS 2799#ifdef CONFIG_IWLWIFI_DEBUGFS
2795 iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats); 2800 iwl_mvm_reset_frame_stats(mvm);
2796#endif 2801#endif
2797 rs_initialize_lq(mvm, sta, lq_sta, band, init); 2802 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2798} 2803}
@@ -2861,12 +2866,13 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2861 int index = *rs_table_index; 2866 int index = *rs_table_index;
2862 2867
2863 for (i = 0; i < num_rates && index < end; i++) { 2868 for (i = 0; i < num_rates && index < end; i++) {
2864 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate)); 2869 for (j = 0; j < num_retries && index < end; j++, index++) {
2865 for (j = 0; j < num_retries && index < end; j++, index++) 2870 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm,
2871 rate));
2866 rs_table[index] = ucode_rate; 2872 rs_table[index] = ucode_rate;
2867 2873 if (toggle_ant)
2868 if (toggle_ant) 2874 rs_toggle_antenna(valid_tx_ant, rate);
2869 rs_toggle_antenna(valid_tx_ant, rate); 2875 }
2870 2876
2871 prev_rate_idx = rate->index; 2877 prev_rate_idx = rate->index;
2872 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); 2878 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);
@@ -2874,7 +2880,7 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2874 break; 2880 break;
2875 } 2881 }
2876 2882
2877 if (!bottom_reached) 2883 if (!bottom_reached && !is_legacy(rate))
2878 rate->index = prev_rate_idx; 2884 rate->index = prev_rate_idx;
2879 2885
2880 *rs_table_index = index; 2886 *rs_table_index = index;
@@ -2910,21 +2916,33 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2910 u8 valid_tx_ant = 0; 2916 u8 valid_tx_ant = 0;
2911 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; 2917 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
2912 bool toggle_ant = false; 2918 bool toggle_ant = false;
2919 bool stbc_allowed = false;
2913 2920
2914 memcpy(&rate, initial_rate, sizeof(rate)); 2921 memcpy(&rate, initial_rate, sizeof(rate));
2915 2922
2916 valid_tx_ant = mvm->fw->valid_tx_ant; 2923 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
2917 rate.stbc = rs_stbc_allow(mvm, sta, lq_sta); 2924
2925 stbc_allowed = rs_stbc_allow(mvm, sta, lq_sta);
2926 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) {
2927 u32 ss_params = RS_SS_PARAMS_VALID;
2928
2929 if (stbc_allowed)
2930 ss_params |= RS_SS_STBC_ALLOWED;
2931 lq_cmd->ss_params = cpu_to_le32(ss_params);
2932 } else {
2933 /* TODO: remove old API when min FW API hits 14 */
2934 rate.stbc = stbc_allowed;
2935 }
2918 2936
2919 if (is_siso(&rate)) { 2937 if (is_siso(&rate)) {
2920 num_rates = RS_INITIAL_SISO_NUM_RATES; 2938 num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;
2921 num_retries = RS_HT_VHT_RETRIES_PER_RATE; 2939 num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
2922 } else if (is_mimo(&rate)) { 2940 } else if (is_mimo(&rate)) {
2923 num_rates = RS_INITIAL_MIMO_NUM_RATES; 2941 num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES;
2924 num_retries = RS_HT_VHT_RETRIES_PER_RATE; 2942 num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
2925 } else { 2943 } else {
2926 num_rates = RS_INITIAL_LEGACY_NUM_RATES; 2944 num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES;
2927 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2945 num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES;
2928 toggle_ant = true; 2946 toggle_ant = true;
2929 } 2947 }
2930 2948
@@ -2935,12 +2953,12 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2935 rs_get_lower_rate_down_column(lq_sta, &rate); 2953 rs_get_lower_rate_down_column(lq_sta, &rate);
2936 2954
2937 if (is_siso(&rate)) { 2955 if (is_siso(&rate)) {
2938 num_rates = RS_SECONDARY_SISO_NUM_RATES; 2956 num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES;
2939 num_retries = RS_SECONDARY_SISO_RETRIES; 2957 num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES;
2940 lq_cmd->mimo_delim = index; 2958 lq_cmd->mimo_delim = index;
2941 } else if (is_legacy(&rate)) { 2959 } else if (is_legacy(&rate)) {
2942 num_rates = RS_SECONDARY_LEGACY_NUM_RATES; 2960 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
2943 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2961 num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
2944 } else { 2962 } else {
2945 WARN_ON_ONCE(1); 2963 WARN_ON_ONCE(1);
2946 } 2964 }
@@ -2953,8 +2971,8 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2953 2971
2954 rs_get_lower_rate_down_column(lq_sta, &rate); 2972 rs_get_lower_rate_down_column(lq_sta, &rate);
2955 2973
2956 num_rates = RS_SECONDARY_LEGACY_NUM_RATES; 2974 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
2957 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2975 num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
2958 2976
2959 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, 2977 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2960 num_rates, num_retries, valid_tx_ant, 2978 num_rates, num_retries, valid_tx_ant,
@@ -2971,9 +2989,9 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2971 struct iwl_mvm_sta *mvmsta; 2989 struct iwl_mvm_sta *mvmsta;
2972 struct iwl_mvm_vif *mvmvif; 2990 struct iwl_mvm_vif *mvmvif;
2973 2991
2974 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 2992 lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START;
2975 lq_cmd->agg_time_limit = 2993 lq_cmd->agg_time_limit =
2976 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 2994 cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT);
2977 2995
2978#ifdef CONFIG_MAC80211_DEBUGFS 2996#ifdef CONFIG_MAC80211_DEBUGFS
2979 if (lq_sta->pers.dbg_fixed_rate) { 2997 if (lq_sta->pers.dbg_fixed_rate) {
@@ -3167,9 +3185,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3167 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 3185 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
3168 lq_sta->pers.dbg_fixed_rate); 3186 lq_sta->pers.dbg_fixed_rate);
3169 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 3187 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
3170 (mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "", 3188 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
3171 (mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "", 3189 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
3172 (mvm->fw->valid_tx_ant & ANT_C) ? "ANT_C" : ""); 3190 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
3173 desc += sprintf(buff+desc, "lq type %s\n", 3191 desc += sprintf(buff+desc, "lq type %s\n",
3174 (is_legacy(rate)) ? "legacy" : 3192 (is_legacy(rate)) ? "legacy" :
3175 is_vht(rate) ? "VHT" : "HT"); 3193 is_vht(rate) ? "VHT" : "HT");
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index defd70a6d9e6..f8f5bf21cc38 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -137,42 +137,10 @@ enum {
137 137
138#define IWL_INVALID_VALUE -1 138#define IWL_INVALID_VALUE -1
139 139
140#define IWL_MIN_RSSI_VAL -100
141#define IWL_MAX_RSSI_VAL 0
142
143/* These values specify how many Tx frame attempts before
144 * searching for a new modulation mode */
145#define IWL_LEGACY_FAILURE_LIMIT 160
146#define IWL_LEGACY_SUCCESS_LIMIT 480
147#define IWL_LEGACY_TABLE_COUNT 160
148
149#define IWL_NONE_LEGACY_FAILURE_LIMIT 400
150#define IWL_NONE_LEGACY_SUCCESS_LIMIT 4500
151#define IWL_NONE_LEGACY_TABLE_COUNT 1500
152
153/* Success ratio (ACKed / attempted tx frames) values (perfect is 128 * 100) */
154#define IWL_RS_GOOD_RATIO 12800 /* 100% */
155#define IWL_RATE_SCALE_SWITCH 10880 /* 85% */
156#define IWL_RATE_HIGH_TH 10880 /* 85% */
157#define IWL_RATE_INCREASE_TH 6400 /* 50% */
158#define RS_SR_FORCE_DECREASE 1920 /* 15% */
159#define RS_SR_NO_DECREASE 10880 /* 85% */
160
161#define TPC_SR_FORCE_INCREASE 9600 /* 75% */
162#define TPC_SR_NO_INCREASE 10880 /* 85% */
163#define TPC_TX_POWER_STEP 3
164#define TPC_MAX_REDUCTION 15 140#define TPC_MAX_REDUCTION 15
165#define TPC_NO_REDUCTION 0 141#define TPC_NO_REDUCTION 0
166#define TPC_INVALID 0xff 142#define TPC_INVALID 0xff
167 143
168#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
169#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
170#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100)
171
172#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
173#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
174#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
175
176#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63) 144#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (63)
177#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63) 145#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (63)
178#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0) 146#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
@@ -181,14 +149,7 @@ enum {
181 149
182/* load per tid defines for A-MPDU activation */ 150/* load per tid defines for A-MPDU activation */
183#define IWL_AGG_TPT_THREHOLD 0 151#define IWL_AGG_TPT_THREHOLD 0
184#define IWL_AGG_LOAD_THRESHOLD 10
185#define IWL_AGG_ALL_TID 0xff 152#define IWL_AGG_ALL_TID 0xff
186#define TID_QUEUE_CELL_SPACING 50 /*mS */
187#define TID_QUEUE_MAX_SIZE 20
188#define TID_ROUND_VALUE 5 /* mS */
189
190#define TID_MAX_TIME_DIFF ((TID_QUEUE_MAX_SIZE - 1) * TID_QUEUE_CELL_SPACING)
191#define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y))
192 153
193enum iwl_table_type { 154enum iwl_table_type {
194 LQ_NONE, 155 LQ_NONE,
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index 94b6e7297a1e..f922131b4eab 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -407,7 +407,7 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
407 } 407 }
408 408
409#ifdef CONFIG_IWLWIFI_DEBUGFS 409#ifdef CONFIG_IWLWIFI_DEBUGFS
410 iwl_mvm_update_frame_stats(mvm, &mvm->drv_rx_stats, rate_n_flags, 410 iwl_mvm_update_frame_stats(mvm, rate_n_flags,
411 rx_status->flag & RX_FLAG_AMPDU_DETAILS); 411 rx_status->flag & RX_FLAG_AMPDU_DETAILS);
412#endif 412#endif
413 iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status, 413 iwl_mvm_pass_packet_to_mac80211(mvm, skb, hdr, len, ampdu_status,
@@ -511,13 +511,17 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
511{ 511{
512 struct iwl_rx_packet *pkt = rxb_addr(rxb); 512 struct iwl_rx_packet *pkt = rxb_addr(rxb);
513 struct iwl_notif_statistics *stats = (void *)&pkt->data; 513 struct iwl_notif_statistics *stats = (void *)&pkt->data;
514 struct mvm_statistics_general_common *common = &stats->general.common;
515 struct iwl_mvm_stat_data data = { 514 struct iwl_mvm_stat_data data = {
516 .stats = stats, 515 .stats = stats,
517 .mvm = mvm, 516 .mvm = mvm,
518 }; 517 };
519 518
520 iwl_mvm_tt_temp_changed(mvm, le32_to_cpu(common->temperature)); 519 /* Only handle rx statistics temperature changes if async temp
520 * notifications are not supported
521 */
522 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_ASYNC_DTM))
523 iwl_mvm_tt_temp_changed(mvm,
524 le32_to_cpu(stats->general.radio_temperature));
521 525
522 iwl_mvm_update_rx_statistics(mvm, stats); 526 iwl_mvm_update_rx_statistics(mvm, stats);
523 527
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index ec9a8e7bae1d..3bd5f34d3285 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -72,6 +72,8 @@
72 72
73#define IWL_PLCP_QUIET_THRESH 1 73#define IWL_PLCP_QUIET_THRESH 1
74#define IWL_ACTIVE_QUIET_TIME 10 74#define IWL_ACTIVE_QUIET_TIME 10
75#define IWL_DENSE_EBS_SCAN_RATIO 5
76#define IWL_SPARSE_EBS_SCAN_RATIO 1
75 77
76struct iwl_mvm_scan_params { 78struct iwl_mvm_scan_params {
77 u32 max_out_time; 79 u32 max_out_time;
@@ -97,7 +99,7 @@ static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
97{ 99{
98 if (mvm->scan_rx_ant != ANT_NONE) 100 if (mvm->scan_rx_ant != ANT_NONE)
99 return mvm->scan_rx_ant; 101 return mvm->scan_rx_ant;
100 return mvm->fw->valid_rx_ant; 102 return iwl_mvm_get_valid_rx_ant(mvm);
101} 103}
102 104
103static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 105static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
@@ -128,7 +130,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
128 u32 tx_ant; 130 u32 tx_ant;
129 131
130 mvm->scan_last_antenna_idx = 132 mvm->scan_last_antenna_idx =
131 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 133 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
132 mvm->scan_last_antenna_idx); 134 mvm->scan_last_antenna_idx);
133 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS; 135 tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
134 136
@@ -288,11 +290,11 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
288 struct ieee80211_vif *vif) 290 struct ieee80211_vif *vif)
289{ 291{
290 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 292 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
291 bool *global_bound = data; 293 int *global_cnt = data;
292 294
293 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt && 295 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
294 mvmvif->phy_ctxt->id < MAX_PHYS) 296 mvmvif->phy_ctxt->id < MAX_PHYS)
295 *global_bound = true; 297 *global_cnt += 1;
296} 298}
297 299
298static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 300static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
@@ -300,27 +302,31 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
300 int n_ssids, u32 flags, 302 int n_ssids, u32 flags,
301 struct iwl_mvm_scan_params *params) 303 struct iwl_mvm_scan_params *params)
302{ 304{
303 bool global_bound = false; 305 int global_cnt = 0;
304 enum ieee80211_band band; 306 enum ieee80211_band band;
305 u8 frag_passive_dwell = 0; 307 u8 frag_passive_dwell = 0;
306 308
307 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 309 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
308 IEEE80211_IFACE_ITER_NORMAL, 310 IEEE80211_IFACE_ITER_NORMAL,
309 iwl_mvm_scan_condition_iterator, 311 iwl_mvm_scan_condition_iterator,
310 &global_bound); 312 &global_cnt);
311 313
312 if (!global_bound) 314 if (!global_cnt)
313 goto not_bound; 315 goto not_bound;
314 316
315 params->suspend_time = 30; 317 params->suspend_time = 30;
316 params->max_out_time = 170; 318 params->max_out_time = 120;
317 319
318 if (iwl_mvm_low_latency(mvm)) { 320 if (iwl_mvm_low_latency(mvm)) {
319 if (mvm->fw->ucode_capa.api[0] & 321 if (mvm->fw->ucode_capa.api[0] &
320 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { 322 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
321 params->suspend_time = 105; 323 params->suspend_time = 105;
322 params->max_out_time = 70; 324 /*
323 frag_passive_dwell = 20; 325 * If there is more than one active interface make
326 * passive scan more fragmented.
327 */
328 frag_passive_dwell = (global_cnt < 2) ? 40 : 20;
329 params->max_out_time = frag_passive_dwell;
324 } else { 330 } else {
325 params->suspend_time = 120; 331 params->suspend_time = 120;
326 params->max_out_time = 120; 332 params->max_out_time = 120;
@@ -537,6 +543,19 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
537 return 0; 543 return 0;
538} 544}
539 545
546int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
547 struct iwl_rx_cmd_buffer *rxb,
548 struct iwl_device_cmd *cmd)
549{
550 struct iwl_rx_packet *pkt = rxb_addr(rxb);
551 struct iwl_scan_complete_notif *notif = (void *)pkt->data;
552
553 IWL_DEBUG_SCAN(mvm,
554 "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
555 notif->status, notif->scanned_channels);
556 return 0;
557}
558
540int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 559int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
541 struct iwl_device_cmd *cmd) 560 struct iwl_device_cmd *cmd)
542{ 561{
@@ -1105,6 +1124,12 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1105 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN, 1124 return iwl_umac_scan_stop(mvm, IWL_UMAC_SCAN_UID_SCHED_SCAN,
1106 notify); 1125 notify);
1107 1126
1127 if (mvm->scan_status == IWL_MVM_SCAN_NONE)
1128 return 0;
1129
1130 if (iwl_mvm_is_radio_killed(mvm))
1131 goto out;
1132
1108 if (mvm->scan_status != IWL_MVM_SCAN_SCHED && 1133 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
1109 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) || 1134 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
1110 mvm->scan_status != IWL_MVM_SCAN_OS)) { 1135 mvm->scan_status != IWL_MVM_SCAN_OS)) {
@@ -1141,6 +1166,7 @@ int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
1141 if (mvm->scan_status == IWL_MVM_SCAN_OS) 1166 if (mvm->scan_status == IWL_MVM_SCAN_OS)
1142 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1167 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1143 1168
1169out:
1144 mvm->scan_status = IWL_MVM_SCAN_NONE; 1170 mvm->scan_status = IWL_MVM_SCAN_NONE;
1145 1171
1146 if (notify) { 1172 if (notify) {
@@ -1297,18 +1323,6 @@ iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1297 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH); 1323 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
1298 cmd->iter_num = cpu_to_le32(1); 1324 cmd->iter_num = cpu_to_le32(1);
1299 1325
1300 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1301 mvm->last_ebs_successful) {
1302 cmd->channel_opt[0].flags =
1303 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1304 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1305 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1306 cmd->channel_opt[1].flags =
1307 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1308 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1309 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1310 }
1311
1312 if (iwl_mvm_rrm_scan_needed(mvm)) 1326 if (iwl_mvm_rrm_scan_needed(mvm))
1313 cmd->scan_flags |= 1327 cmd->scan_flags |=
1314 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED); 1328 cpu_to_le32(IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED);
@@ -1383,6 +1397,22 @@ int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
1383 cmd->schedule[1].iterations = 0; 1397 cmd->schedule[1].iterations = 0;
1384 cmd->schedule[1].full_scan_mul = 0; 1398 cmd->schedule[1].full_scan_mul = 0;
1385 1399
1400 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1401 mvm->last_ebs_successful) {
1402 cmd->channel_opt[0].flags =
1403 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1404 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1405 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1406 cmd->channel_opt[0].non_ebs_ratio =
1407 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1408 cmd->channel_opt[1].flags =
1409 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1410 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1411 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1412 cmd->channel_opt[1].non_ebs_ratio =
1413 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1414 }
1415
1386 for (i = 1; i <= req->req.n_ssids; i++) 1416 for (i = 1; i <= req->req.n_ssids; i++)
1387 ssid_bitmap |= BIT(i); 1417 ssid_bitmap |= BIT(i);
1388 1418
@@ -1467,6 +1497,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1467 if (req->n_ssids == 0) 1497 if (req->n_ssids == 0)
1468 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 1498 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
1469 1499
1500#ifdef CONFIG_IWLWIFI_DEBUGFS
1501 if (mvm->scan_iter_notif_enabled)
1502 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
1503#endif
1504
1470 cmd->scan_flags |= cpu_to_le32(flags); 1505 cmd->scan_flags |= cpu_to_le32(flags);
1471 1506
1472 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); 1507 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
@@ -1483,6 +1518,22 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1483 cmd->schedule[1].iterations = 0xff; 1518 cmd->schedule[1].iterations = 0xff;
1484 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER; 1519 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
1485 1520
1521 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1522 mvm->last_ebs_successful) {
1523 cmd->channel_opt[0].flags =
1524 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1525 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1526 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1527 cmd->channel_opt[0].non_ebs_ratio =
1528 cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
1529 cmd->channel_opt[1].flags =
1530 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1531 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1532 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1533 cmd->channel_opt[1].non_ebs_ratio =
1534 cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
1535 }
1536
1486 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels, 1537 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
1487 ssid_bitmap, cmd); 1538 ssid_bitmap, cmd);
1488 1539
@@ -1612,7 +1663,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1612 SCAN_CONFIG_FLAG_SET_MAC_ADDR | 1663 SCAN_CONFIG_FLAG_SET_MAC_ADDR |
1613 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS| 1664 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
1614 SCAN_CONFIG_N_CHANNELS(num_channels)); 1665 SCAN_CONFIG_N_CHANNELS(num_channels));
1615 scan_config->tx_chains = cpu_to_le32(mvm->fw->valid_tx_ant); 1666 scan_config->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1616 scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm)); 1667 scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1617 scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm); 1668 scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1618 scan_config->out_of_channel_time = cpu_to_le32(170); 1669 scan_config->out_of_channel_time = cpu_to_le32(170);
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index d86fe432e51f..14a848480d04 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -99,7 +99,7 @@ static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm,
99int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 99int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
100 bool update) 100 bool update)
101{ 101{
102 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 102 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
103 struct iwl_mvm_add_sta_cmd add_sta_cmd = { 103 struct iwl_mvm_add_sta_cmd add_sta_cmd = {
104 .sta_id = mvm_sta->sta_id, 104 .sta_id = mvm_sta->sta_id,
105 .mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color), 105 .mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color),
@@ -250,8 +250,8 @@ static void iwl_mvm_tdls_sta_deinit(struct iwl_mvm *mvm,
250 250
251 /* disable the TDLS STA-specific queues */ 251 /* disable the TDLS STA-specific queues */
252 sta_msk = mvmsta->tfd_queue_msk; 252 sta_msk = mvmsta->tfd_queue_msk;
253 for_each_set_bit(i, &sta_msk, sizeof(sta_msk)) 253 for_each_set_bit(i, &sta_msk, sizeof(sta_msk) * BITS_PER_BYTE)
254 iwl_mvm_disable_txq(mvm, i); 254 iwl_mvm_disable_txq(mvm, i, 0);
255} 255}
256 256
257int iwl_mvm_add_sta(struct iwl_mvm *mvm, 257int iwl_mvm_add_sta(struct iwl_mvm *mvm,
@@ -259,7 +259,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
259 struct ieee80211_sta *sta) 259 struct ieee80211_sta *sta)
260{ 260{
261 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 261 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
262 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 262 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
263 int i, ret, sta_id; 263 int i, ret, sta_id;
264 264
265 lockdep_assert_held(&mvm->mutex); 265 lockdep_assert_held(&mvm->mutex);
@@ -464,8 +464,8 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk)
464 if (mvm->tfd_drained[sta_id]) { 464 if (mvm->tfd_drained[sta_id]) {
465 unsigned long i, msk = mvm->tfd_drained[sta_id]; 465 unsigned long i, msk = mvm->tfd_drained[sta_id];
466 466
467 for_each_set_bit(i, &msk, sizeof(msk)) 467 for_each_set_bit(i, &msk, sizeof(msk) * BITS_PER_BYTE)
468 iwl_mvm_disable_txq(mvm, i); 468 iwl_mvm_disable_txq(mvm, i, 0);
469 469
470 mvm->tfd_drained[sta_id] = 0; 470 mvm->tfd_drained[sta_id] = 0;
471 IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n", 471 IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n",
@@ -481,7 +481,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
481 struct ieee80211_sta *sta) 481 struct ieee80211_sta *sta)
482{ 482{
483 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 483 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
484 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 484 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
485 int ret; 485 int ret;
486 486
487 lockdep_assert_held(&mvm->mutex); 487 lockdep_assert_held(&mvm->mutex);
@@ -774,7 +774,7 @@ int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
774int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 774int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
775 int tid, u16 ssn, bool start) 775 int tid, u16 ssn, bool start)
776{ 776{
777 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 777 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
778 struct iwl_mvm_add_sta_cmd cmd = {}; 778 struct iwl_mvm_add_sta_cmd cmd = {};
779 int ret; 779 int ret;
780 u32 status; 780 u32 status;
@@ -834,7 +834,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
834static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 834static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
835 int tid, u8 queue, bool start) 835 int tid, u8 queue, bool start)
836{ 836{
837 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 837 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
838 struct iwl_mvm_add_sta_cmd cmd = {}; 838 struct iwl_mvm_add_sta_cmd cmd = {};
839 int ret; 839 int ret;
840 u32 status; 840 u32 status;
@@ -1058,7 +1058,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1058 1058
1059 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1059 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
1060 1060
1061 iwl_mvm_disable_txq(mvm, txq_id); 1061 iwl_mvm_disable_txq(mvm, txq_id, 0);
1062 return 0; 1062 return 0;
1063 case IWL_AGG_STARTING: 1063 case IWL_AGG_STARTING:
1064 case IWL_EMPTYING_HW_QUEUE_ADDBA: 1064 case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1116,7 +1116,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1116 1116
1117 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1117 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
1118 1118
1119 iwl_mvm_disable_txq(mvm, tid_data->txq_id); 1119 iwl_mvm_disable_txq(mvm, tid_data->txq_id, 0);
1120 } 1120 }
1121 1121
1122 mvm->queue_to_mac80211[tid_data->txq_id] = 1122 mvm->queue_to_mac80211[tid_data->txq_id] =
@@ -1144,10 +1144,10 @@ static int iwl_mvm_set_fw_key_idx(struct iwl_mvm *mvm)
1144static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif, 1144static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
1145 struct ieee80211_sta *sta) 1145 struct ieee80211_sta *sta)
1146{ 1146{
1147 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1147 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1148 1148
1149 if (sta) { 1149 if (sta) {
1150 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1150 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1151 1151
1152 return mvm_sta->sta_id; 1152 return mvm_sta->sta_id;
1153 } 1153 }
@@ -1196,6 +1196,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1196 break; 1196 break;
1197 case WLAN_CIPHER_SUITE_WEP104: 1197 case WLAN_CIPHER_SUITE_WEP104:
1198 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES); 1198 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES);
1199 /* fall through */
1199 case WLAN_CIPHER_SUITE_WEP40: 1200 case WLAN_CIPHER_SUITE_WEP40:
1200 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP); 1201 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP);
1201 memcpy(cmd.key + 3, keyconf->key, keyconf->keylen); 1202 memcpy(cmd.key + 3, keyconf->key, keyconf->keylen);
@@ -1280,7 +1281,7 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
1280 struct ieee80211_vif *vif, 1281 struct ieee80211_vif *vif,
1281 struct ieee80211_sta *sta) 1282 struct ieee80211_sta *sta)
1282{ 1283{
1283 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1284 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1284 1285
1285 if (sta) 1286 if (sta)
1286 return sta->addr; 1287 return sta->addr;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index 2b1e61fac34a..ba615ad2176c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -69,6 +69,7 @@
69 69
70static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) 70static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
71{ 71{
72 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
72 u32 duration = mvm->thermal_throttle.params->ct_kill_duration; 73 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
73 74
74 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) 75 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
@@ -77,12 +78,15 @@ static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
77 IWL_ERR(mvm, "Enter CT Kill\n"); 78 IWL_ERR(mvm, "Enter CT Kill\n");
78 iwl_mvm_set_hw_ctkill_state(mvm, true); 79 iwl_mvm_set_hw_ctkill_state(mvm, true);
79 80
81 tt->throttle = false;
82 tt->dynamic_smps = false;
83
80 /* Don't schedule an exit work if we're in test mode, since 84 /* Don't schedule an exit work if we're in test mode, since
81 * the temperature will not change unless we manually set it 85 * the temperature will not change unless we manually set it
82 * again (or disable testing). 86 * again (or disable testing).
83 */ 87 */
84 if (!mvm->temperature_test) 88 if (!mvm->temperature_test)
85 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, 89 schedule_delayed_work(&tt->ct_kill_exit,
86 round_jiffies_relative(duration * HZ)); 90 round_jiffies_relative(duration * HZ));
87} 91}
88 92
@@ -452,6 +456,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm, u32 min_backoff)
452 tt->params = &iwl7000_tt_params; 456 tt->params = &iwl7000_tt_params;
453 457
454 tt->throttle = false; 458 tt->throttle = false;
459 tt->dynamic_smps = false;
455 tt->min_backoff = min_backoff; 460 tt->min_backoff = min_backoff;
456 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); 461 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
457} 462}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 4333306ccdee..07304e1fd64a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -90,8 +90,6 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
90 90
91 if (ieee80211_is_probe_resp(fc)) 91 if (ieee80211_is_probe_resp(fc))
92 tx_flags |= TX_CMD_FLG_TSF; 92 tx_flags |= TX_CMD_FLG_TSF;
93 else if (ieee80211_is_back_req(fc))
94 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
95 93
96 if (ieee80211_has_morefrags(fc)) 94 if (ieee80211_has_morefrags(fc))
97 tx_flags |= TX_CMD_FLG_MORE_FRAG; 95 tx_flags |= TX_CMD_FLG_MORE_FRAG;
@@ -100,6 +98,15 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
100 u8 *qc = ieee80211_get_qos_ctl(hdr); 98 u8 *qc = ieee80211_get_qos_ctl(hdr);
101 tx_cmd->tid_tspec = qc[0] & 0xf; 99 tx_cmd->tid_tspec = qc[0] & 0xf;
102 tx_flags &= ~TX_CMD_FLG_SEQ_CTL; 100 tx_flags &= ~TX_CMD_FLG_SEQ_CTL;
101 } else if (ieee80211_is_back_req(fc)) {
102 struct ieee80211_bar *bar = (void *)skb->data;
103 u16 control = le16_to_cpu(bar->control);
104
105 tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
106 tx_cmd->tid_tspec = (control &
107 IEEE80211_BAR_CTRL_TID_INFO_MASK) >>
108 IEEE80211_BAR_CTRL_TID_INFO_SHIFT;
109 WARN_ON_ONCE(tx_cmd->tid_tspec >= IWL_MAX_TID_COUNT);
103 } else { 110 } else {
104 tx_cmd->tid_tspec = IWL_TID_NON_QOS; 111 tx_cmd->tid_tspec = IWL_TID_NON_QOS;
105 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) 112 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
@@ -213,7 +220,7 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
213 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); 220 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
214 221
215 mvm->mgmt_last_antenna_idx = 222 mvm->mgmt_last_antenna_idx =
216 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 223 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
217 mvm->mgmt_last_antenna_idx); 224 mvm->mgmt_last_antenna_idx);
218 225
219 if (info->band == IEEE80211_BAND_2GHZ && 226 if (info->band == IEEE80211_BAND_2GHZ &&
@@ -500,7 +507,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
500 IWL_DEBUG_TX_QUEUES(mvm, 507 IWL_DEBUG_TX_QUEUES(mvm,
501 "Can continue DELBA flow ssn = next_recl = %d\n", 508 "Can continue DELBA flow ssn = next_recl = %d\n",
502 tid_data->next_reclaimed); 509 tid_data->next_reclaimed);
503 iwl_mvm_disable_txq(mvm, tid_data->txq_id); 510 iwl_mvm_disable_txq(mvm, tid_data->txq_id, CMD_ASYNC);
504 tid_data->state = IWL_AGG_OFF; 511 tid_data->state = IWL_AGG_OFF;
505 /* 512 /*
506 * we can't hold the mutex - but since we are after a sequence 513 * we can't hold the mutex - but since we are after a sequence
@@ -660,7 +667,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
660 667
661 /* Single frame failure in an AMPDU queue => send BAR */ 668 /* Single frame failure in an AMPDU queue => send BAR */
662 if (txq_id >= mvm->first_agg_queue && 669 if (txq_id >= mvm->first_agg_queue &&
663 !(info->flags & IEEE80211_TX_STAT_ACK)) 670 !(info->flags & IEEE80211_TX_STAT_ACK) &&
671 !(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
664 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 672 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
665 673
666 /* W/A FW bug: seq_ctl is wrong when the status isn't success */ 674 /* W/A FW bug: seq_ctl is wrong when the status isn't success */
@@ -923,6 +931,11 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
923 sta_id = ba_notif->sta_id; 931 sta_id = ba_notif->sta_id;
924 tid = ba_notif->tid; 932 tid = ba_notif->tid;
925 933
934 if (WARN_ONCE(sta_id >= IWL_MVM_STATION_COUNT ||
935 tid >= IWL_MAX_TID_COUNT,
936 "sta_id %d tid %d", sta_id, tid))
937 return 0;
938
926 rcu_read_lock(); 939 rcu_read_lock();
927 940
928 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]); 941 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 917431e30f74..4eb3cad31aa9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -533,47 +533,46 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 533void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
534 const struct iwl_trans_txq_scd_cfg *cfg) 534 const struct iwl_trans_txq_scd_cfg *cfg)
535{ 535{
536 if (iwl_mvm_is_dqa_supported(mvm)) { 536 struct iwl_scd_txq_cfg_cmd cmd = {
537 struct iwl_scd_txq_cfg_cmd cmd = { 537 .scd_queue = queue,
538 .scd_queue = queue, 538 .enable = 1,
539 .enable = 1, 539 .window = cfg->frame_limit,
540 .window = cfg->frame_limit, 540 .sta_id = cfg->sta_id,
541 .sta_id = cfg->sta_id, 541 .ssn = cpu_to_le16(ssn),
542 .ssn = cpu_to_le16(ssn), 542 .tx_fifo = cfg->fifo,
543 .tx_fifo = cfg->fifo, 543 .aggregate = cfg->aggregate,
544 .aggregate = cfg->aggregate, 544 .tid = cfg->tid,
545 .flags = IWL_SCD_FLAGS_DQA_ENABLED, 545 };
546 .tid = cfg->tid, 546
547 .control = IWL_SCD_CONTROL_SET_SSN, 547 if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
548 }; 548 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg);
549 int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, 549 return;
550 sizeof(cmd), &cmd);
551 if (ret)
552 IWL_ERR(mvm,
553 "Failed to configure queue %d on FIFO %d\n",
554 queue, cfg->fifo);
555 } 550 }
556 551
557 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, 552 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL);
558 iwl_mvm_is_dqa_supported(mvm) ? NULL : cfg); 553 WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
554 "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo);
559} 555}
560 556
561void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue) 557void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags)
562{ 558{
563 iwl_trans_txq_disable(mvm->trans, queue, 559 struct iwl_scd_txq_cfg_cmd cmd = {
564 !iwl_mvm_is_dqa_supported(mvm)); 560 .scd_queue = queue,
565 561 .enable = 0,
566 if (iwl_mvm_is_dqa_supported(mvm)) { 562 };
567 struct iwl_scd_txq_cfg_cmd cmd = { 563 int ret;
568 .scd_queue = queue, 564
569 .enable = 0, 565 if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
570 }; 566 iwl_trans_txq_disable(mvm->trans, queue, true);
571 int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, CMD_ASYNC, 567 return;
572 sizeof(cmd), &cmd);
573 if (ret)
574 IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
575 queue, ret);
576 } 568 }
569
570 iwl_trans_txq_disable(mvm->trans, queue, false);
571 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags,
572 sizeof(cmd), &cmd);
573 if (ret)
574 IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
575 queue, ret);
577} 576}
578 577
579/** 578/**
@@ -620,7 +619,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
620 lockdep_assert_held(&mvm->mutex); 619 lockdep_assert_held(&mvm->mutex);
621 620
622 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */ 621 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */
623 if (num_of_ant(mvm->fw->valid_rx_ant) == 1) 622 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
624 return; 623 return;
625 624
626 if (vif->type == NL80211_IFTYPE_AP) 625 if (vif->type == NL80211_IFTYPE_AP)
@@ -662,7 +661,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
662 661
663 lockdep_assert_held(&mvm->mutex); 662 lockdep_assert_held(&mvm->mutex);
664 663
665 if (num_of_ant(mvm->fw->valid_rx_ant) == 1) 664 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
666 return false; 665 return false;
667 666
668 if (mvm->cfg->rx_with_siso_diversity) 667 if (mvm->cfg->rx_with_siso_diversity)
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index d5aadb00dd9e..dbd6bcf52205 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -415,6 +415,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
415 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, 415 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
416 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, 416 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
417 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, 417 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
418 {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)},
419 {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)},
418#endif /* CONFIG_IWLMVM */ 420#endif /* CONFIG_IWLMVM */
419 421
420 {0} 422 {0}
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 1aea6b66c594..e5652d82d79e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -318,6 +318,11 @@ struct iwl_trans_pcie {
318 /*protect hw register */ 318 /*protect hw register */
319 spinlock_t reg_lock; 319 spinlock_t reg_lock;
320 bool cmd_in_flight; 320 bool cmd_in_flight;
321 bool ref_cmd_in_flight;
322
323 /* protect ref counter */
324 spinlock_t ref_lock;
325 u32 ref_count;
321 326
322 dma_addr_t fw_mon_phys; 327 dma_addr_t fw_mon_phys;
323 struct page *fw_mon_page; 328 struct page *fw_mon_page;
@@ -381,6 +386,9 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
381 struct sk_buff_head *skbs); 386 struct sk_buff_head *skbs);
382void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); 387void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
383 388
389void iwl_trans_pcie_ref(struct iwl_trans *trans);
390void iwl_trans_pcie_unref(struct iwl_trans *trans);
391
384static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) 392static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
385{ 393{
386 struct iwl_tfd_tb *tb = &tfd->tbs[idx]; 394 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 523fe0c88dcb..1ff87677c3d3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -443,10 +443,25 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
443 return ret; 443 return ret;
444} 444}
445 445
446static void iwl_pcie_apm_stop(struct iwl_trans *trans) 446static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
447{ 447{
448 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); 448 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
449 449
450 if (op_mode_leave) {
451 if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
452 iwl_pcie_apm_init(trans);
453
454 /* inform ME that we are leaving */
455 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000)
456 iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
457 APMG_PCIDEV_STT_VAL_WAKE_ME);
458 else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
459 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
460 CSR_HW_IF_CONFIG_REG_PREPARE |
461 CSR_HW_IF_CONFIG_REG_ENABLE_PME);
462 mdelay(5);
463 }
464
450 clear_bit(STATUS_DEVICE_ENABLED, &trans->status); 465 clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
451 466
452 /* Stop device's DMA activity */ 467 /* Stop device's DMA activity */
@@ -707,6 +722,11 @@ static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
707 722
708 *first_ucode_section = last_read_idx; 723 *first_ucode_section = last_read_idx;
709 724
725 if (cpu == 1)
726 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFF);
727 else
728 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
729
710 return 0; 730 return 0;
711} 731}
712 732
@@ -893,8 +913,8 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
893 if (ret) 913 if (ret)
894 return ret; 914 return ret;
895 915
896 /* Notify FW loading is done */ 916 if (trans->dbg_dest_tlv)
897 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); 917 iwl_pcie_apply_destination(trans);
898 918
899 /* wait for image verification to complete */ 919 /* wait for image verification to complete */
900 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, 920 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
@@ -916,6 +936,7 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
916static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 936static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
917 const struct fw_img *fw, bool run_in_rfkill) 937 const struct fw_img *fw, bool run_in_rfkill)
918{ 938{
939 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
919 int ret; 940 int ret;
920 bool hw_rfkill; 941 bool hw_rfkill;
921 942
@@ -945,6 +966,9 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
945 return ret; 966 return ret;
946 } 967 }
947 968
969 /* init ref_count to 1 (should be cleared when ucode is loaded) */
970 trans_pcie->ref_count = 1;
971
948 /* make sure rfkill handshake bits are cleared */ 972 /* make sure rfkill handshake bits are cleared */
949 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 973 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
950 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, 974 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
@@ -960,7 +984,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
960 984
961 /* Load the given image to the HW */ 985 /* Load the given image to the HW */
962 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && 986 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
963 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP)) 987 (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP))
964 return iwl_pcie_load_given_ucode_8000b(trans, fw); 988 return iwl_pcie_load_given_ucode_8000b(trans, fw);
965 else 989 else
966 return iwl_pcie_load_given_ucode(trans, fw); 990 return iwl_pcie_load_given_ucode(trans, fw);
@@ -1010,7 +1034,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1010 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1034 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1011 1035
1012 /* Stop the device, and put it in low power state */ 1036 /* Stop the device, and put it in low power state */
1013 iwl_pcie_apm_stop(trans); 1037 iwl_pcie_apm_stop(trans, false);
1014 1038
1015 /* stop and reset the on-board processor */ 1039 /* stop and reset the on-board processor */
1016 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 1040 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
@@ -1192,7 +1216,7 @@ static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans)
1192 iwl_disable_interrupts(trans); 1216 iwl_disable_interrupts(trans);
1193 spin_unlock(&trans_pcie->irq_lock); 1217 spin_unlock(&trans_pcie->irq_lock);
1194 1218
1195 iwl_pcie_apm_stop(trans); 1219 iwl_pcie_apm_stop(trans, true);
1196 1220
1197 spin_lock(&trans_pcie->irq_lock); 1221 spin_lock(&trans_pcie->irq_lock);
1198 iwl_disable_interrupts(trans); 1222 iwl_disable_interrupts(trans);
@@ -1540,6 +1564,38 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
1540 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1564 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1541} 1565}
1542 1566
1567void iwl_trans_pcie_ref(struct iwl_trans *trans)
1568{
1569 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1570 unsigned long flags;
1571
1572 if (iwlwifi_mod_params.d0i3_disable)
1573 return;
1574
1575 spin_lock_irqsave(&trans_pcie->ref_lock, flags);
1576 IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
1577 trans_pcie->ref_count++;
1578 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1579}
1580
1581void iwl_trans_pcie_unref(struct iwl_trans *trans)
1582{
1583 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1584 unsigned long flags;
1585
1586 if (iwlwifi_mod_params.d0i3_disable)
1587 return;
1588
1589 spin_lock_irqsave(&trans_pcie->ref_lock, flags);
1590 IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
1591 if (WARN_ON_ONCE(trans_pcie->ref_count == 0)) {
1592 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1593 return;
1594 }
1595 trans_pcie->ref_count--;
1596 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1597}
1598
1543static const char *get_csr_string(int cmd) 1599static const char *get_csr_string(int cmd)
1544{ 1600{
1545#define IWL_CMD(x) case x: return #x 1601#define IWL_CMD(x) case x: return #x
@@ -2264,6 +2320,9 @@ static const struct iwl_trans_ops trans_ops_pcie = {
2264 .release_nic_access = iwl_trans_pcie_release_nic_access, 2320 .release_nic_access = iwl_trans_pcie_release_nic_access,
2265 .set_bits_mask = iwl_trans_pcie_set_bits_mask, 2321 .set_bits_mask = iwl_trans_pcie_set_bits_mask,
2266 2322
2323 .ref = iwl_trans_pcie_ref,
2324 .unref = iwl_trans_pcie_unref,
2325
2267 .dump_data = iwl_trans_pcie_dump_data, 2326 .dump_data = iwl_trans_pcie_dump_data,
2268}; 2327};
2269 2328
@@ -2291,6 +2350,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2291 trans_pcie->trans = trans; 2350 trans_pcie->trans = trans;
2292 spin_lock_init(&trans_pcie->irq_lock); 2351 spin_lock_init(&trans_pcie->irq_lock);
2293 spin_lock_init(&trans_pcie->reg_lock); 2352 spin_lock_init(&trans_pcie->reg_lock);
2353 spin_lock_init(&trans_pcie->ref_lock);
2294 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 2354 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
2295 2355
2296 err = pci_enable_device(pdev); 2356 err = pci_enable_device(pdev);
@@ -2404,6 +2464,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2404 } 2464 }
2405 2465
2406 trans_pcie->inta_mask = CSR_INI_SET_MASK; 2466 trans_pcie->inta_mask = CSR_INI_SET_MASK;
2467 trans->d0i3_mode = IWL_D0I3_MODE_ON_SUSPEND;
2407 2468
2408 return trans; 2469 return trans;
2409 2470
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 8a6c7a084aa1..d40cd4a67d6e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -985,17 +985,31 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
985 985
986 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 986 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
987 iwl_wake_queue(trans, txq); 987 iwl_wake_queue(trans, txq);
988
989 if (q->read_ptr == q->write_ptr) {
990 IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", q->id);
991 iwl_trans_pcie_unref(trans);
992 }
993
988out: 994out:
989 spin_unlock_bh(&txq->lock); 995 spin_unlock_bh(&txq->lock);
990} 996}
991 997
992static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans) 998static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
999 const struct iwl_host_cmd *cmd)
993{ 1000{
994 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1001 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
995 int ret; 1002 int ret;
996 1003
997 lockdep_assert_held(&trans_pcie->reg_lock); 1004 lockdep_assert_held(&trans_pcie->reg_lock);
998 1005
1006 if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
1007 !trans_pcie->ref_cmd_in_flight) {
1008 trans_pcie->ref_cmd_in_flight = true;
1009 IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
1010 iwl_trans_pcie_ref(trans);
1011 }
1012
999 if (trans_pcie->cmd_in_flight) 1013 if (trans_pcie->cmd_in_flight)
1000 return 0; 1014 return 0;
1001 1015
@@ -1036,6 +1050,12 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1036 1050
1037 lockdep_assert_held(&trans_pcie->reg_lock); 1051 lockdep_assert_held(&trans_pcie->reg_lock);
1038 1052
1053 if (trans_pcie->ref_cmd_in_flight) {
1054 trans_pcie->ref_cmd_in_flight = false;
1055 IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
1056 iwl_trans_pcie_unref(trans);
1057 }
1058
1039 if (WARN_ON(!trans_pcie->cmd_in_flight)) 1059 if (WARN_ON(!trans_pcie->cmd_in_flight))
1040 return 0; 1060 return 0;
1041 1061
@@ -1170,12 +1190,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1170 * Assumes that ssn_idx is valid (!= 0xFFF) */ 1190 * Assumes that ssn_idx is valid (!= 0xFFF) */
1171 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1191 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff);
1172 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1192 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff);
1193 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1194 (ssn & 0xff) | (txq_id << 8));
1173 1195
1174 if (cfg) { 1196 if (cfg) {
1175 u8 frame_limit = cfg->frame_limit; 1197 u8 frame_limit = cfg->frame_limit;
1176 1198
1177 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1178 (ssn & 0xff) | (txq_id << 8));
1179 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn); 1199 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
1180 1200
1181 /* Set up Tx window size and frame limit for this queue */ 1201 /* Set up Tx window size and frame limit for this queue */
@@ -1200,11 +1220,17 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1200 if (txq_id == trans_pcie->cmd_queue && 1220 if (txq_id == trans_pcie->cmd_queue &&
1201 trans_pcie->scd_set_active) 1221 trans_pcie->scd_set_active)
1202 iwl_scd_enable_set_active(trans, BIT(txq_id)); 1222 iwl_scd_enable_set_active(trans, BIT(txq_id));
1223
1224 IWL_DEBUG_TX_QUEUES(trans,
1225 "Activate queue %d on FIFO %d WrPtr: %d\n",
1226 txq_id, fifo, ssn & 0xff);
1227 } else {
1228 IWL_DEBUG_TX_QUEUES(trans,
1229 "Activate queue %d WrPtr: %d\n",
1230 txq_id, ssn & 0xff);
1203 } 1231 }
1204 1232
1205 trans_pcie->txq[txq_id].active = true; 1233 trans_pcie->txq[txq_id].active = true;
1206 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
1207 txq_id, fifo, ssn & 0xff);
1208} 1234}
1209 1235
1210void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, 1236void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
@@ -1473,7 +1499,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1473 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1499 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1474 1500
1475 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1501 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1476 ret = iwl_pcie_set_cmd_in_flight(trans); 1502 ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
1477 if (ret < 0) { 1503 if (ret < 0) {
1478 idx = ret; 1504 idx = ret;
1479 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1505 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
@@ -1819,9 +1845,13 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1819 wait_write_ptr = ieee80211_has_morefrags(fc); 1845 wait_write_ptr = ieee80211_has_morefrags(fc);
1820 1846
1821 /* start timer if queue currently empty */ 1847 /* start timer if queue currently empty */
1822 if (txq->need_update && q->read_ptr == q->write_ptr && 1848 if (q->read_ptr == q->write_ptr) {
1823 trans_pcie->wd_timeout) 1849 if (txq->need_update && trans_pcie->wd_timeout)
1824 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1850 mod_timer(&txq->stuck_timer,
1851 jiffies + trans_pcie->wd_timeout);
1852 IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
1853 iwl_trans_pcie_ref(trans);
1854 }
1825 1855
1826 /* Tell device the write index *just past* this latest filled TFD */ 1856 /* Tell device the write index *just past* this latest filled TFD */
1827 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr); 1857 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 9d4786e7ddff..c5c83cf664d8 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -558,10 +558,10 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
558 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 558 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
559 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac); 559 sta_ptr = mwifiex_get_sta_entry(priv, peer_mac);
560 if (!sta_ptr) { 560 if (!sta_ptr) {
561 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
561 dev_warn(priv->adapter->dev, 562 dev_warn(priv->adapter->dev,
562 "BA setup with unknown TDLS peer %pM!\n", 563 "BA setup with unknown TDLS peer %pM!\n",
563 peer_mac); 564 peer_mac);
564 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
565 return -1; 565 return -1;
566 } 566 }
567 if (sta_ptr->is_11ac_enabled) 567 if (sta_ptr->is_11ac_enabled)
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index f275675cdbd3..8e2e39422ad8 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -130,7 +130,9 @@ static inline u8 mwifiex_space_avail_for_new_ba_stream(
130{ 130{
131 struct mwifiex_private *priv; 131 struct mwifiex_private *priv;
132 u8 i; 132 u8 i;
133 u32 ba_stream_num = 0; 133 u32 ba_stream_num = 0, ba_stream_max;
134
135 ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;
134 136
135 for (i = 0; i < adapter->priv_num; i++) { 137 for (i = 0; i < adapter->priv_num; i++) {
136 priv = adapter->priv[i]; 138 priv = adapter->priv[i];
@@ -139,8 +141,14 @@ static inline u8 mwifiex_space_avail_for_new_ba_stream(
139 &priv->tx_ba_stream_tbl_ptr); 141 &priv->tx_ba_stream_tbl_ptr);
140 } 142 }
141 143
142 return ((ba_stream_num < 144 if (adapter->fw_api_ver == MWIFIEX_FW_V15) {
143 MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) ? true : false); 145 ba_stream_max =
146 GETSUPP_TXBASTREAMS(adapter->hw_dot_11n_dev_cap);
147 if (!ba_stream_max)
148 ba_stream_max = MWIFIEX_MAX_TX_BASTREAM_SUPPORTED;
149 }
150
151 return ((ba_stream_num < ba_stream_max) ? true : false);
144} 152}
145 153
146/* 154/*
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 8720a3d3c755..9b983b5cebbd 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -101,6 +101,13 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
101{ 101{
102 struct txpd *local_tx_pd; 102 struct txpd *local_tx_pd;
103 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); 103 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
104 unsigned int pad;
105 int headroom = (priv->adapter->iface_type ==
106 MWIFIEX_USB) ? 0 : INTF_HEADER_LEN;
107
108 pad = ((void *)skb->data - sizeof(*local_tx_pd) -
109 headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
110 skb_push(skb, pad);
104 111
105 skb_push(skb, sizeof(*local_tx_pd)); 112 skb_push(skb, sizeof(*local_tx_pd));
106 113
@@ -114,10 +121,12 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
114 local_tx_pd->bss_num = priv->bss_num; 121 local_tx_pd->bss_num = priv->bss_num;
115 local_tx_pd->bss_type = priv->bss_type; 122 local_tx_pd->bss_type = priv->bss_type;
116 /* Always zero as the data is followed by struct txpd */ 123 /* Always zero as the data is followed by struct txpd */
117 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); 124 local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) +
125 pad);
118 local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); 126 local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
119 local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - 127 local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
120 sizeof(*local_tx_pd)); 128 sizeof(*local_tx_pd) -
129 pad);
121 130
122 if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT) 131 if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
123 local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET; 132 local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET;
@@ -182,7 +191,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
182 ra_list_flags); 191 ra_list_flags);
183 return -1; 192 return -1;
184 } 193 }
185 skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); 194 skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN);
186 tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); 195 tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr);
187 196
188 memset(tx_info_aggr, 0, sizeof(*tx_info_aggr)); 197 memset(tx_info_aggr, 0, sizeof(*tx_info_aggr));
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index d73fda312c87..c7ca5b734875 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -353,9 +353,6 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
353 353
354 spin_lock_irqsave(&priv->sta_list_spinlock, flags); 354 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
355 if (mwifiex_queuing_ra_based(priv)) { 355 if (mwifiex_queuing_ra_based(priv)) {
356 dev_dbg(priv->adapter->dev,
357 "info: AP/ADHOC:last_seq=%d start_win=%d\n",
358 last_seq, new_node->start_win);
359 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) { 356 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
360 node = mwifiex_get_sta_entry(priv, ta); 357 node = mwifiex_get_sta_entry(priv, ta);
361 if (node) 358 if (node)
@@ -370,6 +367,9 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
370 } 367 }
371 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 368 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
372 369
370 dev_dbg(priv->adapter->dev, "info: last_seq=%d start_win=%d\n",
371 last_seq, new_node->start_win);
372
373 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && 373 if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM &&
374 last_seq >= new_node->start_win) { 374 last_seq >= new_node->start_win) {
375 new_node->start_win = last_seq + 1; 375 new_node->start_win = last_seq + 1;
@@ -391,10 +391,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
391 new_node->timer_context.priv = priv; 391 new_node->timer_context.priv = priv;
392 new_node->timer_context.timer_is_set = false; 392 new_node->timer_context.timer_is_set = false;
393 393
394 init_timer(&new_node->timer_context.timer); 394 setup_timer(&new_node->timer_context.timer, mwifiex_flush_data,
395 new_node->timer_context.timer.function = mwifiex_flush_data; 395 (unsigned long)&new_node->timer_context);
396 new_node->timer_context.timer.data =
397 (unsigned long) &new_node->timer_context;
398 396
399 for (i = 0; i < win_size; ++i) 397 for (i = 0; i < win_size; ++i)
400 new_node->rx_reorder_ptr[i] = NULL; 398 new_node->rx_reorder_ptr[i] = NULL;
@@ -468,10 +466,10 @@ int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
468 sta_ptr = mwifiex_get_sta_entry(priv, 466 sta_ptr = mwifiex_get_sta_entry(priv,
469 cmd_addba_req->peer_mac_addr); 467 cmd_addba_req->peer_mac_addr);
470 if (!sta_ptr) { 468 if (!sta_ptr) {
469 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
471 dev_warn(priv->adapter->dev, 470 dev_warn(priv->adapter->dev,
472 "BA setup with unknown TDLS peer %pM!\n", 471 "BA setup with unknown TDLS peer %pM!\n",
473 cmd_addba_req->peer_mac_addr); 472 cmd_addba_req->peer_mac_addr);
474 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
475 return -1; 473 return -1;
476 } 474 }
477 if (sta_ptr->is_11ac_enabled) 475 if (sta_ptr->is_11ac_enabled)
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 9487d728ac20..fdfd9bf15ed4 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -53,3 +53,5 @@ obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
53 53
54mwifiex_usb-y += usb.o 54mwifiex_usb-y += usb.o
55obj-$(CONFIG_MWIFIEX_USB) += mwifiex_usb.o 55obj-$(CONFIG_MWIFIEX_USB) += mwifiex_usb.o
56
57ccflags-y += -D__CHECK_ENDIAN
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 1996a8b612d2..7be1e9b83fd0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1786,6 +1786,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1786 struct cfg80211_connect_params *sme) 1786 struct cfg80211_connect_params *sme)
1787{ 1787{
1788 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1788 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1789 struct mwifiex_adapter *adapter = priv->adapter;
1789 int ret; 1790 int ret;
1790 1791
1791 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) { 1792 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
@@ -1800,6 +1801,13 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1800 return -EALREADY; 1801 return -EALREADY;
1801 } 1802 }
1802 1803
1804 if (adapter->surprise_removed || adapter->is_cmd_timedout) {
1805 wiphy_err(wiphy,
1806 "%s: Ignore connection. Card removed or FW in bad state\n",
1807 dev->name);
1808 return -EFAULT;
1809 }
1810
1803 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 1811 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1804 (char *) sme->ssid, sme->bssid); 1812 (char *) sme->ssid, sme->bssid);
1805 1813
@@ -2388,6 +2396,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2388 2396
2389 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2397 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2390 2398
2399 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
2400 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
2401 kfree(priv->hist_data);
2402
2391 return 0; 2403 return 0;
2392} 2404}
2393EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf); 2405EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
@@ -2423,30 +2435,16 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
2423} 2435}
2424 2436
2425#ifdef CONFIG_PM 2437#ifdef CONFIG_PM
2426static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, 2438static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2427 struct cfg80211_wowlan *wowlan) 2439 struct cfg80211_wowlan *wowlan)
2428{ 2440{
2429 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 2441 int i, filt_num = 0, ret = 0;
2430 struct mwifiex_ds_mef_cfg mef_cfg;
2431 struct mwifiex_mef_entry *mef_entry;
2432 int i, filt_num = 0, ret;
2433 bool first_pat = true; 2442 bool first_pat = true;
2434 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1]; 2443 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
2435 const u8 ipv4_mc_mac[] = {0x33, 0x33}; 2444 const u8 ipv4_mc_mac[] = {0x33, 0x33};
2436 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e}; 2445 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2437 struct mwifiex_private *priv = 2446 struct mwifiex_ds_mef_cfg mef_cfg;
2438 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 2447 struct mwifiex_mef_entry *mef_entry;
2439
2440 if (!wowlan) {
2441 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2442 return 0;
2443 }
2444
2445 if (!priv->media_connected) {
2446 dev_warn(adapter->dev,
2447 "Can not configure WOWLAN in disconnected state\n");
2448 return 0;
2449 }
2450 2448
2451 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL); 2449 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2452 if (!mef_entry) 2450 if (!mef_entry)
@@ -2461,9 +2459,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2461 for (i = 0; i < wowlan->n_patterns; i++) { 2459 for (i = 0; i < wowlan->n_patterns; i++) {
2462 memset(byte_seq, 0, sizeof(byte_seq)); 2460 memset(byte_seq, 0, sizeof(byte_seq));
2463 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i], 2461 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
2464 byte_seq, 2462 byte_seq,
2465 MWIFIEX_MEF_MAX_BYTESEQ)) { 2463 MWIFIEX_MEF_MAX_BYTESEQ)) {
2466 wiphy_err(wiphy, "Pattern not supported\n"); 2464 dev_err(priv->adapter->dev, "Pattern not supported\n");
2467 kfree(mef_entry); 2465 kfree(mef_entry);
2468 return -EOPNOTSUPP; 2466 return -EOPNOTSUPP;
2469 } 2467 }
@@ -2487,9 +2485,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2487 2485
2488 mef_entry->filter[filt_num].repeat = 1; 2486 mef_entry->filter[filt_num].repeat = 1;
2489 mef_entry->filter[filt_num].offset = 2487 mef_entry->filter[filt_num].offset =
2490 wowlan->patterns[i].pkt_offset; 2488 wowlan->patterns[i].pkt_offset;
2491 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq, 2489 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
2492 sizeof(byte_seq)); 2490 sizeof(byte_seq));
2493 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2491 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2494 2492
2495 if (first_pat) 2493 if (first_pat)
@@ -2504,9 +2502,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2504 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2502 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2505 mef_entry->filter[filt_num].repeat = 16; 2503 mef_entry->filter[filt_num].repeat = 16;
2506 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2504 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2507 ETH_ALEN); 2505 ETH_ALEN);
2508 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2506 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2509 ETH_ALEN; 2507 ETH_ALEN;
2510 mef_entry->filter[filt_num].offset = 28; 2508 mef_entry->filter[filt_num].offset = 28;
2511 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2509 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2512 if (filt_num) 2510 if (filt_num)
@@ -2515,9 +2513,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2515 filt_num++; 2513 filt_num++;
2516 mef_entry->filter[filt_num].repeat = 16; 2514 mef_entry->filter[filt_num].repeat = 16;
2517 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2515 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2518 ETH_ALEN); 2516 ETH_ALEN);
2519 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2517 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2520 ETH_ALEN; 2518 ETH_ALEN;
2521 mef_entry->filter[filt_num].offset = 56; 2519 mef_entry->filter[filt_num].offset = 56;
2522 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2520 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2523 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2521 mef_entry->filter[filt_num].filt_action = TYPE_OR;
@@ -2525,16 +2523,61 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2525 2523
2526 if (!mef_cfg.criteria) 2524 if (!mef_cfg.criteria)
2527 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST | 2525 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
2528 MWIFIEX_CRITERIA_UNICAST | 2526 MWIFIEX_CRITERIA_UNICAST |
2529 MWIFIEX_CRITERIA_MULTICAST; 2527 MWIFIEX_CRITERIA_MULTICAST;
2530 2528
2531 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG, 2529 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2532 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true); 2530 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
2533 2531
2534 kfree(mef_entry); 2532 kfree(mef_entry);
2535 return ret; 2533 return ret;
2536} 2534}
2537 2535
2536static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2537 struct cfg80211_wowlan *wowlan)
2538{
2539 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2540 struct mwifiex_ds_hs_cfg hs_cfg;
2541 int ret = 0;
2542 struct mwifiex_private *priv =
2543 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2544
2545 if (!wowlan) {
2546 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2547 return 0;
2548 }
2549
2550 if (!priv->media_connected) {
2551 dev_warn(adapter->dev,
2552 "Can not configure WOWLAN in disconnected state\n");
2553 return 0;
2554 }
2555
2556 if (wowlan->n_patterns || wowlan->magic_pkt) {
2557 ret = mwifiex_set_mef_filter(priv, wowlan);
2558 if (ret) {
2559 dev_err(adapter->dev, "Failed to set MEF filter\n");
2560 return ret;
2561 }
2562 }
2563
2564 if (wowlan->disconnect) {
2565 memset(&hs_cfg, 0, sizeof(hs_cfg));
2566 hs_cfg.is_invoke_hostcmd = false;
2567 hs_cfg.conditions = HS_CFG_COND_MAC_EVENT;
2568 hs_cfg.gpio = HS_CFG_GPIO_DEF;
2569 hs_cfg.gap = HS_CFG_GAP_DEF;
2570 ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
2571 MWIFIEX_SYNC_CMD, &hs_cfg);
2572 if (ret) {
2573 dev_err(adapter->dev, "Failed to set HS params\n");
2574 return ret;
2575 }
2576 }
2577
2578 return ret;
2579}
2580
2538static int mwifiex_cfg80211_resume(struct wiphy *wiphy) 2581static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
2539{ 2582{
2540 return 0; 2583 return 0;
@@ -2872,7 +2915,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2872 2915
2873#ifdef CONFIG_PM 2916#ifdef CONFIG_PM
2874static const struct wiphy_wowlan_support mwifiex_wowlan_support = { 2917static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
2875 .flags = WIPHY_WOWLAN_MAGIC_PKT, 2918 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
2876 .n_patterns = MWIFIEX_MEF_MAX_FILTERS, 2919 .n_patterns = MWIFIEX_MEF_MAX_FILTERS,
2877 .pattern_min_len = 1, 2920 .pattern_min_len = 1,
2878 .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN, 2921 .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index b8242eb2be6f..f494fc7eeb62 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -509,3 +509,21 @@ u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
509 509
510 return k; 510 return k;
511} 511}
512
513u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
514 u8 rx_rate, u8 rate_info)
515{
516 u8 rate_index = 0;
517
518 /* HT40 */
519 if ((rate_info & BIT(0)) && (rate_info & BIT(1)))
520 rate_index = MWIFIEX_RATE_INDEX_MCS0 +
521 MWIFIEX_BW20_MCS_NUM + rx_rate;
522 else if (rate_info & BIT(0)) /* HT20 */
523 rate_index = MWIFIEX_RATE_INDEX_MCS0 + rx_rate;
524 else
525 rate_index = (rx_rate > MWIFIEX_RATE_INDEX_OFDM0) ?
526 rx_rate - 1 : rx_rate;
527
528 return rate_index;
529}
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 85597200badc..946a2f7a172f 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1008,11 +1008,9 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1008 list_for_each_entry_safe(cmd_node, tmp_node, 1008 list_for_each_entry_safe(cmd_node, tmp_node,
1009 &adapter->scan_pending_q, list) { 1009 &adapter->scan_pending_q, list) {
1010 list_del(&cmd_node->list); 1010 list_del(&cmd_node->list);
1011 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1012 1011
1013 cmd_node->wait_q_enabled = false; 1012 cmd_node->wait_q_enabled = false;
1014 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1013 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1015 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1016 } 1014 }
1017 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1015 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1018 1016
@@ -1070,12 +1068,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1070 list_for_each_entry_safe(cmd_node, tmp_node, 1068 list_for_each_entry_safe(cmd_node, tmp_node,
1071 &adapter->scan_pending_q, list) { 1069 &adapter->scan_pending_q, list) {
1072 list_del(&cmd_node->list); 1070 list_del(&cmd_node->list);
1073 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1074 scan_pending_q_flags);
1075 cmd_node->wait_q_enabled = false; 1071 cmd_node->wait_q_enabled = false;
1076 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1072 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1077 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1078 scan_pending_q_flags);
1079 } 1073 }
1080 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1074 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1081 scan_pending_q_flags); 1075 scan_pending_q_flags);
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 2713f7acd35e..1fb329dc6744 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -39,111 +39,6 @@ static char *bss_modes[] = {
39 "P2P_DEVICE", 39 "P2P_DEVICE",
40}; 40};
41 41
42/* size/addr for mwifiex_debug_info */
43#define item_size(n) (FIELD_SIZEOF(struct mwifiex_debug_info, n))
44#define item_addr(n) (offsetof(struct mwifiex_debug_info, n))
45
46/* size/addr for struct mwifiex_adapter */
47#define adapter_item_size(n) (FIELD_SIZEOF(struct mwifiex_adapter, n))
48#define adapter_item_addr(n) (offsetof(struct mwifiex_adapter, n))
49
50struct mwifiex_debug_data {
51 char name[32]; /* variable/array name */
52 u32 size; /* size of the variable/array */
53 size_t addr; /* address of the variable/array */
54 int num; /* number of variables in an array */
55};
56
57static struct mwifiex_debug_data items[] = {
58 {"int_counter", item_size(int_counter),
59 item_addr(int_counter), 1},
60 {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
61 item_addr(packets_out[WMM_AC_VO]), 1},
62 {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
63 item_addr(packets_out[WMM_AC_VI]), 1},
64 {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
65 item_addr(packets_out[WMM_AC_BE]), 1},
66 {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
67 item_addr(packets_out[WMM_AC_BK]), 1},
68 {"tx_buf_size", item_size(tx_buf_size),
69 item_addr(tx_buf_size), 1},
70 {"curr_tx_buf_size", item_size(curr_tx_buf_size),
71 item_addr(curr_tx_buf_size), 1},
72 {"ps_mode", item_size(ps_mode),
73 item_addr(ps_mode), 1},
74 {"ps_state", item_size(ps_state),
75 item_addr(ps_state), 1},
76 {"is_deep_sleep", item_size(is_deep_sleep),
77 item_addr(is_deep_sleep), 1},
78 {"wakeup_dev_req", item_size(pm_wakeup_card_req),
79 item_addr(pm_wakeup_card_req), 1},
80 {"wakeup_tries", item_size(pm_wakeup_fw_try),
81 item_addr(pm_wakeup_fw_try), 1},
82 {"hs_configured", item_size(is_hs_configured),
83 item_addr(is_hs_configured), 1},
84 {"hs_activated", item_size(hs_activated),
85 item_addr(hs_activated), 1},
86 {"num_tx_timeout", item_size(num_tx_timeout),
87 item_addr(num_tx_timeout), 1},
88 {"is_cmd_timedout", item_size(is_cmd_timedout),
89 item_addr(is_cmd_timedout), 1},
90 {"timeout_cmd_id", item_size(timeout_cmd_id),
91 item_addr(timeout_cmd_id), 1},
92 {"timeout_cmd_act", item_size(timeout_cmd_act),
93 item_addr(timeout_cmd_act), 1},
94 {"last_cmd_id", item_size(last_cmd_id),
95 item_addr(last_cmd_id), DBG_CMD_NUM},
96 {"last_cmd_act", item_size(last_cmd_act),
97 item_addr(last_cmd_act), DBG_CMD_NUM},
98 {"last_cmd_index", item_size(last_cmd_index),
99 item_addr(last_cmd_index), 1},
100 {"last_cmd_resp_id", item_size(last_cmd_resp_id),
101 item_addr(last_cmd_resp_id), DBG_CMD_NUM},
102 {"last_cmd_resp_index", item_size(last_cmd_resp_index),
103 item_addr(last_cmd_resp_index), 1},
104 {"last_event", item_size(last_event),
105 item_addr(last_event), DBG_CMD_NUM},
106 {"last_event_index", item_size(last_event_index),
107 item_addr(last_event_index), 1},
108 {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
109 item_addr(num_cmd_host_to_card_failure), 1},
110 {"num_cmd_sleep_cfm_fail",
111 item_size(num_cmd_sleep_cfm_host_to_card_failure),
112 item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
113 {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
114 item_addr(num_tx_host_to_card_failure), 1},
115 {"num_evt_deauth", item_size(num_event_deauth),
116 item_addr(num_event_deauth), 1},
117 {"num_evt_disassoc", item_size(num_event_disassoc),
118 item_addr(num_event_disassoc), 1},
119 {"num_evt_link_lost", item_size(num_event_link_lost),
120 item_addr(num_event_link_lost), 1},
121 {"num_cmd_deauth", item_size(num_cmd_deauth),
122 item_addr(num_cmd_deauth), 1},
123 {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
124 item_addr(num_cmd_assoc_success), 1},
125 {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
126 item_addr(num_cmd_assoc_failure), 1},
127 {"cmd_sent", item_size(cmd_sent),
128 item_addr(cmd_sent), 1},
129 {"data_sent", item_size(data_sent),
130 item_addr(data_sent), 1},
131 {"cmd_resp_received", item_size(cmd_resp_received),
132 item_addr(cmd_resp_received), 1},
133 {"event_received", item_size(event_received),
134 item_addr(event_received), 1},
135
136 /* variables defined in struct mwifiex_adapter */
137 {"cmd_pending", adapter_item_size(cmd_pending),
138 adapter_item_addr(cmd_pending), 1},
139 {"tx_pending", adapter_item_size(tx_pending),
140 adapter_item_addr(tx_pending), 1},
141 {"rx_pending", adapter_item_size(rx_pending),
142 adapter_item_addr(rx_pending), 1},
143};
144
145static int num_of_items = ARRAY_SIZE(items);
146
147/* 42/*
148 * Proc info file read handler. 43 * Proc info file read handler.
149 * 44 *
@@ -297,6 +192,8 @@ mwifiex_fw_dump_read(struct file *file, char __user *ubuf,
297 * - Number of FCS errors 192 * - Number of FCS errors
298 * - Number of Tx frames 193 * - Number of Tx frames
299 * - WEP ICV error counts 194 * - WEP ICV error counts
195 * - Number of received beacons
196 * - Number of missed beacons
300 */ 197 */
301static ssize_t 198static ssize_t
302mwifiex_getlog_read(struct file *file, char __user *ubuf, 199mwifiex_getlog_read(struct file *file, char __user *ubuf,
@@ -333,7 +230,9 @@ mwifiex_getlog_read(struct file *file, char __user *ubuf,
333 "wepicverrcnt-1 %u\n" 230 "wepicverrcnt-1 %u\n"
334 "wepicverrcnt-2 %u\n" 231 "wepicverrcnt-2 %u\n"
335 "wepicverrcnt-3 %u\n" 232 "wepicverrcnt-3 %u\n"
336 "wepicverrcnt-4 %u\n", 233 "wepicverrcnt-4 %u\n"
234 "bcn_rcv_cnt %u\n"
235 "bcn_miss_cnt %u\n",
337 stats.mcast_tx_frame, 236 stats.mcast_tx_frame,
338 stats.failed, 237 stats.failed,
339 stats.retry, 238 stats.retry,
@@ -349,7 +248,9 @@ mwifiex_getlog_read(struct file *file, char __user *ubuf,
349 stats.wep_icv_error[0], 248 stats.wep_icv_error[0],
350 stats.wep_icv_error[1], 249 stats.wep_icv_error[1],
351 stats.wep_icv_error[2], 250 stats.wep_icv_error[2],
352 stats.wep_icv_error[3]); 251 stats.wep_icv_error[3],
252 stats.bcn_rcv_cnt,
253 stats.bcn_miss_cnt);
353 254
354 255
355 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, 256 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
@@ -360,6 +261,103 @@ free_and_exit:
360 return ret; 261 return ret;
361} 262}
362 263
264/* Sysfs histogram file read handler.
265 *
266 * This function is called when the 'histogram' file is opened for reading
267 * It prints the following histogram information -
268 * - Number of histogram samples
269 * - Receive packet number of each rx_rate
270 * - Receive packet number of each snr
271 * - Receive packet number of each nosie_flr
272 * - Receive packet number of each signal streath
273 */
274static ssize_t
275mwifiex_histogram_read(struct file *file, char __user *ubuf,
276 size_t count, loff_t *ppos)
277{
278 struct mwifiex_private *priv =
279 (struct mwifiex_private *)file->private_data;
280 ssize_t ret;
281 struct mwifiex_histogram_data *phist_data;
282 int i, value;
283 unsigned long page = get_zeroed_page(GFP_KERNEL);
284 char *p = (char *)page;
285
286 if (!p)
287 return -ENOMEM;
288
289 if (!priv || !priv->hist_data)
290 return -EFAULT;
291 phist_data = priv->hist_data;
292
293 p += sprintf(p, "\n"
294 "total samples = %d\n",
295 atomic_read(&phist_data->num_samples));
296
297 p += sprintf(p, "rx rates (in Mbps): 0=1M 1=2M");
298 p += sprintf(p, "2=5.5M 3=11M 4=6M 5=9M 6=12M\n");
299 p += sprintf(p, "7=18M 8=24M 9=36M 10=48M 11=54M");
300 p += sprintf(p, "12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
301
302 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
303 p += sprintf(p, "44-53=MCS0-9(VHT:BW20)");
304 p += sprintf(p, "54-63=MCS0-9(VHT:BW40)");
305 p += sprintf(p, "64-73=MCS0-9(VHT:BW80)\n\n");
306 } else {
307 p += sprintf(p, "\n");
308 }
309
310 for (i = 0; i < MWIFIEX_MAX_RX_RATES; i++) {
311 value = atomic_read(&phist_data->rx_rate[i]);
312 if (value)
313 p += sprintf(p, "rx_rate[%02d] = %d\n", i, value);
314 }
315
316 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
317 for (i = MWIFIEX_MAX_RX_RATES; i < MWIFIEX_MAX_AC_RX_RATES;
318 i++) {
319 value = atomic_read(&phist_data->rx_rate[i]);
320 if (value)
321 p += sprintf(p, "rx_rate[%02d] = %d\n",
322 i, value);
323 }
324 }
325
326 for (i = 0; i < MWIFIEX_MAX_SNR; i++) {
327 value = atomic_read(&phist_data->snr[i]);
328 if (value)
329 p += sprintf(p, "snr[%02ddB] = %d\n", i, value);
330 }
331 for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) {
332 value = atomic_read(&phist_data->noise_flr[i]);
333 if (value)
334 p += sprintf(p, "noise_flr[-%02ddBm] = %d\n",
335 (int)(i-128), value);
336 }
337 for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
338 value = atomic_read(&phist_data->sig_str[i]);
339 if (value)
340 p += sprintf(p, "sig_strength[-%02ddBm] = %d\n",
341 i, value);
342 }
343
344 ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
345 (unsigned long)p - page);
346
347 return ret;
348}
349
350static ssize_t
351mwifiex_histogram_write(struct file *file, const char __user *ubuf,
352 size_t count, loff_t *ppos)
353{
354 struct mwifiex_private *priv = (void *)file->private_data;
355
356 if (priv && priv->hist_data)
357 mwifiex_hist_data_reset(priv);
358 return 0;
359}
360
363static struct mwifiex_debug_info info; 361static struct mwifiex_debug_info info;
364 362
365/* 363/*
@@ -415,13 +413,9 @@ mwifiex_debug_read(struct file *file, char __user *ubuf,
415{ 413{
416 struct mwifiex_private *priv = 414 struct mwifiex_private *priv =
417 (struct mwifiex_private *) file->private_data; 415 (struct mwifiex_private *) file->private_data;
418 struct mwifiex_debug_data *d = &items[0];
419 unsigned long page = get_zeroed_page(GFP_KERNEL); 416 unsigned long page = get_zeroed_page(GFP_KERNEL);
420 char *p = (char *) page; 417 char *p = (char *) page;
421 ssize_t ret; 418 ssize_t ret;
422 size_t size, addr;
423 long val;
424 int i, j;
425 419
426 if (!p) 420 if (!p)
427 return -ENOMEM; 421 return -ENOMEM;
@@ -430,68 +424,7 @@ mwifiex_debug_read(struct file *file, char __user *ubuf,
430 if (ret) 424 if (ret)
431 goto free_and_exit; 425 goto free_and_exit;
432 426
433 for (i = 0; i < num_of_items; i++) { 427 p += mwifiex_debug_info_to_buffer(priv, p, &info);
434 p += sprintf(p, "%s=", d[i].name);
435
436 size = d[i].size / d[i].num;
437
438 if (i < (num_of_items - 3))
439 addr = d[i].addr + (size_t) &info;
440 else /* The last 3 items are struct mwifiex_adapter variables */
441 addr = d[i].addr + (size_t) priv->adapter;
442
443 for (j = 0; j < d[i].num; j++) {
444 switch (size) {
445 case 1:
446 val = *((u8 *) addr);
447 break;
448 case 2:
449 val = *((u16 *) addr);
450 break;
451 case 4:
452 val = *((u32 *) addr);
453 break;
454 case 8:
455 val = *((long long *) addr);
456 break;
457 default:
458 val = -1;
459 break;
460 }
461
462 p += sprintf(p, "%#lx ", val);
463 addr += size;
464 }
465
466 p += sprintf(p, "\n");
467 }
468
469 if (info.tx_tbl_num) {
470 p += sprintf(p, "Tx BA stream table:\n");
471 for (i = 0; i < info.tx_tbl_num; i++)
472 p += sprintf(p, "tid = %d, ra = %pM\n",
473 info.tx_tbl[i].tid, info.tx_tbl[i].ra);
474 }
475
476 if (info.rx_tbl_num) {
477 p += sprintf(p, "Rx reorder table:\n");
478 for (i = 0; i < info.rx_tbl_num; i++) {
479 p += sprintf(p, "tid = %d, ta = %pM, "
480 "start_win = %d, "
481 "win_size = %d, buffer: ",
482 info.rx_tbl[i].tid,
483 info.rx_tbl[i].ta,
484 info.rx_tbl[i].start_win,
485 info.rx_tbl[i].win_size);
486
487 for (j = 0; j < info.rx_tbl[i].win_size; j++)
488 p += sprintf(p, "%c ",
489 info.rx_tbl[i].buffer[j] ?
490 '1' : '0');
491
492 p += sprintf(p, "\n");
493 }
494 }
495 428
496 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, 429 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
497 (unsigned long) p - page); 430 (unsigned long) p - page);
@@ -817,6 +750,7 @@ MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
817MWIFIEX_DFS_FILE_OPS(regrdwr); 750MWIFIEX_DFS_FILE_OPS(regrdwr);
818MWIFIEX_DFS_FILE_OPS(rdeeprom); 751MWIFIEX_DFS_FILE_OPS(rdeeprom);
819MWIFIEX_DFS_FILE_OPS(hscfg); 752MWIFIEX_DFS_FILE_OPS(hscfg);
753MWIFIEX_DFS_FILE_OPS(histogram);
820 754
821/* 755/*
822 * This function creates the debug FS directory structure and the files. 756 * This function creates the debug FS directory structure and the files.
@@ -840,6 +774,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
840 MWIFIEX_DFS_ADD_FILE(rdeeprom); 774 MWIFIEX_DFS_ADD_FILE(rdeeprom);
841 MWIFIEX_DFS_ADD_FILE(fw_dump); 775 MWIFIEX_DFS_ADD_FILE(fw_dump);
842 MWIFIEX_DFS_ADD_FILE(hscfg); 776 MWIFIEX_DFS_ADD_FILE(hscfg);
777 MWIFIEX_DFS_ADD_FILE(histogram);
843} 778}
844 779
845/* 780/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 2269acf41ad8..7aa988e1dc7a 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -32,15 +32,19 @@
32 32
33#define MWIFIEX_MAX_BSS_NUM (3) 33#define MWIFIEX_MAX_BSS_NUM (3)
34 34
35#define MWIFIEX_MIN_DATA_HEADER_LEN 36 /* sizeof(mwifiex_txpd) 35#define MWIFIEX_DMA_ALIGN_SZ 64
36 * + 4 byte alignment 36#define MAX_TXPD_SZ 32
37 */ 37#define INTF_HDR_ALIGN 4
38
39#define MWIFIEX_MIN_DATA_HEADER_LEN (MWIFIEX_DMA_ALIGN_SZ + INTF_HDR_ALIGN + \
40 MAX_TXPD_SZ)
38#define MWIFIEX_MGMT_FRAME_HEADER_SIZE 8 /* sizeof(pkt_type) 41#define MWIFIEX_MGMT_FRAME_HEADER_SIZE 8 /* sizeof(pkt_type)
39 * + sizeof(tx_control) 42 * + sizeof(tx_control)
40 */ 43 */
41 44
42#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2 45#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED 2
43#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16 46#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED 16
47#define MWIFIEX_MAX_TDLS_PEER_SUPPORTED 8
44 48
45#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 64 49#define MWIFIEX_STA_AMPDU_DEF_TXWINSIZE 64
46#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 64 50#define MWIFIEX_STA_AMPDU_DEF_RXWINSIZE 64
@@ -92,6 +96,14 @@
92#define MWIFIEX_TDLS_MAX_FAIL_COUNT 4 96#define MWIFIEX_TDLS_MAX_FAIL_COUNT 4
93#define MWIFIEX_AUTO_TDLS_IDLE_TIME 10 97#define MWIFIEX_AUTO_TDLS_IDLE_TIME 10
94 98
99/* 54M rates, index from 0 to 11 */
100#define MWIFIEX_RATE_INDEX_MCS0 12
101/* 12-27=MCS0-15(BW20) */
102#define MWIFIEX_BW20_MCS_NUM 15
103
104/* Rate index for OFDM 0 */
105#define MWIFIEX_RATE_INDEX_OFDM0 4
106
95enum mwifiex_bss_type { 107enum mwifiex_bss_type {
96 MWIFIEX_BSS_TYPE_STA = 0, 108 MWIFIEX_BSS_TYPE_STA = 0,
97 MWIFIEX_BSS_TYPE_UAP = 1, 109 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -204,4 +216,20 @@ struct mwifiex_chan_stats {
204 u16 cca_scan_dur; 216 u16 cca_scan_dur;
205 u16 cca_busy_dur; 217 u16 cca_busy_dur;
206} __packed; 218} __packed;
219
220#define MWIFIEX_HIST_MAX_SAMPLES 1048576
221#define MWIFIEX_MAX_RX_RATES 44
222#define MWIFIEX_MAX_AC_RX_RATES 74
223#define MWIFIEX_MAX_SNR 256
224#define MWIFIEX_MAX_NOISE_FLR 256
225#define MWIFIEX_MAX_SIG_STRENGTH 256
226
227struct mwifiex_histogram_data {
228 atomic_t rx_rate[MWIFIEX_MAX_AC_RX_RATES];
229 atomic_t snr[MWIFIEX_MAX_SNR];
230 atomic_t noise_flr[MWIFIEX_MAX_NOISE_FLR];
231 atomic_t sig_str[MWIFIEX_MAX_SIG_STRENGTH];
232 atomic_t num_samples;
233};
234
207#endif /* !_MWIFIEX_DECL_H_ */ 235#endif /* !_MWIFIEX_DECL_H_ */
diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c
index 04e56b5fc535..65d8d6d4b6ba 100644
--- a/drivers/net/wireless/mwifiex/ethtool.c
+++ b/drivers/net/wireless/mwifiex/ethtool.c
@@ -76,7 +76,9 @@ mwifiex_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
76 76
77 dump->flag = adapter->curr_mem_idx; 77 dump->flag = adapter->curr_mem_idx;
78 dump->version = 1; 78 dump->version = 1;
79 if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) { 79 if (adapter->curr_mem_idx == MWIFIEX_DRV_INFO_IDX) {
80 dump->len = adapter->drv_info_size;
81 } else if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) {
80 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx]; 82 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
81 dump->len = entry->mem_size; 83 dump->len = entry->mem_size;
82 } else { 84 } else {
@@ -98,6 +100,13 @@ mwifiex_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
98 if (!adapter->if_ops.fw_dump) 100 if (!adapter->if_ops.fw_dump)
99 return -ENOTSUPP; 101 return -ENOTSUPP;
100 102
103 if (adapter->curr_mem_idx == MWIFIEX_DRV_INFO_IDX) {
104 if (!adapter->drv_info_dump)
105 return -EFAULT;
106 memcpy(p, adapter->drv_info_dump, adapter->drv_info_size);
107 return 0;
108 }
109
101 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) { 110 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
102 dev_err(adapter->dev, "firmware dump in progress!!\n"); 111 dev_err(adapter->dev, "firmware dump in progress!!\n");
103 return -EBUSY; 112 return -EBUSY;
@@ -125,6 +134,11 @@ static int mwifiex_set_dump(struct net_device *dev, struct ethtool_dump *val)
125 if (!adapter->if_ops.fw_dump) 134 if (!adapter->if_ops.fw_dump)
126 return -ENOTSUPP; 135 return -ENOTSUPP;
127 136
137 if (val->flag == MWIFIEX_DRV_INFO_IDX) {
138 adapter->curr_mem_idx = MWIFIEX_DRV_INFO_IDX;
139 return 0;
140 }
141
128 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) { 142 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
129 dev_err(adapter->dev, "firmware dump in progress!!\n"); 143 dev_err(adapter->dev, "firmware dump in progress!!\n");
130 return -EBUSY; 144 return -EBUSY;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index fb5936eb82e3..15ad776ae08e 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -233,6 +233,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
233#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) 233#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
234#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) 234#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30))
235#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2)) 235#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2))
236#define GETSUPP_TXBASTREAMS(Dot11nDevCap) ((Dot11nDevCap >> 18) & 0xF)
236 237
237/* httxcfg bitmap 238/* httxcfg bitmap
238 * 0 reserved 239 * 0 reserved
@@ -1076,6 +1077,8 @@ struct host_cmd_ds_802_11_get_log {
1076 __le32 tx_frame; 1077 __le32 tx_frame;
1077 __le32 reserved; 1078 __le32 reserved;
1078 __le32 wep_icv_err_cnt[4]; 1079 __le32 wep_icv_err_cnt[4];
1080 __le32 bcn_rcv_cnt;
1081 __le32 bcn_miss_cnt;
1079}; 1082};
1080 1083
1081/* Enumeration for rate format */ 1084/* Enumeration for rate format */
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 520ad4a3018b..b115e0f94dd7 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -52,6 +52,18 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
52 return 0; 52 return 0;
53} 53}
54 54
55static void wakeup_timer_fn(unsigned long data)
56{
57 struct mwifiex_adapter *adapter = (struct mwifiex_adapter *)data;
58
59 dev_err(adapter->dev, "Firmware wakeup failed\n");
60 adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
61 mwifiex_cancel_all_pending_cmd(adapter);
62
63 if (adapter->if_ops.card_reset)
64 adapter->if_ops.card_reset(adapter);
65}
66
55/* 67/*
56 * This function initializes the private structure and sets default 68 * This function initializes the private structure and sets default
57 * values to the members. 69 * values to the members.
@@ -285,6 +297,9 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
285 adapter->ext_scan = true; 297 adapter->ext_scan = true;
286 adapter->key_api_major_ver = 0; 298 adapter->key_api_major_ver = 0;
287 adapter->key_api_minor_ver = 0; 299 adapter->key_api_minor_ver = 0;
300
301 setup_timer(&adapter->wakeup_timer, wakeup_timer_fn,
302 (unsigned long)adapter);
288} 303}
289 304
290/* 305/*
@@ -391,7 +406,10 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
391 return; 406 return;
392 } 407 }
393 408
409 del_timer(&adapter->wakeup_timer);
394 mwifiex_cancel_all_pending_cmd(adapter); 410 mwifiex_cancel_all_pending_cmd(adapter);
411 wake_up_interruptible(&adapter->cmd_wait_q.wait);
412 wake_up_interruptible(&adapter->hs_activate_wait_q);
395 413
396 /* Free lock variables */ 414 /* Free lock variables */
397 mwifiex_free_lock_list(adapter); 415 mwifiex_free_lock_list(adapter);
@@ -411,6 +429,11 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
411 entry->mem_size = 0; 429 entry->mem_size = 0;
412 } 430 }
413 431
432 if (adapter->drv_info_dump) {
433 vfree(adapter->drv_info_dump);
434 adapter->drv_info_size = 0;
435 }
436
414 if (adapter->sleep_cfm) 437 if (adapter->sleep_cfm)
415 dev_kfree_skb_any(adapter->sleep_cfm); 438 dev_kfree_skb_any(adapter->sleep_cfm);
416} 439}
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 0847f3e07ab7..d2b05c3a96da 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -137,6 +137,8 @@ struct mwifiex_ds_get_stats {
137 u32 fcs_error; 137 u32 fcs_error;
138 u32 tx_frame; 138 u32 tx_frame;
139 u32 wep_icv_error[4]; 139 u32 wep_icv_error[4];
140 u32 bcn_rcv_cnt;
141 u32 bcn_miss_cnt;
140}; 142};
141 143
142#define MWIFIEX_MAX_VER_STR_LEN 128 144#define MWIFIEX_MAX_VER_STR_LEN 128
@@ -180,7 +182,11 @@ struct mwifiex_ds_tx_ba_stream_tbl {
180 u8 amsdu; 182 u8 amsdu;
181}; 183};
182 184
183#define DBG_CMD_NUM 5 185#define DBG_CMD_NUM 5
186
187struct tdls_peer_info {
188 u8 peer_addr[ETH_ALEN];
189};
184 190
185struct mwifiex_debug_info { 191struct mwifiex_debug_info {
186 u32 int_counter; 192 u32 int_counter;
@@ -193,6 +199,9 @@ struct mwifiex_debug_info {
193 u32 rx_tbl_num; 199 u32 rx_tbl_num;
194 struct mwifiex_ds_rx_reorder_tbl rx_tbl 200 struct mwifiex_ds_rx_reorder_tbl rx_tbl
195 [MWIFIEX_MAX_RX_BASTREAM_SUPPORTED]; 201 [MWIFIEX_MAX_RX_BASTREAM_SUPPORTED];
202 u32 tdls_peer_num;
203 struct tdls_peer_info tdls_list
204 [MWIFIEX_MAX_TDLS_PEER_SUPPORTED];
196 u16 ps_mode; 205 u16 ps_mode;
197 u32 ps_state; 206 u32 ps_state;
198 u8 is_deep_sleep; 207 u8 is_deep_sleep;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d4d2223d1f31..d235adb82c94 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -83,9 +83,8 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
83 } 83 }
84 mwifiex_init_lock_list(adapter); 84 mwifiex_init_lock_list(adapter);
85 85
86 init_timer(&adapter->cmd_timer); 86 setup_timer(&adapter->cmd_timer, mwifiex_cmd_timeout_func,
87 adapter->cmd_timer.function = mwifiex_cmd_timeout_func; 87 (unsigned long)adapter);
88 adapter->cmd_timer.data = (unsigned long) adapter;
89 88
90 return 0; 89 return 0;
91 90
@@ -237,6 +236,7 @@ process_start:
237 (is_command_pending(adapter) || 236 (is_command_pending(adapter) ||
238 !mwifiex_wmm_lists_empty(adapter))) { 237 !mwifiex_wmm_lists_empty(adapter))) {
239 adapter->pm_wakeup_fw_try = true; 238 adapter->pm_wakeup_fw_try = true;
239 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
240 adapter->if_ops.wakeup(adapter); 240 adapter->if_ops.wakeup(adapter);
241 continue; 241 continue;
242 } 242 }
@@ -244,6 +244,7 @@ process_start:
244 if (IS_CARD_RX_RCVD(adapter)) { 244 if (IS_CARD_RX_RCVD(adapter)) {
245 adapter->data_received = false; 245 adapter->data_received = false;
246 adapter->pm_wakeup_fw_try = false; 246 adapter->pm_wakeup_fw_try = false;
247 del_timer_sync(&adapter->wakeup_timer);
247 if (adapter->ps_state == PS_STATE_SLEEP) 248 if (adapter->ps_state == PS_STATE_SLEEP)
248 adapter->ps_state = PS_STATE_AWAKE; 249 adapter->ps_state = PS_STATE_AWAKE;
249 } else { 250 } else {
@@ -511,8 +512,7 @@ err_dnld_fw:
511 if (adapter->if_ops.unregister_dev) 512 if (adapter->if_ops.unregister_dev)
512 adapter->if_ops.unregister_dev(adapter); 513 adapter->if_ops.unregister_dev(adapter);
513 514
514 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) || 515 if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
515 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
516 pr_debug("info: %s: shutdown mwifiex\n", __func__); 516 pr_debug("info: %s: shutdown mwifiex\n", __func__);
517 adapter->init_wait_q_woken = false; 517 adapter->init_wait_q_woken = false;
518 518
@@ -801,6 +801,114 @@ mwifiex_tx_timeout(struct net_device *dev)
801 } 801 }
802} 802}
803 803
804void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter)
805{
806 void *p;
807 char drv_version[64];
808 struct usb_card_rec *cardp;
809 struct sdio_mmc_card *sdio_card;
810 struct mwifiex_private *priv;
811 int i, idx;
812 struct netdev_queue *txq;
813 struct mwifiex_debug_info *debug_info;
814
815 if (adapter->drv_info_dump) {
816 vfree(adapter->drv_info_dump);
817 adapter->drv_info_size = 0;
818 }
819
820 dev_info(adapter->dev, "=== DRIVER INFO DUMP START===\n");
821
822 adapter->drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX);
823
824 if (!adapter->drv_info_dump)
825 return;
826
827 p = (char *)(adapter->drv_info_dump);
828 p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
829
830 mwifiex_drv_get_driver_version(adapter, drv_version,
831 sizeof(drv_version) - 1);
832 p += sprintf(p, "driver_version = %s\n", drv_version);
833
834 if (adapter->iface_type == MWIFIEX_USB) {
835 cardp = (struct usb_card_rec *)adapter->card;
836 p += sprintf(p, "tx_cmd_urb_pending = %d\n",
837 atomic_read(&cardp->tx_cmd_urb_pending));
838 p += sprintf(p, "tx_data_urb_pending = %d\n",
839 atomic_read(&cardp->tx_data_urb_pending));
840 p += sprintf(p, "rx_cmd_urb_pending = %d\n",
841 atomic_read(&cardp->rx_cmd_urb_pending));
842 p += sprintf(p, "rx_data_urb_pending = %d\n",
843 atomic_read(&cardp->rx_data_urb_pending));
844 }
845
846 p += sprintf(p, "tx_pending = %d\n",
847 atomic_read(&adapter->tx_pending));
848 p += sprintf(p, "rx_pending = %d\n",
849 atomic_read(&adapter->rx_pending));
850
851 if (adapter->iface_type == MWIFIEX_SDIO) {
852 sdio_card = (struct sdio_mmc_card *)adapter->card;
853 p += sprintf(p, "\nmp_rd_bitmap=0x%x curr_rd_port=0x%x\n",
854 sdio_card->mp_rd_bitmap, sdio_card->curr_rd_port);
855 p += sprintf(p, "mp_wr_bitmap=0x%x curr_wr_port=0x%x\n",
856 sdio_card->mp_wr_bitmap, sdio_card->curr_wr_port);
857 }
858
859 for (i = 0; i < adapter->priv_num; i++) {
860 if (!adapter->priv[i] || !adapter->priv[i]->netdev)
861 continue;
862 priv = adapter->priv[i];
863 p += sprintf(p, "\n[interface : \"%s\"]\n",
864 priv->netdev->name);
865 p += sprintf(p, "wmm_tx_pending[0] = %d\n",
866 atomic_read(&priv->wmm_tx_pending[0]));
867 p += sprintf(p, "wmm_tx_pending[1] = %d\n",
868 atomic_read(&priv->wmm_tx_pending[1]));
869 p += sprintf(p, "wmm_tx_pending[2] = %d\n",
870 atomic_read(&priv->wmm_tx_pending[2]));
871 p += sprintf(p, "wmm_tx_pending[3] = %d\n",
872 atomic_read(&priv->wmm_tx_pending[3]));
873 p += sprintf(p, "media_state=\"%s\"\n", !priv->media_connected ?
874 "Disconnected" : "Connected");
875 p += sprintf(p, "carrier %s\n", (netif_carrier_ok(priv->netdev)
876 ? "on" : "off"));
877 for (idx = 0; idx < priv->netdev->num_tx_queues; idx++) {
878 txq = netdev_get_tx_queue(priv->netdev, idx);
879 p += sprintf(p, "tx queue %d:%s ", idx,
880 netif_tx_queue_stopped(txq) ?
881 "stopped" : "started");
882 }
883 p += sprintf(p, "\n%s: num_tx_timeout = %d\n",
884 priv->netdev->name, priv->num_tx_timeout);
885 }
886
887 if (adapter->iface_type == MWIFIEX_SDIO) {
888 p += sprintf(p, "\n=== SDIO register DUMP===\n");
889 if (adapter->if_ops.reg_dump)
890 p += adapter->if_ops.reg_dump(adapter, p);
891 }
892
893 p += sprintf(p, "\n=== MORE DEBUG INFORMATION\n");
894 debug_info = kzalloc(sizeof(*debug_info), GFP_KERNEL);
895 if (debug_info) {
896 for (i = 0; i < adapter->priv_num; i++) {
897 if (!adapter->priv[i] || !adapter->priv[i]->netdev)
898 continue;
899 priv = adapter->priv[i];
900 mwifiex_get_debug_info(priv, debug_info);
901 p += mwifiex_debug_info_to_buffer(priv, p, debug_info);
902 break;
903 }
904 kfree(debug_info);
905 }
906
907 adapter->drv_info_size = p - adapter->drv_info_dump;
908 dev_info(adapter->dev, "=== DRIVER INFO DUMP END===\n");
909}
910EXPORT_SYMBOL_GPL(mwifiex_dump_drv_info);
911
804/* 912/*
805 * CFG802.11 network device handler for statistics retrieval. 913 * CFG802.11 network device handler for statistics retrieval.
806 */ 914 */
@@ -847,6 +955,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
847 * - Nick name : Set to null 955 * - Nick name : Set to null
848 * - Number of Tx timeout : Set to 0 956 * - Number of Tx timeout : Set to 0
849 * - Device address : Set to current address 957 * - Device address : Set to current address
958 * - Rx histogram statistc : Set to 0
850 * 959 *
851 * In addition, the CFG80211 work queue is also created. 960 * In addition, the CFG80211 work queue is also created.
852 */ 961 */
@@ -867,6 +976,13 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
867 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK; 976 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
868 priv->num_tx_timeout = 0; 977 priv->num_tx_timeout = 0;
869 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); 978 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
979
980 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
981 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
982 priv->hist_data = kmalloc(sizeof(*priv->hist_data), GFP_KERNEL);
983 if (priv->hist_data)
984 mwifiex_hist_data_reset(priv);
985 }
870} 986}
871 987
872/* 988/*
@@ -1000,8 +1116,7 @@ err_init_fw:
1000 pr_debug("info: %s: unregister device\n", __func__); 1116 pr_debug("info: %s: unregister device\n", __func__);
1001 if (adapter->if_ops.unregister_dev) 1117 if (adapter->if_ops.unregister_dev)
1002 adapter->if_ops.unregister_dev(adapter); 1118 adapter->if_ops.unregister_dev(adapter);
1003 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) || 1119 if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) {
1004 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
1005 pr_debug("info: %s: shutdown mwifiex\n", __func__); 1120 pr_debug("info: %s: shutdown mwifiex\n", __func__);
1006 adapter->init_wait_q_woken = false; 1121 adapter->init_wait_q_woken = false;
1007 1122
@@ -1052,6 +1167,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1052 1167
1053 adapter->surprise_removed = true; 1168 adapter->surprise_removed = true;
1054 1169
1170 mwifiex_terminate_workqueue(adapter);
1171
1055 /* Stop data */ 1172 /* Stop data */
1056 for (i = 0; i < adapter->priv_num; i++) { 1173 for (i = 0; i < adapter->priv_num; i++) {
1057 priv = adapter->priv[i]; 1174 priv = adapter->priv[i];
@@ -1094,8 +1211,6 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1094 wiphy_unregister(adapter->wiphy); 1211 wiphy_unregister(adapter->wiphy);
1095 wiphy_free(adapter->wiphy); 1212 wiphy_free(adapter->wiphy);
1096 1213
1097 mwifiex_terminate_workqueue(adapter);
1098
1099 /* Unregister device */ 1214 /* Unregister device */
1100 dev_dbg(adapter->dev, "info: unregister device\n"); 1215 dev_dbg(adapter->dev, "info: unregister device\n");
1101 if (adapter->if_ops.unregister_dev) 1216 if (adapter->if_ops.unregister_dev)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e66993cb5daf..55273eefb785 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -41,6 +41,8 @@
41#include "util.h" 41#include "util.h"
42#include "fw.h" 42#include "fw.h"
43#include "pcie.h" 43#include "pcie.h"
44#include "usb.h"
45#include "sdio.h"
44 46
45extern const char driver_version[]; 47extern const char driver_version[];
46 48
@@ -136,6 +138,8 @@ enum {
136/* Threshold for tx_timeout_cnt before we trigger a card reset */ 138/* Threshold for tx_timeout_cnt before we trigger a card reset */
137#define TX_TIMEOUT_THRESHOLD 6 139#define TX_TIMEOUT_THRESHOLD 6
138 140
141#define MWIFIEX_DRV_INFO_SIZE_MAX 0x40000
142
139struct mwifiex_dbg { 143struct mwifiex_dbg {
140 u32 num_cmd_host_to_card_failure; 144 u32 num_cmd_host_to_card_failure;
141 u32 num_cmd_sleep_cfm_host_to_card_failure; 145 u32 num_cmd_sleep_cfm_host_to_card_failure;
@@ -161,7 +165,6 @@ struct mwifiex_dbg {
161enum MWIFIEX_HARDWARE_STATUS { 165enum MWIFIEX_HARDWARE_STATUS {
162 MWIFIEX_HW_STATUS_READY, 166 MWIFIEX_HW_STATUS_READY,
163 MWIFIEX_HW_STATUS_INITIALIZING, 167 MWIFIEX_HW_STATUS_INITIALIZING,
164 MWIFIEX_HW_STATUS_FW_READY,
165 MWIFIEX_HW_STATUS_INIT_DONE, 168 MWIFIEX_HW_STATUS_INIT_DONE,
166 MWIFIEX_HW_STATUS_RESET, 169 MWIFIEX_HW_STATUS_RESET,
167 MWIFIEX_HW_STATUS_CLOSING, 170 MWIFIEX_HW_STATUS_CLOSING,
@@ -413,6 +416,7 @@ struct mwifiex_roc_cfg {
413}; 416};
414 417
415#define MWIFIEX_FW_DUMP_IDX 0xff 418#define MWIFIEX_FW_DUMP_IDX 0xff
419#define MWIFIEX_DRV_INFO_IDX 20
416#define FW_DUMP_MAX_NAME_LEN 8 420#define FW_DUMP_MAX_NAME_LEN 8
417#define FW_DUMP_HOST_READY 0xEE 421#define FW_DUMP_HOST_READY 0xEE
418#define FW_DUMP_DONE 0xFF 422#define FW_DUMP_DONE 0xFF
@@ -582,6 +586,8 @@ struct mwifiex_private {
582 struct idr ack_status_frames; 586 struct idr ack_status_frames;
583 /* spin lock for ack status */ 587 /* spin lock for ack status */
584 spinlock_t ack_status_lock; 588 spinlock_t ack_status_lock;
589 /** rx histogram data */
590 struct mwifiex_histogram_data *hist_data;
585}; 591};
586 592
587enum mwifiex_ba_status { 593enum mwifiex_ba_status {
@@ -717,6 +723,7 @@ struct mwifiex_if_ops {
717 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); 723 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
718 void (*card_reset) (struct mwifiex_adapter *); 724 void (*card_reset) (struct mwifiex_adapter *);
719 void (*fw_dump)(struct mwifiex_adapter *); 725 void (*fw_dump)(struct mwifiex_adapter *);
726 int (*reg_dump)(struct mwifiex_adapter *, char *);
720 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 727 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
721 void (*iface_work)(struct work_struct *work); 728 void (*iface_work)(struct work_struct *work);
722 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); 729 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
@@ -823,6 +830,7 @@ struct mwifiex_adapter {
823 u16 gen_null_pkt; 830 u16 gen_null_pkt;
824 u16 pps_uapsd_mode; 831 u16 pps_uapsd_mode;
825 u32 pm_wakeup_fw_try; 832 u32 pm_wakeup_fw_try;
833 struct timer_list wakeup_timer;
826 u8 is_hs_configured; 834 u8 is_hs_configured;
827 struct mwifiex_hs_config_param hs_cfg; 835 struct mwifiex_hs_config_param hs_cfg;
828 u8 hs_activated; 836 u8 hs_activated;
@@ -865,6 +873,8 @@ struct mwifiex_adapter {
865 struct memory_type_mapping *mem_type_mapping_tbl; 873 struct memory_type_mapping *mem_type_mapping_tbl;
866 u8 num_mem_types; 874 u8 num_mem_types;
867 u8 curr_mem_idx; 875 u8 curr_mem_idx;
876 void *drv_info_dump;
877 u32 drv_info_size;
868 bool scan_chan_gap_enabled; 878 bool scan_chan_gap_enabled;
869 struct sk_buff_head rx_data_q; 879 struct sk_buff_head rx_data_q;
870 struct mwifiex_chan_stats *chan_stats; 880 struct mwifiex_chan_stats *chan_stats;
@@ -1324,6 +1334,8 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
1324 u8 *buf, int len); 1334 u8 *buf, int len);
1325int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action); 1335int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action);
1326int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac); 1336int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac);
1337int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1338 struct tdls_peer_info *buf);
1327void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); 1339void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
1328bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); 1340bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
1329u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, 1341u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
@@ -1348,6 +1360,16 @@ struct sk_buff *
1348mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, 1360mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
1349 struct sk_buff *skb, u8 flag, u64 *cookie); 1361 struct sk_buff *skb, u8 flag, u64 *cookie);
1350 1362
1363void mwifiex_hist_data_set(struct mwifiex_private *priv, u8 rx_rate, s8 snr,
1364 s8 nflr);
1365void mwifiex_hist_data_reset(struct mwifiex_private *priv);
1366void mwifiex_hist_data_add(struct mwifiex_private *priv,
1367 u8 rx_rate, s8 snr, s8 nflr);
1368u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1369 u8 rx_rate, u8 ht_info);
1370
1371void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1372
1351#ifdef CONFIG_DEBUG_FS 1373#ifdef CONFIG_DEBUG_FS
1352void mwifiex_debugfs_init(void); 1374void mwifiex_debugfs_init(void);
1353void mwifiex_debugfs_remove(void); 1375void mwifiex_debugfs_remove(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index c3a20f94f3c9..a460b0e6a151 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1952,8 +1952,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1952 offset += txlen; 1952 offset += txlen;
1953 } while (true); 1953 } while (true);
1954 1954
1955 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", 1955 dev_notice(adapter->dev,
1956 offset); 1956 "info: FW download over, size %d bytes\n", offset);
1957 1957
1958 ret = 0; 1958 ret = 0;
1959 1959
@@ -2064,6 +2064,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
2064 * state until cookie is set */ 2064 * state until cookie is set */
2065 adapter->ps_state = PS_STATE_AWAKE; 2065 adapter->ps_state = PS_STATE_AWAKE;
2066 adapter->pm_wakeup_fw_try = false; 2066 adapter->pm_wakeup_fw_try = false;
2067 del_timer(&adapter->wakeup_timer);
2067 } 2068 }
2068 } 2069 }
2069} 2070}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 984a7a4fa93b..e304f0731647 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1429,6 +1429,12 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1429 return -EBUSY; 1429 return -EBUSY;
1430 } 1430 }
1431 1431
1432 if (adapter->surprise_removed || adapter->is_cmd_timedout) {
1433 dev_err(adapter->dev,
1434 "Ignore scan. Card removed or firmware in bad state\n");
1435 return -EFAULT;
1436 }
1437
1432 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 1438 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1433 adapter->scan_processing = true; 1439 adapter->scan_processing = true;
1434 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 1440 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 933dae137850..a70f103359ea 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -986,8 +986,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
986 offset += txlen; 986 offset += txlen;
987 } while (true); 987 } while (true);
988 988
989 dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", 989 dev_notice(adapter->dev,
990 offset); 990 "info: FW download over, size %d bytes\n", offset);
991 991
992 ret = 0; 992 ret = 0;
993done: 993done:
@@ -1958,8 +1958,8 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1958 1958
1959 pr_err("Resetting card...\n"); 1959 pr_err("Resetting card...\n");
1960 mmc_remove_host(target); 1960 mmc_remove_host(target);
1961 /* 20ms delay is based on experiment with sdhci controller */ 1961 /* 200ms delay is based on experiment with sdhci controller */
1962 mdelay(20); 1962 mdelay(200);
1963 target->rescan_entered = 0; /* rescan non-removable cards */ 1963 target->rescan_entered = 0; /* rescan non-removable cards */
1964 mmc_add_host(target); 1964 mmc_add_host(target);
1965} 1965}
@@ -2023,6 +2023,8 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2023 u32 memory_size; 2023 u32 memory_size;
2024 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL }; 2024 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
2025 2025
2026 mwifiex_dump_drv_info(adapter);
2027
2026 if (!card->supports_fw_dump) 2028 if (!card->supports_fw_dump)
2027 return; 2029 return;
2028 2030
@@ -2166,6 +2168,99 @@ static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2166 schedule_work(&adapter->iface_work); 2168 schedule_work(&adapter->iface_work);
2167} 2169}
2168 2170
2171/* Function to dump SDIO function registers and SDIO scratch registers in case
2172 * of FW crash
2173 */
2174static int
2175mwifiex_sdio_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
2176{
2177 char *p = drv_buf;
2178 struct sdio_mmc_card *cardp = adapter->card;
2179 int ret = 0;
2180 u8 count, func, data, index = 0, size = 0;
2181 u8 reg, reg_start, reg_end;
2182 char buf[256], *ptr;
2183
2184 if (!p)
2185 return 0;
2186
2187 dev_info(adapter->dev, "SDIO register DUMP START\n");
2188
2189 mwifiex_pm_wakeup_card(adapter);
2190
2191 sdio_claim_host(cardp->func);
2192
2193 for (count = 0; count < 5; count++) {
2194 memset(buf, 0, sizeof(buf));
2195 ptr = buf;
2196
2197 switch (count) {
2198 case 0:
2199 /* Read the registers of SDIO function0 */
2200 func = count;
2201 reg_start = 0;
2202 reg_end = 9;
2203 break;
2204 case 1:
2205 /* Read the registers of SDIO function1 */
2206 func = count;
2207 reg_start = cardp->reg->func1_dump_reg_start;
2208 reg_end = cardp->reg->func1_dump_reg_end;
2209 break;
2210 case 2:
2211 index = 0;
2212 func = 1;
2213 reg_start = cardp->reg->func1_spec_reg_table[index++];
2214 size = cardp->reg->func1_spec_reg_num;
2215 reg_end = cardp->reg->func1_spec_reg_table[size-1];
2216 break;
2217 default:
2218 /* Read the scratch registers of SDIO function1 */
2219 if (count == 4)
2220 mdelay(100);
2221 func = 1;
2222 reg_start = cardp->reg->func1_scratch_reg;
2223 reg_end = reg_start + MWIFIEX_SDIO_SCRATCH_SIZE;
2224 }
2225
2226 if (count != 2)
2227 ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ",
2228 func, reg_start, reg_end);
2229 else
2230 ptr += sprintf(ptr, "SDIO Func%d: ", func);
2231
2232 for (reg = reg_start; reg <= reg_end;) {
2233 if (func == 0)
2234 data = sdio_f0_readb(cardp->func, reg, &ret);
2235 else
2236 data = sdio_readb(cardp->func, reg, &ret);
2237
2238 if (count == 2)
2239 ptr += sprintf(ptr, "(%#x) ", reg);
2240 if (!ret) {
2241 ptr += sprintf(ptr, "%02x ", data);
2242 } else {
2243 ptr += sprintf(ptr, "ERR");
2244 break;
2245 }
2246
2247 if (count == 2 && reg < reg_end)
2248 reg = cardp->reg->func1_spec_reg_table[index++];
2249 else
2250 reg++;
2251 }
2252
2253 dev_info(adapter->dev, "%s\n", buf);
2254 p += sprintf(p, "%s\n", buf);
2255 }
2256
2257 sdio_release_host(cardp->func);
2258
2259 dev_info(adapter->dev, "SDIO register DUMP END\n");
2260
2261 return p - drv_buf;
2262}
2263
2169static struct mwifiex_if_ops sdio_ops = { 2264static struct mwifiex_if_ops sdio_ops = {
2170 .init_if = mwifiex_init_sdio, 2265 .init_if = mwifiex_init_sdio,
2171 .cleanup_if = mwifiex_cleanup_sdio, 2266 .cleanup_if = mwifiex_cleanup_sdio,
@@ -2188,6 +2283,7 @@ static struct mwifiex_if_ops sdio_ops = {
2188 .card_reset = mwifiex_sdio_card_reset, 2283 .card_reset = mwifiex_sdio_card_reset,
2189 .iface_work = mwifiex_sdio_work, 2284 .iface_work = mwifiex_sdio_work,
2190 .fw_dump = mwifiex_sdio_fw_dump, 2285 .fw_dump = mwifiex_sdio_fw_dump,
2286 .reg_dump = mwifiex_sdio_reg_dump,
2191}; 2287};
2192 2288
2193/* 2289/*
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 54c07156dd78..895eea054c9e 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -44,6 +44,9 @@
44 44
45#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000 45#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
46 46
47#define MWIFIEX_MAX_FUNC2_REG_NUM 13
48#define MWIFIEX_SDIO_SCRATCH_SIZE 10
49
47#define SDIO_MPA_ADDR_BASE 0x1000 50#define SDIO_MPA_ADDR_BASE 0x1000
48#define CTRL_PORT 0 51#define CTRL_PORT 0
49#define CTRL_PORT_MASK 0x0001 52#define CTRL_PORT_MASK 0x0001
@@ -219,6 +222,11 @@ struct mwifiex_sdio_card_reg {
219 u8 fw_dump_ctrl; 222 u8 fw_dump_ctrl;
220 u8 fw_dump_start; 223 u8 fw_dump_start;
221 u8 fw_dump_end; 224 u8 fw_dump_end;
225 u8 func1_dump_reg_start;
226 u8 func1_dump_reg_end;
227 u8 func1_scratch_reg;
228 u8 func1_spec_reg_num;
229 u8 func1_spec_reg_table[MWIFIEX_MAX_FUNC2_REG_NUM];
222}; 230};
223 231
224struct sdio_mmc_card { 232struct sdio_mmc_card {
@@ -291,6 +299,11 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
291 .rd_len_p0_l = 0x08, 299 .rd_len_p0_l = 0x08,
292 .rd_len_p0_u = 0x09, 300 .rd_len_p0_u = 0x09,
293 .card_misc_cfg_reg = 0x6c, 301 .card_misc_cfg_reg = 0x6c,
302 .func1_dump_reg_start = 0x0,
303 .func1_dump_reg_end = 0x9,
304 .func1_scratch_reg = 0x60,
305 .func1_spec_reg_num = 5,
306 .func1_spec_reg_table = {0x28, 0x30, 0x34, 0x38, 0x3c},
294}; 307};
295 308
296static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = { 309static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
@@ -335,6 +348,12 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
335 .fw_dump_ctrl = 0xe2, 348 .fw_dump_ctrl = 0xe2,
336 .fw_dump_start = 0xe3, 349 .fw_dump_start = 0xe3,
337 .fw_dump_end = 0xea, 350 .fw_dump_end = 0xea,
351 .func1_dump_reg_start = 0x0,
352 .func1_dump_reg_end = 0xb,
353 .func1_scratch_reg = 0xc0,
354 .func1_spec_reg_num = 8,
355 .func1_spec_reg_table = {0x4C, 0x50, 0x54, 0x55, 0x58,
356 0x59, 0x5c, 0x5d},
338}; 357};
339 358
340static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = { 359static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = {
@@ -376,6 +395,13 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = {
376 .cmd_cfg_1 = 0xc5, 395 .cmd_cfg_1 = 0xc5,
377 .cmd_cfg_2 = 0xc6, 396 .cmd_cfg_2 = 0xc6,
378 .cmd_cfg_3 = 0xc7, 397 .cmd_cfg_3 = 0xc7,
398 .func1_dump_reg_start = 0x10,
399 .func1_dump_reg_end = 0x17,
400 .func1_scratch_reg = 0x90,
401 .func1_spec_reg_num = 13,
402 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D, 0x60,
403 0x61, 0x62, 0x64, 0x65, 0x66,
404 0x68, 0x69, 0x6a},
379}; 405};
380 406
381static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { 407static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 1c2ca291d1f5..f7b920d7a95a 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -26,6 +26,10 @@
26#include "11n.h" 26#include "11n.h"
27#include "11ac.h" 27#include "11ac.h"
28 28
29static bool disable_auto_ds;
30module_param(disable_auto_ds, bool, 0);
31MODULE_PARM_DESC(disable_auto_ds,
32 "deepsleep enabled=0(default), deepsleep disabled=1");
29/* 33/*
30 * This function prepares command to set/get RSSI information. 34 * This function prepares command to set/get RSSI information.
31 * 35 *
@@ -2031,7 +2035,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2031 if (ret) 2035 if (ret)
2032 return -1; 2036 return -1;
2033 2037
2034 if (first_sta && priv->adapter->iface_type != MWIFIEX_USB && 2038 if (!disable_auto_ds &&
2039 first_sta && priv->adapter->iface_type != MWIFIEX_USB &&
2035 priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 2040 priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
2036 /* Enable auto deep sleep */ 2041 /* Enable auto deep sleep */
2037 auto_ds.auto_ds = DEEP_SLEEP_ON; 2042 auto_ds.auto_ds = DEEP_SLEEP_ON;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index b65e1014b0fc..65d10a33eab5 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -248,6 +248,8 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv,
248 le32_to_cpu(get_log->wep_icv_err_cnt[2]); 248 le32_to_cpu(get_log->wep_icv_err_cnt[2]);
249 stats->wep_icv_error[3] = 249 stats->wep_icv_error[3] =
250 le32_to_cpu(get_log->wep_icv_err_cnt[3]); 250 le32_to_cpu(get_log->wep_icv_err_cnt[3]);
251 stats->bcn_rcv_cnt = le32_to_cpu(get_log->bcn_rcv_cnt);
252 stats->bcn_miss_cnt = le32_to_cpu(get_log->bcn_miss_cnt);
251 } 253 }
252 254
253 return 0; 255 return 0;
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index b8c171df6223..419e35f1dbf3 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -90,6 +90,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
90 priv->is_data_rate_auto = true; 90 priv->is_data_rate_auto = true;
91 priv->data_rate = 0; 91 priv->data_rate = 0;
92 92
93 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
94 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && priv->hist_data)
95 mwifiex_hist_data_reset(priv);
96
93 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 97 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
94 priv->adhoc_state = ADHOC_IDLE; 98 priv->adhoc_state = ADHOC_IDLE;
95 priv->adhoc_is_link_sensed = false; 99 priv->adhoc_is_link_sensed = false;
@@ -308,6 +312,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
308 adapter->ps_state = PS_STATE_AWAKE; 312 adapter->ps_state = PS_STATE_AWAKE;
309 adapter->pm_wakeup_card_req = false; 313 adapter->pm_wakeup_card_req = false;
310 adapter->pm_wakeup_fw_try = false; 314 adapter->pm_wakeup_fw_try = false;
315 mod_timer(&adapter->wakeup_timer,
316 jiffies + (HZ*3));
311 break; 317 break;
312 } 318 }
313 if (!mwifiex_send_null_packet 319 if (!mwifiex_send_null_packet
@@ -322,6 +328,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
322 adapter->ps_state = PS_STATE_AWAKE; 328 adapter->ps_state = PS_STATE_AWAKE;
323 adapter->pm_wakeup_card_req = false; 329 adapter->pm_wakeup_card_req = false;
324 adapter->pm_wakeup_fw_try = false; 330 adapter->pm_wakeup_fw_try = false;
331 del_timer_sync(&adapter->wakeup_timer);
325 332
326 break; 333 break;
327 334
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 1626868a4b5c..fb9c5fc83e5d 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -902,9 +902,12 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
902 if (wep_key->key_length) { 902 if (wep_key->key_length) {
903 void *enc_key; 903 void *enc_key;
904 904
905 if (encrypt_key->key_disable) 905 if (encrypt_key->key_disable) {
906 memset(&priv->wep_key[index], 0, 906 memset(&priv->wep_key[index], 0,
907 sizeof(struct mwifiex_wep_key)); 907 sizeof(struct mwifiex_wep_key));
908 if (wep_key->key_length)
909 goto done;
910 }
908 911
909 if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2) 912 if (adapter->key_api_major_ver == KEY_API_VER_MAJOR_V2)
910 enc_key = encrypt_key; 913 enc_key = encrypt_key;
@@ -918,6 +921,7 @@ static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
918 return ret; 921 return ret;
919 } 922 }
920 923
924done:
921 if (priv->sec_info.wep_enabled) 925 if (priv->sec_info.wep_enabled)
922 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; 926 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
923 else 927 else
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index c2ad3b63ae70..b8729c9394e9 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -90,6 +90,7 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
90 struct ethhdr *eth; 90 struct ethhdr *eth;
91 u16 rx_pkt_off, rx_pkt_len; 91 u16 rx_pkt_off, rx_pkt_len;
92 u8 *offset; 92 u8 *offset;
93 u8 adj_rx_rate = 0;
93 94
94 local_rx_pd = (struct rxpd *) (skb->data); 95 local_rx_pd = (struct rxpd *) (skb->data);
95 96
@@ -155,6 +156,14 @@ int mwifiex_process_rx_packet(struct mwifiex_private *priv,
155 156
156 priv->rxpd_htinfo = local_rx_pd->ht_info; 157 priv->rxpd_htinfo = local_rx_pd->ht_info;
157 158
159 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
160 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
161 adj_rx_rate = mwifiex_adjust_data_rate(priv, priv->rxpd_rate,
162 priv->rxpd_htinfo);
163 mwifiex_hist_data_add(priv, adj_rx_rate, local_rx_pd->snr,
164 local_rx_pd->nf);
165 }
166
158 ret = mwifiex_recv_packet(priv, skb); 167 ret = mwifiex_recv_packet(priv, skb);
159 if (ret == -1) 168 if (ret == -1)
160 dev_err(priv->adapter->dev, "recv packet failed\n"); 169 dev_err(priv->adapter->dev, "recv packet failed\n");
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index b896d7375b52..1debe76017b1 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -47,8 +47,10 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
47 struct mwifiex_adapter *adapter = priv->adapter; 47 struct mwifiex_adapter *adapter = priv->adapter;
48 struct txpd *local_tx_pd; 48 struct txpd *local_tx_pd;
49 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); 49 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
50 u8 pad; 50 unsigned int pad;
51 u16 pkt_type, pkt_offset; 51 u16 pkt_type, pkt_offset;
52 int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
53 INTF_HEADER_LEN;
52 54
53 if (!skb->len) { 55 if (!skb->len) {
54 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); 56 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
@@ -56,13 +58,12 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
56 return skb->data; 58 return skb->data;
57 } 59 }
58 60
59 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; 61 BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);
60 62
61 /* If skb->data is not aligned; add padding */ 63 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
62 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
63 64
64 BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN 65 pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)-
65 + pad)); 66 NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1);
66 skb_push(skb, sizeof(*local_tx_pd) + pad); 67 skb_push(skb, sizeof(*local_tx_pd) + pad);
67 68
68 local_tx_pd = (struct txpd *) skb->data; 69 local_tx_pd = (struct txpd *) skb->data;
@@ -70,8 +71,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
70 local_tx_pd->bss_num = priv->bss_num; 71 local_tx_pd->bss_num = priv->bss_num;
71 local_tx_pd->bss_type = priv->bss_type; 72 local_tx_pd->bss_type = priv->bss_type;
72 local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len - 73 local_tx_pd->tx_pkt_length = cpu_to_le16((u16)(skb->len -
73 (sizeof(struct txpd) 74 (sizeof(struct txpd) +
74 + pad))); 75 pad)));
75 76
76 local_tx_pd->priority = (u8) skb->priority; 77 local_tx_pd->priority = (u8) skb->priority;
77 local_tx_pd->pkt_delay_2ms = 78 local_tx_pd->pkt_delay_2ms =
@@ -115,7 +116,7 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
115 local_tx_pd->tx_pkt_offset = cpu_to_le16(pkt_offset); 116 local_tx_pd->tx_pkt_offset = cpu_to_le16(pkt_offset);
116 117
117 /* make space for INTF_HEADER_LEN */ 118 /* make space for INTF_HEADER_LEN */
118 skb_push(skb, INTF_HEADER_LEN); 119 skb_push(skb, hroom);
119 120
120 if (!local_tx_pd->tx_control) 121 if (!local_tx_pd->tx_control)
121 /* TxCtrl set by user or default */ 122 /* TxCtrl set by user or default */
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 22884b429be7..087d84762cd3 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -1123,6 +1123,36 @@ int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac)
1123 return TDLS_NOT_SETUP; 1123 return TDLS_NOT_SETUP;
1124} 1124}
1125 1125
1126int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1127 struct tdls_peer_info *buf)
1128{
1129 struct mwifiex_sta_node *sta_ptr;
1130 struct tdls_peer_info *peer = buf;
1131 int count = 0;
1132 unsigned long flags;
1133
1134 if (!ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info))
1135 return 0;
1136
1137 /* make sure we are in station mode and connected */
1138 if (!(priv->bss_type == MWIFIEX_BSS_TYPE_STA && priv->media_connected))
1139 return 0;
1140
1141 spin_lock_irqsave(&priv->sta_list_spinlock, flags);
1142 list_for_each_entry(sta_ptr, &priv->sta_list, list) {
1143 if (sta_ptr->tdls_status == TDLS_SETUP_COMPLETE) {
1144 ether_addr_copy(peer->peer_addr, sta_ptr->mac_addr);
1145 peer++;
1146 count++;
1147 if (count >= MWIFIEX_MAX_TDLS_PEER_SUPPORTED)
1148 break;
1149 }
1150 }
1151 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
1152
1153 return count;
1154}
1155
1126void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv) 1156void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv)
1127{ 1157{
1128 struct mwifiex_sta_node *sta_ptr; 1158 struct mwifiex_sta_node *sta_ptr;
@@ -1367,9 +1397,8 @@ void mwifiex_check_auto_tdls(unsigned long context)
1367 1397
1368void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv) 1398void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv)
1369{ 1399{
1370 init_timer(&priv->auto_tdls_timer); 1400 setup_timer(&priv->auto_tdls_timer, mwifiex_check_auto_tdls,
1371 priv->auto_tdls_timer.function = mwifiex_check_auto_tdls; 1401 (unsigned long)priv);
1372 priv->auto_tdls_timer.data = (unsigned long)priv;
1373 priv->auto_tdls_timer_active = true; 1402 priv->auto_tdls_timer_active = true;
1374 mod_timer(&priv->auto_tdls_timer, 1403 mod_timer(&priv->auto_tdls_timer,
1375 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S)); 1404 jiffies + msecs_to_jiffies(MWIFIEX_TIMER_10S));
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 3b3a970e2086..96ff39722f8f 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -131,6 +131,8 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
131 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); 131 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
132 memcpy(priv->netdev->dev_addr, adapter->event_body + 2, 132 memcpy(priv->netdev->dev_addr, adapter->event_body + 2,
133 ETH_ALEN); 133 ETH_ALEN);
134 if (priv->hist_data)
135 mwifiex_hist_data_reset(priv);
134 break; 136 break;
135 case EVENT_UAP_MIC_COUNTERMEASURES: 137 case EVENT_UAP_MIC_COUNTERMEASURES:
136 /* For future development */ 138 /* For future development */
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index be3a203a529b..38ac4d74c486 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -348,8 +348,10 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
348 struct mwifiex_adapter *adapter = priv->adapter; 348 struct mwifiex_adapter *adapter = priv->adapter;
349 struct uap_txpd *txpd; 349 struct uap_txpd *txpd;
350 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); 350 struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
351 int pad, len; 351 int pad;
352 u16 pkt_type; 352 u16 pkt_type, pkt_offset;
353 int hroom = (priv->adapter->iface_type == MWIFIEX_USB) ? 0 :
354 INTF_HEADER_LEN;
353 355
354 if (!skb->len) { 356 if (!skb->len) {
355 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len); 357 dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
@@ -357,22 +359,21 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
357 return skb->data; 359 return skb->data;
358 } 360 }
359 361
360 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; 362 BUG_ON(skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN);
361
362 /* If skb->data is not aligned, add padding */
363 pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
364 363
365 len = sizeof(*txpd) + pad; 364 pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0;
366 365
367 BUG_ON(skb_headroom(skb) < len + INTF_HEADER_LEN); 366 pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) &
367 (MWIFIEX_DMA_ALIGN_SZ - 1);
368 368
369 skb_push(skb, len); 369 skb_push(skb, sizeof(*txpd) + pad);
370 370
371 txpd = (struct uap_txpd *)skb->data; 371 txpd = (struct uap_txpd *)skb->data;
372 memset(txpd, 0, sizeof(*txpd)); 372 memset(txpd, 0, sizeof(*txpd));
373 txpd->bss_num = priv->bss_num; 373 txpd->bss_num = priv->bss_num;
374 txpd->bss_type = priv->bss_type; 374 txpd->bss_type = priv->bss_type;
375 txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len)); 375 txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - (sizeof(*txpd) +
376 pad)));
376 txpd->priority = (u8)skb->priority; 377 txpd->priority = (u8)skb->priority;
377 378
378 txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb); 379 txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
@@ -392,16 +393,17 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
392 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]); 393 cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
393 394
394 /* Offset of actual data */ 395 /* Offset of actual data */
396 pkt_offset = sizeof(*txpd) + pad;
395 if (pkt_type == PKT_TYPE_MGMT) { 397 if (pkt_type == PKT_TYPE_MGMT) {
396 /* Set the packet type and add header for management frame */ 398 /* Set the packet type and add header for management frame */
397 txpd->tx_pkt_type = cpu_to_le16(pkt_type); 399 txpd->tx_pkt_type = cpu_to_le16(pkt_type);
398 len += MWIFIEX_MGMT_FRAME_HEADER_SIZE; 400 pkt_offset += MWIFIEX_MGMT_FRAME_HEADER_SIZE;
399 } 401 }
400 402
401 txpd->tx_pkt_offset = cpu_to_le16(len); 403 txpd->tx_pkt_offset = cpu_to_le16(pkt_offset);
402 404
403 /* make space for INTF_HEADER_LEN */ 405 /* make space for INTF_HEADER_LEN */
404 skb_push(skb, INTF_HEADER_LEN); 406 skb_push(skb, hroom);
405 407
406 if (!txpd->tx_control) 408 if (!txpd->tx_control)
407 /* TxCtrl set by user or default */ 409 /* TxCtrl set by user or default */
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 1b56495ec872..6c62995028e6 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -930,7 +930,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
930 } while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries); 930 } while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries);
931 931
932cleanup: 932cleanup:
933 dev_dbg(adapter->dev, "%s: %d bytes downloaded\n", __func__, tlen); 933 dev_notice(adapter->dev,
934 "info: FW download over, size %d bytes\n", tlen);
934 935
935 kfree(recv_buff); 936 kfree(recv_buff);
936 kfree(fwdata); 937 kfree(fwdata);
@@ -990,6 +991,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
990{ 991{
991 /* Simulation of HS_AWAKE event */ 992 /* Simulation of HS_AWAKE event */
992 adapter->pm_wakeup_fw_try = false; 993 adapter->pm_wakeup_fw_try = false;
994 del_timer_sync(&adapter->wakeup_timer);
993 adapter->pm_wakeup_card_req = false; 995 adapter->pm_wakeup_card_req = false;
994 adapter->ps_state = PS_STATE_AWAKE; 996 adapter->ps_state = PS_STATE_AWAKE;
995 997
@@ -1010,6 +1012,13 @@ static void mwifiex_usb_submit_rem_rx_urbs(struct mwifiex_adapter *adapter)
1010 } 1012 }
1011} 1013}
1012 1014
1015/* This function is called after the card has woken up. */
1016static inline int
1017mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
1018{
1019 return 0;
1020}
1021
1013static struct mwifiex_if_ops usb_ops = { 1022static struct mwifiex_if_ops usb_ops = {
1014 .register_dev = mwifiex_register_dev, 1023 .register_dev = mwifiex_register_dev,
1015 .unregister_dev = mwifiex_unregister_dev, 1024 .unregister_dev = mwifiex_unregister_dev,
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index a7cbba1355af..0ad1bebc3f93 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -96,11 +96,4 @@ struct fw_data {
96 u8 data[1]; 96 u8 data[1];
97}; 97};
98 98
99/* This function is called after the card has woken up. */
100static inline int
101mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
102{
103 return 0;
104}
105
106#endif /*_MWIFIEX_USB_H */ 99#endif /*_MWIFIEX_USB_H */
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index b1768fbf98f2..707319799942 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -25,6 +25,96 @@
25#include "wmm.h" 25#include "wmm.h"
26#include "11n.h" 26#include "11n.h"
27 27
28static struct mwifiex_debug_data items[] = {
29 {"int_counter", item_size(int_counter),
30 item_addr(int_counter), 1},
31 {"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
32 item_addr(packets_out[WMM_AC_VO]), 1},
33 {"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
34 item_addr(packets_out[WMM_AC_VI]), 1},
35 {"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
36 item_addr(packets_out[WMM_AC_BE]), 1},
37 {"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
38 item_addr(packets_out[WMM_AC_BK]), 1},
39 {"tx_buf_size", item_size(tx_buf_size),
40 item_addr(tx_buf_size), 1},
41 {"curr_tx_buf_size", item_size(curr_tx_buf_size),
42 item_addr(curr_tx_buf_size), 1},
43 {"ps_mode", item_size(ps_mode),
44 item_addr(ps_mode), 1},
45 {"ps_state", item_size(ps_state),
46 item_addr(ps_state), 1},
47 {"is_deep_sleep", item_size(is_deep_sleep),
48 item_addr(is_deep_sleep), 1},
49 {"wakeup_dev_req", item_size(pm_wakeup_card_req),
50 item_addr(pm_wakeup_card_req), 1},
51 {"wakeup_tries", item_size(pm_wakeup_fw_try),
52 item_addr(pm_wakeup_fw_try), 1},
53 {"hs_configured", item_size(is_hs_configured),
54 item_addr(is_hs_configured), 1},
55 {"hs_activated", item_size(hs_activated),
56 item_addr(hs_activated), 1},
57 {"num_tx_timeout", item_size(num_tx_timeout),
58 item_addr(num_tx_timeout), 1},
59 {"is_cmd_timedout", item_size(is_cmd_timedout),
60 item_addr(is_cmd_timedout), 1},
61 {"timeout_cmd_id", item_size(timeout_cmd_id),
62 item_addr(timeout_cmd_id), 1},
63 {"timeout_cmd_act", item_size(timeout_cmd_act),
64 item_addr(timeout_cmd_act), 1},
65 {"last_cmd_id", item_size(last_cmd_id),
66 item_addr(last_cmd_id), DBG_CMD_NUM},
67 {"last_cmd_act", item_size(last_cmd_act),
68 item_addr(last_cmd_act), DBG_CMD_NUM},
69 {"last_cmd_index", item_size(last_cmd_index),
70 item_addr(last_cmd_index), 1},
71 {"last_cmd_resp_id", item_size(last_cmd_resp_id),
72 item_addr(last_cmd_resp_id), DBG_CMD_NUM},
73 {"last_cmd_resp_index", item_size(last_cmd_resp_index),
74 item_addr(last_cmd_resp_index), 1},
75 {"last_event", item_size(last_event),
76 item_addr(last_event), DBG_CMD_NUM},
77 {"last_event_index", item_size(last_event_index),
78 item_addr(last_event_index), 1},
79 {"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
80 item_addr(num_cmd_host_to_card_failure), 1},
81 {"num_cmd_sleep_cfm_fail",
82 item_size(num_cmd_sleep_cfm_host_to_card_failure),
83 item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
84 {"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
85 item_addr(num_tx_host_to_card_failure), 1},
86 {"num_evt_deauth", item_size(num_event_deauth),
87 item_addr(num_event_deauth), 1},
88 {"num_evt_disassoc", item_size(num_event_disassoc),
89 item_addr(num_event_disassoc), 1},
90 {"num_evt_link_lost", item_size(num_event_link_lost),
91 item_addr(num_event_link_lost), 1},
92 {"num_cmd_deauth", item_size(num_cmd_deauth),
93 item_addr(num_cmd_deauth), 1},
94 {"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
95 item_addr(num_cmd_assoc_success), 1},
96 {"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
97 item_addr(num_cmd_assoc_failure), 1},
98 {"cmd_sent", item_size(cmd_sent),
99 item_addr(cmd_sent), 1},
100 {"data_sent", item_size(data_sent),
101 item_addr(data_sent), 1},
102 {"cmd_resp_received", item_size(cmd_resp_received),
103 item_addr(cmd_resp_received), 1},
104 {"event_received", item_size(event_received),
105 item_addr(event_received), 1},
106
107 /* variables defined in struct mwifiex_adapter */
108 {"cmd_pending", adapter_item_size(cmd_pending),
109 adapter_item_addr(cmd_pending), 1},
110 {"tx_pending", adapter_item_size(tx_pending),
111 adapter_item_addr(tx_pending), 1},
112 {"rx_pending", adapter_item_size(rx_pending),
113 adapter_item_addr(rx_pending), 1},
114};
115
116static int num_of_items = ARRAY_SIZE(items);
117
28/* 118/*
29 * Firmware initialization complete callback handler. 119 * Firmware initialization complete callback handler.
30 * 120 *
@@ -97,6 +187,8 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
97 info->rx_tbl); 187 info->rx_tbl);
98 info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv, 188 info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(priv,
99 info->tx_tbl); 189 info->tx_tbl);
190 info->tdls_peer_num = mwifiex_get_tdls_list(priv,
191 info->tdls_list);
100 info->ps_mode = adapter->ps_mode; 192 info->ps_mode = adapter->ps_mode;
101 info->ps_state = adapter->ps_state; 193 info->ps_state = adapter->ps_state;
102 info->is_deep_sleep = adapter->is_deep_sleep; 194 info->is_deep_sleep = adapter->is_deep_sleep;
@@ -141,6 +233,93 @@ int mwifiex_get_debug_info(struct mwifiex_private *priv,
141 return 0; 233 return 0;
142} 234}
143 235
236int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf,
237 struct mwifiex_debug_info *info)
238{
239 char *p = buf;
240 struct mwifiex_debug_data *d = &items[0];
241 size_t size, addr;
242 long val;
243 int i, j;
244
245 if (!info)
246 return 0;
247
248 for (i = 0; i < num_of_items; i++) {
249 p += sprintf(p, "%s=", d[i].name);
250
251 size = d[i].size / d[i].num;
252
253 if (i < (num_of_items - 3))
254 addr = d[i].addr + (size_t)info;
255 else /* The last 3 items are struct mwifiex_adapter variables */
256 addr = d[i].addr + (size_t)priv->adapter;
257
258 for (j = 0; j < d[i].num; j++) {
259 switch (size) {
260 case 1:
261 val = *((u8 *)addr);
262 break;
263 case 2:
264 val = *((u16 *)addr);
265 break;
266 case 4:
267 val = *((u32 *)addr);
268 break;
269 case 8:
270 val = *((long long *)addr);
271 break;
272 default:
273 val = -1;
274 break;
275 }
276
277 p += sprintf(p, "%#lx ", val);
278 addr += size;
279 }
280
281 p += sprintf(p, "\n");
282 }
283
284 if (info->tx_tbl_num) {
285 p += sprintf(p, "Tx BA stream table:\n");
286 for (i = 0; i < info->tx_tbl_num; i++)
287 p += sprintf(p, "tid = %d, ra = %pM\n",
288 info->tx_tbl[i].tid, info->tx_tbl[i].ra);
289 }
290
291 if (info->rx_tbl_num) {
292 p += sprintf(p, "Rx reorder table:\n");
293 for (i = 0; i < info->rx_tbl_num; i++) {
294 p += sprintf(p, "tid = %d, ta = %pM, ",
295 info->rx_tbl[i].tid,
296 info->rx_tbl[i].ta);
297 p += sprintf(p, "start_win = %d, ",
298 info->rx_tbl[i].start_win);
299 p += sprintf(p, "win_size = %d, buffer: ",
300 info->rx_tbl[i].win_size);
301
302 for (j = 0; j < info->rx_tbl[i].win_size; j++)
303 p += sprintf(p, "%c ",
304 info->rx_tbl[i].buffer[j] ?
305 '1' : '0');
306
307 p += sprintf(p, "\n");
308 }
309 }
310
311 if (info->tdls_peer_num) {
312 p += sprintf(p, "TDLS peer table:\n");
313 for (i = 0; i < info->tdls_peer_num; i++) {
314 p += sprintf(p, "peer = %pM",
315 info->tdls_list[i].peer_addr);
316 p += sprintf(p, "\n");
317 }
318 }
319
320 return p - buf;
321}
322
144static int 323static int
145mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len, 324mwifiex_parse_mgmt_packet(struct mwifiex_private *priv, u8 *payload, u16 len,
146 struct rxpd *rx_pd) 325 struct rxpd *rx_pd)
@@ -404,3 +583,44 @@ void mwifiex_del_all_sta_list(struct mwifiex_private *priv)
404 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); 583 spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
405 return; 584 return;
406} 585}
586
587/* This function adds histogram data to histogram array*/
588void mwifiex_hist_data_add(struct mwifiex_private *priv,
589 u8 rx_rate, s8 snr, s8 nflr)
590{
591 struct mwifiex_histogram_data *phist_data = priv->hist_data;
592
593 if (atomic_read(&phist_data->num_samples) > MWIFIEX_HIST_MAX_SAMPLES)
594 mwifiex_hist_data_reset(priv);
595 mwifiex_hist_data_set(priv, rx_rate, snr, nflr);
596}
597
598/* function to add histogram record */
599void mwifiex_hist_data_set(struct mwifiex_private *priv, u8 rx_rate, s8 snr,
600 s8 nflr)
601{
602 struct mwifiex_histogram_data *phist_data = priv->hist_data;
603
604 atomic_inc(&phist_data->num_samples);
605 atomic_inc(&phist_data->rx_rate[rx_rate]);
606 atomic_inc(&phist_data->snr[snr]);
607 atomic_inc(&phist_data->noise_flr[128 + nflr]);
608 atomic_inc(&phist_data->sig_str[nflr - snr]);
609}
610
611/* function to reset histogram data during init/reset */
612void mwifiex_hist_data_reset(struct mwifiex_private *priv)
613{
614 int ix;
615 struct mwifiex_histogram_data *phist_data = priv->hist_data;
616
617 atomic_set(&phist_data->num_samples, 0);
618 for (ix = 0; ix < MWIFIEX_MAX_AC_RX_RATES; ix++)
619 atomic_set(&phist_data->rx_rate[ix], 0);
620 for (ix = 0; ix < MWIFIEX_MAX_SNR; ix++)
621 atomic_set(&phist_data->snr[ix], 0);
622 for (ix = 0; ix < MWIFIEX_MAX_NOISE_FLR; ix++)
623 atomic_set(&phist_data->noise_flr[ix], 0);
624 for (ix = 0; ix < MWIFIEX_MAX_SIG_STRENGTH; ix++)
625 atomic_set(&phist_data->sig_str[ix], 0);
626}
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index 40296cb4a3f1..b541d66c01eb 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -20,6 +20,8 @@
20#ifndef _MWIFIEX_UTIL_H_ 20#ifndef _MWIFIEX_UTIL_H_
21#define _MWIFIEX_UTIL_H_ 21#define _MWIFIEX_UTIL_H_
22 22
23struct mwifiex_private;
24
23struct mwifiex_dma_mapping { 25struct mwifiex_dma_mapping {
24 dma_addr_t addr; 26 dma_addr_t addr;
25 size_t len; 27 size_t len;
@@ -33,6 +35,21 @@ struct mwifiex_cb {
33 }; 35 };
34}; 36};
35 37
38/* size/addr for mwifiex_debug_info */
39#define item_size(n) (FIELD_SIZEOF(struct mwifiex_debug_info, n))
40#define item_addr(n) (offsetof(struct mwifiex_debug_info, n))
41
42/* size/addr for struct mwifiex_adapter */
43#define adapter_item_size(n) (FIELD_SIZEOF(struct mwifiex_adapter, n))
44#define adapter_item_addr(n) (offsetof(struct mwifiex_adapter, n))
45
46struct mwifiex_debug_data {
47 char name[32]; /* variable/array name */
48 u32 size; /* size of the variable/array */
49 size_t addr; /* address of the variable/array */
50 int num; /* number of variables in an array */
51};
52
36static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb) 53static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
37{ 54{
38 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb; 55 struct mwifiex_cb *cb = (struct mwifiex_cb *)skb->cb;
@@ -73,4 +90,7 @@ static inline dma_addr_t MWIFIEX_SKB_DMA_ADDR(struct sk_buff *skb)
73 return mapping.addr; 90 return mapping.addr;
74} 91}
75 92
93int mwifiex_debug_info_to_buffer(struct mwifiex_private *priv, char *buf,
94 struct mwifiex_debug_info *info);
95
76#endif /* !_MWIFIEX_UTIL_H_ */ 96#endif /* !_MWIFIEX_UTIL_H_ */
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index 60698b020851..6d831d4d1b5f 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -1,7 +1,8 @@
1config HERMES 1config HERMES
2 tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" 2 tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
3 depends on (PPC_PMAC || PCI || PCMCIA) 3 depends on (PPC_PMAC || PCI || PCMCIA)
4 depends on CFG80211 && CFG80211_WEXT 4 depends on CFG80211
5 select CFG80211_WEXT
5 select WIRELESS_EXT 6 select WIRELESS_EXT
6 select WEXT_SPY 7 select WEXT_SPY
7 select WEXT_PRIV 8 select WEXT_PRIV
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index 995846422dc0..91f05442de28 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -364,9 +364,7 @@ static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv,
364 atomic_set(&ctx->refcount, 1); 364 atomic_set(&ctx->refcount, 1);
365 init_completion(&ctx->done); 365 init_completion(&ctx->done);
366 366
367 init_timer(&ctx->timer); 367 setup_timer(&ctx->timer, ezusb_request_timerfn, (u_long)ctx);
368 ctx->timer.function = ezusb_request_timerfn;
369 ctx->timer.data = (u_long) ctx;
370 return ctx; 368 return ctx;
371} 369}
372 370
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index bc065e8e348b..5367d510b22d 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -220,6 +220,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
220 struct sk_buff *skb; 220 struct sk_buff *skb;
221 size_t eeprom_hdr_size; 221 size_t eeprom_hdr_size;
222 int ret = 0; 222 int ret = 0;
223 long timeout;
223 224
224 if (priv->fw_var >= 0x509) 225 if (priv->fw_var >= 0x509)
225 eeprom_hdr_size = sizeof(*eeprom_hdr); 226 eeprom_hdr_size = sizeof(*eeprom_hdr);
@@ -249,9 +250,11 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
249 250
250 p54_tx(priv, skb); 251 p54_tx(priv, skb);
251 252
252 if (!wait_for_completion_interruptible_timeout( 253 timeout = wait_for_completion_interruptible_timeout(
253 &priv->eeprom_comp, HZ)) { 254 &priv->eeprom_comp, HZ);
254 wiphy_err(priv->hw->wiphy, "device does not respond!\n"); 255 if (timeout <= 0) {
256 wiphy_err(priv->hw->wiphy,
257 "device does not respond or signal received!\n");
255 ret = -EBUSY; 258 ret = -EBUSY;
256 } 259 }
257 priv->eeprom = NULL; 260 priv->eeprom = NULL;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index d4aee64fb5ea..27a49068d32d 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -431,6 +431,7 @@ static int p54p_open(struct ieee80211_hw *dev)
431{ 431{
432 struct p54p_priv *priv = dev->priv; 432 struct p54p_priv *priv = dev->priv;
433 int err; 433 int err;
434 long timeout;
434 435
435 init_completion(&priv->boot_comp); 436 init_completion(&priv->boot_comp);
436 err = request_irq(priv->pdev->irq, p54p_interrupt, 437 err = request_irq(priv->pdev->irq, p54p_interrupt,
@@ -468,10 +469,12 @@ static int p54p_open(struct ieee80211_hw *dev)
468 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET)); 469 P54P_WRITE(dev_int, cpu_to_le32(ISL38XX_DEV_INT_RESET));
469 P54P_READ(dev_int); 470 P54P_READ(dev_int);
470 471
471 if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { 472 timeout = wait_for_completion_interruptible_timeout(
473 &priv->boot_comp, HZ);
474 if (timeout <= 0) {
472 wiphy_err(dev->wiphy, "Cannot boot firmware!\n"); 475 wiphy_err(dev->wiphy, "Cannot boot firmware!\n");
473 p54p_stop(dev); 476 p54p_stop(dev);
474 return -ETIMEDOUT; 477 return timeout ? -ERESTARTSYS : -ETIMEDOUT;
475 } 478 }
476 479
477 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE)); 480 P54P_WRITE(int_enable, cpu_to_le32(ISL38XX_INT_IDENT_UPDATE));
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 1122dc44c9fd..48a2cad29477 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -240,7 +240,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
240 rt2x00dev->rf_channel = libconf.rf.channel; 240 rt2x00dev->rf_channel = libconf.rf.channel;
241 } 241 }
242 242
243 if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && 243 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_PS_AUTOWAKE) &&
244 (ieee80211_flags & IEEE80211_CONF_CHANGE_PS)) 244 (ieee80211_flags & IEEE80211_CONF_CHANGE_PS))
245 cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); 245 cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
246 246
@@ -257,7 +257,7 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
257 rt2x00link_reset_tuner(rt2x00dev, false); 257 rt2x00link_reset_tuner(rt2x00dev, false);
258 258
259 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && 259 if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
260 test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && 260 rt2x00_has_cap_flag(rt2x00dev, REQUIRE_PS_AUTOWAKE) &&
261 (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && 261 (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
262 (conf->flags & IEEE80211_CONF_PS)) { 262 (conf->flags & IEEE80211_CONF_PS)) {
263 beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; 263 beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9967a1d9f0ec..5639ed816813 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -351,7 +351,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
351 /* 351 /*
352 * Remove L2 padding which was added during 352 * Remove L2 padding which was added during
353 */ 353 */
354 if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) 354 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
355 rt2x00queue_remove_l2pad(entry->skb, header_length); 355 rt2x00queue_remove_l2pad(entry->skb, header_length);
356 356
357 /* 357 /*
@@ -460,7 +460,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
460 * send the status report back. 460 * send the status report back.
461 */ 461 */
462 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { 462 if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
463 if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags)) 463 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_TASKLET_CONTEXT))
464 ieee80211_tx_status(rt2x00dev->hw, entry->skb); 464 ieee80211_tx_status(rt2x00dev->hw, entry->skb);
465 else 465 else
466 ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); 466 ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
@@ -1056,9 +1056,9 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
1056 /* 1056 /*
1057 * Take TX headroom required for alignment into account. 1057 * Take TX headroom required for alignment into account.
1058 */ 1058 */
1059 if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags)) 1059 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_L2PAD))
1060 rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE; 1060 rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
1061 else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) 1061 else if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA))
1062 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; 1062 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
1063 1063
1064 /* 1064 /*
@@ -1069,7 +1069,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
1069 /* 1069 /*
1070 * Allocate tx status FIFO for driver use. 1070 * Allocate tx status FIFO for driver use.
1071 */ 1071 */
1072 if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) { 1072 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_TXSTATUS_FIFO)) {
1073 /* 1073 /*
1074 * Allocate the txstatus fifo. In the worst case the tx 1074 * Allocate the txstatus fifo. In the worst case the tx
1075 * status fifo has to hold the tx status of all entries 1075 * status fifo has to hold the tx status of all entries
@@ -1131,7 +1131,7 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
1131 /* 1131 /*
1132 * Stop rfkill polling. 1132 * Stop rfkill polling.
1133 */ 1133 */
1134 if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1134 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DELAYED_RFKILL))
1135 rt2x00rfkill_unregister(rt2x00dev); 1135 rt2x00rfkill_unregister(rt2x00dev);
1136 1136
1137 /* 1137 /*
@@ -1173,7 +1173,7 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
1173 /* 1173 /*
1174 * Start rfkill polling. 1174 * Start rfkill polling.
1175 */ 1175 */
1176 if (test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1176 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DELAYED_RFKILL))
1177 rt2x00rfkill_register(rt2x00dev); 1177 rt2x00rfkill_register(rt2x00dev);
1178 1178
1179 return 0; 1179 return 0;
@@ -1389,7 +1389,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1389 /* 1389 /*
1390 * Start rfkill polling. 1390 * Start rfkill polling.
1391 */ 1391 */
1392 if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1392 if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DELAYED_RFKILL))
1393 rt2x00rfkill_register(rt2x00dev); 1393 rt2x00rfkill_register(rt2x00dev);
1394 1394
1395 return 0; 1395 return 0;
@@ -1408,7 +1408,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1408 /* 1408 /*
1409 * Stop rfkill polling. 1409 * Stop rfkill polling.
1410 */ 1410 */
1411 if (!test_bit(REQUIRE_DELAYED_RFKILL, &rt2x00dev->cap_flags)) 1411 if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DELAYED_RFKILL))
1412 rt2x00rfkill_unregister(rt2x00dev); 1412 rt2x00rfkill_unregister(rt2x00dev);
1413 1413
1414 /* 1414 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c
index fbae2799e3ee..5813300f68a2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00firmware.c
+++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c
@@ -96,7 +96,7 @@ int rt2x00lib_load_firmware(struct rt2x00_dev *rt2x00dev)
96{ 96{
97 int retval; 97 int retval;
98 98
99 if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags)) 99 if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_FIRMWARE))
100 return 0; 100 return 0;
101 101
102 if (!rt2x00dev->fw) { 102 if (!rt2x00dev->fw) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index cb40245a0695..300876df056f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -119,7 +119,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw,
119 * Use the ATIM queue if appropriate and present. 119 * Use the ATIM queue if appropriate and present.
120 */ 120 */
121 if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && 121 if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
122 test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) 122 rt2x00_has_cap_flag(rt2x00dev, REQUIRE_ATIM_QUEUE))
123 qid = QID_ATIM; 123 qid = QID_ATIM;
124 124
125 queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); 125 queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 66ff36447b94..68b620b2462f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -85,7 +85,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp)
85 memset(skbdesc, 0, sizeof(*skbdesc)); 85 memset(skbdesc, 0, sizeof(*skbdesc));
86 skbdesc->entry = entry; 86 skbdesc->entry = entry;
87 87
88 if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) { 88 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA)) {
89 dma_addr_t skb_dma; 89 dma_addr_t skb_dma;
90 90
91 skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, 91 skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len,
@@ -198,7 +198,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
198 198
199 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); 199 __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
200 200
201 if (!test_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags)) { 201 if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_SW_SEQNO)) {
202 /* 202 /*
203 * rt2800 has a H/W (or F/W) bug, device incorrectly increase 203 * rt2800 has a H/W (or F/W) bug, device incorrectly increase
204 * seqno on retransmited data (non-QOS) frames. To workaround 204 * seqno on retransmited data (non-QOS) frames. To workaround
@@ -484,7 +484,7 @@ static void rt2x00queue_create_tx_descriptor(struct rt2x00_dev *rt2x00dev,
484 rt2x00crypto_create_tx_descriptor(rt2x00dev, skb, txdesc); 484 rt2x00crypto_create_tx_descriptor(rt2x00dev, skb, txdesc);
485 rt2x00queue_create_tx_descriptor_seq(rt2x00dev, skb, txdesc); 485 rt2x00queue_create_tx_descriptor_seq(rt2x00dev, skb, txdesc);
486 486
487 if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags)) 487 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_HT_TX_DESC))
488 rt2x00queue_create_tx_descriptor_ht(rt2x00dev, skb, txdesc, 488 rt2x00queue_create_tx_descriptor_ht(rt2x00dev, skb, txdesc,
489 sta, hwrate); 489 sta, hwrate);
490 else 490 else
@@ -526,7 +526,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry,
526 /* 526 /*
527 * Map the skb to DMA. 527 * Map the skb to DMA.
528 */ 528 */
529 if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags) && 529 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_DMA) &&
530 rt2x00queue_map_txskb(entry)) 530 rt2x00queue_map_txskb(entry))
531 return -ENOMEM; 531 return -ENOMEM;
532 532
@@ -646,7 +646,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
646 */ 646 */
647 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && 647 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
648 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) { 648 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
649 if (test_bit(REQUIRE_COPY_IV, &queue->rt2x00dev->cap_flags)) 649 if (rt2x00_has_cap_flag(queue->rt2x00dev, REQUIRE_COPY_IV))
650 rt2x00crypto_tx_copy_iv(skb, &txdesc); 650 rt2x00crypto_tx_copy_iv(skb, &txdesc);
651 else 651 else
652 rt2x00crypto_tx_remove_iv(skb, &txdesc); 652 rt2x00crypto_tx_remove_iv(skb, &txdesc);
@@ -660,9 +660,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb,
660 * PCI and USB devices, while header alignment only is valid 660 * PCI and USB devices, while header alignment only is valid
661 * for PCI devices. 661 * for PCI devices.
662 */ 662 */
663 if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags)) 663 if (rt2x00_has_cap_flag(queue->rt2x00dev, REQUIRE_L2PAD))
664 rt2x00queue_insert_l2pad(skb, txdesc.header_length); 664 rt2x00queue_insert_l2pad(skb, txdesc.header_length);
665 else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) 665 else if (rt2x00_has_cap_flag(queue->rt2x00dev, REQUIRE_DMA))
666 rt2x00queue_align_frame(skb); 666 rt2x00queue_align_frame(skb);
667 667
668 /* 668 /*
@@ -1178,7 +1178,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev)
1178 if (status) 1178 if (status)
1179 goto exit; 1179 goto exit;
1180 1180
1181 if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) { 1181 if (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_ATIM_QUEUE)) {
1182 status = rt2x00queue_alloc_entries(rt2x00dev->atim); 1182 status = rt2x00queue_alloc_entries(rt2x00dev->atim);
1183 if (status) 1183 if (status)
1184 goto exit; 1184 goto exit;
@@ -1234,7 +1234,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev)
1234 struct data_queue *queue; 1234 struct data_queue *queue;
1235 enum data_queue_qid qid; 1235 enum data_queue_qid qid;
1236 unsigned int req_atim = 1236 unsigned int req_atim =
1237 !!test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags); 1237 rt2x00_has_cap_flag(rt2x00dev, REQUIRE_ATIM_QUEUE);
1238 1238
1239 /* 1239 /*
1240 * We need the following queues: 1240 * We need the following queues:
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 892270dd3e7b..7627af6098eb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -274,7 +274,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
274 * Schedule the delayed work for reading the TX status 274 * Schedule the delayed work for reading the TX status
275 * from the device. 275 * from the device.
276 */ 276 */
277 if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) || 277 if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_TXSTATUS_FIFO) ||
278 !kfifo_is_empty(&rt2x00dev->txstatus_fifo)) 278 !kfifo_is_empty(&rt2x00dev->txstatus_fifo))
279 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); 279 queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
280} 280}
@@ -456,7 +456,7 @@ static bool rt2x00usb_flush_entry(struct queue_entry *entry, void *data)
456 * Kill guardian urb (if required by driver). 456 * Kill guardian urb (if required by driver).
457 */ 457 */
458 if ((entry->queue->qid == QID_BEACON) && 458 if ((entry->queue->qid == QID_BEACON) &&
459 (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))) 459 (rt2x00_has_cap_flag(rt2x00dev, REQUIRE_BEACON_GUARD)))
460 usb_kill_urb(bcn_priv->guardian_urb); 460 usb_kill_urb(bcn_priv->guardian_urb);
461 461
462 return false; 462 return false;
@@ -655,7 +655,7 @@ static int rt2x00usb_alloc_entries(struct data_queue *queue)
655 * then we are done. 655 * then we are done.
656 */ 656 */
657 if (queue->qid != QID_BEACON || 657 if (queue->qid != QID_BEACON ||
658 !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) 658 !rt2x00_has_cap_flag(rt2x00dev, REQUIRE_BEACON_GUARD))
659 return 0; 659 return 0;
660 660
661 for (i = 0; i < queue->limit; i++) { 661 for (i = 0; i < queue->limit; i++) {
@@ -690,7 +690,7 @@ static void rt2x00usb_free_entries(struct data_queue *queue)
690 * then we are done. 690 * then we are done.
691 */ 691 */
692 if (queue->qid != QID_BEACON || 692 if (queue->qid != QID_BEACON ||
693 !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)) 693 !rt2x00_has_cap_flag(rt2x00dev, REQUIRE_BEACON_GUARD))
694 return; 694 return;
695 695
696 for (i = 0; i < queue->limit; i++) { 696 for (i = 0; i < queue->limit; i++) {
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index deab85236bfd..eb203163ed05 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1871,3 +1871,40 @@ bool rtl_btc_status_false(void)
1871 return false; 1871 return false;
1872} 1872}
1873EXPORT_SYMBOL_GPL(rtl_btc_status_false); 1873EXPORT_SYMBOL_GPL(rtl_btc_status_false);
1874
1875void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igvalue)
1876{
1877 struct rtl_priv *rtlpriv = rtl_priv(hw);
1878 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1879
1880 dm_digtable->dig_enable_flag = true;
1881 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
1882 dm_digtable->cur_igvalue = cur_igvalue;
1883 dm_digtable->pre_igvalue = 0;
1884 dm_digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
1885 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
1886 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
1887 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
1888 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
1889 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
1890 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
1891 dm_digtable->rx_gain_max = DM_DIG_MAX;
1892 dm_digtable->rx_gain_min = DM_DIG_MIN;
1893 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
1894 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
1895 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
1896 dm_digtable->pre_cck_cca_thres = 0xff;
1897 dm_digtable->cur_cck_cca_thres = 0x83;
1898 dm_digtable->forbidden_igi = DM_DIG_MIN;
1899 dm_digtable->large_fa_hit = 0;
1900 dm_digtable->recover_cnt = 0;
1901 dm_digtable->dig_min_0 = 0x25;
1902 dm_digtable->dig_min_1 = 0x25;
1903 dm_digtable->media_connect_0 = false;
1904 dm_digtable->media_connect_1 = false;
1905 rtlpriv->dm.dm_initialgain_enable = true;
1906 dm_digtable->bt30_cur_igi = 0x32;
1907 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
1908 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
1909}
1910EXPORT_SYMBOL(rtl_dm_diginit);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 8c87eb54be66..7b64e34f421e 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -35,6 +35,46 @@
35 35
36#define RTL_SUPPORTED_CTRL_FILTER 0xFF 36#define RTL_SUPPORTED_CTRL_FILTER 0xFF
37 37
38#define DM_DIG_THRESH_HIGH 40
39#define DM_DIG_THRESH_LOW 35
40#define DM_FALSEALARM_THRESH_LOW 400
41#define DM_FALSEALARM_THRESH_HIGH 1000
42
43#define DM_DIG_MAX 0x3e
44#define DM_DIG_MIN 0x1e
45#define DM_DIG_MAX_AP 0x32
46#define DM_DIG_BACKOFF_MAX 12
47#define DM_DIG_BACKOFF_MIN -4
48#define DM_DIG_BACKOFF_DEFAULT 10
49
50enum cck_packet_detection_threshold {
51 CCK_PD_STAGE_LOWRSSI = 0,
52 CCK_PD_STAGE_HIGHRSSI = 1,
53 CCK_FA_STAGE_LOW = 2,
54 CCK_FA_STAGE_HIGH = 3,
55 CCK_PD_STAGE_MAX = 4,
56};
57
58enum dm_dig_ext_port_alg_e {
59 DIG_EXT_PORT_STAGE_0 = 0,
60 DIG_EXT_PORT_STAGE_1 = 1,
61 DIG_EXT_PORT_STAGE_2 = 2,
62 DIG_EXT_PORT_STAGE_3 = 3,
63 DIG_EXT_PORT_STAGE_MAX = 4,
64};
65
66enum dm_dig_connect_e {
67 DIG_STA_DISCONNECT,
68 DIG_STA_CONNECT,
69 DIG_STA_BEFORE_CONNECT,
70 DIG_MULTISTA_DISCONNECT,
71 DIG_MULTISTA_CONNECT,
72 DIG_AP_DISCONNECT,
73 DIG_AP_CONNECT,
74 DIG_AP_ADD_STATION,
75 DIG_CONNECT_MAX
76};
77
38extern const struct ieee80211_ops rtl_ops; 78extern const struct ieee80211_ops rtl_ops;
39void rtl_fw_cb(const struct firmware *firmware, void *context); 79void rtl_fw_cb(const struct firmware *firmware, void *context);
40void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context); 80void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context);
@@ -44,5 +84,6 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
44void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data); 84void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
45bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); 85bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
46bool rtl_btc_status_false(void); 86bool rtl_btc_status_false(void);
87void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval);
47 88
48#endif 89#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
index 2aa34d9055f0..d930c1f78721 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../base.h" 27#include "../base.h"
28#include "../pci.h" 28#include "../pci.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "phy.h" 32#include "phy.h"
@@ -341,38 +342,6 @@ static void dm_tx_pwr_track_set_pwr(struct ieee80211_hw *hw,
341 } 342 }
342} 343}
343 344
344static void rtl88e_dm_diginit(struct ieee80211_hw *hw)
345{
346 struct rtl_priv *rtlpriv = rtl_priv(hw);
347 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
348
349 dm_dig->dig_enable_flag = true;
350 dm_dig->cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
351 dm_dig->pre_igvalue = 0;
352 dm_dig->cur_sta_cstate = DIG_STA_DISCONNECT;
353 dm_dig->presta_cstate = DIG_STA_DISCONNECT;
354 dm_dig->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
355 dm_dig->rssi_lowthresh = DM_DIG_THRESH_LOW;
356 dm_dig->rssi_highthresh = DM_DIG_THRESH_HIGH;
357 dm_dig->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
358 dm_dig->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
359 dm_dig->rx_gain_max = DM_DIG_MAX;
360 dm_dig->rx_gain_min = DM_DIG_MIN;
361 dm_dig->back_val = DM_DIG_BACKOFF_DEFAULT;
362 dm_dig->back_range_max = DM_DIG_BACKOFF_MAX;
363 dm_dig->back_range_min = DM_DIG_BACKOFF_MIN;
364 dm_dig->pre_cck_cca_thres = 0xff;
365 dm_dig->cur_cck_cca_thres = 0x83;
366 dm_dig->forbidden_igi = DM_DIG_MIN;
367 dm_dig->large_fa_hit = 0;
368 dm_dig->recover_cnt = 0;
369 dm_dig->dig_min_0 = 0x25;
370 dm_dig->dig_min_1 = 0x25;
371 dm_dig->media_connect_0 = false;
372 dm_dig->media_connect_1 = false;
373 rtlpriv->dm.dm_initialgain_enable = true;
374}
375
376static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 345static u8 rtl88e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
377{ 346{
378 struct rtl_priv *rtlpriv = rtl_priv(hw); 347 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1796,9 +1765,10 @@ static void rtl88e_dm_antenna_diversity(struct ieee80211_hw *hw)
1796void rtl88e_dm_init(struct ieee80211_hw *hw) 1765void rtl88e_dm_init(struct ieee80211_hw *hw)
1797{ 1766{
1798 struct rtl_priv *rtlpriv = rtl_priv(hw); 1767 struct rtl_priv *rtlpriv = rtl_priv(hw);
1768 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
1799 1769
1800 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1770 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1801 rtl88e_dm_diginit(hw); 1771 rtl_dm_diginit(hw, cur_igvalue);
1802 rtl88e_dm_init_dynamic_txpower(hw); 1772 rtl88e_dm_init_dynamic_txpower(hw);
1803 rtl88e_dm_init_edca_turbo(hw); 1773 rtl88e_dm_init_edca_turbo(hw);
1804 rtl88e_dm_init_rate_adaptive_mask(hw); 1774 rtl88e_dm_init_rate_adaptive_mask(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
index 64f1f3ea9807..071ccee69eae 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.h
@@ -186,28 +186,12 @@
186#define BW_AUTO_SWITCH_HIGH_LOW 25 186#define BW_AUTO_SWITCH_HIGH_LOW 25
187#define BW_AUTO_SWITCH_LOW_HIGH 30 187#define BW_AUTO_SWITCH_LOW_HIGH 30
188 188
189#define DM_DIG_THRESH_HIGH 40
190#define DM_DIG_THRESH_LOW 35
191
192#define DM_FALSEALARM_THRESH_LOW 400
193#define DM_FALSEALARM_THRESH_HIGH 1000
194
195#define DM_DIG_MAX 0x3e
196#define DM_DIG_MIN 0x1e
197
198#define DM_DIG_MAX_AP 0x32
199#define DM_DIG_MIN_AP 0x20
200
201#define DM_DIG_FA_UPPER 0x3e 189#define DM_DIG_FA_UPPER 0x3e
202#define DM_DIG_FA_LOWER 0x1e 190#define DM_DIG_FA_LOWER 0x1e
203#define DM_DIG_FA_TH0 0x200 191#define DM_DIG_FA_TH0 0x200
204#define DM_DIG_FA_TH1 0x300 192#define DM_DIG_FA_TH1 0x300
205#define DM_DIG_FA_TH2 0x400 193#define DM_DIG_FA_TH2 0x400
206 194
207#define DM_DIG_BACKOFF_MAX 12
208#define DM_DIG_BACKOFF_MIN -4
209#define DM_DIG_BACKOFF_DEFAULT 10
210
211#define RXPATHSELECTION_SS_TH_W 30 195#define RXPATHSELECTION_SS_TH_W 30
212#define RXPATHSELECTION_DIFF_TH 18 196#define RXPATHSELECTION_DIFF_TH 18
213 197
@@ -262,14 +246,6 @@ enum tag_dynamic_init_gain_operation_type_definition {
262 DIG_OP_TYPE_MAX 246 DIG_OP_TYPE_MAX
263}; 247};
264 248
265enum tag_cck_packet_detection_threshold_type_definition {
266 CCK_PD_STAGE_LOWRSSI = 0,
267 CCK_PD_STAGE_HIGHRSSI = 1,
268 CCK_FA_STAGE_LOW = 2,
269 CCK_FA_STAGE_HIGH = 3,
270 CCK_PD_STAGE_MAX = 4,
271};
272
273enum dm_1r_cca_e { 249enum dm_1r_cca_e {
274 CCA_1R = 0, 250 CCA_1R = 0,
275 CCA_2R = 1, 251 CCA_2R = 1,
@@ -288,23 +264,6 @@ enum dm_sw_ant_switch_e {
288 ANS_ANTENNA_MAX = 3, 264 ANS_ANTENNA_MAX = 3,
289}; 265};
290 266
291enum dm_dig_ext_port_alg_e {
292 DIG_EXT_PORT_STAGE_0 = 0,
293 DIG_EXT_PORT_STAGE_1 = 1,
294 DIG_EXT_PORT_STAGE_2 = 2,
295 DIG_EXT_PORT_STAGE_3 = 3,
296 DIG_EXT_PORT_STAGE_MAX = 4,
297};
298
299enum dm_dig_connect_e {
300 DIG_STA_DISCONNECT = 0,
301 DIG_STA_CONNECT = 1,
302 DIG_STA_BEFORE_CONNECT = 2,
303 DIG_MULTISTA_DISCONNECT = 3,
304 DIG_MULTISTA_CONNECT = 4,
305 DIG_CONNECT_MAX
306};
307
308enum pwr_track_control_method { 267enum pwr_track_control_method {
309 BBSWING, 268 BBSWING,
310 TXAGC 269 TXAGC
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index f6cb5aedfdd1..f5ee67cda73a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -32,6 +32,7 @@
32#include "phy_common.h" 32#include "phy_common.h"
33#include "../pci.h" 33#include "../pci.h"
34#include "../base.h" 34#include "../base.h"
35#include "../core.h"
35 36
36#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) 37#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
37#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) 38#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
@@ -194,36 +195,6 @@ void dm_savepowerindex(struct ieee80211_hw *hw)
194} 195}
195EXPORT_SYMBOL_GPL(dm_savepowerindex); 196EXPORT_SYMBOL_GPL(dm_savepowerindex);
196 197
197static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
198{
199 struct rtl_priv *rtlpriv = rtl_priv(hw);
200 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
201
202 dm_digtable->dig_enable_flag = true;
203 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
204 dm_digtable->cur_igvalue = 0x20;
205 dm_digtable->pre_igvalue = 0x0;
206 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
207 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
208 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
209 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
210 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
211 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
212 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
213 dm_digtable->rx_gain_max = DM_DIG_MAX;
214 dm_digtable->rx_gain_min = DM_DIG_MIN;
215 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
216 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
217 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
218 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
219 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi;
220
221 dm_digtable->forbidden_igi = DM_DIG_MIN;
222 dm_digtable->large_fa_hit = 0;
223 dm_digtable->recover_cnt = 0;
224 dm_digtable->dig_dynamic_min = 0x25;
225}
226
227static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 198static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
228{ 199{
229 struct rtl_priv *rtlpriv = rtl_priv(hw); 200 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -507,27 +478,27 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
507 if (dm_digtable->rssi_val_min > 100) 478 if (dm_digtable->rssi_val_min > 100)
508 dm_digtable->rssi_val_min = 100; 479 dm_digtable->rssi_val_min = 100;
509 480
510 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { 481 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
511 if (dm_digtable->rssi_val_min <= 25) 482 if (dm_digtable->rssi_val_min <= 25)
512 dm_digtable->cur_cck_pd_state = 483 dm_digtable->cur_cck_pd_state =
513 CCK_PD_STAGE_LowRssi; 484 CCK_PD_STAGE_LOWRSSI;
514 else 485 else
515 dm_digtable->cur_cck_pd_state = 486 dm_digtable->cur_cck_pd_state =
516 CCK_PD_STAGE_HighRssi; 487 CCK_PD_STAGE_HIGHRSSI;
517 } else { 488 } else {
518 if (dm_digtable->rssi_val_min <= 20) 489 if (dm_digtable->rssi_val_min <= 20)
519 dm_digtable->cur_cck_pd_state = 490 dm_digtable->cur_cck_pd_state =
520 CCK_PD_STAGE_LowRssi; 491 CCK_PD_STAGE_LOWRSSI;
521 else 492 else
522 dm_digtable->cur_cck_pd_state = 493 dm_digtable->cur_cck_pd_state =
523 CCK_PD_STAGE_HighRssi; 494 CCK_PD_STAGE_HIGHRSSI;
524 } 495 }
525 } else { 496 } else {
526 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 497 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
527 } 498 }
528 499
529 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 500 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
530 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) || 501 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) ||
531 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX)) 502 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
532 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83); 503 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
533 else 504 else
@@ -1374,7 +1345,7 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
1374 rtlpriv->dm.undec_sm_pwdb = -1; 1345 rtlpriv->dm.undec_sm_pwdb = -1;
1375 rtlpriv->dm.undec_sm_cck = -1; 1346 rtlpriv->dm.undec_sm_cck = -1;
1376 rtlpriv->dm.dm_initialgain_enable = true; 1347 rtlpriv->dm.dm_initialgain_enable = true;
1377 rtl92c_dm_diginit(hw); 1348 rtl_dm_diginit(hw, 0x20);
1378 1349
1379 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE; 1350 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
1380 rtl92c_dm_init_dynamic_txpower(hw); 1351 rtl92c_dm_init_dynamic_txpower(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
index 4f232a063636..4422e31fedd9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
@@ -47,25 +47,12 @@
47#define BW_AUTO_SWITCH_HIGH_LOW 25 47#define BW_AUTO_SWITCH_HIGH_LOW 25
48#define BW_AUTO_SWITCH_LOW_HIGH 30 48#define BW_AUTO_SWITCH_LOW_HIGH 30
49 49
50#define DM_DIG_THRESH_HIGH 40
51#define DM_DIG_THRESH_LOW 35
52
53#define DM_FALSEALARM_THRESH_LOW 400
54#define DM_FALSEALARM_THRESH_HIGH 1000
55
56#define DM_DIG_MAX 0x3e
57#define DM_DIG_MIN 0x1e
58
59#define DM_DIG_FA_UPPER 0x32 50#define DM_DIG_FA_UPPER 0x32
60#define DM_DIG_FA_LOWER 0x20 51#define DM_DIG_FA_LOWER 0x20
61#define DM_DIG_FA_TH0 0x20 52#define DM_DIG_FA_TH0 0x20
62#define DM_DIG_FA_TH1 0x100 53#define DM_DIG_FA_TH1 0x100
63#define DM_DIG_FA_TH2 0x200 54#define DM_DIG_FA_TH2 0x200
64 55
65#define DM_DIG_BACKOFF_MAX 12
66#define DM_DIG_BACKOFF_MIN -4
67#define DM_DIG_BACKOFF_DEFAULT 10
68
69#define RXPATHSELECTION_SS_TH_lOW 30 56#define RXPATHSELECTION_SS_TH_lOW 30
70#define RXPATHSELECTION_DIFF_TH 18 57#define RXPATHSELECTION_DIFF_TH 18
71 58
@@ -123,14 +110,6 @@ enum tag_dynamic_init_gain_operation_type_definition {
123 DIG_OP_TYPE_MAX 110 DIG_OP_TYPE_MAX
124}; 111};
125 112
126enum tag_cck_packet_detection_threshold_type_definition {
127 CCK_PD_STAGE_LowRssi = 0,
128 CCK_PD_STAGE_HighRssi = 1,
129 CCK_FA_STAGE_Low = 2,
130 CCK_FA_STAGE_High = 3,
131 CCK_PD_STAGE_MAX = 4,
132};
133
134enum dm_1r_cca_e { 113enum dm_1r_cca_e {
135 CCA_1R = 0, 114 CCA_1R = 0,
136 CCA_2R = 1, 115 CCA_2R = 1,
@@ -149,23 +128,6 @@ enum dm_sw_ant_switch_e {
149 ANS_ANTENNA_MAX = 3, 128 ANS_ANTENNA_MAX = 3,
150}; 129};
151 130
152enum dm_dig_ext_port_alg_e {
153 DIG_EXT_PORT_STAGE_0 = 0,
154 DIG_EXT_PORT_STAGE_1 = 1,
155 DIG_EXT_PORT_STAGE_2 = 2,
156 DIG_EXT_PORT_STAGE_3 = 3,
157 DIG_EXT_PORT_STAGE_MAX = 4,
158};
159
160enum dm_dig_connect_e {
161 DIG_STA_DISCONNECT = 0,
162 DIG_STA_CONNECT = 1,
163 DIG_STA_BEFORE_CONNECT = 2,
164 DIG_MULTISTA_DISCONNECT = 3,
165 DIG_MULTISTA_CONNECT = 4,
166 DIG_CONNECT_MAX
167};
168
169void rtl92c_dm_init(struct ieee80211_hw *hw); 131void rtl92c_dm_init(struct ieee80211_hw *hw);
170void rtl92c_dm_watchdog(struct ieee80211_hw *hw); 132void rtl92c_dm_watchdog(struct ieee80211_hw *hw);
171void rtl92c_dm_write_dig(struct ieee80211_hw *hw); 133void rtl92c_dm_write_dig(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
index 74f9c083b80d..09898cf2e07a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
@@ -30,6 +30,7 @@
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../base.h" 31#include "../base.h"
32#include "../pci.h" 32#include "../pci.h"
33#include "../core.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
index 9c5311c299fd..38ba707015f5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
@@ -42,25 +42,12 @@
42#define BW_AUTO_SWITCH_HIGH_LOW 25 42#define BW_AUTO_SWITCH_HIGH_LOW 25
43#define BW_AUTO_SWITCH_LOW_HIGH 30 43#define BW_AUTO_SWITCH_LOW_HIGH 30
44 44
45#define DM_DIG_THRESH_HIGH 40
46#define DM_DIG_THRESH_LOW 35
47
48#define DM_FALSEALARM_THRESH_LOW 400
49#define DM_FALSEALARM_THRESH_HIGH 1000
50
51#define DM_DIG_MAX 0x3e
52#define DM_DIG_MIN 0x1e
53
54#define DM_DIG_FA_UPPER 0x32 45#define DM_DIG_FA_UPPER 0x32
55#define DM_DIG_FA_LOWER 0x20 46#define DM_DIG_FA_LOWER 0x20
56#define DM_DIG_FA_TH0 0x20 47#define DM_DIG_FA_TH0 0x20
57#define DM_DIG_FA_TH1 0x100 48#define DM_DIG_FA_TH1 0x100
58#define DM_DIG_FA_TH2 0x200 49#define DM_DIG_FA_TH2 0x200
59 50
60#define DM_DIG_BACKOFF_MAX 12
61#define DM_DIG_BACKOFF_MIN -4
62#define DM_DIG_BACKOFF_DEFAULT 10
63
64#define RXPATHSELECTION_SS_TH_lOW 30 51#define RXPATHSELECTION_SS_TH_lOW 30
65#define RXPATHSELECTION_DIFF_TH 18 52#define RXPATHSELECTION_DIFF_TH 18
66 53
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
index 304c443b89b2..a1be5a68edfb 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c
@@ -29,6 +29,7 @@
29 29
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../base.h" 31#include "../base.h"
32#include "../core.h"
32#include "reg.h" 33#include "reg.h"
33#include "def.h" 34#include "def.h"
34#include "phy.h" 35#include "phy.h"
@@ -155,34 +156,6 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
155 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ 156 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */
156}; 157};
157 158
158static void rtl92d_dm_diginit(struct ieee80211_hw *hw)
159{
160 struct rtl_priv *rtlpriv = rtl_priv(hw);
161 struct dig_t *de_digtable = &rtlpriv->dm_digtable;
162
163 de_digtable->dig_enable_flag = true;
164 de_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
165 de_digtable->cur_igvalue = 0x20;
166 de_digtable->pre_igvalue = 0x0;
167 de_digtable->cursta_cstate = DIG_STA_DISCONNECT;
168 de_digtable->presta_cstate = DIG_STA_DISCONNECT;
169 de_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
170 de_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
171 de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
172 de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
173 de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
174 de_digtable->rx_gain_max = DM_DIG_FA_UPPER;
175 de_digtable->rx_gain_min = DM_DIG_FA_LOWER;
176 de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
177 de_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
178 de_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
179 de_digtable->pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
180 de_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
181 de_digtable->large_fa_hit = 0;
182 de_digtable->recover_cnt = 0;
183 de_digtable->forbidden_igi = DM_DIG_FA_LOWER;
184}
185
186static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 159static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
187{ 160{
188 u32 ret_value; 161 u32 ret_value;
@@ -1305,7 +1278,9 @@ void rtl92d_dm_init(struct ieee80211_hw *hw)
1305 struct rtl_priv *rtlpriv = rtl_priv(hw); 1278 struct rtl_priv *rtlpriv = rtl_priv(hw);
1306 1279
1307 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1280 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1308 rtl92d_dm_diginit(hw); 1281 rtl_dm_diginit(hw, 0x20);
1282 rtlpriv->dm_digtable.rx_gain_max = DM_DIG_FA_UPPER;
1283 rtlpriv->dm_digtable.rx_gain_min = DM_DIG_FA_LOWER;
1309 rtl92d_dm_init_dynamic_txpower(hw); 1284 rtl92d_dm_init_dynamic_txpower(hw);
1310 rtl92d_dm_init_edca_turbo(hw); 1285 rtl92d_dm_init_edca_turbo(hw);
1311 rtl92d_dm_init_rate_adaptive_mask(hw); 1286 rtl92d_dm_init_rate_adaptive_mask(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
index 3fea0c11c24a..f2d318ceeb28 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h
@@ -42,25 +42,12 @@
42#define BW_AUTO_SWITCH_HIGH_LOW 25 42#define BW_AUTO_SWITCH_HIGH_LOW 25
43#define BW_AUTO_SWITCH_LOW_HIGH 30 43#define BW_AUTO_SWITCH_LOW_HIGH 30
44 44
45#define DM_DIG_THRESH_HIGH 40
46#define DM_DIG_THRESH_LOW 35
47
48#define DM_FALSEALARM_THRESH_LOW 400
49#define DM_FALSEALARM_THRESH_HIGH 1000
50
51#define DM_DIG_MAX 0x3e
52#define DM_DIG_MIN 0x1c
53
54#define DM_DIG_FA_UPPER 0x32 45#define DM_DIG_FA_UPPER 0x32
55#define DM_DIG_FA_LOWER 0x20 46#define DM_DIG_FA_LOWER 0x20
56#define DM_DIG_FA_TH0 0x100 47#define DM_DIG_FA_TH0 0x100
57#define DM_DIG_FA_TH1 0x400 48#define DM_DIG_FA_TH1 0x400
58#define DM_DIG_FA_TH2 0x600 49#define DM_DIG_FA_TH2 0x600
59 50
60#define DM_DIG_BACKOFF_MAX 12
61#define DM_DIG_BACKOFF_MIN -4
62#define DM_DIG_BACKOFF_DEFAULT 10
63
64#define RXPATHSELECTION_SS_TH_lOW 30 51#define RXPATHSELECTION_SS_TH_lOW 30
65#define RXPATHSELECTION_DIFF_TH 18 52#define RXPATHSELECTION_DIFF_TH 18
66 53
@@ -108,14 +95,6 @@ enum tag_dynamic_init_gain_operation_type_definition {
108 DIG_OP_TYPE_MAX 95 DIG_OP_TYPE_MAX
109}; 96};
110 97
111enum tag_cck_packet_detection_threshold_type_definition {
112 CCK_PD_STAGE_LOWRSSI = 0,
113 CCK_PD_STAGE_HIGHRSSI = 1,
114 CCK_FA_STAGE_LOW = 2,
115 CCK_FA_STAGE_HIGH = 3,
116 CCK_PD_STAGE_MAX = 4,
117};
118
119enum dm_1r_cca { 98enum dm_1r_cca {
120 CCA_1R = 0, 99 CCA_1R = 0,
121 CCA_2R = 1, 100 CCA_2R = 1,
@@ -134,23 +113,6 @@ enum dm_sw_ant_switch {
134 ANS_ANTENNA_MAX = 3, 113 ANS_ANTENNA_MAX = 3,
135}; 114};
136 115
137enum dm_dig_ext_port_alg {
138 DIG_EXT_PORT_STAGE_0 = 0,
139 DIG_EXT_PORT_STAGE_1 = 1,
140 DIG_EXT_PORT_STAGE_2 = 2,
141 DIG_EXT_PORT_STAGE_3 = 3,
142 DIG_EXT_PORT_STAGE_MAX = 4,
143};
144
145enum dm_dig_connect {
146 DIG_STA_DISCONNECT = 0,
147 DIG_STA_CONNECT = 1,
148 DIG_STA_BEFORE_CONNECT = 2,
149 DIG_MULTISTA_DISCONNECT = 3,
150 DIG_MULTISTA_CONNECT = 4,
151 DIG_CONNECT_MAX
152};
153
154void rtl92d_dm_init(struct ieee80211_hw *hw); 116void rtl92d_dm_init(struct ieee80211_hw *hw);
155void rtl92d_dm_watchdog(struct ieee80211_hw *hw); 117void rtl92d_dm_watchdog(struct ieee80211_hw *hw);
156void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw); 118void rtl92d_dm_init_edca_turbo(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 280c3da42993..01bcc2d218dc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -546,7 +546,7 @@ static bool _rtl92de_llt_table_init(struct ieee80211_hw *hw)
546 txpktbuf_bndy = 246; 546 txpktbuf_bndy = 246;
547 value8 = 0; 547 value8 = 0;
548 value32 = 0x80bf0d29; 548 value32 = 0x80bf0d29;
549 } else if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { 549 } else {
550 maxPage = 127; 550 maxPage = 127;
551 txpktbuf_bndy = 123; 551 txpktbuf_bndy = 123;
552 value8 = 0; 552 value8 = 0;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c
index 77deedf79d1d..459f3d0efa2f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/dm.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../base.h" 27#include "../base.h"
28#include "../pci.h" 28#include "../pci.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "phy.h" 32#include "phy.h"
@@ -151,35 +152,6 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
151 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */ 152 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} /* 32, -16.0dB */
152}; 153};
153 154
154static void rtl92ee_dm_diginit(struct ieee80211_hw *hw)
155{
156 struct rtl_priv *rtlpriv = rtl_priv(hw);
157 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
158
159 dm_dig->cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N,
160 DM_BIT_IGI_11N);
161 dm_dig->rssi_lowthresh = DM_DIG_THRESH_LOW;
162 dm_dig->rssi_highthresh = DM_DIG_THRESH_HIGH;
163 dm_dig->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
164 dm_dig->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
165 dm_dig->rx_gain_max = DM_DIG_MAX;
166 dm_dig->rx_gain_min = DM_DIG_MIN;
167 dm_dig->back_val = DM_DIG_BACKOFF_DEFAULT;
168 dm_dig->back_range_max = DM_DIG_BACKOFF_MAX;
169 dm_dig->back_range_min = DM_DIG_BACKOFF_MIN;
170 dm_dig->pre_cck_cca_thres = 0xff;
171 dm_dig->cur_cck_cca_thres = 0x83;
172 dm_dig->forbidden_igi = DM_DIG_MIN;
173 dm_dig->large_fa_hit = 0;
174 dm_dig->recover_cnt = 0;
175 dm_dig->dig_dynamic_min = DM_DIG_MIN;
176 dm_dig->dig_dynamic_min_1 = DM_DIG_MIN;
177 dm_dig->media_connect_0 = false;
178 dm_dig->media_connect_1 = false;
179 rtlpriv->dm.dm_initialgain_enable = true;
180 dm_dig->bt30_cur_igi = 0x32;
181}
182
183static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 155static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
184{ 156{
185 u32 ret_value; 157 u32 ret_value;
@@ -298,7 +270,7 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
298 struct rtl_priv *rtlpriv = rtl_priv(hw); 270 struct rtl_priv *rtlpriv = rtl_priv(hw);
299 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 271 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
300 struct dig_t *dm_dig = &rtlpriv->dm_digtable; 272 struct dig_t *dm_dig = &rtlpriv->dm_digtable;
301 u8 dig_dynamic_min , dig_maxofmin; 273 u8 dig_min_0, dig_maxofmin;
302 bool bfirstconnect , bfirstdisconnect; 274 bool bfirstconnect , bfirstdisconnect;
303 u8 dm_dig_max, dm_dig_min; 275 u8 dm_dig_max, dm_dig_min;
304 u8 current_igi = dm_dig->cur_igvalue; 276 u8 current_igi = dm_dig->cur_igvalue;
@@ -308,7 +280,7 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
308 if (mac->act_scanning) 280 if (mac->act_scanning)
309 return; 281 return;
310 282
311 dig_dynamic_min = dm_dig->dig_dynamic_min; 283 dig_min_0 = dm_dig->dig_min_0;
312 bfirstconnect = (mac->link_state >= MAC80211_LINKED) && 284 bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
313 !dm_dig->media_connect_0; 285 !dm_dig->media_connect_0;
314 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) && 286 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
@@ -329,19 +301,19 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
329 if (rtlpriv->dm.one_entry_only) { 301 if (rtlpriv->dm.one_entry_only) {
330 offset = 0; 302 offset = 0;
331 if (dm_dig->rssi_val_min - offset < dm_dig_min) 303 if (dm_dig->rssi_val_min - offset < dm_dig_min)
332 dig_dynamic_min = dm_dig_min; 304 dig_min_0 = dm_dig_min;
333 else if (dm_dig->rssi_val_min - offset > 305 else if (dm_dig->rssi_val_min - offset >
334 dig_maxofmin) 306 dig_maxofmin)
335 dig_dynamic_min = dig_maxofmin; 307 dig_min_0 = dig_maxofmin;
336 else 308 else
337 dig_dynamic_min = dm_dig->rssi_val_min - offset; 309 dig_min_0 = dm_dig->rssi_val_min - offset;
338 } else { 310 } else {
339 dig_dynamic_min = dm_dig_min; 311 dig_min_0 = dm_dig_min;
340 } 312 }
341 313
342 } else { 314 } else {
343 dm_dig->rx_gain_max = dm_dig_max; 315 dm_dig->rx_gain_max = dm_dig_max;
344 dig_dynamic_min = dm_dig_min; 316 dig_min_0 = dm_dig_min;
345 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); 317 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
346 } 318 }
347 319
@@ -368,10 +340,10 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
368 } else { 340 } else {
369 if (dm_dig->large_fa_hit < 3) { 341 if (dm_dig->large_fa_hit < 3) {
370 if ((dm_dig->forbidden_igi - 1) < 342 if ((dm_dig->forbidden_igi - 1) <
371 dig_dynamic_min) { 343 dig_min_0) {
372 dm_dig->forbidden_igi = dig_dynamic_min; 344 dm_dig->forbidden_igi = dig_min_0;
373 dm_dig->rx_gain_min = 345 dm_dig->rx_gain_min =
374 dig_dynamic_min; 346 dig_min_0;
375 } else { 347 } else {
376 dm_dig->forbidden_igi--; 348 dm_dig->forbidden_igi--;
377 dm_dig->rx_gain_min = 349 dm_dig->rx_gain_min =
@@ -430,7 +402,7 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw)
430 rtl92ee_dm_write_dig(hw , current_igi); 402 rtl92ee_dm_write_dig(hw , current_igi);
431 dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ? 403 dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ?
432 true : false); 404 true : false);
433 dm_dig->dig_dynamic_min = dig_dynamic_min; 405 dm_dig->dig_min_0 = dig_min_0;
434} 406}
435 407
436void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres) 408void rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres)
@@ -1088,10 +1060,11 @@ static void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
1088void rtl92ee_dm_init(struct ieee80211_hw *hw) 1060void rtl92ee_dm_init(struct ieee80211_hw *hw)
1089{ 1061{
1090 struct rtl_priv *rtlpriv = rtl_priv(hw); 1062 struct rtl_priv *rtlpriv = rtl_priv(hw);
1063 u32 cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N, DM_BIT_IGI_11N);
1091 1064
1092 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1065 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1093 1066
1094 rtl92ee_dm_diginit(hw); 1067 rtl_dm_diginit(hw, cur_igvalue);
1095 rtl92ee_dm_init_rate_adaptive_mask(hw); 1068 rtl92ee_dm_init_rate_adaptive_mask(hw);
1096 rtl92ee_dm_init_primary_cca_check(hw); 1069 rtl92ee_dm_init_primary_cca_check(hw);
1097 rtl92ee_dm_init_edca_turbo(hw); 1070 rtl92ee_dm_init_edca_turbo(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h
index 881db7d6fef7..107d5a488fa8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/dm.h
@@ -189,28 +189,12 @@
189#define BW_AUTO_SWITCH_HIGH_LOW 25 189#define BW_AUTO_SWITCH_HIGH_LOW 25
190#define BW_AUTO_SWITCH_LOW_HIGH 30 190#define BW_AUTO_SWITCH_LOW_HIGH 30
191 191
192#define DM_DIG_THRESH_HIGH 40
193#define DM_DIG_THRESH_LOW 35
194
195#define DM_FALSEALARM_THRESH_LOW 400
196#define DM_FALSEALARM_THRESH_HIGH 1000
197
198#define DM_DIG_MAX 0x3e
199#define DM_DIG_MIN 0x1e
200
201#define DM_DIG_MAX_AP 0x32
202#define DM_DIG_MIN_AP 0x20
203
204#define DM_DIG_FA_UPPER 0x3e 192#define DM_DIG_FA_UPPER 0x3e
205#define DM_DIG_FA_LOWER 0x1e 193#define DM_DIG_FA_LOWER 0x1e
206#define DM_DIG_FA_TH0 0x200 194#define DM_DIG_FA_TH0 0x200
207#define DM_DIG_FA_TH1 0x300 195#define DM_DIG_FA_TH1 0x300
208#define DM_DIG_FA_TH2 0x400 196#define DM_DIG_FA_TH2 0x400
209 197
210#define DM_DIG_BACKOFF_MAX 12
211#define DM_DIG_BACKOFF_MIN -4
212#define DM_DIG_BACKOFF_DEFAULT 10
213
214#define RXPATHSELECTION_SS_TH_LOW 30 198#define RXPATHSELECTION_SS_TH_LOW 30
215#define RXPATHSELECTION_DIFF_TH 18 199#define RXPATHSELECTION_DIFF_TH 18
216 200
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
index b3a2d5ec59e6..575980b88658 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -29,6 +29,7 @@
29 29
30#include "../wifi.h" 30#include "../wifi.h"
31#include "../base.h" 31#include "../base.h"
32#include "../core.h"
32#include "reg.h" 33#include "reg.h"
33#include "def.h" 34#include "def.h"
34#include "phy.h" 35#include "phy.h"
@@ -469,7 +470,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
469 if (digtable->backoff_enable_flag) 470 if (digtable->backoff_enable_flag)
470 rtl92s_backoff_enable_flag(hw); 471 rtl92s_backoff_enable_flag(hw);
471 else 472 else
472 digtable->back_val = DM_DIG_BACKOFF; 473 digtable->back_val = DM_DIG_BACKOFF_MAX;
473 474
474 if ((digtable->rssi_val + 10 - digtable->back_val) > 475 if ((digtable->rssi_val + 10 - digtable->back_val) >
475 digtable->rx_gain_max) 476 digtable->rx_gain_max)
@@ -503,7 +504,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
503 digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 504 digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
504 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); 505 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
505 506
506 digtable->back_val = DM_DIG_BACKOFF; 507 digtable->back_val = DM_DIG_BACKOFF_MAX;
507 digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; 508 digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
508 digtable->pre_igvalue = 0; 509 digtable->pre_igvalue = 0;
509 return; 510 return;
@@ -691,7 +692,7 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
691 692
692 /* for dig debug rssi value */ 693 /* for dig debug rssi value */
693 digtable->rssi_val = 50; 694 digtable->rssi_val = 50;
694 digtable->back_val = DM_DIG_BACKOFF; 695 digtable->back_val = DM_DIG_BACKOFF_MAX;
695 digtable->rx_gain_max = DM_DIG_MAX; 696 digtable->rx_gain_max = DM_DIG_MAX;
696 697
697 digtable->rx_gain_min = DM_DIG_MIN; 698 digtable->rx_gain_min = DM_DIG_MIN;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
index 2e9052c8fe4b..de6ac796c74d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
@@ -54,24 +54,6 @@ enum dm_dig_sta {
54 DM_STA_DIG_MAX 54 DM_STA_DIG_MAX
55}; 55};
56 56
57enum dm_dig_connect {
58 DIG_STA_DISCONNECT = 0,
59 DIG_STA_CONNECT = 1,
60 DIG_STA_BEFORE_CONNECT = 2,
61 DIG_AP_DISCONNECT = 3,
62 DIG_AP_CONNECT = 4,
63 DIG_AP_ADD_STATION = 5,
64 DIG_CONNECT_MAX
65};
66
67enum dm_dig_ext_port_alg {
68 DIG_EXT_PORT_STAGE_0 = 0,
69 DIG_EXT_PORT_STAGE_1 = 1,
70 DIG_EXT_PORT_STAGE_2 = 2,
71 DIG_EXT_PORT_STAGE_3 = 3,
72 DIG_EXT_PORT_STAGE_MAX = 4,
73};
74
75enum dm_ratr_sta { 57enum dm_ratr_sta {
76 DM_RATR_STA_HIGH = 0, 58 DM_RATR_STA_HIGH = 0,
77 DM_RATR_STA_MIDDLEHIGH = 1, 59 DM_RATR_STA_MIDDLEHIGH = 1,
@@ -99,22 +81,12 @@ enum dm_ratr_sta {
99#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 81#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
100#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 82#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
101 83
102#define DM_DIG_THRESH_HIGH 40
103#define DM_DIG_THRESH_LOW 35
104#define DM_FALSEALARM_THRESH_LOW 40
105#define DM_FALSEALARM_THRESH_HIGH 1000
106#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 84#define DM_DIG_HIGH_PWR_THRESH_HIGH 75
107#define DM_DIG_HIGH_PWR_THRESH_LOW 70 85#define DM_DIG_HIGH_PWR_THRESH_LOW 70
108#define DM_DIG_BACKOFF 12
109#define DM_DIG_MAX 0x3e
110#define DM_DIG_MIN 0x1c
111#define DM_DIG_MIN_Netcore 0x12 86#define DM_DIG_MIN_Netcore 0x12
112#define DM_DIG_BACKOFF_MAX 12
113#define DM_DIG_BACKOFF_MIN -4
114 87
115void rtl92s_dm_watchdog(struct ieee80211_hw *hw); 88void rtl92s_dm_watchdog(struct ieee80211_hw *hw);
116void rtl92s_dm_init(struct ieee80211_hw *hw); 89void rtl92s_dm_init(struct ieee80211_hw *hw);
117void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw); 90void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw);
118 91
119#endif 92#endif
120
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
index a0e86922780a..4c1c96c96a5a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../base.h" 27#include "../base.h"
28#include "../pci.h" 28#include "../pci.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "phy.h" 32#include "phy.h"
@@ -146,31 +147,6 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
146 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} 147 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
147}; 148};
148 149
149static void rtl8723e_dm_diginit(struct ieee80211_hw *hw)
150{
151 struct rtl_priv *rtlpriv = rtl_priv(hw);
152 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
153
154 dm_digtable->dig_enable_flag = true;
155 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
156 dm_digtable->cur_igvalue = 0x20;
157 dm_digtable->pre_igvalue = 0x0;
158 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
159 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
160 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
161 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
162 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
163 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
164 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
165 dm_digtable->rx_gain_max = DM_DIG_MAX;
166 dm_digtable->rx_gain_min = DM_DIG_MIN;
167 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
168 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
169 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
170 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
171 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
172}
173
174static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 150static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
175{ 151{
176 struct rtl_priv *rtlpriv = rtl_priv(hw); 152 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -395,30 +371,30 @@ static void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
395 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 371 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
396 dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw); 372 dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw);
397 373
398 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { 374 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
399 if (dm_digtable->rssi_val_min <= 25) 375 if (dm_digtable->rssi_val_min <= 25)
400 dm_digtable->cur_cck_pd_state = 376 dm_digtable->cur_cck_pd_state =
401 CCK_PD_STAGE_LowRssi; 377 CCK_PD_STAGE_LOWRSSI;
402 else 378 else
403 dm_digtable->cur_cck_pd_state = 379 dm_digtable->cur_cck_pd_state =
404 CCK_PD_STAGE_HighRssi; 380 CCK_PD_STAGE_HIGHRSSI;
405 } else { 381 } else {
406 if (dm_digtable->rssi_val_min <= 20) 382 if (dm_digtable->rssi_val_min <= 20)
407 dm_digtable->cur_cck_pd_state = 383 dm_digtable->cur_cck_pd_state =
408 CCK_PD_STAGE_LowRssi; 384 CCK_PD_STAGE_LOWRSSI;
409 else 385 else
410 dm_digtable->cur_cck_pd_state = 386 dm_digtable->cur_cck_pd_state =
411 CCK_PD_STAGE_HighRssi; 387 CCK_PD_STAGE_HIGHRSSI;
412 } 388 }
413 } else { 389 } else {
414 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 390 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
415 } 391 }
416 392
417 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 393 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
418 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { 394 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
419 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) 395 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
420 dm_digtable->cur_cck_fa_state = 396 dm_digtable->cur_cck_fa_state =
421 CCK_FA_STAGE_High; 397 CCK_FA_STAGE_HIGH;
422 else 398 else
423 dm_digtable->cur_cck_fa_state = 399 dm_digtable->cur_cck_fa_state =
424 CCK_FA_STAGE_LOW; 400 CCK_FA_STAGE_LOW;
@@ -818,7 +794,7 @@ void rtl8723e_dm_init(struct ieee80211_hw *hw)
818 struct rtl_priv *rtlpriv = rtl_priv(hw); 794 struct rtl_priv *rtlpriv = rtl_priv(hw);
819 795
820 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 796 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
821 rtl8723e_dm_diginit(hw); 797 rtl_dm_diginit(hw, 0x20);
822 rtl8723_dm_init_dynamic_txpower(hw); 798 rtl8723_dm_init_dynamic_txpower(hw);
823 rtl8723_dm_init_edca_turbo(hw); 799 rtl8723_dm_init_edca_turbo(hw);
824 rtl8723e_dm_init_rate_adaptive_mask(hw); 800 rtl8723e_dm_init_rate_adaptive_mask(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
index 6fa0feb05f6d..57111052e86b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h
@@ -42,25 +42,12 @@
42#define BW_AUTO_SWITCH_HIGH_LOW 25 42#define BW_AUTO_SWITCH_HIGH_LOW 25
43#define BW_AUTO_SWITCH_LOW_HIGH 30 43#define BW_AUTO_SWITCH_LOW_HIGH 30
44 44
45#define DM_DIG_THRESH_HIGH 40
46#define DM_DIG_THRESH_LOW 35
47
48#define DM_FALSEALARM_THRESH_LOW 400
49#define DM_FALSEALARM_THRESH_HIGH 1000
50
51#define DM_DIG_MAX 0x3e
52#define DM_DIG_MIN 0x1e
53
54#define DM_DIG_FA_UPPER 0x32 45#define DM_DIG_FA_UPPER 0x32
55#define DM_DIG_FA_LOWER 0x20 46#define DM_DIG_FA_LOWER 0x20
56#define DM_DIG_FA_TH0 0x20 47#define DM_DIG_FA_TH0 0x20
57#define DM_DIG_FA_TH1 0x100 48#define DM_DIG_FA_TH1 0x100
58#define DM_DIG_FA_TH2 0x200 49#define DM_DIG_FA_TH2 0x200
59 50
60#define DM_DIG_BACKOFF_MAX 12
61#define DM_DIG_BACKOFF_MIN -4
62#define DM_DIG_BACKOFF_DEFAULT 10
63
64#define RXPATHSELECTION_SS_TH_LOW 30 51#define RXPATHSELECTION_SS_TH_LOW 30
65#define RXPATHSELECTION_DIFF_TH 18 52#define RXPATHSELECTION_DIFF_TH 18
66 53
@@ -108,14 +95,6 @@ enum tag_dynamic_init_gain_operation_type_definition {
108 DIG_OP_TYPE_MAX 95 DIG_OP_TYPE_MAX
109}; 96};
110 97
111enum tag_cck_packet_detection_threshold_type_definition {
112 CCK_PD_STAGE_LowRssi = 0,
113 CCK_PD_STAGE_HighRssi = 1,
114 CCK_FA_STAGE_LOW = 2,
115 CCK_FA_STAGE_High = 3,
116 CCK_PD_STAGE_MAX = 4,
117};
118
119enum dm_1r_cca_e { 98enum dm_1r_cca_e {
120 CCA_1R = 0, 99 CCA_1R = 0,
121 CCA_2R = 1, 100 CCA_2R = 1,
@@ -134,23 +113,6 @@ enum dm_sw_ant_switch_e {
134 ANS_ANTENNA_MAX = 3, 113 ANS_ANTENNA_MAX = 3,
135}; 114};
136 115
137enum dm_dig_ext_port_alg_e {
138 DIG_EXT_PORT_STAGE_0 = 0,
139 DIG_EXT_PORT_STAGE_1 = 1,
140 DIG_EXT_PORT_STAGE_2 = 2,
141 DIG_EXT_PORT_STAGE_3 = 3,
142 DIG_EXT_PORT_STAGE_MAX = 4,
143};
144
145enum dm_dig_connect_e {
146 DIG_STA_DISCONNECT = 0,
147 DIG_STA_CONNECT = 1,
148 DIG_STA_BEFORE_CONNECT = 2,
149 DIG_MULTISTA_DISCONNECT = 3,
150 DIG_MULTISTA_CONNECT = 4,
151 DIG_CONNECT_MAX
152};
153
154#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1) 116#define BT_RSSI_STATE_NORMAL_POWER BIT_OFFSET_LEN_MASK_32(0, 1)
155#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1) 117#define BT_RSSI_STATE_AMDPU_OFF BIT_OFFSET_LEN_MASK_32(1, 1)
156#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1) 118#define BT_RSSI_STATE_SPECIAL_LOW BIT_OFFSET_LEN_MASK_32(2, 1)
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
index dd7eb4371f49..2367e8f47a5b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../base.h" 27#include "../base.h"
28#include "../pci.h" 28#include "../pci.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "phy.h" 32#include "phy.h"
@@ -211,35 +212,6 @@ void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
211 (pwr_val << 16) | (pwr_val << 24); 212 (pwr_val << 16) | (pwr_val << 24);
212} 213}
213 214
214static void rtl8723be_dm_diginit(struct ieee80211_hw *hw)
215{
216 struct rtl_priv *rtlpriv = rtl_priv(hw);
217 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
218
219 dm_digtable->dig_enable_flag = true;
220 dm_digtable->cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
221 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
222 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
223 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
224 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
225 dm_digtable->rx_gain_max = DM_DIG_MAX;
226 dm_digtable->rx_gain_min = DM_DIG_MIN;
227 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
228 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
229 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
230 dm_digtable->pre_cck_cca_thres = 0xff;
231 dm_digtable->cur_cck_cca_thres = 0x83;
232 dm_digtable->forbidden_igi = DM_DIG_MIN;
233 dm_digtable->large_fa_hit = 0;
234 dm_digtable->recover_cnt = 0;
235 dm_digtable->dig_dynamic_min = DM_DIG_MIN;
236 dm_digtable->dig_dynamic_min_1 = DM_DIG_MIN;
237 dm_digtable->media_connect_0 = false;
238 dm_digtable->media_connect_1 = false;
239 rtlpriv->dm.dm_initialgain_enable = true;
240 dm_digtable->bt30_cur_igi = 0x32;
241}
242
243void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) 215void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
244{ 216{
245 struct rtl_priv *rtlpriv = rtl_priv(hw); 217 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -293,9 +265,10 @@ static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
293void rtl8723be_dm_init(struct ieee80211_hw *hw) 265void rtl8723be_dm_init(struct ieee80211_hw *hw)
294{ 266{
295 struct rtl_priv *rtlpriv = rtl_priv(hw); 267 struct rtl_priv *rtlpriv = rtl_priv(hw);
268 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
296 269
297 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 270 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
298 rtl8723be_dm_diginit(hw); 271 rtl_dm_diginit(hw, cur_igvalue);
299 rtl8723be_dm_init_rate_adaptive_mask(hw); 272 rtl8723be_dm_init_rate_adaptive_mask(hw);
300 rtl8723_dm_init_edca_turbo(hw); 273 rtl8723_dm_init_edca_turbo(hw);
301 rtl8723_dm_init_dynamic_bb_powersaving(hw); 274 rtl8723_dm_init_dynamic_bb_powersaving(hw);
@@ -424,7 +397,7 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
424 struct rtl_priv *rtlpriv = rtl_priv(hw); 397 struct rtl_priv *rtlpriv = rtl_priv(hw);
425 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 398 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
426 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 399 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
427 u8 dig_dynamic_min, dig_maxofmin; 400 u8 dig_min_0, dig_maxofmin;
428 bool bfirstconnect, bfirstdisconnect; 401 bool bfirstconnect, bfirstdisconnect;
429 u8 dm_dig_max, dm_dig_min; 402 u8 dm_dig_max, dm_dig_min;
430 u8 current_igi = dm_digtable->cur_igvalue; 403 u8 current_igi = dm_digtable->cur_igvalue;
@@ -434,7 +407,7 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
434 if (mac->act_scanning) 407 if (mac->act_scanning)
435 return; 408 return;
436 409
437 dig_dynamic_min = dm_digtable->dig_dynamic_min; 410 dig_min_0 = dm_digtable->dig_min_0;
438 bfirstconnect = (mac->link_state >= MAC80211_LINKED) && 411 bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
439 !dm_digtable->media_connect_0; 412 !dm_digtable->media_connect_0;
440 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) && 413 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
@@ -456,20 +429,20 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
456 if (rtlpriv->dm.one_entry_only) { 429 if (rtlpriv->dm.one_entry_only) {
457 offset = 12; 430 offset = 12;
458 if (dm_digtable->rssi_val_min - offset < dm_dig_min) 431 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
459 dig_dynamic_min = dm_dig_min; 432 dig_min_0 = dm_dig_min;
460 else if (dm_digtable->rssi_val_min - offset > 433 else if (dm_digtable->rssi_val_min - offset >
461 dig_maxofmin) 434 dig_maxofmin)
462 dig_dynamic_min = dig_maxofmin; 435 dig_min_0 = dig_maxofmin;
463 else 436 else
464 dig_dynamic_min = 437 dig_min_0 =
465 dm_digtable->rssi_val_min - offset; 438 dm_digtable->rssi_val_min - offset;
466 } else { 439 } else {
467 dig_dynamic_min = dm_dig_min; 440 dig_min_0 = dm_dig_min;
468 } 441 }
469 442
470 } else { 443 } else {
471 dm_digtable->rx_gain_max = dm_dig_max; 444 dm_digtable->rx_gain_max = dm_dig_max;
472 dig_dynamic_min = dm_dig_min; 445 dig_min_0 = dm_dig_min;
473 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); 446 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
474 } 447 }
475 448
@@ -497,11 +470,11 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
497 } else { 470 } else {
498 if (dm_digtable->large_fa_hit < 3) { 471 if (dm_digtable->large_fa_hit < 3) {
499 if ((dm_digtable->forbidden_igi - 1) < 472 if ((dm_digtable->forbidden_igi - 1) <
500 dig_dynamic_min) { 473 dig_min_0) {
501 dm_digtable->forbidden_igi = 474 dm_digtable->forbidden_igi =
502 dig_dynamic_min; 475 dig_min_0;
503 dm_digtable->rx_gain_min = 476 dm_digtable->rx_gain_min =
504 dig_dynamic_min; 477 dig_min_0;
505 } else { 478 } else {
506 dm_digtable->forbidden_igi--; 479 dm_digtable->forbidden_igi--;
507 dm_digtable->rx_gain_min = 480 dm_digtable->rx_gain_min =
@@ -552,7 +525,7 @@ static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
552 rtl8723be_dm_write_dig(hw, current_igi); 525 rtl8723be_dm_write_dig(hw, current_igi);
553 dm_digtable->media_connect_0 = 526 dm_digtable->media_connect_0 =
554 ((mac->link_state >= MAC80211_LINKED) ? true : false); 527 ((mac->link_state >= MAC80211_LINKED) ? true : false);
555 dm_digtable->dig_dynamic_min = dig_dynamic_min; 528 dm_digtable->dig_min_0 = dig_min_0;
556} 529}
557 530
558static void rtl8723be_dm_false_alarm_counter_statistics( 531static void rtl8723be_dm_false_alarm_counter_statistics(
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
index e4c0e8ae6f47..f752a2cad63d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/dm.h
@@ -180,28 +180,12 @@
180#define BW_AUTO_SWITCH_HIGH_LOW 25 180#define BW_AUTO_SWITCH_HIGH_LOW 25
181#define BW_AUTO_SWITCH_LOW_HIGH 30 181#define BW_AUTO_SWITCH_LOW_HIGH 30
182 182
183#define DM_DIG_THRESH_HIGH 40
184#define DM_DIG_THRESH_LOW 35
185
186#define DM_FALSEALARM_THRESH_LOW 400
187#define DM_FALSEALARM_THRESH_HIGH 1000
188
189#define DM_DIG_MAX 0x3e
190#define DM_DIG_MIN 0x1e
191
192#define DM_DIG_MAX_AP 0x32
193#define DM_DIG_MIN_AP 0x20
194
195#define DM_DIG_FA_UPPER 0x3e 183#define DM_DIG_FA_UPPER 0x3e
196#define DM_DIG_FA_LOWER 0x1e 184#define DM_DIG_FA_LOWER 0x1e
197#define DM_DIG_FA_TH0 0x200 185#define DM_DIG_FA_TH0 0x200
198#define DM_DIG_FA_TH1 0x300 186#define DM_DIG_FA_TH1 0x300
199#define DM_DIG_FA_TH2 0x400 187#define DM_DIG_FA_TH2 0x400
200 188
201#define DM_DIG_BACKOFF_MAX 12
202#define DM_DIG_BACKOFF_MIN -4
203#define DM_DIG_BACKOFF_DEFAULT 10
204
205#define RXPATHSELECTION_SS_TH_LOW 30 189#define RXPATHSELECTION_SS_TH_LOW 30
206#define RXPATHSELECTION_DIFF_TH 18 190#define RXPATHSELECTION_DIFF_TH 18
207 191
@@ -252,23 +236,6 @@ enum dm_sw_ant_switch_e {
252 ANS_ANTENNA_MAX = 3, 236 ANS_ANTENNA_MAX = 3,
253}; 237};
254 238
255enum dm_dig_ext_port_alg_e {
256 DIG_EXT_PORT_STAGE_0 = 0,
257 DIG_EXT_PORT_STAGE_1 = 1,
258 DIG_EXT_PORT_STAGE_2 = 2,
259 DIG_EXT_PORT_STAGE_3 = 3,
260 DIG_EXT_PORT_STAGE_MAX = 4,
261};
262
263enum dm_dig_connect_e {
264 DIG_STA_DISCONNECT = 0,
265 DIG_STA_CONNECT = 1,
266 DIG_STA_BEFORE_CONNECT = 2,
267 DIG_MULTISTA_DISCONNECT = 3,
268 DIG_MULTISTA_CONNECT = 4,
269 DIG_CONNECT_MAX
270};
271
272enum pwr_track_control_method { 239enum pwr_track_control_method {
273 BBSWING, 240 BBSWING,
274 TXAGC 241 TXAGC
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
index 223eb42992bd..1017f02d7bf7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
@@ -387,12 +387,14 @@ module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
387module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444); 387module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
388module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog, 388module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog,
389 bool, 0444); 389 bool, 0444);
390MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); 390MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
391MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); 391MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
392MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n"); 392MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
393MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
393MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); 394MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
394MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 395MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
395MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); 396MODULE_PARM_DESC(disable_watchdog,
397 "Set to 1 to disable the watchdog (default 0)\n");
396 398
397static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); 399static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
398 400
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
index ba30b0d250fd..0b2082dc48f1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.c
@@ -26,6 +26,7 @@
26#include "../wifi.h" 26#include "../wifi.h"
27#include "../base.h" 27#include "../base.h"
28#include "../pci.h" 28#include "../pci.h"
29#include "../core.h"
29#include "reg.h" 30#include "reg.h"
30#include "def.h" 31#include "def.h"
31#include "phy.h" 32#include "phy.h"
@@ -519,34 +520,6 @@ void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
519 } 520 }
520} 521}
521 522
522static void rtl8821ae_dm_diginit(struct ieee80211_hw *hw)
523{
524 struct rtl_priv *rtlpriv = rtl_priv(hw);
525 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
526
527 dm_digtable->cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
528 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
529 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
530 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
531 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
532 dm_digtable->rx_gain_max = DM_DIG_MAX;
533 dm_digtable->rx_gain_min = DM_DIG_MIN;
534 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
535 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
536 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
537 dm_digtable->pre_cck_cca_thres = 0xff;
538 dm_digtable->cur_cck_cca_thres = 0x83;
539 dm_digtable->forbidden_igi = DM_DIG_MIN;
540 dm_digtable->large_fa_hit = 0;
541 dm_digtable->recover_cnt = 0;
542 dm_digtable->dig_dynamic_min = DM_DIG_MIN;
543 dm_digtable->dig_dynamic_min_1 = DM_DIG_MIN;
544 dm_digtable->media_connect_0 = false;
545 dm_digtable->media_connect_1 = false;
546 rtlpriv->dm.dm_initialgain_enable = true;
547 dm_digtable->bt30_cur_igi = 0x32;
548}
549
550void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw) 523void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
551{ 524{
552 struct rtl_priv *rtlpriv = rtl_priv(hw); 525 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -606,6 +579,7 @@ void rtl8821ae_dm_init(struct ieee80211_hw *hw)
606{ 579{
607 struct rtl_priv *rtlpriv = rtl_priv(hw); 580 struct rtl_priv *rtlpriv = rtl_priv(hw);
608 struct rtl_phy *rtlphy = &rtlpriv->phy; 581 struct rtl_phy *rtlphy = &rtlpriv->phy;
582 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
609 583
610 spin_lock(&rtlpriv->locks.iqk_lock); 584 spin_lock(&rtlpriv->locks.iqk_lock);
611 rtlphy->lck_inprogress = false; 585 rtlphy->lck_inprogress = false;
@@ -613,7 +587,7 @@ void rtl8821ae_dm_init(struct ieee80211_hw *hw)
613 587
614 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 588 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
615 rtl8821ae_dm_common_info_self_init(hw); 589 rtl8821ae_dm_common_info_self_init(hw);
616 rtl8821ae_dm_diginit(hw); 590 rtl_dm_diginit(hw, cur_igvalue);
617 rtl8821ae_dm_init_rate_adaptive_mask(hw); 591 rtl8821ae_dm_init_rate_adaptive_mask(hw);
618 rtl8821ae_dm_init_edca_turbo(hw); 592 rtl8821ae_dm_init_edca_turbo(hw);
619 rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw); 593 rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
@@ -822,7 +796,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
822 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 796 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
823 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 797 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
824 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 798 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
825 u8 dig_dynamic_min; 799 u8 dig_min_0;
826 u8 dig_max_of_min; 800 u8 dig_max_of_min;
827 bool first_connect, first_disconnect; 801 bool first_connect, first_disconnect;
828 u8 dm_dig_max, dm_dig_min, offset; 802 u8 dm_dig_max, dm_dig_min, offset;
@@ -837,7 +811,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
837 } 811 }
838 812
839 /*add by Neil Chen to avoid PSD is processing*/ 813 /*add by Neil Chen to avoid PSD is processing*/
840 dig_dynamic_min = dm_digtable->dig_dynamic_min; 814 dig_min_0 = dm_digtable->dig_min_0;
841 first_connect = (mac->link_state >= MAC80211_LINKED) && 815 first_connect = (mac->link_state >= MAC80211_LINKED) &&
842 (!dm_digtable->media_connect_0); 816 (!dm_digtable->media_connect_0);
843 first_disconnect = (mac->link_state < MAC80211_LINKED) && 817 first_disconnect = (mac->link_state < MAC80211_LINKED) &&
@@ -876,23 +850,23 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
876 offset = 0; 850 offset = 0;
877 851
878 if (dm_digtable->rssi_val_min - offset < dm_dig_min) 852 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
879 dig_dynamic_min = dm_dig_min; 853 dig_min_0 = dm_dig_min;
880 else if (dm_digtable->rssi_val_min - 854 else if (dm_digtable->rssi_val_min -
881 offset > dig_max_of_min) 855 offset > dig_max_of_min)
882 dig_dynamic_min = dig_max_of_min; 856 dig_min_0 = dig_max_of_min;
883 else 857 else
884 dig_dynamic_min = 858 dig_min_0 =
885 dm_digtable->rssi_val_min - offset; 859 dm_digtable->rssi_val_min - offset;
886 860
887 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, 861 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
888 "bOneEntryOnly=TRUE, dig_dynamic_min=0x%x\n", 862 "bOneEntryOnly=TRUE, dig_min_0=0x%x\n",
889 dig_dynamic_min); 863 dig_min_0);
890 } else { 864 } else {
891 dig_dynamic_min = dm_dig_min; 865 dig_min_0 = dm_dig_min;
892 } 866 }
893 } else { 867 } else {
894 dm_digtable->rx_gain_max = dm_dig_max; 868 dm_digtable->rx_gain_max = dm_dig_max;
895 dig_dynamic_min = dm_dig_min; 869 dig_min_0 = dm_dig_min;
896 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, 870 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
897 "No Link\n"); 871 "No Link\n");
898 } 872 }
@@ -925,11 +899,11 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
925 } else { 899 } else {
926 if (dm_digtable->large_fa_hit < 3) { 900 if (dm_digtable->large_fa_hit < 3) {
927 if ((dm_digtable->forbidden_igi - 1) < 901 if ((dm_digtable->forbidden_igi - 1) <
928 dig_dynamic_min) { 902 dig_min_0) {
929 dm_digtable->forbidden_igi = 903 dm_digtable->forbidden_igi =
930 dig_dynamic_min; 904 dig_min_0;
931 dm_digtable->rx_gain_min = 905 dm_digtable->rx_gain_min =
932 dig_dynamic_min; 906 dig_min_0;
933 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, 907 RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
934 "Normal Case: At Lower Bound\n"); 908 "Normal Case: At Lower Bound\n");
935 } else { 909 } else {
@@ -1024,7 +998,7 @@ static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
1024 rtl8821ae_dm_write_dig(hw, current_igi); 998 rtl8821ae_dm_write_dig(hw, current_igi);
1025 dm_digtable->media_connect_0 = 999 dm_digtable->media_connect_0 =
1026 ((mac->link_state >= MAC80211_LINKED) ? true : false); 1000 ((mac->link_state >= MAC80211_LINKED) ? true : false);
1027 dm_digtable->dig_dynamic_min = dig_dynamic_min; 1001 dm_digtable->dig_min_0 = dig_min_0;
1028} 1002}
1029 1003
1030static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw) 1004static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h
index 9dd40dd316c1..625a6bbb21fc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/dm.h
@@ -187,28 +187,12 @@
187#define BW_AUTO_SWITCH_HIGH_LOW 25 187#define BW_AUTO_SWITCH_HIGH_LOW 25
188#define BW_AUTO_SWITCH_LOW_HIGH 30 188#define BW_AUTO_SWITCH_LOW_HIGH 30
189 189
190#define DM_DIG_THRESH_HIGH 40
191#define DM_DIG_THRESH_LOW 35
192
193#define DM_FALSEALARM_THRESH_LOW 400
194#define DM_FALSEALARM_THRESH_HIGH 1000
195
196#define DM_DIG_MAX 0x3e
197#define DM_DIG_MIN 0x1e
198
199#define DM_DIG_MAX_AP 0x32
200#define DM_DIG_MIN_AP 0x20
201
202#define DM_DIG_FA_UPPER 0x3e 190#define DM_DIG_FA_UPPER 0x3e
203#define DM_DIG_FA_LOWER 0x1e 191#define DM_DIG_FA_LOWER 0x1e
204#define DM_DIG_FA_TH0 200 192#define DM_DIG_FA_TH0 200
205#define DM_DIG_FA_TH1 0x300 193#define DM_DIG_FA_TH1 0x300
206#define DM_DIG_FA_TH2 0x400 194#define DM_DIG_FA_TH2 0x400
207 195
208#define DM_DIG_BACKOFF_MAX 12
209#define DM_DIG_BACKOFF_MIN -4
210#define DM_DIG_BACKOFF_DEFAULT 10
211
212#define RXPATHSELECTION_SS_TH_LOW 30 196#define RXPATHSELECTION_SS_TH_LOW 30
213#define RXPATHSELECTION_DIFF_TH 18 197#define RXPATHSELECTION_DIFF_TH 18
214 198
@@ -262,14 +246,6 @@ enum tag_dynamic_init_gain_operation_type_definition {
262 DIG_OP_TYPE_MAX 246 DIG_OP_TYPE_MAX
263}; 247};
264 248
265enum tag_cck_packet_detection_threshold_type_definition {
266 CCK_PD_STAGE_LOWRSSI = 0,
267 CCK_PD_STAGE_HIGHRSSI = 1,
268 CCK_FA_STAGE_LOW = 2,
269 CCK_FA_STAGE_HIGH = 3,
270 CCK_PD_STAGE_MAX = 4,
271};
272
273enum dm_1r_cca_e { 249enum dm_1r_cca_e {
274 CCA_1R = 0, 250 CCA_1R = 0,
275 CCA_2R = 1, 251 CCA_2R = 1,
@@ -288,23 +264,6 @@ enum dm_sw_ant_switch_e {
288 ANS_ANTENNA_MAX = 3, 264 ANS_ANTENNA_MAX = 3,
289}; 265};
290 266
291enum dm_dig_ext_port_alg_e {
292 DIG_EXT_PORT_STAGE_0 = 0,
293 DIG_EXT_PORT_STAGE_1 = 1,
294 DIG_EXT_PORT_STAGE_2 = 2,
295 DIG_EXT_PORT_STAGE_3 = 3,
296 DIG_EXT_PORT_STAGE_MAX = 4,
297};
298
299enum dm_dig_connect_e {
300 DIG_STA_DISCONNECT = 0,
301 DIG_STA_CONNECT = 1,
302 DIG_STA_BEFORE_CONNECT = 2,
303 DIG_MULTISTA_DISCONNECT = 3,
304 DIG_MULTISTA_CONNECT = 4,
305 DIG_CONNECT_MAX
306};
307
308enum pwr_track_control_method { 267enum pwr_track_control_method {
309 BBSWING, 268 BBSWING,
310 TXAGC, 269 TXAGC,
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 7a718fdb82cd..b53d9dd7a595 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2412,8 +2412,6 @@ struct dig_t {
2412 u8 pre_ccastate; 2412 u8 pre_ccastate;
2413 u8 cur_ccasate; 2413 u8 cur_ccasate;
2414 u8 large_fa_hit; 2414 u8 large_fa_hit;
2415 u8 dig_dynamic_min;
2416 u8 dig_dynamic_min_1;
2417 u8 forbidden_igi; 2415 u8 forbidden_igi;
2418 u8 dig_state; 2416 u8 dig_state;
2419 u8 dig_highpwrstate; 2417 u8 dig_highpwrstate;
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index d6d0d6d9c7a8..144d1f8ba473 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -250,6 +250,7 @@ static struct wlcore_conf wl12xx_conf = {
250 .keep_alive_interval = 55000, 250 .keep_alive_interval = 55000,
251 .max_listen_interval = 20, 251 .max_listen_interval = 20,
252 .sta_sleep_auth = WL1271_PSM_ILLEGAL, 252 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
253 .suspend_rx_ba_activity = 0,
253 }, 254 },
254 .itrim = { 255 .itrim = {
255 .enable = false, 256 .enable = false,
@@ -1728,6 +1729,9 @@ static struct wlcore_ops wl12xx_ops = {
1728 .convert_hwaddr = wl12xx_convert_hwaddr, 1729 .convert_hwaddr = wl12xx_convert_hwaddr,
1729 .lnk_high_prio = wl12xx_lnk_high_prio, 1730 .lnk_high_prio = wl12xx_lnk_high_prio,
1730 .lnk_low_prio = wl12xx_lnk_low_prio, 1731 .lnk_low_prio = wl12xx_lnk_low_prio,
1732 .interrupt_notify = NULL,
1733 .rx_ba_filter = NULL,
1734 .ap_sleep = NULL,
1731}; 1735};
1732 1736
1733static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { 1737static struct ieee80211_sta_ht_cap wl12xx_ht_cap = {
diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c
index a169bb5a5dbf..67f2a0eec854 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.c
+++ b/drivers/net/wireless/ti/wl18xx/acx.c
@@ -24,6 +24,7 @@
24#include "../wlcore/acx.h" 24#include "../wlcore/acx.h"
25 25
26#include "acx.h" 26#include "acx.h"
27#include "wl18xx.h"
27 28
28int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, 29int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
29 u32 sdio_blk_size, u32 extra_mem_blks, 30 u32 sdio_blk_size, u32 extra_mem_blks,
@@ -194,3 +195,90 @@ out:
194 kfree(acx); 195 kfree(acx);
195 return ret; 196 return ret;
196} 197}
198
199/*
200 * When the host is suspended, we don't want to get any fast-link/PSM
201 * notifications
202 */
203int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl,
204 bool action)
205{
206 struct wl18xx_acx_interrupt_notify *acx;
207 int ret = 0;
208
209 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
210 if (!acx) {
211 ret = -ENOMEM;
212 goto out;
213 }
214
215 acx->enable = action;
216 ret = wl1271_cmd_configure(wl, ACX_INTERRUPT_NOTIFY, acx, sizeof(*acx));
217 if (ret < 0) {
218 wl1271_warning("acx interrupt notify setting failed: %d", ret);
219 goto out;
220 }
221
222out:
223 kfree(acx);
224 return ret;
225}
226
227/*
228 * When the host is suspended, we can configure the FW to disable RX BA
229 * notifications.
230 */
231int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action)
232{
233 struct wl18xx_acx_rx_ba_filter *acx;
234 int ret = 0;
235
236 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
237 if (!acx) {
238 ret = -ENOMEM;
239 goto out;
240 }
241
242 acx->enable = (u32)action;
243 ret = wl1271_cmd_configure(wl, ACX_RX_BA_FILTER, acx, sizeof(*acx));
244 if (ret < 0) {
245 wl1271_warning("acx rx ba activity filter setting failed: %d",
246 ret);
247 goto out;
248 }
249
250out:
251 kfree(acx);
252 return ret;
253}
254
255int wl18xx_acx_ap_sleep(struct wl1271 *wl)
256{
257 struct wl18xx_priv *priv = wl->priv;
258 struct acx_ap_sleep_cfg *acx;
259 struct conf_ap_sleep_settings *conf = &priv->conf.ap_sleep;
260 int ret;
261
262 wl1271_debug(DEBUG_ACX, "acx config ap sleep");
263
264 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
265 if (!acx) {
266 ret = -ENOMEM;
267 goto out;
268 }
269
270 acx->idle_duty_cycle = conf->idle_duty_cycle;
271 acx->connected_duty_cycle = conf->connected_duty_cycle;
272 acx->max_stations_thresh = conf->max_stations_thresh;
273 acx->idle_conn_thresh = conf->idle_conn_thresh;
274
275 ret = wl1271_cmd_configure(wl, ACX_AP_SLEEP_CFG, acx, sizeof(*acx));
276 if (ret < 0) {
277 wl1271_warning("acx config ap-sleep failed: %d", ret);
278 goto out;
279 }
280
281out:
282 kfree(acx);
283 return ret;
284}
diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h
index 0e636def1217..4afccd4b9467 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.h
+++ b/drivers/net/wireless/ti/wl18xx/acx.h
@@ -32,7 +32,10 @@ enum {
32 ACX_SIM_CONFIG = 0x0053, 32 ACX_SIM_CONFIG = 0x0053,
33 ACX_CLEAR_STATISTICS = 0x0054, 33 ACX_CLEAR_STATISTICS = 0x0054,
34 ACX_AUTO_RX_STREAMING = 0x0055, 34 ACX_AUTO_RX_STREAMING = 0x0055,
35 ACX_PEER_CAP = 0x0056 35 ACX_PEER_CAP = 0x0056,
36 ACX_INTERRUPT_NOTIFY = 0x0057,
37 ACX_RX_BA_FILTER = 0x0058,
38 ACX_AP_SLEEP_CFG = 0x0059
36}; 39};
37 40
38/* numbers of bits the length field takes (add 1 for the actual number) */ 41/* numbers of bits the length field takes (add 1 for the actual number) */
@@ -326,6 +329,44 @@ struct wlcore_acx_peer_cap {
326 u8 padding; 329 u8 padding;
327} __packed; 330} __packed;
328 331
332/*
333 * ACX_INTERRUPT_NOTIFY
334 * enable/disable fast-link/PSM notification from FW
335 */
336struct wl18xx_acx_interrupt_notify {
337 struct acx_header header;
338 u32 enable;
339};
340
341/*
342 * ACX_RX_BA_FILTER
343 * enable/disable RX BA filtering in FW
344 */
345struct wl18xx_acx_rx_ba_filter {
346 struct acx_header header;
347 u32 enable;
348};
349
350struct acx_ap_sleep_cfg {
351 struct acx_header header;
352 /* Duty Cycle (20-80% of staying Awake) for IDLE AP
353 * (0: disable)
354 */
355 u8 idle_duty_cycle;
356 /* Duty Cycle (20-80% of staying Awake) for Connected AP
357 * (0: disable)
358 */
359 u8 connected_duty_cycle;
360 /* Maximum stations that are allowed to be connected to AP
361 * (255: no limit)
362 */
363 u8 max_stations_thresh;
364 /* Timeout till enabling the Sleep Mechanism after data stops
365 * [unit: 100 msec]
366 */
367 u8 idle_conn_thresh;
368} __packed;
369
329int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, 370int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap,
330 u32 sdio_blk_size, u32 extra_mem_blks, 371 u32 sdio_blk_size, u32 extra_mem_blks,
331 u32 len_field_size); 372 u32 len_field_size);
@@ -336,5 +377,8 @@ int wl18xx_acx_set_peer_cap(struct wl1271 *wl,
336 struct ieee80211_sta_ht_cap *ht_cap, 377 struct ieee80211_sta_ht_cap *ht_cap,
337 bool allow_ht_operation, 378 bool allow_ht_operation,
338 u32 rate_set, u8 hlid); 379 u32 rate_set, u8 hlid);
380int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl, bool action);
381int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action);
382int wl18xx_acx_ap_sleep(struct wl1271 *wl);
339 383
340#endif /* __WL18XX_ACX_H__ */ 384#endif /* __WL18XX_ACX_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c
index 44f0b205b065..a8d176ddc73c 100644
--- a/drivers/net/wireless/ti/wl18xx/cmd.c
+++ b/drivers/net/wireless/ti/wl18xx/cmd.c
@@ -33,7 +33,8 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl,
33 u32 supported_rates; 33 u32 supported_rates;
34 int ret; 34 int ret;
35 35
36 wl1271_debug(DEBUG_ACX, "cmd channel switch"); 36 wl1271_debug(DEBUG_ACX, "cmd channel switch (count=%d)",
37 ch_switch->count);
37 38
38 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 39 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
39 if (!cmd) { 40 if (!cmd) {
@@ -60,8 +61,12 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl,
60 goto out_free; 61 goto out_free;
61 } 62 }
62 63
63 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES | 64 supported_rates = CONF_TX_ENABLED_RATES | CONF_TX_MCS_RATES;
64 wlcore_hw_sta_get_ap_rate_mask(wl, wlvif); 65 if (wlvif->bss_type == BSS_TYPE_STA_BSS)
66 supported_rates |= wlcore_hw_sta_get_ap_rate_mask(wl, wlvif);
67 else
68 supported_rates |=
69 wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
65 if (wlvif->p2p) 70 if (wlvif->p2p)
66 supported_rates &= ~CONF_TX_CCK_RATES; 71 supported_rates &= ~CONF_TX_CCK_RATES;
67 cmd->local_supported_rates = cpu_to_le32(supported_rates); 72 cmd->local_supported_rates = cpu_to_le32(supported_rates);
@@ -167,3 +172,85 @@ out_free:
167out: 172out:
168 return ret; 173 return ret;
169} 174}
175
176int wl18xx_cmd_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start)
177{
178 struct wlcore_cmd_cac_start *cmd;
179 int ret = 0;
180
181 wl1271_debug(DEBUG_CMD, "cmd cac (channel %d) %s",
182 wlvif->channel, start ? "start" : "stop");
183
184 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
185 if (!cmd)
186 return -ENOMEM;
187
188 cmd->role_id = wlvif->role_id;
189 cmd->channel = wlvif->channel;
190 if (wlvif->band == IEEE80211_BAND_5GHZ)
191 cmd->band = WLCORE_BAND_5GHZ;
192 cmd->bandwidth = wlcore_get_native_channel_type(wlvif->channel_type);
193
194 ret = wl1271_cmd_send(wl,
195 start ? CMD_CAC_START : CMD_CAC_STOP,
196 cmd, sizeof(*cmd), 0);
197 if (ret < 0) {
198 wl1271_error("failed to send cac command");
199 goto out_free;
200 }
201
202out_free:
203 kfree(cmd);
204 return ret;
205}
206
207int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel)
208{
209 struct wl18xx_cmd_dfs_radar_debug *cmd;
210 int ret = 0;
211
212 wl1271_debug(DEBUG_CMD, "cmd radar detection debug (chan %d)",
213 channel);
214
215 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
216 if (!cmd)
217 return -ENOMEM;
218
219 cmd->channel = channel;
220
221 ret = wl1271_cmd_send(wl, CMD_DFS_RADAR_DETECTION_DEBUG,
222 cmd, sizeof(*cmd), 0);
223 if (ret < 0) {
224 wl1271_error("failed to send radar detection debug command");
225 goto out_free;
226 }
227
228out_free:
229 kfree(cmd);
230 return ret;
231}
232
233int wl18xx_cmd_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif)
234{
235 struct wl18xx_cmd_dfs_master_restart *cmd;
236 int ret = 0;
237
238 wl1271_debug(DEBUG_CMD, "cmd dfs master restart (role %d)",
239 wlvif->role_id);
240
241 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
242 if (!cmd)
243 return -ENOMEM;
244
245 cmd->role_id = wlvif->role_id;
246
247 ret = wl1271_cmd_send(wl, CMD_DFS_MASTER_RESTART,
248 cmd, sizeof(*cmd), 0);
249 if (ret < 0) {
250 wl1271_error("failed to send dfs master restart command");
251 goto out_free;
252 }
253out_free:
254 kfree(cmd);
255 return ret;
256}
diff --git a/drivers/net/wireless/ti/wl18xx/cmd.h b/drivers/net/wireless/ti/wl18xx/cmd.h
index 92499e2dfa83..7f9440a2bff8 100644
--- a/drivers/net/wireless/ti/wl18xx/cmd.h
+++ b/drivers/net/wireless/ti/wl18xx/cmd.h
@@ -59,6 +59,30 @@ struct wl18xx_cmd_smart_config_set_group_key {
59 u8 key[16]; 59 u8 key[16];
60} __packed; 60} __packed;
61 61
62struct wl18xx_cmd_dfs_radar_debug {
63 struct wl1271_cmd_header header;
64
65 u8 channel;
66 u8 padding[3];
67} __packed;
68
69struct wl18xx_cmd_dfs_master_restart {
70 struct wl1271_cmd_header header;
71
72 u8 role_id;
73 u8 padding[3];
74} __packed;
75
76/* cac_start and cac_stop share the same params */
77struct wlcore_cmd_cac_start {
78 struct wl1271_cmd_header header;
79
80 u8 role_id;
81 u8 channel;
82 u8 band;
83 u8 bandwidth;
84} __packed;
85
62int wl18xx_cmd_channel_switch(struct wl1271 *wl, 86int wl18xx_cmd_channel_switch(struct wl1271 *wl,
63 struct wl12xx_vif *wlvif, 87 struct wl12xx_vif *wlvif,
64 struct ieee80211_channel_switch *ch_switch); 88 struct ieee80211_channel_switch *ch_switch);
@@ -66,4 +90,7 @@ int wl18xx_cmd_smart_config_start(struct wl1271 *wl, u32 group_bitmap);
66int wl18xx_cmd_smart_config_stop(struct wl1271 *wl); 90int wl18xx_cmd_smart_config_stop(struct wl1271 *wl);
67int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id, 91int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
68 u8 key_len, u8 *key); 92 u8 key_len, u8 *key);
93int wl18xx_cmd_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start);
94int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel);
95int wl18xx_cmd_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif);
69#endif 96#endif
diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h
index e34302e3b51d..71f1ec448ba5 100644
--- a/drivers/net/wireless/ti/wl18xx/conf.h
+++ b/drivers/net/wireless/ti/wl18xx/conf.h
@@ -23,7 +23,7 @@
23#define __WL18XX_CONF_H__ 23#define __WL18XX_CONF_H__
24 24
25#define WL18XX_CONF_MAGIC 0x10e100ca 25#define WL18XX_CONF_MAGIC 0x10e100ca
26#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0006) 26#define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0007)
27#define WL18XX_CONF_MASK 0x0000ffff 27#define WL18XX_CONF_MASK 0x0000ffff
28#define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ 28#define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \
29 sizeof(struct wl18xx_priv_conf)) 29 sizeof(struct wl18xx_priv_conf))
@@ -110,12 +110,33 @@ struct wl18xx_ht_settings {
110 u8 mode; 110 u8 mode;
111} __packed; 111} __packed;
112 112
113struct conf_ap_sleep_settings {
114 /* Duty Cycle (20-80% of staying Awake) for IDLE AP
115 * (0: disable)
116 */
117 u8 idle_duty_cycle;
118 /* Duty Cycle (20-80% of staying Awake) for Connected AP
119 * (0: disable)
120 */
121 u8 connected_duty_cycle;
122 /* Maximum stations that are allowed to be connected to AP
123 * (255: no limit)
124 */
125 u8 max_stations_thresh;
126 /* Timeout till enabling the Sleep Mechanism after data stops
127 * [unit: 100 msec]
128 */
129 u8 idle_conn_thresh;
130} __packed;
131
113struct wl18xx_priv_conf { 132struct wl18xx_priv_conf {
114 /* Module params structures */ 133 /* Module params structures */
115 struct wl18xx_ht_settings ht; 134 struct wl18xx_ht_settings ht;
116 135
117 /* this structure is copied wholesale to FW */ 136 /* this structure is copied wholesale to FW */
118 struct wl18xx_mac_and_phy_params phy; 137 struct wl18xx_mac_and_phy_params phy;
138
139 struct conf_ap_sleep_settings ap_sleep;
119} __packed; 140} __packed;
120 141
121#endif /* __WL18XX_CONF_H__ */ 142#endif /* __WL18XX_CONF_H__ */
diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c
index 7f1669cdea09..c93fae95baac 100644
--- a/drivers/net/wireless/ti/wl18xx/debugfs.c
+++ b/drivers/net/wireless/ti/wl18xx/debugfs.c
@@ -22,9 +22,12 @@
22 22
23#include "../wlcore/debugfs.h" 23#include "../wlcore/debugfs.h"
24#include "../wlcore/wlcore.h" 24#include "../wlcore/wlcore.h"
25#include "../wlcore/debug.h"
26#include "../wlcore/ps.h"
25 27
26#include "wl18xx.h" 28#include "wl18xx.h"
27#include "acx.h" 29#include "acx.h"
30#include "cmd.h"
28#include "debugfs.h" 31#include "debugfs.h"
29 32
30#define WL18XX_DEBUGFS_FWSTATS_FILE(a, b, c) \ 33#define WL18XX_DEBUGFS_FWSTATS_FILE(a, b, c) \
@@ -239,6 +242,45 @@ static const struct file_operations clear_fw_stats_ops = {
239 .llseek = default_llseek, 242 .llseek = default_llseek,
240}; 243};
241 244
245static ssize_t radar_detection_write(struct file *file,
246 const char __user *user_buf,
247 size_t count, loff_t *ppos)
248{
249 struct wl1271 *wl = file->private_data;
250 int ret;
251 u8 channel;
252
253 ret = kstrtou8_from_user(user_buf, count, 10, &channel);
254 if (ret < 0) {
255 wl1271_warning("illegal channel");
256 return -EINVAL;
257 }
258
259 mutex_lock(&wl->mutex);
260
261 if (unlikely(wl->state != WLCORE_STATE_ON))
262 goto out;
263
264 ret = wl1271_ps_elp_wakeup(wl);
265 if (ret < 0)
266 goto out;
267
268 ret = wl18xx_cmd_radar_detection_debug(wl, channel);
269 if (ret < 0)
270 count = ret;
271
272 wl1271_ps_elp_sleep(wl);
273out:
274 mutex_unlock(&wl->mutex);
275 return count;
276}
277
278static const struct file_operations radar_detection_ops = {
279 .write = radar_detection_write,
280 .open = simple_open,
281 .llseek = default_llseek,
282};
283
242int wl18xx_debugfs_add_files(struct wl1271 *wl, 284int wl18xx_debugfs_add_files(struct wl1271 *wl,
243 struct dentry *rootdir) 285 struct dentry *rootdir)
244{ 286{
@@ -390,6 +432,7 @@ int wl18xx_debugfs_add_files(struct wl1271 *wl,
390 DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks); 432 DEBUGFS_FWSTATS_ADD(mem, fw_gen_free_mem_blks);
391 433
392 DEBUGFS_ADD(conf, moddir); 434 DEBUGFS_ADD(conf, moddir);
435 DEBUGFS_ADD(radar_detection, moddir);
393 436
394 return 0; 437 return 0;
395 438
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c
index eb1848e08424..c28f06854195 100644
--- a/drivers/net/wireless/ti/wl18xx/event.c
+++ b/drivers/net/wireless/ti/wl18xx/event.c
@@ -47,6 +47,19 @@ int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
47 return wlcore_cmd_wait_for_event_or_timeout(wl, local_event, timeout); 47 return wlcore_cmd_wait_for_event_or_timeout(wl, local_event, timeout);
48} 48}
49 49
50static const char *wl18xx_radar_type_decode(u8 radar_type)
51{
52 switch (radar_type) {
53 case RADAR_TYPE_REGULAR:
54 return "REGULAR";
55 case RADAR_TYPE_CHIRP:
56 return "CHIRP";
57 case RADAR_TYPE_NONE:
58 default:
59 return "N/A";
60 }
61}
62
50static int wlcore_smart_config_sync_event(struct wl1271 *wl, u8 sync_channel, 63static int wlcore_smart_config_sync_event(struct wl1271 *wl, u8 sync_channel,
51 u8 sync_band) 64 u8 sync_band)
52{ 65{
@@ -115,6 +128,14 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl)
115 wl18xx_scan_completed(wl, wl->scan_wlvif); 128 wl18xx_scan_completed(wl, wl->scan_wlvif);
116 } 129 }
117 130
131 if (vector & RADAR_DETECTED_EVENT_ID) {
132 wl1271_info("radar event: channel %d type %s",
133 mbox->radar_channel,
134 wl18xx_radar_type_decode(mbox->radar_type));
135
136 ieee80211_radar_detected(wl->hw);
137 }
138
118 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) { 139 if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
119 wl1271_debug(DEBUG_EVENT, 140 wl1271_debug(DEBUG_EVENT,
120 "PERIODIC_SCAN_REPORT_EVENT (results %d)", 141 "PERIODIC_SCAN_REPORT_EVENT (results %d)",
diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h
index 0680312d4943..266ee87834e4 100644
--- a/drivers/net/wireless/ti/wl18xx/event.h
+++ b/drivers/net/wireless/ti/wl18xx/event.h
@@ -42,6 +42,12 @@ enum {
42 SMART_CONFIG_DECODE_EVENT_ID = BIT(23), 42 SMART_CONFIG_DECODE_EVENT_ID = BIT(23),
43}; 43};
44 44
45enum wl18xx_radar_types {
46 RADAR_TYPE_NONE,
47 RADAR_TYPE_REGULAR,
48 RADAR_TYPE_CHIRP
49};
50
45struct wl18xx_event_mailbox { 51struct wl18xx_event_mailbox {
46 __le32 events_vector; 52 __le32 events_vector;
47 53
@@ -83,13 +89,19 @@ struct wl18xx_event_mailbox {
83 u8 sc_token_len; 89 u8 sc_token_len;
84 u8 padding1; 90 u8 padding1;
85 u8 sc_ssid[32]; 91 u8 sc_ssid[32];
86 u8 sc_pwd[32]; 92 u8 sc_pwd[64];
87 u8 sc_token[32]; 93 u8 sc_token[32];
88 94
89 /* smart config sync channel */ 95 /* smart config sync channel */
90 u8 sc_sync_channel; 96 u8 sc_sync_channel;
91 u8 sc_sync_band; 97 u8 sc_sync_band;
92 u8 padding2[2]; 98 u8 padding2[2];
99
100 /* radar detect */
101 u8 radar_channel;
102 u8 radar_type;
103
104 u8 padding3[2];
93} __packed; 105} __packed;
94 106
95int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event, 107int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 8e562610bf16..717c4f5a02c2 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -378,6 +378,7 @@ static struct wlcore_conf wl18xx_conf = {
378 .keep_alive_interval = 55000, 378 .keep_alive_interval = 55000,
379 .max_listen_interval = 20, 379 .max_listen_interval = 20,
380 .sta_sleep_auth = WL1271_PSM_ILLEGAL, 380 .sta_sleep_auth = WL1271_PSM_ILLEGAL,
381 .suspend_rx_ba_activity = 0,
381 }, 382 },
382 .itrim = { 383 .itrim = {
383 .enable = false, 384 .enable = false,
@@ -567,6 +568,12 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = {
567 .high_power_val_2nd = 0xff, 568 .high_power_val_2nd = 0xff,
568 .tx_rf_margin = 1, 569 .tx_rf_margin = 1,
569 }, 570 },
571 .ap_sleep = { /* disabled by default */
572 .idle_duty_cycle = 0,
573 .connected_duty_cycle = 0,
574 .max_stations_thresh = 0,
575 .idle_conn_thresh = 0,
576 },
570}; 577};
571 578
572static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = { 579static const struct wlcore_partition_set wl18xx_ptable[PART_TABLE_LEN] = {
@@ -648,7 +655,7 @@ static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = {
648}; 655};
649 656
650/* TODO: maybe move to a new header file? */ 657/* TODO: maybe move to a new header file? */
651#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-3.bin" 658#define WL18XX_FW_NAME "ti-connectivity/wl18xx-fw-4.bin"
652 659
653static int wl18xx_identify_chip(struct wl1271 *wl) 660static int wl18xx_identify_chip(struct wl1271 *wl)
654{ 661{
@@ -983,6 +990,7 @@ static int wl18xx_boot(struct wl1271 *wl)
983 990
984 wl->event_mask = BSS_LOSS_EVENT_ID | 991 wl->event_mask = BSS_LOSS_EVENT_ID |
985 SCAN_COMPLETE_EVENT_ID | 992 SCAN_COMPLETE_EVENT_ID |
993 RADAR_DETECTED_EVENT_ID |
986 RSSI_SNR_TRIGGER_0_EVENT_ID | 994 RSSI_SNR_TRIGGER_0_EVENT_ID |
987 PERIODIC_SCAN_COMPLETE_EVENT_ID | 995 PERIODIC_SCAN_COMPLETE_EVENT_ID |
988 PERIODIC_SCAN_REPORT_EVENT_ID | 996 PERIODIC_SCAN_REPORT_EVENT_ID |
@@ -1559,26 +1567,19 @@ static u32 wl18xx_pre_pkt_send(struct wl1271 *wl,
1559} 1567}
1560 1568
1561static void wl18xx_sta_rc_update(struct wl1271 *wl, 1569static void wl18xx_sta_rc_update(struct wl1271 *wl,
1562 struct wl12xx_vif *wlvif, 1570 struct wl12xx_vif *wlvif)
1563 struct ieee80211_sta *sta,
1564 u32 changed)
1565{ 1571{
1566 bool wide = sta->bandwidth >= IEEE80211_STA_RX_BW_40; 1572 bool wide = wlvif->rc_update_bw >= IEEE80211_STA_RX_BW_40;
1567 1573
1568 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide); 1574 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update wide %d", wide);
1569 1575
1570 if (!(changed & IEEE80211_RC_BW_CHANGED))
1571 return;
1572
1573 mutex_lock(&wl->mutex);
1574
1575 /* sanity */ 1576 /* sanity */
1576 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS)) 1577 if (WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS))
1577 goto out; 1578 return;
1578 1579
1579 /* ignore the change before association */ 1580 /* ignore the change before association */
1580 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1581 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1581 goto out; 1582 return;
1582 1583
1583 /* 1584 /*
1584 * If we started out as wide, we can change the operation mode. If we 1585 * If we started out as wide, we can change the operation mode. If we
@@ -1589,9 +1590,6 @@ static void wl18xx_sta_rc_update(struct wl1271 *wl,
1589 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide); 1590 wl18xx_acx_peer_ht_operation_mode(wl, wlvif->sta.hlid, wide);
1590 else 1591 else
1591 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif)); 1592 ieee80211_connection_loss(wl12xx_wlvif_to_vif(wlvif));
1592
1593out:
1594 mutex_unlock(&wl->mutex);
1595} 1593}
1596 1594
1597static int wl18xx_set_peer_cap(struct wl1271 *wl, 1595static int wl18xx_set_peer_cap(struct wl1271 *wl,
@@ -1703,6 +1701,11 @@ static struct wlcore_ops wl18xx_ops = {
1703 .smart_config_start = wl18xx_cmd_smart_config_start, 1701 .smart_config_start = wl18xx_cmd_smart_config_start,
1704 .smart_config_stop = wl18xx_cmd_smart_config_stop, 1702 .smart_config_stop = wl18xx_cmd_smart_config_stop,
1705 .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key, 1703 .smart_config_set_group_key = wl18xx_cmd_smart_config_set_group_key,
1704 .interrupt_notify = wl18xx_acx_interrupt_notify_config,
1705 .rx_ba_filter = wl18xx_acx_rx_ba_filter,
1706 .ap_sleep = wl18xx_acx_ap_sleep,
1707 .set_cac = wl18xx_cmd_set_cac,
1708 .dfs_master_restart = wl18xx_cmd_dfs_master_restart,
1706}; 1709};
1707 1710
1708/* HT cap appropriate for wide channels in 2Ghz */ 1711/* HT cap appropriate for wide channels in 2Ghz */
@@ -1796,6 +1799,10 @@ wl18xx_iface_combinations[] = {
1796 .limits = wl18xx_iface_ap_limits, 1799 .limits = wl18xx_iface_ap_limits,
1797 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits), 1800 .n_limits = ARRAY_SIZE(wl18xx_iface_ap_limits),
1798 .num_different_channels = 1, 1801 .num_different_channels = 1,
1802 .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) |
1803 BIT(NL80211_CHAN_HT20) |
1804 BIT(NL80211_CHAN_HT40MINUS) |
1805 BIT(NL80211_CHAN_HT40PLUS),
1799 } 1806 }
1800}; 1807};
1801 1808
diff --git a/drivers/net/wireless/ti/wl18xx/wl18xx.h b/drivers/net/wireless/ti/wl18xx/wl18xx.h
index 6a2b88030c1d..71e9e382ce80 100644
--- a/drivers/net/wireless/ti/wl18xx/wl18xx.h
+++ b/drivers/net/wireless/ti/wl18xx/wl18xx.h
@@ -26,10 +26,10 @@
26 26
27/* minimum FW required for driver */ 27/* minimum FW required for driver */
28#define WL18XX_CHIP_VER 8 28#define WL18XX_CHIP_VER 8
29#define WL18XX_IFTYPE_VER 8 29#define WL18XX_IFTYPE_VER 9
30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE 30#define WL18XX_MAJOR_VER WLCORE_FW_VER_IGNORE
31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE 31#define WL18XX_SUBTYPE_VER WLCORE_FW_VER_IGNORE
32#define WL18XX_MINOR_VER 13 32#define WL18XX_MINOR_VER 11
33 33
34#define WL18XX_CMD_MAX_SIZE 740 34#define WL18XX_CMD_MAX_SIZE 740
35 35
diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c
index b924ceadc02c..f28fa3b5029d 100644
--- a/drivers/net/wireless/ti/wlcore/acx.c
+++ b/drivers/net/wireless/ti/wlcore/acx.c
@@ -1725,7 +1725,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl)
1725 acx->decrease_delta = conf->decrease_delta; 1725 acx->decrease_delta = conf->decrease_delta;
1726 acx->quiet_time = conf->quiet_time; 1726 acx->quiet_time = conf->quiet_time;
1727 acx->increase_time = conf->increase_time; 1727 acx->increase_time = conf->increase_time;
1728 acx->window_size = acx->window_size; 1728 acx->window_size = conf->window_size;
1729 1729
1730 ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx, 1730 ret = wl1271_cmd_configure(wl, ACX_CONFIG_HANGOVER, acx,
1731 sizeof(*acx)); 1731 sizeof(*acx));
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index b82661962d33..c26fc2106e5b 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -403,7 +403,7 @@ void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
403 WARN_ON_ONCE(wl->active_link_count < 0); 403 WARN_ON_ONCE(wl->active_link_count < 0);
404} 404}
405 405
406static u8 wlcore_get_native_channel_type(u8 nl_channel_type) 406u8 wlcore_get_native_channel_type(u8 nl_channel_type)
407{ 407{
408 switch (nl_channel_type) { 408 switch (nl_channel_type) {
409 case NL80211_CHAN_NO_HT: 409 case NL80211_CHAN_NO_HT:
@@ -419,6 +419,7 @@ static u8 wlcore_get_native_channel_type(u8 nl_channel_type)
419 return WLCORE_CHAN_NO_HT; 419 return WLCORE_CHAN_NO_HT;
420 } 420 }
421} 421}
422EXPORT_SYMBOL_GPL(wlcore_get_native_channel_type);
422 423
423static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, 424static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
424 struct wl12xx_vif *wlvif, 425 struct wl12xx_vif *wlvif,
@@ -1686,9 +1687,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1686{ 1687{
1687 struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL; 1688 struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
1688 int ret = 0, i, b, ch_bit_idx; 1689 int ret = 0, i, b, ch_bit_idx;
1689 struct ieee80211_channel *channel;
1690 u32 tmp_ch_bitmap[2]; 1690 u32 tmp_ch_bitmap[2];
1691 u16 ch;
1692 struct wiphy *wiphy = wl->hw->wiphy; 1691 struct wiphy *wiphy = wl->hw->wiphy;
1693 struct ieee80211_supported_band *band; 1692 struct ieee80211_supported_band *band;
1694 bool timeout = false; 1693 bool timeout = false;
@@ -1703,12 +1702,16 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1703 for (b = IEEE80211_BAND_2GHZ; b <= IEEE80211_BAND_5GHZ; b++) { 1702 for (b = IEEE80211_BAND_2GHZ; b <= IEEE80211_BAND_5GHZ; b++) {
1704 band = wiphy->bands[b]; 1703 band = wiphy->bands[b];
1705 for (i = 0; i < band->n_channels; i++) { 1704 for (i = 0; i < band->n_channels; i++) {
1706 channel = &band->channels[i]; 1705 struct ieee80211_channel *channel = &band->channels[i];
1707 ch = channel->hw_value; 1706 u16 ch = channel->hw_value;
1707 u32 flags = channel->flags;
1708 1708
1709 if (channel->flags & (IEEE80211_CHAN_DISABLED | 1709 if (flags & (IEEE80211_CHAN_DISABLED |
1710 IEEE80211_CHAN_RADAR | 1710 IEEE80211_CHAN_NO_IR))
1711 IEEE80211_CHAN_NO_IR)) 1711 continue;
1712
1713 if ((flags & IEEE80211_CHAN_RADAR) &&
1714 channel->dfs_state != NL80211_DFS_AVAILABLE)
1712 continue; 1715 continue;
1713 1716
1714 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch); 1717 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
@@ -1733,6 +1736,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1733 1736
1734 cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]); 1737 cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
1735 cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]); 1738 cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
1739 cmd->dfs_region = wl->dfs_region;
1736 1740
1737 wl1271_debug(DEBUG_CMD, 1741 wl1271_debug(DEBUG_CMD,
1738 "cmd reg domain bitmap1: 0x%08x, bitmap2: 0x%08x", 1742 "cmd reg domain bitmap1: 0x%08x, bitmap2: 0x%08x",
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index 453684a71d30..e14cd407a6ae 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -105,6 +105,7 @@ int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif,
105void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid); 105void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid);
106int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, 106int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl,
107 u32 mask, bool *timeout); 107 u32 mask, bool *timeout);
108u8 wlcore_get_native_channel_type(u8 nl_channel_type);
108 109
109enum wl1271_commands { 110enum wl1271_commands {
110 CMD_INTERROGATE = 1, /* use this to read information elements */ 111 CMD_INTERROGATE = 1, /* use this to read information elements */
@@ -172,6 +173,11 @@ enum wl1271_commands {
172 CMD_SMART_CONFIG_STOP = 62, 173 CMD_SMART_CONFIG_STOP = 62,
173 CMD_SMART_CONFIG_SET_GROUP_KEY = 63, 174 CMD_SMART_CONFIG_SET_GROUP_KEY = 63,
174 175
176 CMD_CAC_START = 64,
177 CMD_CAC_STOP = 65,
178 CMD_DFS_MASTER_RESTART = 66,
179 CMD_DFS_RADAR_DETECTION_DEBUG = 67,
180
175 MAX_COMMAND_ID = 0xFFFF, 181 MAX_COMMAND_ID = 0xFFFF,
176}; 182};
177 183
@@ -642,6 +648,8 @@ struct wl12xx_cmd_regdomain_dfs_config {
642 648
643 __le32 ch_bit_map1; 649 __le32 ch_bit_map1;
644 __le32 ch_bit_map2; 650 __le32 ch_bit_map2;
651 u8 dfs_region;
652 u8 padding[3];
645} __packed; 653} __packed;
646 654
647struct wl12xx_cmd_config_fwlog { 655struct wl12xx_cmd_config_fwlog {
diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h
index 40995c42bef8..166add00b50f 100644
--- a/drivers/net/wireless/ti/wlcore/conf.h
+++ b/drivers/net/wireless/ti/wlcore/conf.h
@@ -997,6 +997,11 @@ struct conf_conn_settings {
997 * whether we can go to ELP. 997 * whether we can go to ELP.
998 */ 998 */
999 u8 sta_sleep_auth; 999 u8 sta_sleep_auth;
1000
1001 /*
1002 * Default RX BA Activity filter configuration
1003 */
1004 u8 suspend_rx_ba_activity;
1000} __packed; 1005} __packed;
1001 1006
1002enum { 1007enum {
@@ -1347,7 +1352,7 @@ struct conf_recovery_settings {
1347 * version, the two LSB are the lower driver's private conf 1352 * version, the two LSB are the lower driver's private conf
1348 * version. 1353 * version.
1349 */ 1354 */
1350#define WLCORE_CONF_VERSION (0x0005 << 16) 1355#define WLCORE_CONF_VERSION (0x0006 << 16)
1351#define WLCORE_CONF_MASK 0xffff0000 1356#define WLCORE_CONF_MASK 0xffff0000
1352#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ 1357#define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \
1353 sizeof(struct wlcore_conf)) 1358 sizeof(struct wlcore_conf))
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c
index 0be21f62fcb0..68f3bf229b5a 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.c
+++ b/drivers/net/wireless/ti/wlcore/debugfs.c
@@ -929,17 +929,10 @@ static ssize_t beacon_filtering_write(struct file *file,
929{ 929{
930 struct wl1271 *wl = file->private_data; 930 struct wl1271 *wl = file->private_data;
931 struct wl12xx_vif *wlvif; 931 struct wl12xx_vif *wlvif;
932 char buf[10];
933 size_t len;
934 unsigned long value; 932 unsigned long value;
935 int ret; 933 int ret;
936 934
937 len = min(count, sizeof(buf) - 1); 935 ret = kstrtoul_from_user(user_buf, count, 0, &value);
938 if (copy_from_user(buf, user_buf, len))
939 return -EFAULT;
940 buf[len] = '\0';
941
942 ret = kstrtoul(buf, 0, &value);
943 if (ret < 0) { 936 if (ret < 0) {
944 wl1271_warning("illegal value for beacon_filtering!"); 937 wl1271_warning("illegal value for beacon_filtering!");
945 return -EINVAL; 938 return -EINVAL;
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 5153640f4532..c42e78955e7b 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -139,7 +139,7 @@ void wlcore_event_channel_switch(struct wl1271 *wl,
139 wl1271_debug(DEBUG_EVENT, "%s: roles=0x%lx success=%d", 139 wl1271_debug(DEBUG_EVENT, "%s: roles=0x%lx success=%d",
140 __func__, roles_bitmap, success); 140 __func__, roles_bitmap, success);
141 141
142 wl12xx_for_each_wlvif_sta(wl, wlvif) { 142 wl12xx_for_each_wlvif(wl, wlvif) {
143 if (wlvif->role_id == WL12XX_INVALID_ROLE_ID || 143 if (wlvif->role_id == WL12XX_INVALID_ROLE_ID ||
144 !test_bit(wlvif->role_id , &roles_bitmap)) 144 !test_bit(wlvif->role_id , &roles_bitmap))
145 continue; 145 continue;
@@ -150,8 +150,13 @@ void wlcore_event_channel_switch(struct wl1271 *wl,
150 150
151 vif = wl12xx_wlvif_to_vif(wlvif); 151 vif = wl12xx_wlvif_to_vif(wlvif);
152 152
153 ieee80211_chswitch_done(vif, success); 153 if (wlvif->bss_type == BSS_TYPE_STA_BSS) {
154 cancel_delayed_work(&wlvif->channel_switch_work); 154 ieee80211_chswitch_done(vif, success);
155 cancel_delayed_work(&wlvif->channel_switch_work);
156 } else {
157 set_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags);
158 ieee80211_csa_finish(vif);
159 }
155 } 160 }
156} 161}
157EXPORT_SYMBOL_GPL(wlcore_event_channel_switch); 162EXPORT_SYMBOL_GPL(wlcore_event_channel_switch);
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index aa9f82c72296..eec56935b1b6 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -211,11 +211,35 @@ wlcore_hw_pre_pkt_send(struct wl1271 *wl, u32 buf_offset, u32 last_len)
211} 211}
212 212
213static inline void 213static inline void
214wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif, 214wlcore_hw_sta_rc_update(struct wl1271 *wl, struct wl12xx_vif *wlvif)
215 struct ieee80211_sta *sta, u32 changed)
216{ 215{
217 if (wl->ops->sta_rc_update) 216 if (wl->ops->sta_rc_update)
218 wl->ops->sta_rc_update(wl, wlvif, sta, changed); 217 wl->ops->sta_rc_update(wl, wlvif);
218}
219
220static inline int
221wlcore_hw_interrupt_notify(struct wl1271 *wl, bool action)
222{
223 if (wl->ops->interrupt_notify)
224 return wl->ops->interrupt_notify(wl, action);
225 return 0;
226}
227
228static inline int
229wlcore_hw_rx_ba_filter(struct wl1271 *wl, bool action)
230{
231 if (wl->ops->rx_ba_filter)
232 return wl->ops->rx_ba_filter(wl, action);
233 return 0;
234}
235
236static inline int
237wlcore_hw_ap_sleep(struct wl1271 *wl)
238{
239 if (wl->ops->ap_sleep)
240 return wl->ops->ap_sleep(wl);
241
242 return 0;
219} 243}
220 244
221static inline int 245static inline int
@@ -287,4 +311,22 @@ wlcore_smart_config_set_group_key(struct wl1271 *wl, u16 group_id,
287 311
288 return wl->ops->smart_config_set_group_key(wl, group_id, key_len, key); 312 return wl->ops->smart_config_set_group_key(wl, group_id, key_len, key);
289} 313}
314
315static inline int
316wlcore_hw_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start)
317{
318 if (!wl->ops->set_cac)
319 return -EINVAL;
320
321 return wl->ops->set_cac(wl, wlvif, start);
322}
323
324static inline int
325wlcore_hw_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif)
326{
327 if (!wl->ops->dfs_master_restart)
328 return -EINVAL;
329
330 return wl->ops->dfs_master_restart(wl, wlvif);
331}
290#endif 332#endif
diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c
index 199e94120864..5ca1fb161a50 100644
--- a/drivers/net/wireless/ti/wlcore/init.c
+++ b/drivers/net/wireless/ti/wlcore/init.c
@@ -392,6 +392,11 @@ static int wl1271_ap_hw_init(struct wl1271 *wl, struct wl12xx_vif *wlvif)
392 if (ret < 0) 392 if (ret < 0)
393 return ret; 393 return ret;
394 394
395 /* configure AP sleep, if enabled */
396 ret = wlcore_hw_ap_sleep(wl);
397 if (ret < 0)
398 return ret;
399
395 return 0; 400 return 0;
396} 401}
397 402
@@ -567,8 +572,7 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif)
567 /* consider all existing roles before configuring psm. */ 572 /* consider all existing roles before configuring psm. */
568 573
569 if (wl->ap_count == 0 && is_ap) { /* first AP */ 574 if (wl->ap_count == 0 && is_ap) { /* first AP */
570 /* Configure for power always on */ 575 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP);
571 ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);
572 if (ret < 0) 576 if (ret < 0)
573 return ret; 577 return ret;
574 578
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index a2133b1fd631..1e136993580f 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -79,22 +79,12 @@ static int wl12xx_set_authorized(struct wl1271 *wl, struct wl12xx_vif *wlvif)
79static void wl1271_reg_notify(struct wiphy *wiphy, 79static void wl1271_reg_notify(struct wiphy *wiphy,
80 struct regulatory_request *request) 80 struct regulatory_request *request)
81{ 81{
82 struct ieee80211_supported_band *band;
83 struct ieee80211_channel *ch;
84 int i;
85 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 82 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
86 struct wl1271 *wl = hw->priv; 83 struct wl1271 *wl = hw->priv;
87 84
88 band = wiphy->bands[IEEE80211_BAND_5GHZ]; 85 /* copy the current dfs region */
89 for (i = 0; i < band->n_channels; i++) { 86 if (request)
90 ch = &band->channels[i]; 87 wl->dfs_region = request->dfs_region;
91 if (ch->flags & IEEE80211_CHAN_DISABLED)
92 continue;
93
94 if (ch->flags & IEEE80211_CHAN_RADAR)
95 ch->flags |= IEEE80211_CHAN_NO_IR;
96
97 }
98 88
99 wlcore_regdomain_config(wl); 89 wlcore_regdomain_config(wl);
100} 90}
@@ -226,6 +216,29 @@ void wl12xx_rearm_tx_watchdog_locked(struct wl1271 *wl)
226 msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout)); 216 msecs_to_jiffies(wl->conf.tx.tx_watchdog_timeout));
227} 217}
228 218
219static void wlcore_rc_update_work(struct work_struct *work)
220{
221 int ret;
222 struct wl12xx_vif *wlvif = container_of(work, struct wl12xx_vif,
223 rc_update_work);
224 struct wl1271 *wl = wlvif->wl;
225
226 mutex_lock(&wl->mutex);
227
228 if (unlikely(wl->state != WLCORE_STATE_ON))
229 goto out;
230
231 ret = wl1271_ps_elp_wakeup(wl);
232 if (ret < 0)
233 goto out;
234
235 wlcore_hw_sta_rc_update(wl, wlvif);
236
237 wl1271_ps_elp_sleep(wl);
238out:
239 mutex_unlock(&wl->mutex);
240}
241
229static void wl12xx_tx_watchdog_work(struct work_struct *work) 242static void wl12xx_tx_watchdog_work(struct work_struct *work)
230{ 243{
231 struct delayed_work *dwork; 244 struct delayed_work *dwork;
@@ -1662,19 +1675,15 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1662 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1675 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags))
1663 goto out; 1676 goto out;
1664 1677
1665 ret = wl1271_ps_elp_wakeup(wl);
1666 if (ret < 0)
1667 goto out;
1668
1669 ret = wl1271_configure_wowlan(wl, wow); 1678 ret = wl1271_configure_wowlan(wl, wow);
1670 if (ret < 0) 1679 if (ret < 0)
1671 goto out_sleep; 1680 goto out;
1672 1681
1673 if ((wl->conf.conn.suspend_wake_up_event == 1682 if ((wl->conf.conn.suspend_wake_up_event ==
1674 wl->conf.conn.wake_up_event) && 1683 wl->conf.conn.wake_up_event) &&
1675 (wl->conf.conn.suspend_listen_interval == 1684 (wl->conf.conn.suspend_listen_interval ==
1676 wl->conf.conn.listen_interval)) 1685 wl->conf.conn.listen_interval))
1677 goto out_sleep; 1686 goto out;
1678 1687
1679 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1688 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1680 wl->conf.conn.suspend_wake_up_event, 1689 wl->conf.conn.suspend_wake_up_event,
@@ -1682,29 +1691,28 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl,
1682 1691
1683 if (ret < 0) 1692 if (ret < 0)
1684 wl1271_error("suspend: set wake up conditions failed: %d", ret); 1693 wl1271_error("suspend: set wake up conditions failed: %d", ret);
1685
1686out_sleep:
1687 wl1271_ps_elp_sleep(wl);
1688out: 1694out:
1689 return ret; 1695 return ret;
1690 1696
1691} 1697}
1692 1698
1693static int wl1271_configure_suspend_ap(struct wl1271 *wl, 1699static int wl1271_configure_suspend_ap(struct wl1271 *wl,
1694 struct wl12xx_vif *wlvif) 1700 struct wl12xx_vif *wlvif,
1701 struct cfg80211_wowlan *wow)
1695{ 1702{
1696 int ret = 0; 1703 int ret = 0;
1697 1704
1698 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) 1705 if (!test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags))
1699 goto out; 1706 goto out;
1700 1707
1701 ret = wl1271_ps_elp_wakeup(wl); 1708 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true);
1702 if (ret < 0) 1709 if (ret < 0)
1703 goto out; 1710 goto out;
1704 1711
1705 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, true); 1712 ret = wl1271_configure_wowlan(wl, wow);
1713 if (ret < 0)
1714 goto out;
1706 1715
1707 wl1271_ps_elp_sleep(wl);
1708out: 1716out:
1709 return ret; 1717 return ret;
1710 1718
@@ -1717,7 +1725,7 @@ static int wl1271_configure_suspend(struct wl1271 *wl,
1717 if (wlvif->bss_type == BSS_TYPE_STA_BSS) 1725 if (wlvif->bss_type == BSS_TYPE_STA_BSS)
1718 return wl1271_configure_suspend_sta(wl, wlvif, wow); 1726 return wl1271_configure_suspend_sta(wl, wlvif, wow);
1719 if (wlvif->bss_type == BSS_TYPE_AP_BSS) 1727 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
1720 return wl1271_configure_suspend_ap(wl, wlvif); 1728 return wl1271_configure_suspend_ap(wl, wlvif, wow);
1721 return 0; 1729 return 0;
1722} 1730}
1723 1731
@@ -1730,21 +1738,18 @@ static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1730 if ((!is_ap) && (!is_sta)) 1738 if ((!is_ap) && (!is_sta))
1731 return; 1739 return;
1732 1740
1733 if (is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 1741 if ((is_sta && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) ||
1742 (is_ap && !test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)))
1734 return; 1743 return;
1735 1744
1736 ret = wl1271_ps_elp_wakeup(wl); 1745 wl1271_configure_wowlan(wl, NULL);
1737 if (ret < 0)
1738 return;
1739 1746
1740 if (is_sta) { 1747 if (is_sta) {
1741 wl1271_configure_wowlan(wl, NULL);
1742
1743 if ((wl->conf.conn.suspend_wake_up_event == 1748 if ((wl->conf.conn.suspend_wake_up_event ==
1744 wl->conf.conn.wake_up_event) && 1749 wl->conf.conn.wake_up_event) &&
1745 (wl->conf.conn.suspend_listen_interval == 1750 (wl->conf.conn.suspend_listen_interval ==
1746 wl->conf.conn.listen_interval)) 1751 wl->conf.conn.listen_interval))
1747 goto out_sleep; 1752 return;
1748 1753
1749 ret = wl1271_acx_wake_up_conditions(wl, wlvif, 1754 ret = wl1271_acx_wake_up_conditions(wl, wlvif,
1750 wl->conf.conn.wake_up_event, 1755 wl->conf.conn.wake_up_event,
@@ -1757,9 +1762,6 @@ static void wl1271_configure_resume(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1757 } else if (is_ap) { 1762 } else if (is_ap) {
1758 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false); 1763 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, false);
1759 } 1764 }
1760
1761out_sleep:
1762 wl1271_ps_elp_sleep(wl);
1763} 1765}
1764 1766
1765static int wl1271_op_suspend(struct ieee80211_hw *hw, 1767static int wl1271_op_suspend(struct ieee80211_hw *hw,
@@ -1781,6 +1783,13 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1781 wl1271_tx_flush(wl); 1783 wl1271_tx_flush(wl);
1782 1784
1783 mutex_lock(&wl->mutex); 1785 mutex_lock(&wl->mutex);
1786
1787 ret = wl1271_ps_elp_wakeup(wl);
1788 if (ret < 0) {
1789 mutex_unlock(&wl->mutex);
1790 return ret;
1791 }
1792
1784 wl->wow_enabled = true; 1793 wl->wow_enabled = true;
1785 wl12xx_for_each_wlvif(wl, wlvif) { 1794 wl12xx_for_each_wlvif(wl, wlvif) {
1786 ret = wl1271_configure_suspend(wl, wlvif, wow); 1795 ret = wl1271_configure_suspend(wl, wlvif, wow);
@@ -1790,7 +1799,27 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
1790 return ret; 1799 return ret;
1791 } 1800 }
1792 } 1801 }
1802
1803 /* disable fast link flow control notifications from FW */
1804 ret = wlcore_hw_interrupt_notify(wl, false);
1805 if (ret < 0)
1806 goto out_sleep;
1807
1808 /* if filtering is enabled, configure the FW to drop all RX BA frames */
1809 ret = wlcore_hw_rx_ba_filter(wl,
1810 !!wl->conf.conn.suspend_rx_ba_activity);
1811 if (ret < 0)
1812 goto out_sleep;
1813
1814out_sleep:
1815 wl1271_ps_elp_sleep(wl);
1793 mutex_unlock(&wl->mutex); 1816 mutex_unlock(&wl->mutex);
1817
1818 if (ret < 0) {
1819 wl1271_warning("couldn't prepare device to suspend");
1820 return ret;
1821 }
1822
1794 /* flush any remaining work */ 1823 /* flush any remaining work */
1795 wl1271_debug(DEBUG_MAC80211, "flushing remaining works"); 1824 wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
1796 1825
@@ -1864,13 +1893,29 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
1864 if (pending_recovery) { 1893 if (pending_recovery) {
1865 wl1271_warning("queuing forgotten recovery on resume"); 1894 wl1271_warning("queuing forgotten recovery on resume");
1866 ieee80211_queue_work(wl->hw, &wl->recovery_work); 1895 ieee80211_queue_work(wl->hw, &wl->recovery_work);
1867 goto out; 1896 goto out_sleep;
1868 } 1897 }
1869 1898
1899 ret = wl1271_ps_elp_wakeup(wl);
1900 if (ret < 0)
1901 goto out;
1902
1870 wl12xx_for_each_wlvif(wl, wlvif) { 1903 wl12xx_for_each_wlvif(wl, wlvif) {
1871 wl1271_configure_resume(wl, wlvif); 1904 wl1271_configure_resume(wl, wlvif);
1872 } 1905 }
1873 1906
1907 ret = wlcore_hw_interrupt_notify(wl, true);
1908 if (ret < 0)
1909 goto out_sleep;
1910
1911 /* if filtering is enabled, configure the FW to drop all RX BA frames */
1912 ret = wlcore_hw_rx_ba_filter(wl, false);
1913 if (ret < 0)
1914 goto out_sleep;
1915
1916out_sleep:
1917 wl1271_ps_elp_sleep(wl);
1918
1874out: 1919out:
1875 wl->wow_enabled = false; 1920 wl->wow_enabled = false;
1876 1921
@@ -2279,6 +2324,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
2279 wl1271_rx_streaming_enable_work); 2324 wl1271_rx_streaming_enable_work);
2280 INIT_WORK(&wlvif->rx_streaming_disable_work, 2325 INIT_WORK(&wlvif->rx_streaming_disable_work,
2281 wl1271_rx_streaming_disable_work); 2326 wl1271_rx_streaming_disable_work);
2327 INIT_WORK(&wlvif->rc_update_work, wlcore_rc_update_work);
2282 INIT_DELAYED_WORK(&wlvif->channel_switch_work, 2328 INIT_DELAYED_WORK(&wlvif->channel_switch_work,
2283 wlcore_channel_switch_work); 2329 wlcore_channel_switch_work);
2284 INIT_DELAYED_WORK(&wlvif->connection_loss_work, 2330 INIT_DELAYED_WORK(&wlvif->connection_loss_work,
@@ -2724,6 +2770,7 @@ unlock:
2724 del_timer_sync(&wlvif->rx_streaming_timer); 2770 del_timer_sync(&wlvif->rx_streaming_timer);
2725 cancel_work_sync(&wlvif->rx_streaming_enable_work); 2771 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2726 cancel_work_sync(&wlvif->rx_streaming_disable_work); 2772 cancel_work_sync(&wlvif->rx_streaming_disable_work);
2773 cancel_work_sync(&wlvif->rc_update_work);
2727 cancel_delayed_work_sync(&wlvif->connection_loss_work); 2774 cancel_delayed_work_sync(&wlvif->connection_loss_work);
2728 cancel_delayed_work_sync(&wlvif->channel_switch_work); 2775 cancel_delayed_work_sync(&wlvif->channel_switch_work);
2729 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work); 2776 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
@@ -4073,8 +4120,14 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
4073 ret = wlcore_set_beacon_template(wl, vif, is_ap); 4120 ret = wlcore_set_beacon_template(wl, vif, is_ap);
4074 if (ret < 0) 4121 if (ret < 0)
4075 goto out; 4122 goto out;
4076 }
4077 4123
4124 if (test_and_clear_bit(WLVIF_FLAG_BEACON_DISABLED,
4125 &wlvif->flags)) {
4126 ret = wlcore_hw_dfs_master_restart(wl, wlvif);
4127 if (ret < 0)
4128 goto out;
4129 }
4130 }
4078out: 4131out:
4079 if (ret != 0) 4132 if (ret != 0)
4080 wl1271_error("beacon info change failed: %d", ret); 4133 wl1271_error("beacon info change failed: %d", ret);
@@ -4575,10 +4628,46 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
4575 struct ieee80211_chanctx_conf *ctx, 4628 struct ieee80211_chanctx_conf *ctx,
4576 u32 changed) 4629 u32 changed)
4577{ 4630{
4631 struct wl1271 *wl = hw->priv;
4632 struct wl12xx_vif *wlvif;
4633 int ret;
4634 int channel = ieee80211_frequency_to_channel(
4635 ctx->def.chan->center_freq);
4636
4578 wl1271_debug(DEBUG_MAC80211, 4637 wl1271_debug(DEBUG_MAC80211,
4579 "mac80211 change chanctx %d (type %d) changed 0x%x", 4638 "mac80211 change chanctx %d (type %d) changed 0x%x",
4580 ieee80211_frequency_to_channel(ctx->def.chan->center_freq), 4639 channel, cfg80211_get_chandef_type(&ctx->def), changed);
4581 cfg80211_get_chandef_type(&ctx->def), changed); 4640
4641 mutex_lock(&wl->mutex);
4642
4643 ret = wl1271_ps_elp_wakeup(wl);
4644 if (ret < 0)
4645 goto out;
4646
4647 wl12xx_for_each_wlvif(wl, wlvif) {
4648 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
4649
4650 rcu_read_lock();
4651 if (rcu_access_pointer(vif->chanctx_conf) != ctx) {
4652 rcu_read_unlock();
4653 continue;
4654 }
4655 rcu_read_unlock();
4656
4657 /* start radar if needed */
4658 if (changed & IEEE80211_CHANCTX_CHANGE_RADAR &&
4659 wlvif->bss_type == BSS_TYPE_AP_BSS &&
4660 ctx->radar_enabled && !wlvif->radar_enabled &&
4661 ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
4662 wl1271_debug(DEBUG_MAC80211, "Start radar detection");
4663 wlcore_hw_set_cac(wl, wlvif, true);
4664 wlvif->radar_enabled = true;
4665 }
4666 }
4667
4668 wl1271_ps_elp_sleep(wl);
4669out:
4670 mutex_unlock(&wl->mutex);
4582} 4671}
4583 4672
4584static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, 4673static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -4589,13 +4678,26 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4589 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4678 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4590 int channel = ieee80211_frequency_to_channel( 4679 int channel = ieee80211_frequency_to_channel(
4591 ctx->def.chan->center_freq); 4680 ctx->def.chan->center_freq);
4681 int ret = -EINVAL;
4592 4682
4593 wl1271_debug(DEBUG_MAC80211, 4683 wl1271_debug(DEBUG_MAC80211,
4594 "mac80211 assign chanctx (role %d) %d (type %d)", 4684 "mac80211 assign chanctx (role %d) %d (type %d) (radar %d dfs_state %d)",
4595 wlvif->role_id, channel, cfg80211_get_chandef_type(&ctx->def)); 4685 wlvif->role_id, channel,
4686 cfg80211_get_chandef_type(&ctx->def),
4687 ctx->radar_enabled, ctx->def.chan->dfs_state);
4596 4688
4597 mutex_lock(&wl->mutex); 4689 mutex_lock(&wl->mutex);
4598 4690
4691 if (unlikely(wl->state != WLCORE_STATE_ON))
4692 goto out;
4693
4694 if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
4695 goto out;
4696
4697 ret = wl1271_ps_elp_wakeup(wl);
4698 if (ret < 0)
4699 goto out;
4700
4599 wlvif->band = ctx->def.chan->band; 4701 wlvif->band = ctx->def.chan->band;
4600 wlvif->channel = channel; 4702 wlvif->channel = channel;
4601 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def); 4703 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
@@ -4603,6 +4705,15 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4603 /* update default rates according to the band */ 4705 /* update default rates according to the band */
4604 wl1271_set_band_rate(wl, wlvif); 4706 wl1271_set_band_rate(wl, wlvif);
4605 4707
4708 if (ctx->radar_enabled &&
4709 ctx->def.chan->dfs_state == NL80211_DFS_USABLE) {
4710 wl1271_debug(DEBUG_MAC80211, "Start radar detection");
4711 wlcore_hw_set_cac(wl, wlvif, true);
4712 wlvif->radar_enabled = true;
4713 }
4714
4715 wl1271_ps_elp_sleep(wl);
4716out:
4606 mutex_unlock(&wl->mutex); 4717 mutex_unlock(&wl->mutex);
4607 4718
4608 return 0; 4719 return 0;
@@ -4614,6 +4725,7 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4614{ 4725{
4615 struct wl1271 *wl = hw->priv; 4726 struct wl1271 *wl = hw->priv;
4616 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4727 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4728 int ret;
4617 4729
4618 wl1271_debug(DEBUG_MAC80211, 4730 wl1271_debug(DEBUG_MAC80211,
4619 "mac80211 unassign chanctx (role %d) %d (type %d)", 4731 "mac80211 unassign chanctx (role %d) %d (type %d)",
@@ -4622,6 +4734,99 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4622 cfg80211_get_chandef_type(&ctx->def)); 4734 cfg80211_get_chandef_type(&ctx->def));
4623 4735
4624 wl1271_tx_flush(wl); 4736 wl1271_tx_flush(wl);
4737
4738 mutex_lock(&wl->mutex);
4739
4740 if (unlikely(wl->state != WLCORE_STATE_ON))
4741 goto out;
4742
4743 if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)))
4744 goto out;
4745
4746 ret = wl1271_ps_elp_wakeup(wl);
4747 if (ret < 0)
4748 goto out;
4749
4750 if (wlvif->radar_enabled) {
4751 wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
4752 wlcore_hw_set_cac(wl, wlvif, false);
4753 wlvif->radar_enabled = false;
4754 }
4755
4756 wl1271_ps_elp_sleep(wl);
4757out:
4758 mutex_unlock(&wl->mutex);
4759}
4760
4761static int __wlcore_switch_vif_chan(struct wl1271 *wl,
4762 struct wl12xx_vif *wlvif,
4763 struct ieee80211_chanctx_conf *new_ctx)
4764{
4765 int channel = ieee80211_frequency_to_channel(
4766 new_ctx->def.chan->center_freq);
4767
4768 wl1271_debug(DEBUG_MAC80211,
4769 "switch vif (role %d) %d -> %d chan_type: %d",
4770 wlvif->role_id, wlvif->channel, channel,
4771 cfg80211_get_chandef_type(&new_ctx->def));
4772
4773 if (WARN_ON_ONCE(wlvif->bss_type != BSS_TYPE_AP_BSS))
4774 return 0;
4775
4776 WARN_ON(!test_bit(WLVIF_FLAG_BEACON_DISABLED, &wlvif->flags));
4777
4778 if (wlvif->radar_enabled) {
4779 wl1271_debug(DEBUG_MAC80211, "Stop radar detection");
4780 wlcore_hw_set_cac(wl, wlvif, false);
4781 wlvif->radar_enabled = false;
4782 }
4783
4784 wlvif->band = new_ctx->def.chan->band;
4785 wlvif->channel = channel;
4786 wlvif->channel_type = cfg80211_get_chandef_type(&new_ctx->def);
4787
4788 /* start radar if needed */
4789 if (new_ctx->radar_enabled) {
4790 wl1271_debug(DEBUG_MAC80211, "Start radar detection");
4791 wlcore_hw_set_cac(wl, wlvif, true);
4792 wlvif->radar_enabled = true;
4793 }
4794
4795 return 0;
4796}
4797
4798static int
4799wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw,
4800 struct ieee80211_vif_chanctx_switch *vifs,
4801 int n_vifs,
4802 enum ieee80211_chanctx_switch_mode mode)
4803{
4804 struct wl1271 *wl = hw->priv;
4805 int i, ret;
4806
4807 wl1271_debug(DEBUG_MAC80211,
4808 "mac80211 switch chanctx n_vifs %d mode %d",
4809 n_vifs, mode);
4810
4811 mutex_lock(&wl->mutex);
4812
4813 ret = wl1271_ps_elp_wakeup(wl);
4814 if (ret < 0)
4815 goto out;
4816
4817 for (i = 0; i < n_vifs; i++) {
4818 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vifs[i].vif);
4819
4820 ret = __wlcore_switch_vif_chan(wl, wlvif, vifs[i].new_ctx);
4821 if (ret)
4822 goto out_sleep;
4823 }
4824out_sleep:
4825 wl1271_ps_elp_sleep(wl);
4826out:
4827 mutex_unlock(&wl->mutex);
4828
4829 return 0;
4625} 4830}
4626 4831
4627static int wl1271_op_conf_tx(struct ieee80211_hw *hw, 4832static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
@@ -5229,6 +5434,83 @@ out:
5229 mutex_unlock(&wl->mutex); 5434 mutex_unlock(&wl->mutex);
5230} 5435}
5231 5436
5437static const void *wlcore_get_beacon_ie(struct wl1271 *wl,
5438 struct wl12xx_vif *wlvif,
5439 u8 eid)
5440{
5441 int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
5442 struct sk_buff *beacon =
5443 ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif));
5444
5445 if (!beacon)
5446 return NULL;
5447
5448 return cfg80211_find_ie(eid,
5449 beacon->data + ieoffset,
5450 beacon->len - ieoffset);
5451}
5452
5453static int wlcore_get_csa_count(struct wl1271 *wl, struct wl12xx_vif *wlvif,
5454 u8 *csa_count)
5455{
5456 const u8 *ie;
5457 const struct ieee80211_channel_sw_ie *ie_csa;
5458
5459 ie = wlcore_get_beacon_ie(wl, wlvif, WLAN_EID_CHANNEL_SWITCH);
5460 if (!ie)
5461 return -EINVAL;
5462
5463 ie_csa = (struct ieee80211_channel_sw_ie *)&ie[2];
5464 *csa_count = ie_csa->count;
5465
5466 return 0;
5467}
5468
5469static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw,
5470 struct ieee80211_vif *vif,
5471 struct cfg80211_chan_def *chandef)
5472{
5473 struct wl1271 *wl = hw->priv;
5474 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5475 struct ieee80211_channel_switch ch_switch = {
5476 .block_tx = true,
5477 .chandef = *chandef,
5478 };
5479 int ret;
5480
5481 wl1271_debug(DEBUG_MAC80211,
5482 "mac80211 channel switch beacon (role %d)",
5483 wlvif->role_id);
5484
5485 ret = wlcore_get_csa_count(wl, wlvif, &ch_switch.count);
5486 if (ret < 0) {
5487 wl1271_error("error getting beacon (for CSA counter)");
5488 return;
5489 }
5490
5491 mutex_lock(&wl->mutex);
5492
5493 if (unlikely(wl->state != WLCORE_STATE_ON)) {
5494 ret = -EBUSY;
5495 goto out;
5496 }
5497
5498 ret = wl1271_ps_elp_wakeup(wl);
5499 if (ret < 0)
5500 goto out;
5501
5502 ret = wl->ops->channel_switch(wl, wlvif, &ch_switch);
5503 if (ret)
5504 goto out_sleep;
5505
5506 set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags);
5507
5508out_sleep:
5509 wl1271_ps_elp_sleep(wl);
5510out:
5511 mutex_unlock(&wl->mutex);
5512}
5513
5232static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 5514static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5233 u32 queues, bool drop) 5515 u32 queues, bool drop)
5234{ 5516{
@@ -5371,9 +5653,15 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5371 u32 changed) 5653 u32 changed)
5372{ 5654{
5373 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5655 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5374 struct wl1271 *wl = hw->priv;
5375 5656
5376 wlcore_hw_sta_rc_update(wl, wlvif, sta, changed); 5657 wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update");
5658
5659 if (!(changed & IEEE80211_RC_BW_CHANGED))
5660 return;
5661
5662 /* this callback is atomic, so schedule a new work */
5663 wlvif->rc_update_bw = sta->bandwidth;
5664 ieee80211_queue_work(hw, &wlvif->rc_update_work);
5377} 5665}
5378 5666
5379static void wlcore_op_sta_statistics(struct ieee80211_hw *hw, 5667static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
@@ -5599,6 +5887,7 @@ static const struct ieee80211_ops wl1271_ops = {
5599 .set_bitrate_mask = wl12xx_set_bitrate_mask, 5887 .set_bitrate_mask = wl12xx_set_bitrate_mask,
5600 .set_default_unicast_key = wl1271_op_set_default_key_idx, 5888 .set_default_unicast_key = wl1271_op_set_default_key_idx,
5601 .channel_switch = wl12xx_op_channel_switch, 5889 .channel_switch = wl12xx_op_channel_switch,
5890 .channel_switch_beacon = wlcore_op_channel_switch_beacon,
5602 .flush = wlcore_op_flush, 5891 .flush = wlcore_op_flush,
5603 .remain_on_channel = wlcore_op_remain_on_channel, 5892 .remain_on_channel = wlcore_op_remain_on_channel,
5604 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel, 5893 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel,
@@ -5607,6 +5896,7 @@ static const struct ieee80211_ops wl1271_ops = {
5607 .change_chanctx = wlcore_op_change_chanctx, 5896 .change_chanctx = wlcore_op_change_chanctx,
5608 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, 5897 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5609 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, 5898 .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx,
5899 .switch_vif_chanctx = wlcore_op_switch_vif_chanctx,
5610 .sta_rc_update = wlcore_op_sta_rc_update, 5900 .sta_rc_update = wlcore_op_sta_rc_update,
5611 .sta_statistics = wlcore_op_sta_statistics, 5901 .sta_statistics = wlcore_op_sta_statistics,
5612 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5902 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
@@ -5813,7 +6103,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5813 6103
5814 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | 6104 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
5815 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 6105 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5816 WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 6106 WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
6107 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
5817 6108
5818 /* make sure all our channels fit in the scanned_ch bitmask */ 6109 /* make sure all our channels fit in the scanned_ch bitmask */
5819 BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) + 6110 BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index b52516eed7b2..4cd316e61466 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -56,9 +56,6 @@ void wl1271_elp_work(struct work_struct *work)
56 goto out; 56 goto out;
57 57
58 wl12xx_for_each_wlvif(wl, wlvif) { 58 wl12xx_for_each_wlvif(wl, wlvif) {
59 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
60 goto out;
61
62 if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && 59 if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
63 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) 60 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
64 goto out; 61 goto out;
@@ -95,9 +92,6 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
95 return; 92 return;
96 93
97 wl12xx_for_each_wlvif(wl, wlvif) { 94 wl12xx_for_each_wlvif(wl, wlvif) {
98 if (wlvif->bss_type == BSS_TYPE_AP_BSS)
99 return;
100
101 if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) && 95 if (!test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags) &&
102 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) 96 test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags))
103 return; 97 return;
@@ -108,6 +102,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
108 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, 102 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
109 msecs_to_jiffies(timeout)); 103 msecs_to_jiffies(timeout));
110} 104}
105EXPORT_SYMBOL_GPL(wl1271_ps_elp_sleep);
111 106
112int wl1271_ps_elp_wakeup(struct wl1271 *wl) 107int wl1271_ps_elp_wakeup(struct wl1271 *wl)
113{ 108{
@@ -175,6 +170,7 @@ err:
175out: 170out:
176 return 0; 171 return 0;
177} 172}
173EXPORT_SYMBOL_GPL(wl1271_ps_elp_wakeup);
178 174
179int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, 175int wl1271_ps_set_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
180 enum wl1271_cmd_ps_mode mode) 176 enum wl1271_cmd_ps_mode mode)
diff --git a/drivers/net/wireless/ti/wlcore/vendor_cmd.c b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
index ad86a48dcfcb..fd4e9ba176c9 100644
--- a/drivers/net/wireless/ti/wlcore/vendor_cmd.c
+++ b/drivers/net/wireless/ti/wlcore/vendor_cmd.c
@@ -21,7 +21,7 @@ static const
21struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = { 21struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = {
22 [WLCORE_VENDOR_ATTR_FREQ] = { .type = NLA_U32 }, 22 [WLCORE_VENDOR_ATTR_FREQ] = { .type = NLA_U32 },
23 [WLCORE_VENDOR_ATTR_GROUP_ID] = { .type = NLA_U32 }, 23 [WLCORE_VENDOR_ATTR_GROUP_ID] = { .type = NLA_U32 },
24 [WLCORE_VENDOR_ATTR_GROUP_KEY] = { .type = NLA_U32, 24 [WLCORE_VENDOR_ATTR_GROUP_KEY] = { .type = NLA_BINARY,
25 .len = WLAN_MAX_KEY_LEN }, 25 .len = WLAN_MAX_KEY_LEN },
26}; 26};
27 27
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index df78cf12ef15..d599c869e6e8 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -106,8 +106,7 @@ struct wlcore_ops {
106 struct wl12xx_vif *wlvif, 106 struct wl12xx_vif *wlvif,
107 struct ieee80211_channel_switch *ch_switch); 107 struct ieee80211_channel_switch *ch_switch);
108 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len); 108 u32 (*pre_pkt_send)(struct wl1271 *wl, u32 buf_offset, u32 last_len);
109 void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif, 109 void (*sta_rc_update)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
110 struct ieee80211_sta *sta, u32 changed);
111 int (*set_peer_cap)(struct wl1271 *wl, 110 int (*set_peer_cap)(struct wl1271 *wl,
112 struct ieee80211_sta_ht_cap *ht_cap, 111 struct ieee80211_sta_ht_cap *ht_cap,
113 bool allow_ht_operation, 112 bool allow_ht_operation,
@@ -117,10 +116,16 @@ struct wlcore_ops {
117 struct wl1271_link *lnk); 116 struct wl1271_link *lnk);
118 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid, 117 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid,
119 struct wl1271_link *lnk); 118 struct wl1271_link *lnk);
119 int (*interrupt_notify)(struct wl1271 *wl, bool action);
120 int (*rx_ba_filter)(struct wl1271 *wl, bool action);
121 int (*ap_sleep)(struct wl1271 *wl);
120 int (*smart_config_start)(struct wl1271 *wl, u32 group_bitmap); 122 int (*smart_config_start)(struct wl1271 *wl, u32 group_bitmap);
121 int (*smart_config_stop)(struct wl1271 *wl); 123 int (*smart_config_stop)(struct wl1271 *wl);
122 int (*smart_config_set_group_key)(struct wl1271 *wl, u16 group_id, 124 int (*smart_config_set_group_key)(struct wl1271 *wl, u16 group_id,
123 u8 key_len, u8 *key); 125 u8 key_len, u8 *key);
126 int (*set_cac)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
127 bool start);
128 int (*dfs_master_restart)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
124}; 129};
125 130
126enum wlcore_partitions { 131enum wlcore_partitions {
@@ -460,6 +465,9 @@ struct wl1271 {
460 /* HW HT (11n) capabilities */ 465 /* HW HT (11n) capabilities */
461 struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS]; 466 struct ieee80211_sta_ht_cap ht_cap[WLCORE_NUM_BANDS];
462 467
468 /* the current dfs region */
469 enum nl80211_dfs_regions dfs_region;
470
463 /* size of the private FW status data */ 471 /* size of the private FW status data */
464 size_t fw_status_len; 472 size_t fw_status_len;
465 size_t fw_status_priv_len; 473 size_t fw_status_priv_len;
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 0e52556044d9..3396ce5a934d 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -251,6 +251,7 @@ enum wl12xx_vif_flags {
251 WLVIF_FLAG_AP_PROBE_RESP_SET, 251 WLVIF_FLAG_AP_PROBE_RESP_SET,
252 WLVIF_FLAG_IN_USE, 252 WLVIF_FLAG_IN_USE,
253 WLVIF_FLAG_ACTIVE, 253 WLVIF_FLAG_ACTIVE,
254 WLVIF_FLAG_BEACON_DISABLED,
254}; 255};
255 256
256struct wl12xx_vif; 257struct wl12xx_vif;
@@ -434,6 +435,8 @@ struct wl12xx_vif {
434 435
435 bool wmm_enabled; 436 bool wmm_enabled;
436 437
438 bool radar_enabled;
439
437 /* Rx Streaming */ 440 /* Rx Streaming */
438 struct work_struct rx_streaming_enable_work; 441 struct work_struct rx_streaming_enable_work;
439 struct work_struct rx_streaming_disable_work; 442 struct work_struct rx_streaming_disable_work;
@@ -463,6 +466,10 @@ struct wl12xx_vif {
463 /* work for canceling ROC after pending auth reply */ 466 /* work for canceling ROC after pending auth reply */
464 struct delayed_work pending_auth_complete_work; 467 struct delayed_work pending_auth_complete_work;
465 468
469 /* update rate conrol */
470 enum ieee80211_sta_rx_bandwidth rc_update_bw;
471 struct work_struct rc_update_work;
472
466 /* 473 /*
467 * total freed FW packets on the link. 474 * total freed FW packets on the link.
468 * For STA this holds the PN of the link to the AP. 475 * For STA this holds the PN of the link to the AP.
diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h
index f24d245f8394..1b5fc0c3b1b5 100644
--- a/include/linux/bcma/bcma_soc.h
+++ b/include/linux/bcma/bcma_soc.h
@@ -5,8 +5,6 @@
5 5
6struct bcma_soc { 6struct bcma_soc {
7 struct bcma_bus bus; 7 struct bcma_bus bus;
8 struct bcma_device core_cc;
9 struct bcma_device core_mips;
10}; 8};
11 9
12int __init bcma_host_soc_register(struct bcma_soc *soc); 10int __init bcma_host_soc_register(struct bcma_soc *soc);
diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h
index 0f01fe065424..996807963716 100644
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -24,13 +24,15 @@
24 * Vendors and devices. Sort key: vendor first, device next. 24 * Vendors and devices. Sort key: vendor first, device next.
25 */ 25 */
26#define SDIO_VENDOR_ID_BROADCOM 0x02d0 26#define SDIO_VENDOR_ID_BROADCOM 0x02d0
27#define SDIO_DEVICE_ID_BROADCOM_43143 43143 27#define SDIO_DEVICE_ID_BROADCOM_43143 0xa887
28#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 28#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
29#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 29#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
30#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 30#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
31#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 31#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
32#define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c
33#define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d
32#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 34#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
33#define SDIO_DEVICE_ID_BROADCOM_43362 43362 35#define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
34#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 36#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
35 37
36#define SDIO_VENDOR_ID_INTEL 0x0089 38#define SDIO_VENDOR_ID_INTEL 0x0089