aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 23:01:30 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-10 23:01:30 -0500
commitc5ce28df0e7c01a1de23c36ebdefcd803f2b6cbb (patch)
tree9830baf38832769e1cf621708889111bbe3c93df /drivers/net/wireless
parent29afc4e9a408f2304e09c6dd0dbcfbd2356d0faa (diff)
parent9399f0c51489ae8c16d6559b82a452fdc1895e91 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: 1) More iov_iter conversion work from Al Viro. [ The "crypto: switch af_alg_make_sg() to iov_iter" commit was wrong, and this pull actually adds an extra commit on top of the branch I'm pulling to fix that up, so that the pre-merge state is ok. - Linus ] 2) Various optimizations to the ipv4 forwarding information base trie lookup implementation. From Alexander Duyck. 3) Remove sock_iocb altogether, from CHristoph Hellwig. 4) Allow congestion control algorithm selection via routing metrics. From Daniel Borkmann. 5) Make ipv4 uncached route list per-cpu, from Eric Dumazet. 6) Handle rfs hash collisions more gracefully, also from Eric Dumazet. 7) Add xmit_more support to r8169, e1000, and e1000e drivers. From Florian Westphal. 8) Transparent Ethernet Bridging support for GRO, from Jesse Gross. 9) Add BPF packet actions to packet scheduler, from Jiri Pirko. 10) Add support for uniqu flow IDs to openvswitch, from Joe Stringer. 11) New NetCP ethernet driver, from Muralidharan Karicheri and Wingman Kwok. 12) More sanely handle out-of-window dupacks, which can result in serious ACK storms. From Neal Cardwell. 13) Various rhashtable bug fixes and enhancements, from Herbert Xu, Patrick McHardy, and Thomas Graf. 14) Support xmit_more in be2net, from Sathya Perla. 15) Group Policy extensions for vxlan, from Thomas Graf. 16) Remove Checksum Offload support for vxlan, from Tom Herbert. 17) Like ipv4, support lockless transmit over ipv6 UDP sockets. From Vlad Yasevich. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1494+1 commits) crypto: fix af_alg_make_sg() conversion to iov_iter ipv4: Namespecify TCP PMTU mechanism i40e: Fix for stats init function call in Rx setup tcp: don't include Fast Open option in SYN-ACK on pure SYN-data openvswitch: Only set TUNNEL_VXLAN_OPT if VXLAN-GBP metadata is set ipv6: Make __ipv6_select_ident static ipv6: Fix fragment id assignment on LE arches. bridge: Fix inability to add non-vlan fdb entry net: Mellanox: Delete unnecessary checks before the function call "vunmap" cxgb4: Add support in cxgb4 to get expansion rom version via ethtool ethtool: rename reserved1 memeber in ethtool_drvinfo for expansion ROM version net: dsa: Remove redundant phy_attach() IB/mlx4: Reset flow support for IB kernel ULPs IB/mlx4: Always use the correct port for mirrored multicast attachments net/bonding: Fix potential bad memory access during bonding events tipc: remove tipc_snprintf tipc: nl compat add noop and remove legacy nl framework tipc: convert legacy nl stats show to nl compat tipc: convert legacy nl net id get to nl compat tipc: convert legacy nl net id set to nl compat ...
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/adm8211.c1
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/Makefile6
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.c14
-rw-r--r--drivers/net/wireless/ath/ath10k/ce.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c322
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h61
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c122
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h11
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c243
-rw-r--r--drivers/net/wireless/ath/ath10k/htc.c6
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/htt.h87
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c402
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_tx.c99
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.c58
-rw-r--r--drivers/net/wireless/ath/ath10k/hw.h136
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c666
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c170
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.h7
-rw-r--r--drivers/net/wireless/ath/ath10k/rx_desc.h25
-rw-r--r--drivers/net/wireless/ath/ath10k/spectral.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/targaddrs.h5
-rw-r--r--drivers/net/wireless/ath/ath10k/testmode.c5
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.c244
-rw-r--r--drivers/net/wireless/ath/ath10k/thermal.h58
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h68
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c9
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h1064
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c2696
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.h1444
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c2238
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h449
-rw-r--r--drivers/net/wireless/ath/ath5k/ahb.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c16
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c1
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c2
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c17
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.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_calib.c61
-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/ar9003_wow.c315
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar956x_initvals.h1046
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h15
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c263
-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/gpio.c2
-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.c53
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h40
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c90
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h129
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_wow.h128
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c228
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c83
-rw-r--r--drivers/net/wireless/ath/carl9170/cmd.c12
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c6
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c2
-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/Kconfig9
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile1
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c179
-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.c205
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c15
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c65
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c277
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c151
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h158
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h183
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform_msm.c257
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c239
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h70
-rw-r--r--drivers/net/wireless/atmel.c12
-rw-r--r--drivers/net/wireless/b43/Kconfig9
-rw-r--r--drivers/net/wireless/b43/Makefile1
-rw-r--r--drivers/net/wireless/b43/b43.h3
-rw-r--r--drivers/net/wireless/b43/main.c71
-rw-r--r--drivers/net/wireless/b43/phy_ac.c92
-rw-r--r--drivers/net/wireless/b43/phy_ac.h38
-rw-r--r--drivers/net/wireless/b43/phy_common.c9
-rw-r--r--drivers/net/wireless/b43/phy_common.h2
-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.c90
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bus.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c227
-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.c34
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/common.h (renamed from drivers/net/wireless/ath/wil6210/wil_platform_msm.h)24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/commonring.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.c42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/core.h34
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/firmware.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/flowring.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h55
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c54
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c178
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.h12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/utils.c32
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h12
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_utils.h4
-rw-r--r--drivers/net/wireless/cw1200/fwio.c40
-rw-r--r--drivers/net/wireless/cw1200/main.c6
-rw-r--r--drivers/net/wireless/cw1200/pm.c5
-rw-r--r--drivers/net/wireless/cw1200/queue.c4
-rw-r--r--drivers/net/wireless/cw1200/scan.c8
-rw-r--r--drivers/net/wireless/cw1200/sta.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c2
-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.c31
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tt.c13
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c2
-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.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c88
-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.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scd.h41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h50
-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.h35
-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.h40
-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.c117
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c24
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c362
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h88
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c83
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c551
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h53
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c68
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c44
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tdls.c63
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c79
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h18
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c78
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c100
-rw-r--r--drivers/net/wireless/libertas/cfg.c12
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c33
-rw-r--r--drivers/net/wireless/mwifiex/11h.c198
-rw-r--r--drivers/net/wireless/mwifiex/11n.c6
-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.c16
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c951
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c22
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c46
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c281
-rw-r--r--drivers/net/wireless/mwifiex/decl.h55
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c16
-rw-r--r--drivers/net/wireless/mwifiex/fw.h61
-rw-r--r--drivers/net/wireless/mwifiex/ie.c89
-rw-r--r--drivers/net/wireless/mwifiex/init.c35
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h11
-rw-r--r--drivers/net/wireless/mwifiex/main.c147
-rw-r--r--drivers/net/wireless/mwifiex/main.h84
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c7
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h3
-rw-r--r--drivers/net/wireless/mwifiex/scan.c16
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c111
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h49
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c24
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c7
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c18
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c38
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c9
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c28
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c35
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c70
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c50
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c28
-rw-r--r--drivers/net/wireless/mwifiex/usb.c27
-rw-r--r--drivers/net/wireless/mwifiex/usb.h11
-rw-r--r--drivers/net/wireless/mwifiex/util.c222
-rw-r--r--drivers/net/wireless/mwifiex/util.h20
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c3
-rw-r--r--drivers/net/wireless/mwl8k.c12
-rw-r--r--drivers/net/wireless/orinoco/Kconfig3
-rw-r--r--drivers/net/wireless/orinoco/main.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c4
-rw-r--r--drivers/net/wireless/p54/eeprom.c6
-rw-r--r--drivers/net/wireless/p54/fwio.c9
-rw-r--r--drivers/net/wireless/p54/main.c10
-rw-r--r--drivers/net/wireless/p54/p54pci.c7
-rw-r--r--drivers/net/wireless/p54/txrx.c12
-rw-r--r--drivers/net/wireless/rndis_wlan.c4
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio_ops.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c12
-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/base.c156
-rw-r--r--drivers/net/wireless/rtlwifi/base.h4
-rw-r--r--drivers/net/wireless/rtlwifi/core.c72
-rw-r--r--drivers/net/wireless/rtlwifi/core.h42
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c31
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h7
-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/rtl8188ee/trx.c162
-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/rtl8192c/fw_common.h1
-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/rtl8192ce/hw.c165
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c28
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/trx.c20
-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/fw.c17
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/fw.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/trx.c27
-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/rtl8192ee/fw.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/hw.c166
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/reg.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/sw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/trx.c200
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/trx.h12
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h8
-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/rtl8192se/sw.c30
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c23
-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/rtl8723ae/trx.c162
-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/phy.c25
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/phy.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c10
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/trx.c162
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/def.h54
-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/rtl8821ae/pwrseq.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/sw.c74
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/trx.c232
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h99
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c5
-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.c405
-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
339 files changed, 20462 insertions, 6641 deletions
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/ath.h b/drivers/net/wireless/ath/ath.h
index ccba4fea7269..1eebe2ea3dfb 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -64,6 +64,7 @@ enum ath_op_flags {
64 ATH_OP_HW_RESET, 64 ATH_OP_HW_RESET,
65 ATH_OP_SCANNING, 65 ATH_OP_SCANNING,
66 ATH_OP_MULTI_CHANNEL, 66 ATH_OP_MULTI_CHANNEL,
67 ATH_OP_WOW_ENABLED,
67}; 68};
68 69
69enum ath_bus_type { 70enum ath_bus_type {
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
index 8b1b1adb477a..f4dbb3e93bf8 100644
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -8,11 +8,15 @@ 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 bmi.o 11 wmi-tlv.o \
12 bmi.o \
13 hw.o
12 14
13ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o 15ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
14ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o 16ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
15ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o 17ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
18ath10k_core-$(CONFIG_THERMAL) += thermal.o
19ath10k_core-$(CONFIG_MAC80211_DEBUGFS) += debugfs_sta.o
16 20
17obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o 21obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
18ath10k_pci-y += pci.o \ 22ath10k_pci-y += pci.o \
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index a156e6e48708..e508c65b6ba8 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -803,7 +803,7 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar)
803 int ce_id; 803 int ce_id;
804 804
805 for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { 805 for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
806 u32 ctrl_addr = ath10k_ce_base_address(ce_id); 806 u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
807 807
808 ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); 808 ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
809 ath10k_ce_error_intr_disable(ar, ctrl_addr); 809 ath10k_ce_error_intr_disable(ar, ctrl_addr);
@@ -832,7 +832,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
832 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 832 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
833 struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; 833 struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
834 struct ath10k_ce_ring *src_ring = ce_state->src_ring; 834 struct ath10k_ce_ring *src_ring = ce_state->src_ring;
835 u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); 835 u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id);
836 836
837 nentries = roundup_pow_of_two(attr->src_nentries); 837 nentries = roundup_pow_of_two(attr->src_nentries);
838 838
@@ -869,7 +869,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
869 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 869 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
870 struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; 870 struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
871 struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; 871 struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
872 u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); 872 u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id);
873 873
874 nentries = roundup_pow_of_two(attr->dest_nentries); 874 nentries = roundup_pow_of_two(attr->dest_nentries);
875 875
@@ -1051,7 +1051,7 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
1051 1051
1052static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) 1052static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
1053{ 1053{
1054 u32 ctrl_addr = ath10k_ce_base_address(ce_id); 1054 u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
1055 1055
1056 ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); 1056 ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0);
1057 ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); 1057 ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0);
@@ -1061,7 +1061,7 @@ static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
1061 1061
1062static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) 1062static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
1063{ 1063{
1064 u32 ctrl_addr = ath10k_ce_base_address(ce_id); 1064 u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id);
1065 1065
1066 ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); 1066 ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0);
1067 ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); 1067 ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0);
@@ -1093,10 +1093,12 @@ 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;
1099 ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); 1101 ce_state->ctrl_addr = ath10k_ce_base_address(ar, ce_id);
1100 ce_state->attr_flags = attr->flags; 1102 ce_state->attr_flags = attr->flags;
1101 ce_state->src_sz_max = attr->src_sz_max; 1103 ce_state->src_sz_max = attr->src_sz_max;
1102 1104
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index 617a151e8ce4..c18647b87f71 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -394,7 +394,7 @@ struct ce_attr {
394#define DST_WATERMARK_HIGH_RESET 0 394#define DST_WATERMARK_HIGH_RESET 0
395#define DST_WATERMARK_ADDRESS 0x0050 395#define DST_WATERMARK_ADDRESS 0x0050
396 396
397static inline u32 ath10k_ce_base_address(unsigned int ce_id) 397static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id)
398{ 398{
399 return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id; 399 return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
400} 400}
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 7762061a1944..310e12bc078a 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,57 @@ 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,
58 },
59 },
60 {
61 .id = QCA6174_HW_2_1_VERSION,
62 .name = "qca6174 hw2.1",
63 .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
64 .uart_pin = 6,
65 .fw = {
66 .dir = QCA6174_HW_2_1_FW_DIR,
67 .fw = QCA6174_HW_2_1_FW_FILE,
68 .otp = QCA6174_HW_2_1_OTP_FILE,
69 .board = QCA6174_HW_2_1_BOARD_DATA_FILE,
70 .board_size = QCA6174_BOARD_DATA_SZ,
71 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
72 },
73 },
74 {
75 .id = QCA6174_HW_3_0_VERSION,
76 .name = "qca6174 hw3.0",
77 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
78 .uart_pin = 6,
79 .fw = {
80 .dir = QCA6174_HW_3_0_FW_DIR,
81 .fw = QCA6174_HW_3_0_FW_FILE,
82 .otp = QCA6174_HW_3_0_OTP_FILE,
83 .board = QCA6174_HW_3_0_BOARD_DATA_FILE,
84 .board_size = QCA6174_BOARD_DATA_SZ,
85 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
86 },
87 },
88 {
89 .id = QCA6174_HW_3_2_VERSION,
90 .name = "qca6174 hw3.2",
91 .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
92 .uart_pin = 6,
93 .fw = {
94 /* uses same binaries as hw3.0 */
95 .dir = QCA6174_HW_3_0_FW_DIR,
96 .fw = QCA6174_HW_3_0_FW_FILE,
97 .otp = QCA6174_HW_3_0_OTP_FILE,
98 .board = QCA6174_HW_3_0_BOARD_DATA_FILE,
99 .board_size = QCA6174_BOARD_DATA_SZ,
100 .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
56 }, 101 },
57 }, 102 },
58}; 103};
@@ -146,8 +191,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, 191static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
147 size_t data_len) 192 size_t data_len)
148{ 193{
149 u32 board_data_size = QCA988X_BOARD_DATA_SZ; 194 u32 board_data_size = ar->hw_params.fw.board_size;
150 u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; 195 u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
151 u32 board_ext_data_addr; 196 u32 board_ext_data_addr;
152 int ret; 197 int ret;
153 198
@@ -193,7 +238,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, 238static int ath10k_download_board_data(struct ath10k *ar, const void *data,
194 size_t data_len) 239 size_t data_len)
195{ 240{
196 u32 board_data_size = QCA988X_BOARD_DATA_SZ; 241 u32 board_data_size = ar->hw_params.fw.board_size;
197 u32 address; 242 u32 address;
198 int ret; 243 int ret;
199 244
@@ -249,6 +294,63 @@ static int ath10k_download_cal_file(struct ath10k *ar)
249 return 0; 294 return 0;
250} 295}
251 296
297static int ath10k_download_cal_dt(struct ath10k *ar)
298{
299 struct device_node *node;
300 int data_len;
301 void *data;
302 int ret;
303
304 node = ar->dev->of_node;
305 if (!node)
306 /* Device Tree is optional, don't print any warnings if
307 * there's no node for ath10k.
308 */
309 return -ENOENT;
310
311 if (!of_get_property(node, "qcom,ath10k-calibration-data",
312 &data_len)) {
313 /* The calibration data node is optional */
314 return -ENOENT;
315 }
316
317 if (data_len != QCA988X_CAL_DATA_LEN) {
318 ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
319 data_len);
320 ret = -EMSGSIZE;
321 goto out;
322 }
323
324 data = kmalloc(data_len, GFP_KERNEL);
325 if (!data) {
326 ret = -ENOMEM;
327 goto out;
328 }
329
330 ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
331 data, data_len);
332 if (ret) {
333 ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
334 ret);
335 goto out_free;
336 }
337
338 ret = ath10k_download_board_data(ar, data, data_len);
339 if (ret) {
340 ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
341 ret);
342 goto out_free;
343 }
344
345 ret = 0;
346
347out_free:
348 kfree(data);
349
350out:
351 return ret;
352}
353
252static int ath10k_download_and_run_otp(struct ath10k *ar) 354static int ath10k_download_and_run_otp(struct ath10k *ar)
253{ 355{
254 u32 result, address = ar->hw_params.patch_load_addr; 356 u32 result, address = ar->hw_params.patch_load_addr;
@@ -447,7 +549,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
447 int ie_id, i, index, bit, ret; 549 int ie_id, i, index, bit, ret;
448 struct ath10k_fw_ie *hdr; 550 struct ath10k_fw_ie *hdr;
449 const u8 *data; 551 const u8 *data;
450 __le32 *timestamp; 552 __le32 *timestamp, *version;
451 553
452 /* first fetch the firmware file (firmware-*.bin) */ 554 /* first fetch the firmware file (firmware-*.bin) */
453 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); 555 ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
@@ -562,6 +664,17 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
562 ar->otp_len = ie_len; 664 ar->otp_len = ie_len;
563 665
564 break; 666 break;
667 case ATH10K_FW_IE_WMI_OP_VERSION:
668 if (ie_len != sizeof(u32))
669 break;
670
671 version = (__le32 *)data;
672
673 ar->wmi.op_version = le32_to_cpup(version);
674
675 ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
676 ar->wmi.op_version);
677 break;
565 default: 678 default:
566 ath10k_warn(ar, "Unknown FW IE: %u\n", 679 ath10k_warn(ar, "Unknown FW IE: %u\n",
567 le32_to_cpu(hdr->id)); 680 le32_to_cpu(hdr->id));
@@ -582,13 +695,6 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
582 goto err; 695 goto err;
583 } 696 }
584 697
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 */ 698 /* now fetch the board file */
593 if (ar->hw_params.fw.board == NULL) { 699 if (ar->hw_params.fw.board == NULL) {
594 ath10k_err(ar, "board data file not defined"); 700 ath10k_err(ar, "board data file not defined");
@@ -624,6 +730,13 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
624 /* calibration file is optional, don't check for any errors */ 730 /* calibration file is optional, don't check for any errors */
625 ath10k_fetch_cal_file(ar); 731 ath10k_fetch_cal_file(ar);
626 732
733 ar->fw_api = 4;
734 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
735
736 ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
737 if (ret == 0)
738 goto success;
739
627 ar->fw_api = 3; 740 ar->fw_api = 3;
628 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); 741 ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
629 742
@@ -662,7 +775,17 @@ static int ath10k_download_cal_data(struct ath10k *ar)
662 } 775 }
663 776
664 ath10k_dbg(ar, ATH10K_DBG_BOOT, 777 ath10k_dbg(ar, ATH10K_DBG_BOOT,
665 "boot did not find a calibration file, try OTP next: %d\n", 778 "boot did not find a calibration file, try DT next: %d\n",
779 ret);
780
781 ret = ath10k_download_cal_dt(ar);
782 if (ret == 0) {
783 ar->cal_mode = ATH10K_CAL_MODE_DT;
784 goto done;
785 }
786
787 ath10k_dbg(ar, ATH10K_DBG_BOOT,
788 "boot did not find DT entry, try OTP next: %d\n",
666 ret); 789 ret);
667 790
668 ret = ath10k_download_and_run_otp(ar); 791 ret = ath10k_download_and_run_otp(ar);
@@ -696,7 +819,7 @@ static int ath10k_init_uart(struct ath10k *ar)
696 if (!uart_print) 819 if (!uart_print)
697 return 0; 820 return 0;
698 821
699 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); 822 ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
700 if (ret) { 823 if (ret) {
701 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); 824 ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
702 return ret; 825 return ret;
@@ -764,6 +887,7 @@ static void ath10k_core_restart(struct work_struct *work)
764 complete_all(&ar->offchan_tx_completed); 887 complete_all(&ar->offchan_tx_completed);
765 complete_all(&ar->install_key_done); 888 complete_all(&ar->install_key_done);
766 complete_all(&ar->vdev_setup_done); 889 complete_all(&ar->vdev_setup_done);
890 complete_all(&ar->thermal.wmi_sync);
767 wake_up(&ar->htt.empty_tx_wq); 891 wake_up(&ar->htt.empty_tx_wq);
768 wake_up(&ar->wmi.tx_credits_wq); 892 wake_up(&ar->wmi.tx_credits_wq);
769 wake_up(&ar->peer_mapping_wq); 893 wake_up(&ar->peer_mapping_wq);
@@ -799,15 +923,63 @@ static void ath10k_core_restart(struct work_struct *work)
799 mutex_unlock(&ar->conf_mutex); 923 mutex_unlock(&ar->conf_mutex);
800} 924}
801 925
802static void ath10k_core_init_max_sta_count(struct ath10k *ar) 926static int ath10k_core_init_firmware_features(struct ath10k *ar)
803{ 927{
804 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 928 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
805 ar->max_num_peers = TARGET_10X_NUM_PEERS; 929 !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
806 ar->max_num_stations = TARGET_10X_NUM_STATIONS; 930 ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
807 } else { 931 return -EINVAL;
932 }
933
934 if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
935 ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
936 ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
937 return -EINVAL;
938 }
939
940 /* Backwards compatibility for firmwares without
941 * ATH10K_FW_IE_WMI_OP_VERSION.
942 */
943 if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
944 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
945 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
946 ar->fw_features))
947 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
948 else
949 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
950 } else {
951 ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
952 }
953 }
954
955 switch (ar->wmi.op_version) {
956 case ATH10K_FW_WMI_OP_VERSION_MAIN:
808 ar->max_num_peers = TARGET_NUM_PEERS; 957 ar->max_num_peers = TARGET_NUM_PEERS;
809 ar->max_num_stations = TARGET_NUM_STATIONS; 958 ar->max_num_stations = TARGET_NUM_STATIONS;
959 ar->max_num_vdevs = TARGET_NUM_VDEVS;
960 ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
961 break;
962 case ATH10K_FW_WMI_OP_VERSION_10_1:
963 case ATH10K_FW_WMI_OP_VERSION_10_2:
964 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
965 ar->max_num_peers = TARGET_10X_NUM_PEERS;
966 ar->max_num_stations = TARGET_10X_NUM_STATIONS;
967 ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
968 ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
969 break;
970 case ATH10K_FW_WMI_OP_VERSION_TLV:
971 ar->max_num_peers = TARGET_TLV_NUM_PEERS;
972 ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
973 ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
974 ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
975 break;
976 case ATH10K_FW_WMI_OP_VERSION_UNSET:
977 case ATH10K_FW_WMI_OP_VERSION_MAX:
978 WARN_ON(1);
979 return -EINVAL;
810 } 980 }
981
982 return 0;
811} 983}
812 984
813int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) 985int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
@@ -932,6 +1104,18 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
932 goto err_hif_stop; 1104 goto err_hif_stop;
933 } 1105 }
934 1106
1107 /* If firmware indicates Full Rx Reorder support it must be used in a
1108 * slightly different manner. Let HTT code know.
1109 */
1110 ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
1111 ar->wmi.svc_map));
1112
1113 status = ath10k_htt_rx_ring_refill(ar);
1114 if (status) {
1115 ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
1116 goto err_hif_stop;
1117 }
1118
935 /* we don't care about HTT in UTF mode */ 1119 /* we don't care about HTT in UTF mode */
936 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { 1120 if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
937 status = ath10k_htt_setup(&ar->htt); 1121 status = ath10k_htt_setup(&ar->htt);
@@ -945,10 +1129,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
945 if (status) 1129 if (status)
946 goto err_hif_stop; 1130 goto err_hif_stop;
947 1131
948 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) 1132 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 1133
953 INIT_LIST_HEAD(&ar->arvifs); 1134 INIT_LIST_HEAD(&ar->arvifs);
954 1135
@@ -1025,8 +1206,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1025 ret = ath10k_bmi_get_target_info(ar, &target_info); 1206 ret = ath10k_bmi_get_target_info(ar, &target_info);
1026 if (ret) { 1207 if (ret) {
1027 ath10k_err(ar, "could not get target info (%d)\n", ret); 1208 ath10k_err(ar, "could not get target info (%d)\n", ret);
1028 ath10k_hif_power_down(ar); 1209 goto err_power_down;
1029 return ret;
1030 } 1210 }
1031 1211
1032 ar->target_version = target_info.version; 1212 ar->target_version = target_info.version;
@@ -1035,28 +1215,28 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1035 ret = ath10k_init_hw_params(ar); 1215 ret = ath10k_init_hw_params(ar);
1036 if (ret) { 1216 if (ret) {
1037 ath10k_err(ar, "could not get hw params (%d)\n", ret); 1217 ath10k_err(ar, "could not get hw params (%d)\n", ret);
1038 ath10k_hif_power_down(ar); 1218 goto err_power_down;
1039 return ret;
1040 } 1219 }
1041 1220
1042 ret = ath10k_core_fetch_firmware_files(ar); 1221 ret = ath10k_core_fetch_firmware_files(ar);
1043 if (ret) { 1222 if (ret) {
1044 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); 1223 ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
1045 ath10k_hif_power_down(ar); 1224 goto err_power_down;
1046 return ret;
1047 } 1225 }
1048 1226
1049 ath10k_core_init_max_sta_count(ar); 1227 ret = ath10k_core_init_firmware_features(ar);
1228 if (ret) {
1229 ath10k_err(ar, "fatal problem with firmware features: %d\n",
1230 ret);
1231 goto err_free_firmware_files;
1232 }
1050 1233
1051 mutex_lock(&ar->conf_mutex); 1234 mutex_lock(&ar->conf_mutex);
1052 1235
1053 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); 1236 ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
1054 if (ret) { 1237 if (ret) {
1055 ath10k_err(ar, "could not init core (%d)\n", ret); 1238 ath10k_err(ar, "could not init core (%d)\n", ret);
1056 ath10k_core_free_firmware_files(ar); 1239 goto err_unlock;
1057 ath10k_hif_power_down(ar);
1058 mutex_unlock(&ar->conf_mutex);
1059 return ret;
1060 } 1240 }
1061 1241
1062 ath10k_print_driver_info(ar); 1242 ath10k_print_driver_info(ar);
@@ -1066,34 +1246,17 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
1066 1246
1067 ath10k_hif_power_down(ar); 1247 ath10k_hif_power_down(ar);
1068 return 0; 1248 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 1249
1078 /* Check that we are not using hw1.0 (some of them have same pci id 1250err_unlock:
1079 * as hw2.0) before doing anything else as ath10k crashes horribly 1251 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 1252
1086 case QCA988X_HW_2_0_CHIP_ID_REV: 1253err_free_firmware_files:
1087 /* known hardware revision, continue normally */ 1254 ath10k_core_free_firmware_files(ar);
1088 return 0;
1089 1255
1090 default: 1256err_power_down:
1091 ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n", 1257 ath10k_hif_power_down(ar);
1092 ar->chip_id);
1093 return 0;
1094 }
1095 1258
1096 return 0; 1259 return ret;
1097} 1260}
1098 1261
1099static void ath10k_core_register_work(struct work_struct *work) 1262static void ath10k_core_register_work(struct work_struct *work)
@@ -1125,9 +1288,18 @@ static void ath10k_core_register_work(struct work_struct *work)
1125 goto err_debug_destroy; 1288 goto err_debug_destroy;
1126 } 1289 }
1127 1290
1291 status = ath10k_thermal_register(ar);
1292 if (status) {
1293 ath10k_err(ar, "could not register thermal device: %d\n",
1294 status);
1295 goto err_spectral_destroy;
1296 }
1297
1128 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); 1298 set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
1129 return; 1299 return;
1130 1300
1301err_spectral_destroy:
1302 ath10k_spectral_destroy(ar);
1131err_debug_destroy: 1303err_debug_destroy:
1132 ath10k_debug_destroy(ar); 1304 ath10k_debug_destroy(ar);
1133err_unregister_mac: 1305err_unregister_mac:
@@ -1143,16 +1315,7 @@ err:
1143 1315
1144int ath10k_core_register(struct ath10k *ar, u32 chip_id) 1316int ath10k_core_register(struct ath10k *ar, u32 chip_id)
1145{ 1317{
1146 int status;
1147
1148 ar->chip_id = chip_id; 1318 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); 1319 queue_work(ar->workqueue, &ar->register_work);
1157 1320
1158 return 0; 1321 return 0;
@@ -1166,6 +1329,7 @@ void ath10k_core_unregister(struct ath10k *ar)
1166 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) 1329 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
1167 return; 1330 return;
1168 1331
1332 ath10k_thermal_unregister(ar);
1169 /* Stop spectral before unregistering from mac80211 to remove the 1333 /* Stop spectral before unregistering from mac80211 to remove the
1170 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree 1334 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
1171 * would be already be free'd recursively, leading to a double free. 1335 * would be already be free'd recursively, leading to a double free.
@@ -1187,6 +1351,7 @@ EXPORT_SYMBOL(ath10k_core_unregister);
1187 1351
1188struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, 1352struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1189 enum ath10k_bus bus, 1353 enum ath10k_bus bus,
1354 enum ath10k_hw_rev hw_rev,
1190 const struct ath10k_hif_ops *hif_ops) 1355 const struct ath10k_hif_ops *hif_ops)
1191{ 1356{
1192 struct ath10k *ar; 1357 struct ath10k *ar;
@@ -1198,13 +1363,25 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1198 1363
1199 ar->ath_common.priv = ar; 1364 ar->ath_common.priv = ar;
1200 ar->ath_common.hw = ar->hw; 1365 ar->ath_common.hw = ar->hw;
1201
1202 ar->p2p = !!ath10k_p2p;
1203 ar->dev = dev; 1366 ar->dev = dev;
1204 1367 ar->hw_rev = hw_rev;
1205 ar->hif.ops = hif_ops; 1368 ar->hif.ops = hif_ops;
1206 ar->hif.bus = bus; 1369 ar->hif.bus = bus;
1207 1370
1371 switch (hw_rev) {
1372 case ATH10K_HW_QCA988X:
1373 ar->regs = &qca988x_regs;
1374 break;
1375 case ATH10K_HW_QCA6174:
1376 ar->regs = &qca6174_regs;
1377 break;
1378 default:
1379 ath10k_err(ar, "unsupported core hardware revision %d\n",
1380 hw_rev);
1381 ret = -ENOTSUPP;
1382 goto err_free_mac;
1383 }
1384
1208 init_completion(&ar->scan.started); 1385 init_completion(&ar->scan.started);
1209 init_completion(&ar->scan.completed); 1386 init_completion(&ar->scan.completed);
1210 init_completion(&ar->scan.on_channel); 1387 init_completion(&ar->scan.on_channel);
@@ -1212,6 +1389,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
1212 1389
1213 init_completion(&ar->install_key_done); 1390 init_completion(&ar->install_key_done);
1214 init_completion(&ar->vdev_setup_done); 1391 init_completion(&ar->vdev_setup_done);
1392 init_completion(&ar->thermal.wmi_sync);
1215 1393
1216 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); 1394 INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
1217 1395
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 514c219263a5..d60e46fe6d19 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)
@@ -96,6 +97,11 @@ struct ath10k_skb_cb {
96 } bcn; 97 } bcn;
97} __packed; 98} __packed;
98 99
100struct ath10k_skb_rxcb {
101 dma_addr_t paddr;
102 struct hlist_node hlist;
103};
104
99static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) 105static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
100{ 106{
101 BUILD_BUG_ON(sizeof(struct ath10k_skb_cb) > 107 BUILD_BUG_ON(sizeof(struct ath10k_skb_cb) >
@@ -103,6 +109,15 @@ static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb)
103 return (struct ath10k_skb_cb *)&IEEE80211_SKB_CB(skb)->driver_data; 109 return (struct ath10k_skb_cb *)&IEEE80211_SKB_CB(skb)->driver_data;
104} 110}
105 111
112static inline struct ath10k_skb_rxcb *ATH10K_SKB_RXCB(struct sk_buff *skb)
113{
114 BUILD_BUG_ON(sizeof(struct ath10k_skb_rxcb) > sizeof(skb->cb));
115 return (struct ath10k_skb_rxcb *)skb->cb;
116}
117
118#define ATH10K_RXCB_SKB(rxcb) \
119 container_of((void *)rxcb, struct sk_buff, cb)
120
106static inline u32 host_interest_item_address(u32 item_offset) 121static inline u32 host_interest_item_address(u32 item_offset)
107{ 122{
108 return QCA988X_HOST_INTEREST_ADDRESS + item_offset; 123 return QCA988X_HOST_INTEREST_ADDRESS + item_offset;
@@ -120,6 +135,7 @@ struct ath10k_mem_chunk {
120}; 135};
121 136
122struct ath10k_wmi { 137struct ath10k_wmi {
138 enum ath10k_fw_wmi_op_version op_version;
123 enum ath10k_htc_ep_id eid; 139 enum ath10k_htc_ep_id eid;
124 struct completion service_ready; 140 struct completion service_ready;
125 struct completion unified_ready; 141 struct completion unified_ready;
@@ -128,6 +144,7 @@ struct ath10k_wmi {
128 struct wmi_cmd_map *cmd; 144 struct wmi_cmd_map *cmd;
129 struct wmi_vdev_param_map *vdev_param; 145 struct wmi_vdev_param_map *vdev_param;
130 struct wmi_pdev_param_map *pdev_param; 146 struct wmi_pdev_param_map *pdev_param;
147 const struct wmi_ops *ops;
131 148
132 u32 num_mem_chunks; 149 u32 num_mem_chunks;
133 struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS]; 150 struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
@@ -236,10 +253,21 @@ struct ath10k_sta {
236 u32 smps; 253 u32 smps;
237 254
238 struct work_struct update_wk; 255 struct work_struct update_wk;
256
257#ifdef CONFIG_MAC80211_DEBUGFS
258 /* protected by conf_mutex */
259 bool aggr_mode;
260#endif
239}; 261};
240 262
241#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) 263#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
242 264
265enum ath10k_beacon_state {
266 ATH10K_BEACON_SCHEDULED = 0,
267 ATH10K_BEACON_SENDING,
268 ATH10K_BEACON_SENT,
269};
270
243struct ath10k_vif { 271struct ath10k_vif {
244 struct list_head list; 272 struct list_head list;
245 273
@@ -250,7 +278,7 @@ struct ath10k_vif {
250 u32 dtim_period; 278 u32 dtim_period;
251 struct sk_buff *beacon; 279 struct sk_buff *beacon;
252 /* protected by data_lock */ 280 /* protected by data_lock */
253 bool beacon_sent; 281 enum ath10k_beacon_state beacon_state;
254 void *beacon_buf; 282 void *beacon_buf;
255 dma_addr_t beacon_paddr; 283 dma_addr_t beacon_paddr;
256 284
@@ -263,10 +291,8 @@ struct ath10k_vif {
263 u32 aid; 291 u32 aid;
264 u8 bssid[ETH_ALEN]; 292 u8 bssid[ETH_ALEN];
265 293
266 struct work_struct wep_key_work;
267 struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; 294 struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1];
268 u8 def_wep_key_idx; 295 s8 def_wep_key_idx;
269 u8 def_wep_key_newidx;
270 296
271 u16 tx_seq_no; 297 u16 tx_seq_no;
272 298
@@ -293,6 +319,7 @@ struct ath10k_vif {
293 bool use_cts_prot; 319 bool use_cts_prot;
294 int num_legacy_stations; 320 int num_legacy_stations;
295 int txpower; 321 int txpower;
322 struct wmi_wmm_params_all_arg wmm_params;
296}; 323};
297 324
298struct ath10k_vif_iter { 325struct ath10k_vif_iter {
@@ -323,8 +350,10 @@ struct ath10k_debug {
323 350
324 /* protected by conf_mutex */ 351 /* protected by conf_mutex */
325 u32 fw_dbglog_mask; 352 u32 fw_dbglog_mask;
353 u32 fw_dbglog_level;
326 u32 pktlog_filter; 354 u32 pktlog_filter;
327 u32 reg_addr; 355 u32 reg_addr;
356 u32 nf_cal_period;
328 357
329 u8 htt_max_amsdu; 358 u8 htt_max_amsdu;
330 u8 htt_max_ampdu; 359 u8 htt_max_ampdu;
@@ -369,7 +398,7 @@ enum ath10k_fw_features {
369 /* wmi_mgmt_rx_hdr contains extra RSSI information */ 398 /* wmi_mgmt_rx_hdr contains extra RSSI information */
370 ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0, 399 ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0,
371 400
372 /* firmware from 10X branch */ 401 /* Firmware from 10X branch. Deprecated, don't use in new code. */
373 ATH10K_FW_FEATURE_WMI_10X = 1, 402 ATH10K_FW_FEATURE_WMI_10X = 1,
374 403
375 /* firmware support tx frame management over WMI, otherwise it's HTT */ 404 /* firmware support tx frame management over WMI, otherwise it's HTT */
@@ -378,8 +407,9 @@ enum ath10k_fw_features {
378 /* Firmware does not support P2P */ 407 /* Firmware does not support P2P */
379 ATH10K_FW_FEATURE_NO_P2P = 3, 408 ATH10K_FW_FEATURE_NO_P2P = 3,
380 409
381 /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit 410 /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature
382 * is required to be set as well. 411 * bit is required to be set as well. Deprecated, don't use in new
412 * code.
383 */ 413 */
384 ATH10K_FW_FEATURE_WMI_10_2 = 4, 414 ATH10K_FW_FEATURE_WMI_10_2 = 4,
385 415
@@ -401,6 +431,7 @@ enum ath10k_dev_flags {
401enum ath10k_cal_mode { 431enum ath10k_cal_mode {
402 ATH10K_CAL_MODE_FILE, 432 ATH10K_CAL_MODE_FILE,
403 ATH10K_CAL_MODE_OTP, 433 ATH10K_CAL_MODE_OTP,
434 ATH10K_CAL_MODE_DT,
404}; 435};
405 436
406static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) 437static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
@@ -410,6 +441,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
410 return "file"; 441 return "file";
411 case ATH10K_CAL_MODE_OTP: 442 case ATH10K_CAL_MODE_OTP:
412 return "otp"; 443 return "otp";
444 case ATH10K_CAL_MODE_DT:
445 return "dt";
413 } 446 }
414 447
415 return "unknown"; 448 return "unknown";
@@ -444,6 +477,7 @@ struct ath10k {
444 struct device *dev; 477 struct device *dev;
445 u8 mac_addr[ETH_ALEN]; 478 u8 mac_addr[ETH_ALEN];
446 479
480 enum ath10k_hw_rev hw_rev;
447 u32 chip_id; 481 u32 chip_id;
448 u32 target_version; 482 u32 target_version;
449 u8 fw_version_major; 483 u8 fw_version_major;
@@ -459,9 +493,6 @@ struct ath10k {
459 493
460 DECLARE_BITMAP(fw_features, ATH10K_FW_FEATURE_COUNT); 494 DECLARE_BITMAP(fw_features, ATH10K_FW_FEATURE_COUNT);
461 495
462 struct targetdef *targetdef;
463 struct hostdef *hostdef;
464
465 bool p2p; 496 bool p2p;
466 497
467 struct { 498 struct {
@@ -471,6 +502,7 @@ struct ath10k {
471 502
472 struct completion target_suspend; 503 struct completion target_suspend;
473 504
505 const struct ath10k_hw_regs *regs;
474 struct ath10k_bmi bmi; 506 struct ath10k_bmi bmi;
475 struct ath10k_wmi wmi; 507 struct ath10k_wmi wmi;
476 struct ath10k_htc htc; 508 struct ath10k_htc htc;
@@ -480,12 +512,15 @@ struct ath10k {
480 u32 id; 512 u32 id;
481 const char *name; 513 const char *name;
482 u32 patch_load_addr; 514 u32 patch_load_addr;
515 int uart_pin;
483 516
484 struct ath10k_hw_params_fw { 517 struct ath10k_hw_params_fw {
485 const char *dir; 518 const char *dir;
486 const char *fw; 519 const char *fw;
487 const char *otp; 520 const char *otp;
488 const char *board; 521 const char *board;
522 size_t board_size;
523 size_t board_ext_size;
489 } fw; 524 } fw;
490 } hw_params; 525 } hw_params;
491 526
@@ -548,7 +583,6 @@ struct ath10k {
548 u8 cfg_tx_chainmask; 583 u8 cfg_tx_chainmask;
549 u8 cfg_rx_chainmask; 584 u8 cfg_rx_chainmask;
550 585
551 struct wmi_pdev_set_wmm_params_arg wmm_params;
552 struct completion install_key_done; 586 struct completion install_key_done;
553 587
554 struct completion vdev_setup_done; 588 struct completion vdev_setup_done;
@@ -571,6 +605,7 @@ struct ath10k {
571 605
572 int max_num_peers; 606 int max_num_peers;
573 int max_num_stations; 607 int max_num_stations;
608 int max_num_vdevs;
574 609
575 struct work_struct offchan_tx_work; 610 struct work_struct offchan_tx_work;
576 struct sk_buff_head offchan_tx_queue; 611 struct sk_buff_head offchan_tx_queue;
@@ -610,6 +645,7 @@ struct ath10k {
610 /* protected by conf_mutex */ 645 /* protected by conf_mutex */
611 const struct firmware *utf; 646 const struct firmware *utf;
612 DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT); 647 DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT);
648 enum ath10k_fw_wmi_op_version orig_wmi_op_version;
613 649
614 /* protected by data_lock */ 650 /* protected by data_lock */
615 bool utf_monitor; 651 bool utf_monitor;
@@ -622,12 +658,15 @@ struct ath10k {
622 u32 fw_cold_reset_counter; 658 u32 fw_cold_reset_counter;
623 } stats; 659 } stats;
624 660
661 struct ath10k_thermal thermal;
662
625 /* must be last */ 663 /* must be last */
626 u8 drv_priv[0] __aligned(sizeof(void *)); 664 u8 drv_priv[0] __aligned(sizeof(void *));
627}; 665};
628 666
629struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, 667struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
630 enum ath10k_bus bus, 668 enum ath10k_bus bus,
669 enum ath10k_hw_rev hw_rev,
631 const struct ath10k_hif_ops *hif_ops); 670 const struct ath10k_hif_ops *hif_ops);
632void ath10k_core_destroy(struct ath10k *ar); 671void ath10k_core_destroy(struct ath10k *ar);
633 672
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index a716758f14b0..d2281e5c2ffe 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",
@@ -373,7 +371,7 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
373 371
374 ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, 372 ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete,
375 1*HZ); 373 1*HZ);
376 if (ret <= 0) 374 if (ret == 0)
377 return -ETIMEDOUT; 375 return -ETIMEDOUT;
378 376
379 spin_lock_bh(&ar->data_lock); 377 spin_lock_bh(&ar->data_lock);
@@ -1320,10 +1318,10 @@ static ssize_t ath10k_read_fw_dbglog(struct file *file,
1320{ 1318{
1321 struct ath10k *ar = file->private_data; 1319 struct ath10k *ar = file->private_data;
1322 unsigned int len; 1320 unsigned int len;
1323 char buf[32]; 1321 char buf[64];
1324 1322
1325 len = scnprintf(buf, sizeof(buf), "0x%08x\n", 1323 len = scnprintf(buf, sizeof(buf), "0x%08x %u\n",
1326 ar->debug.fw_dbglog_mask); 1324 ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level);
1327 1325
1328 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1326 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1329} 1327}
@@ -1333,19 +1331,32 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file,
1333 size_t count, loff_t *ppos) 1331 size_t count, loff_t *ppos)
1334{ 1332{
1335 struct ath10k *ar = file->private_data; 1333 struct ath10k *ar = file->private_data;
1336 unsigned long mask;
1337 int ret; 1334 int ret;
1335 char buf[64];
1336 unsigned int log_level, mask;
1338 1337
1339 ret = kstrtoul_from_user(user_buf, count, 0, &mask); 1338 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
1340 if (ret) 1339
1341 return ret; 1340 /* make sure that buf is null terminated */
1341 buf[sizeof(buf) - 1] = 0;
1342
1343 ret = sscanf(buf, "%x %u", &mask, &log_level);
1344
1345 if (!ret)
1346 return -EINVAL;
1347
1348 if (ret == 1)
1349 /* default if user did not specify */
1350 log_level = ATH10K_DBGLOG_LEVEL_WARN;
1342 1351
1343 mutex_lock(&ar->conf_mutex); 1352 mutex_lock(&ar->conf_mutex);
1344 1353
1345 ar->debug.fw_dbglog_mask = mask; 1354 ar->debug.fw_dbglog_mask = mask;
1355 ar->debug.fw_dbglog_level = log_level;
1346 1356
1347 if (ar->state == ATH10K_STATE_ON) { 1357 if (ar->state == ATH10K_STATE_ON) {
1348 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 1358 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1359 ar->debug.fw_dbglog_level);
1349 if (ret) { 1360 if (ret) {
1350 ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n", 1361 ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n",
1351 ret); 1362 ret);
@@ -1607,6 +1618,73 @@ static const struct file_operations fops_cal_data = {
1607 .llseek = default_llseek, 1618 .llseek = default_llseek,
1608}; 1619};
1609 1620
1621static ssize_t ath10k_read_nf_cal_period(struct file *file,
1622 char __user *user_buf,
1623 size_t count, loff_t *ppos)
1624{
1625 struct ath10k *ar = file->private_data;
1626 unsigned int len;
1627 char buf[32];
1628
1629 len = scnprintf(buf, sizeof(buf), "%d\n",
1630 ar->debug.nf_cal_period);
1631
1632 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1633}
1634
1635static ssize_t ath10k_write_nf_cal_period(struct file *file,
1636 const char __user *user_buf,
1637 size_t count, loff_t *ppos)
1638{
1639 struct ath10k *ar = file->private_data;
1640 unsigned long period;
1641 int ret;
1642
1643 ret = kstrtoul_from_user(user_buf, count, 0, &period);
1644 if (ret)
1645 return ret;
1646
1647 if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
1648 return -EINVAL;
1649
1650 /* there's no way to switch back to the firmware default */
1651 if (period == 0)
1652 return -EINVAL;
1653
1654 mutex_lock(&ar->conf_mutex);
1655
1656 ar->debug.nf_cal_period = period;
1657
1658 if (ar->state != ATH10K_STATE_ON) {
1659 /* firmware is not running, nothing else to do */
1660 ret = count;
1661 goto exit;
1662 }
1663
1664 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
1665 ar->debug.nf_cal_period);
1666 if (ret) {
1667 ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
1668 ret);
1669 goto exit;
1670 }
1671
1672 ret = count;
1673
1674exit:
1675 mutex_unlock(&ar->conf_mutex);
1676
1677 return ret;
1678}
1679
1680static const struct file_operations fops_nf_cal_period = {
1681 .read = ath10k_read_nf_cal_period,
1682 .write = ath10k_write_nf_cal_period,
1683 .open = simple_open,
1684 .owner = THIS_MODULE,
1685 .llseek = default_llseek,
1686};
1687
1610int ath10k_debug_start(struct ath10k *ar) 1688int ath10k_debug_start(struct ath10k *ar)
1611{ 1689{
1612 int ret; 1690 int ret;
@@ -1620,7 +1698,8 @@ int ath10k_debug_start(struct ath10k *ar)
1620 ret); 1698 ret);
1621 1699
1622 if (ar->debug.fw_dbglog_mask) { 1700 if (ar->debug.fw_dbglog_mask) {
1623 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); 1701 ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask,
1702 ATH10K_DBGLOG_LEVEL_WARN);
1624 if (ret) 1703 if (ret)
1625 /* not serious */ 1704 /* not serious */
1626 ath10k_warn(ar, "failed to enable dbglog during start: %d", 1705 ath10k_warn(ar, "failed to enable dbglog during start: %d",
@@ -1642,6 +1721,16 @@ int ath10k_debug_start(struct ath10k *ar)
1642 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); 1721 ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
1643 } 1722 }
1644 1723
1724 if (ar->debug.nf_cal_period) {
1725 ret = ath10k_wmi_pdev_set_param(ar,
1726 ar->wmi.pdev_param->cal_period,
1727 ar->debug.nf_cal_period);
1728 if (ret)
1729 /* not serious */
1730 ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
1731 ret);
1732 }
1733
1645 return ret; 1734 return ret;
1646} 1735}
1647 1736
@@ -1880,6 +1969,9 @@ int ath10k_debug_register(struct ath10k *ar)
1880 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy, 1969 debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
1881 ar, &fops_cal_data); 1970 ar, &fops_cal_data);
1882 1971
1972 debugfs_create_file("nf_cal_period", S_IRUSR | S_IWUSR,
1973 ar->debug.debugfs_phy, ar, &fops_nf_cal_period);
1974
1883 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) { 1975 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
1884 debugfs_create_file("dfs_simulate_radar", S_IWUSR, 1976 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
1885 ar->debug.debugfs_phy, ar, 1977 ar->debug.debugfs_phy, ar,
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 1b87a5dbec53..a12b8323f9f1 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -48,6 +48,12 @@ enum ath10k_pktlog_filter {
48 ATH10K_PKTLOG_ANY = 0x00000001f, 48 ATH10K_PKTLOG_ANY = 0x00000001f,
49}; 49};
50 50
51enum ath10k_dbg_aggr_mode {
52 ATH10K_DBG_AGGR_MODE_AUTO,
53 ATH10K_DBG_AGGR_MODE_MANUAL,
54 ATH10K_DBG_AGGR_MODE_MAX,
55};
56
51extern unsigned int ath10k_debug_mask; 57extern unsigned int ath10k_debug_mask;
52 58
53__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...); 59__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
@@ -77,7 +83,6 @@ int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
77void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, 83void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
78 struct ieee80211_vif *vif, 84 struct ieee80211_vif *vif,
79 struct ethtool_stats *stats, u64 *data); 85 struct ethtool_stats *stats, u64 *data);
80
81#else 86#else
82static inline int ath10k_debug_start(struct ath10k *ar) 87static inline int ath10k_debug_start(struct ath10k *ar)
83{ 88{
@@ -129,6 +134,10 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
129#define ath10k_debug_get_et_stats NULL 134#define ath10k_debug_get_et_stats NULL
130 135
131#endif /* CONFIG_ATH10K_DEBUGFS */ 136#endif /* CONFIG_ATH10K_DEBUGFS */
137#ifdef CONFIG_MAC80211_DEBUGFS
138void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
139 struct ieee80211_sta *sta, struct dentry *dir);
140#endif /* CONFIG_MAC80211_DEBUGFS */
132 141
133#ifdef CONFIG_ATH10K_DEBUG 142#ifdef CONFIG_ATH10K_DEBUG
134__printf(3, 4) void ath10k_dbg(struct ath10k *ar, 143__printf(3, 4) void ath10k_dbg(struct ath10k *ar,
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
new file mode 100644
index 000000000000..95b5c49374e0
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.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 "core.h"
18#include "wmi-ops.h"
19#include "debug.h"
20
21static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file,
22 char __user *user_buf,
23 size_t count, loff_t *ppos)
24{
25 struct ieee80211_sta *sta = file->private_data;
26 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
27 struct ath10k *ar = arsta->arvif->ar;
28 char buf[32];
29 int len = 0;
30
31 mutex_lock(&ar->conf_mutex);
32 len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n",
33 (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ?
34 "auto" : "manual");
35 mutex_unlock(&ar->conf_mutex);
36
37 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
38}
39
40static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file,
41 const char __user *user_buf,
42 size_t count, loff_t *ppos)
43{
44 struct ieee80211_sta *sta = file->private_data;
45 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
46 struct ath10k *ar = arsta->arvif->ar;
47 u32 aggr_mode;
48 int ret;
49
50 if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode))
51 return -EINVAL;
52
53 if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX)
54 return -EINVAL;
55
56 mutex_lock(&ar->conf_mutex);
57 if ((ar->state != ATH10K_STATE_ON) ||
58 (aggr_mode == arsta->aggr_mode)) {
59 ret = count;
60 goto out;
61 }
62
63 ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr);
64 if (ret) {
65 ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret);
66 goto out;
67 }
68
69 arsta->aggr_mode = aggr_mode;
70out:
71 mutex_unlock(&ar->conf_mutex);
72 return ret;
73}
74
75static const struct file_operations fops_aggr_mode = {
76 .read = ath10k_dbg_sta_read_aggr_mode,
77 .write = ath10k_dbg_sta_write_aggr_mode,
78 .open = simple_open,
79 .owner = THIS_MODULE,
80 .llseek = default_llseek,
81};
82
83static ssize_t ath10k_dbg_sta_write_addba(struct file *file,
84 const char __user *user_buf,
85 size_t count, loff_t *ppos)
86{
87 struct ieee80211_sta *sta = file->private_data;
88 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
89 struct ath10k *ar = arsta->arvif->ar;
90 u32 tid, buf_size;
91 int ret;
92 char buf[64];
93
94 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
95
96 /* make sure that buf is null terminated */
97 buf[sizeof(buf) - 1] = '\0';
98
99 ret = sscanf(buf, "%u %u", &tid, &buf_size);
100 if (ret != 2)
101 return -EINVAL;
102
103 /* Valid TID values are 0 through 15 */
104 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
105 return -EINVAL;
106
107 mutex_lock(&ar->conf_mutex);
108 if ((ar->state != ATH10K_STATE_ON) ||
109 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
110 ret = count;
111 goto out;
112 }
113
114 ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr,
115 tid, buf_size);
116 if (ret) {
117 ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n",
118 arsta->arvif->vdev_id, sta->addr, tid, buf_size);
119 }
120
121 ret = count;
122out:
123 mutex_unlock(&ar->conf_mutex);
124 return ret;
125}
126
127static const struct file_operations fops_addba = {
128 .write = ath10k_dbg_sta_write_addba,
129 .open = simple_open,
130 .owner = THIS_MODULE,
131 .llseek = default_llseek,
132};
133
134static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file,
135 const char __user *user_buf,
136 size_t count, loff_t *ppos)
137{
138 struct ieee80211_sta *sta = file->private_data;
139 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
140 struct ath10k *ar = arsta->arvif->ar;
141 u32 tid, status;
142 int ret;
143 char buf[64];
144
145 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
146
147 /* make sure that buf is null terminated */
148 buf[sizeof(buf) - 1] = '\0';
149
150 ret = sscanf(buf, "%u %u", &tid, &status);
151 if (ret != 2)
152 return -EINVAL;
153
154 /* Valid TID values are 0 through 15 */
155 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
156 return -EINVAL;
157
158 mutex_lock(&ar->conf_mutex);
159 if ((ar->state != ATH10K_STATE_ON) ||
160 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
161 ret = count;
162 goto out;
163 }
164
165 ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr,
166 tid, status);
167 if (ret) {
168 ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n",
169 arsta->arvif->vdev_id, sta->addr, tid, status);
170 }
171 ret = count;
172out:
173 mutex_unlock(&ar->conf_mutex);
174 return ret;
175}
176
177static const struct file_operations fops_addba_resp = {
178 .write = ath10k_dbg_sta_write_addba_resp,
179 .open = simple_open,
180 .owner = THIS_MODULE,
181 .llseek = default_llseek,
182};
183
184static ssize_t ath10k_dbg_sta_write_delba(struct file *file,
185 const char __user *user_buf,
186 size_t count, loff_t *ppos)
187{
188 struct ieee80211_sta *sta = file->private_data;
189 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
190 struct ath10k *ar = arsta->arvif->ar;
191 u32 tid, initiator, reason;
192 int ret;
193 char buf[64];
194
195 simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
196
197 /* make sure that buf is null terminated */
198 buf[sizeof(buf) - 1] = '\0';
199
200 ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason);
201 if (ret != 3)
202 return -EINVAL;
203
204 /* Valid TID values are 0 through 15 */
205 if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2)
206 return -EINVAL;
207
208 mutex_lock(&ar->conf_mutex);
209 if ((ar->state != ATH10K_STATE_ON) ||
210 (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) {
211 ret = count;
212 goto out;
213 }
214
215 ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr,
216 tid, initiator, reason);
217 if (ret) {
218 ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n",
219 arsta->arvif->vdev_id, sta->addr, tid, initiator,
220 reason);
221 }
222 ret = count;
223out:
224 mutex_unlock(&ar->conf_mutex);
225 return ret;
226}
227
228static const struct file_operations fops_delba = {
229 .write = ath10k_dbg_sta_write_delba,
230 .open = simple_open,
231 .owner = THIS_MODULE,
232 .llseek = default_llseek,
233};
234
235void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
236 struct ieee80211_sta *sta, struct dentry *dir)
237{
238 debugfs_create_file("aggr_mode", S_IRUGO | S_IWUSR, dir, sta,
239 &fops_aggr_mode);
240 debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba);
241 debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp);
242 debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba);
243}
diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
index f1946a6be442..2fd9e180272b 100644
--- a/drivers/net/wireless/ath/ath10k/htc.c
+++ b/drivers/net/wireless/ath/ath10k/htc.c
@@ -703,11 +703,9 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
703 /* wait for response */ 703 /* wait for response */
704 status = wait_for_completion_timeout(&htc->ctl_resp, 704 status = wait_for_completion_timeout(&htc->ctl_resp,
705 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ); 705 ATH10K_HTC_CONN_SVC_TIMEOUT_HZ);
706 if (status <= 0) { 706 if (status == 0) {
707 if (status == 0)
708 status = -ETIMEDOUT;
709 ath10k_err(ar, "Service connect timeout: %d\n", status); 707 ath10k_err(ar, "Service connect timeout: %d\n", status);
710 return status; 708 return -ETIMEDOUT;
711 } 709 }
712 710
713 /* we controlled the buffer creation, it's aligned */ 711 /* we controlled the buffer creation, it's aligned */
diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
index 56cb4aceb383..4f59ab923e48 100644
--- a/drivers/net/wireless/ath/ath10k/htt.c
+++ b/drivers/net/wireless/ath/ath10k/htt.c
@@ -53,7 +53,6 @@ int ath10k_htt_init(struct ath10k *ar)
53 struct ath10k_htt *htt = &ar->htt; 53 struct ath10k_htt *htt = &ar->htt;
54 54
55 htt->ar = ar; 55 htt->ar = ar;
56 htt->max_throughput_mbps = 800;
57 56
58 /* 57 /*
59 * Prefetch enough data to satisfy target 58 * Prefetch enough data to satisfy target
@@ -102,7 +101,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
102 101
103 status = wait_for_completion_timeout(&htt->target_version_received, 102 status = wait_for_completion_timeout(&htt->target_version_received,
104 HTT_TARGET_VERSION_TIMEOUT_HZ); 103 HTT_TARGET_VERSION_TIMEOUT_HZ);
105 if (status <= 0) { 104 if (status == 0) {
106 ath10k_warn(ar, "htt version request timed out\n"); 105 ath10k_warn(ar, "htt version request timed out\n");
107 return -ETIMEDOUT; 106 return -ETIMEDOUT;
108 } 107 }
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 1bd5545af903..874bf44ff7a2 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -21,6 +21,7 @@
21#include <linux/bug.h> 21#include <linux/bug.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/dmapool.h> 23#include <linux/dmapool.h>
24#include <linux/hashtable.h>
24#include <net/mac80211.h> 25#include <net/mac80211.h>
25 26
26#include "htc.h" 27#include "htc.h"
@@ -286,7 +287,19 @@ enum htt_t2h_msg_type {
286 HTT_T2H_MSG_TYPE_RC_UPDATE_IND = 0xc, 287 HTT_T2H_MSG_TYPE_RC_UPDATE_IND = 0xc,
287 HTT_T2H_MSG_TYPE_TX_INSPECT_IND = 0xd, 288 HTT_T2H_MSG_TYPE_TX_INSPECT_IND = 0xd,
288 HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION = 0xe, 289 HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION = 0xe,
290 HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND = 0xf,
291 HTT_T2H_MSG_TYPE_RX_PN_IND = 0x10,
292 HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND = 0x11,
293 HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND = 0x12,
294 /* 0x13 reservd */
295 HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE = 0x14,
296
297 /* FIXME: Do not depend on this event id. Numbering of this event id is
298 * broken across different firmware revisions and HTT version fails to
299 * indicate this.
300 */
289 HTT_T2H_MSG_TYPE_TEST, 301 HTT_T2H_MSG_TYPE_TEST,
302
290 /* keep this last */ 303 /* keep this last */
291 HTT_T2H_NUM_MSGS 304 HTT_T2H_NUM_MSGS
292}; 305};
@@ -655,6 +668,53 @@ struct htt_rx_fragment_indication {
655#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_MASK 0x00000FC0 668#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_MASK 0x00000FC0
656#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_LSB 6 669#define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_LSB 6
657 670
671struct htt_rx_pn_ind {
672 __le16 peer_id;
673 u8 tid;
674 u8 seqno_start;
675 u8 seqno_end;
676 u8 pn_ie_count;
677 u8 reserved;
678 u8 pn_ies[0];
679} __packed;
680
681struct htt_rx_offload_msdu {
682 __le16 msdu_len;
683 __le16 peer_id;
684 u8 vdev_id;
685 u8 tid;
686 u8 fw_desc;
687 u8 payload[0];
688} __packed;
689
690struct htt_rx_offload_ind {
691 u8 reserved;
692 __le16 msdu_count;
693} __packed;
694
695struct htt_rx_in_ord_msdu_desc {
696 __le32 msdu_paddr;
697 __le16 msdu_len;
698 u8 fw_desc;
699 u8 reserved;
700} __packed;
701
702struct htt_rx_in_ord_ind {
703 u8 info;
704 __le16 peer_id;
705 u8 vdev_id;
706 u8 reserved;
707 __le16 msdu_count;
708 struct htt_rx_in_ord_msdu_desc msdu_descs[0];
709} __packed;
710
711#define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f
712#define HTT_RX_IN_ORD_IND_INFO_TID_LSB 0
713#define HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK 0x00000020
714#define HTT_RX_IN_ORD_IND_INFO_OFFLOAD_LSB 5
715#define HTT_RX_IN_ORD_IND_INFO_FRAG_MASK 0x00000040
716#define HTT_RX_IN_ORD_IND_INFO_FRAG_LSB 6
717
658/* 718/*
659 * target -> host test message definition 719 * target -> host test message definition
660 * 720 *
@@ -1150,6 +1210,9 @@ struct htt_resp {
1150 struct htt_rx_test rx_test; 1210 struct htt_rx_test rx_test;
1151 struct htt_pktlog_msg pktlog_msg; 1211 struct htt_pktlog_msg pktlog_msg;
1152 struct htt_stats_conf stats_conf; 1212 struct htt_stats_conf stats_conf;
1213 struct htt_rx_pn_ind rx_pn_ind;
1214 struct htt_rx_offload_ind rx_offload_ind;
1215 struct htt_rx_in_ord_ind rx_in_ord_ind;
1153 }; 1216 };
1154} __packed; 1217} __packed;
1155 1218
@@ -1182,7 +1245,6 @@ struct ath10k_htt {
1182 struct ath10k *ar; 1245 struct ath10k *ar;
1183 enum ath10k_htc_ep_id eid; 1246 enum ath10k_htc_ep_id eid;
1184 1247
1185 int max_throughput_mbps;
1186 u8 target_version_major; 1248 u8 target_version_major;
1187 u8 target_version_minor; 1249 u8 target_version_minor;
1188 struct completion target_version_received; 1250 struct completion target_version_received;
@@ -1198,6 +1260,20 @@ struct ath10k_htt {
1198 * filled. 1260 * filled.
1199 */ 1261 */
1200 struct sk_buff **netbufs_ring; 1262 struct sk_buff **netbufs_ring;
1263
1264 /* This is used only with firmware supporting IN_ORD_IND.
1265 *
1266 * With Full Rx Reorder the HTT Rx Ring is more of a temporary
1267 * buffer ring from which buffer addresses are copied by the
1268 * firmware to MAC Rx ring. Firmware then delivers IN_ORD_IND
1269 * pointing to specific (re-ordered) buffers.
1270 *
1271 * FIXME: With kernel generic hashing functions there's a lot
1272 * of hash collisions for sk_buffs.
1273 */
1274 bool in_ord_rx;
1275 DECLARE_HASHTABLE(skb_table, 4);
1276
1201 /* 1277 /*
1202 * Ring of buffer addresses - 1278 * Ring of buffer addresses -
1203 * This ring holds the "physical" device address of the 1279 * This ring holds the "physical" device address of the
@@ -1252,12 +1328,11 @@ struct ath10k_htt {
1252 1328
1253 unsigned int prefetch_len; 1329 unsigned int prefetch_len;
1254 1330
1255 /* Protects access to %pending_tx, %used_msdu_ids */ 1331 /* Protects access to pending_tx, num_pending_tx */
1256 spinlock_t tx_lock; 1332 spinlock_t tx_lock;
1257 int max_num_pending_tx; 1333 int max_num_pending_tx;
1258 int num_pending_tx; 1334 int num_pending_tx;
1259 struct sk_buff **pending_tx; 1335 struct idr pending_tx;
1260 unsigned long *used_msdu_ids; /* bitmap */
1261 wait_queue_head_t empty_tx_wq; 1336 wait_queue_head_t empty_tx_wq;
1262 struct dma_pool *tx_pool; 1337 struct dma_pool *tx_pool;
1263 1338
@@ -1271,6 +1346,7 @@ struct ath10k_htt {
1271 struct tasklet_struct txrx_compl_task; 1346 struct tasklet_struct txrx_compl_task;
1272 struct sk_buff_head tx_compl_q; 1347 struct sk_buff_head tx_compl_q;
1273 struct sk_buff_head rx_compl_q; 1348 struct sk_buff_head rx_compl_q;
1349 struct sk_buff_head rx_in_ord_compl_q;
1274 1350
1275 /* rx_status template */ 1351 /* rx_status template */
1276 struct ieee80211_rx_status rx_status; 1352 struct ieee80211_rx_status rx_status;
@@ -1334,6 +1410,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt);
1334void ath10k_htt_tx_free(struct ath10k_htt *htt); 1410void ath10k_htt_tx_free(struct ath10k_htt *htt);
1335 1411
1336int ath10k_htt_rx_alloc(struct ath10k_htt *htt); 1412int ath10k_htt_rx_alloc(struct ath10k_htt *htt);
1413int ath10k_htt_rx_ring_refill(struct ath10k *ar);
1337void ath10k_htt_rx_free(struct ath10k_htt *htt); 1414void ath10k_htt_rx_free(struct ath10k_htt *htt);
1338 1415
1339void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); 1416void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb);
@@ -1346,7 +1423,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
1346 u8 max_subfrms_amsdu); 1423 u8 max_subfrms_amsdu);
1347 1424
1348void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); 1425void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
1349int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt); 1426int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb);
1350void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id); 1427void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id);
1351int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *); 1428int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *);
1352int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *); 1429int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 9c782a42665e..c1da44f65a4d 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -25,8 +25,8 @@
25 25
26#include <linux/log2.h> 26#include <linux/log2.h>
27 27
28#define HTT_RX_RING_SIZE 1024 28#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
29#define HTT_RX_RING_FILL_LEVEL 1000 29#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
30 30
31/* when under memory pressure rx ring refill may fail and needs a retry */ 31/* when under memory pressure rx ring refill may fail and needs a retry */
32#define HTT_RX_RING_REFILL_RETRY_MS 50 32#define HTT_RX_RING_REFILL_RETRY_MS 50
@@ -34,31 +34,70 @@
34static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); 34static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
35static void ath10k_htt_txrx_compl_task(unsigned long ptr); 35static void ath10k_htt_txrx_compl_task(unsigned long ptr);
36 36
37static struct sk_buff *
38ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr)
39{
40 struct ath10k_skb_rxcb *rxcb;
41
42 hash_for_each_possible(ar->htt.rx_ring.skb_table, rxcb, hlist, paddr)
43 if (rxcb->paddr == paddr)
44 return ATH10K_RXCB_SKB(rxcb);
45
46 WARN_ON_ONCE(1);
47 return NULL;
48}
49
37static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt) 50static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt)
38{ 51{
39 struct sk_buff *skb; 52 struct sk_buff *skb;
40 struct ath10k_skb_cb *cb; 53 struct ath10k_skb_rxcb *rxcb;
54 struct hlist_node *n;
41 int i; 55 int i;
42 56
43 for (i = 0; i < htt->rx_ring.fill_cnt; i++) { 57 if (htt->rx_ring.in_ord_rx) {
44 skb = htt->rx_ring.netbufs_ring[i]; 58 hash_for_each_safe(htt->rx_ring.skb_table, i, n, rxcb, hlist) {
45 cb = ATH10K_SKB_CB(skb); 59 skb = ATH10K_RXCB_SKB(rxcb);
46 dma_unmap_single(htt->ar->dev, cb->paddr, 60 dma_unmap_single(htt->ar->dev, rxcb->paddr,
47 skb->len + skb_tailroom(skb), 61 skb->len + skb_tailroom(skb),
48 DMA_FROM_DEVICE); 62 DMA_FROM_DEVICE);
49 dev_kfree_skb_any(skb); 63 hash_del(&rxcb->hlist);
64 dev_kfree_skb_any(skb);
65 }
66 } else {
67 for (i = 0; i < htt->rx_ring.size; i++) {
68 skb = htt->rx_ring.netbufs_ring[i];
69 if (!skb)
70 continue;
71
72 rxcb = ATH10K_SKB_RXCB(skb);
73 dma_unmap_single(htt->ar->dev, rxcb->paddr,
74 skb->len + skb_tailroom(skb),
75 DMA_FROM_DEVICE);
76 dev_kfree_skb_any(skb);
77 }
50 } 78 }
51 79
52 htt->rx_ring.fill_cnt = 0; 80 htt->rx_ring.fill_cnt = 0;
81 hash_init(htt->rx_ring.skb_table);
82 memset(htt->rx_ring.netbufs_ring, 0,
83 htt->rx_ring.size * sizeof(htt->rx_ring.netbufs_ring[0]));
53} 84}
54 85
55static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) 86static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
56{ 87{
57 struct htt_rx_desc *rx_desc; 88 struct htt_rx_desc *rx_desc;
89 struct ath10k_skb_rxcb *rxcb;
58 struct sk_buff *skb; 90 struct sk_buff *skb;
59 dma_addr_t paddr; 91 dma_addr_t paddr;
60 int ret = 0, idx; 92 int ret = 0, idx;
61 93
94 /* The Full Rx Reorder firmware has no way of telling the host
95 * implicitly when it copied HTT Rx Ring buffers to MAC Rx Ring.
96 * To keep things simple make sure ring is always half empty. This
97 * guarantees there'll be no replenishment overruns possible.
98 */
99 BUILD_BUG_ON(HTT_RX_RING_FILL_LEVEL >= HTT_RX_RING_SIZE / 2);
100
62 idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr); 101 idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr);
63 while (num > 0) { 102 while (num > 0) {
64 skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN); 103 skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN);
@@ -86,17 +125,29 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
86 goto fail; 125 goto fail;
87 } 126 }
88 127
89 ATH10K_SKB_CB(skb)->paddr = paddr; 128 rxcb = ATH10K_SKB_RXCB(skb);
129 rxcb->paddr = paddr;
90 htt->rx_ring.netbufs_ring[idx] = skb; 130 htt->rx_ring.netbufs_ring[idx] = skb;
91 htt->rx_ring.paddrs_ring[idx] = __cpu_to_le32(paddr); 131 htt->rx_ring.paddrs_ring[idx] = __cpu_to_le32(paddr);
92 htt->rx_ring.fill_cnt++; 132 htt->rx_ring.fill_cnt++;
93 133
134 if (htt->rx_ring.in_ord_rx) {
135 hash_add(htt->rx_ring.skb_table,
136 &ATH10K_SKB_RXCB(skb)->hlist,
137 (u32)paddr);
138 }
139
94 num--; 140 num--;
95 idx++; 141 idx++;
96 idx &= htt->rx_ring.size_mask; 142 idx &= htt->rx_ring.size_mask;
97 } 143 }
98 144
99fail: 145fail:
146 /*
147 * Make sure the rx buffer is updated before available buffer
148 * index to avoid any potential rx ring corruption.
149 */
150 mb();
100 *htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx); 151 *htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx);
101 return ret; 152 return ret;
102} 153}
@@ -153,22 +204,20 @@ static void ath10k_htt_rx_ring_refill_retry(unsigned long arg)
153 ath10k_htt_rx_msdu_buff_replenish(htt); 204 ath10k_htt_rx_msdu_buff_replenish(htt);
154} 205}
155 206
156static void ath10k_htt_rx_ring_clean_up(struct ath10k_htt *htt) 207int ath10k_htt_rx_ring_refill(struct ath10k *ar)
157{ 208{
158 struct sk_buff *skb; 209 struct ath10k_htt *htt = &ar->htt;
159 int i; 210 int ret;
160 211
161 for (i = 0; i < htt->rx_ring.size; i++) { 212 spin_lock_bh(&htt->rx_ring.lock);
162 skb = htt->rx_ring.netbufs_ring[i]; 213 ret = ath10k_htt_rx_ring_fill_n(htt, (htt->rx_ring.fill_level -
163 if (!skb) 214 htt->rx_ring.fill_cnt));
164 continue; 215 spin_unlock_bh(&htt->rx_ring.lock);
165 216
166 dma_unmap_single(htt->ar->dev, ATH10K_SKB_CB(skb)->paddr, 217 if (ret)
167 skb->len + skb_tailroom(skb), 218 ath10k_htt_rx_ring_free(htt);
168 DMA_FROM_DEVICE); 219
169 dev_kfree_skb_any(skb); 220 return ret;
170 htt->rx_ring.netbufs_ring[i] = NULL;
171 }
172} 221}
173 222
174void ath10k_htt_rx_free(struct ath10k_htt *htt) 223void ath10k_htt_rx_free(struct ath10k_htt *htt)
@@ -179,8 +228,9 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt)
179 228
180 skb_queue_purge(&htt->tx_compl_q); 229 skb_queue_purge(&htt->tx_compl_q);
181 skb_queue_purge(&htt->rx_compl_q); 230 skb_queue_purge(&htt->rx_compl_q);
231 skb_queue_purge(&htt->rx_in_ord_compl_q);
182 232
183 ath10k_htt_rx_ring_clean_up(htt); 233 ath10k_htt_rx_ring_free(htt);
184 234
185 dma_free_coherent(htt->ar->dev, 235 dma_free_coherent(htt->ar->dev,
186 (htt->rx_ring.size * 236 (htt->rx_ring.size *
@@ -212,6 +262,7 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
212 idx = htt->rx_ring.sw_rd_idx.msdu_payld; 262 idx = htt->rx_ring.sw_rd_idx.msdu_payld;
213 msdu = htt->rx_ring.netbufs_ring[idx]; 263 msdu = htt->rx_ring.netbufs_ring[idx];
214 htt->rx_ring.netbufs_ring[idx] = NULL; 264 htt->rx_ring.netbufs_ring[idx] = NULL;
265 htt->rx_ring.paddrs_ring[idx] = 0;
215 266
216 idx++; 267 idx++;
217 idx &= htt->rx_ring.size_mask; 268 idx &= htt->rx_ring.size_mask;
@@ -219,7 +270,7 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
219 htt->rx_ring.fill_cnt--; 270 htt->rx_ring.fill_cnt--;
220 271
221 dma_unmap_single(htt->ar->dev, 272 dma_unmap_single(htt->ar->dev,
222 ATH10K_SKB_CB(msdu)->paddr, 273 ATH10K_SKB_RXCB(msdu)->paddr,
223 msdu->len + skb_tailroom(msdu), 274 msdu->len + skb_tailroom(msdu),
224 DMA_FROM_DEVICE); 275 DMA_FROM_DEVICE);
225 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ", 276 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ",
@@ -379,6 +430,82 @@ static void ath10k_htt_rx_replenish_task(unsigned long ptr)
379 ath10k_htt_rx_msdu_buff_replenish(htt); 430 ath10k_htt_rx_msdu_buff_replenish(htt);
380} 431}
381 432
433static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt,
434 u32 paddr)
435{
436 struct ath10k *ar = htt->ar;
437 struct ath10k_skb_rxcb *rxcb;
438 struct sk_buff *msdu;
439
440 lockdep_assert_held(&htt->rx_ring.lock);
441
442 msdu = ath10k_htt_rx_find_skb_paddr(ar, paddr);
443 if (!msdu)
444 return NULL;
445
446 rxcb = ATH10K_SKB_RXCB(msdu);
447 hash_del(&rxcb->hlist);
448 htt->rx_ring.fill_cnt--;
449
450 dma_unmap_single(htt->ar->dev, rxcb->paddr,
451 msdu->len + skb_tailroom(msdu),
452 DMA_FROM_DEVICE);
453 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ",
454 msdu->data, msdu->len + skb_tailroom(msdu));
455
456 return msdu;
457}
458
459static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt,
460 struct htt_rx_in_ord_ind *ev,
461 struct sk_buff_head *list)
462{
463 struct ath10k *ar = htt->ar;
464 struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs;
465 struct htt_rx_desc *rxd;
466 struct sk_buff *msdu;
467 int msdu_count;
468 bool is_offload;
469 u32 paddr;
470
471 lockdep_assert_held(&htt->rx_ring.lock);
472
473 msdu_count = __le16_to_cpu(ev->msdu_count);
474 is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
475
476 while (msdu_count--) {
477 paddr = __le32_to_cpu(msdu_desc->msdu_paddr);
478
479 msdu = ath10k_htt_rx_pop_paddr(htt, paddr);
480 if (!msdu) {
481 __skb_queue_purge(list);
482 return -ENOENT;
483 }
484
485 __skb_queue_tail(list, msdu);
486
487 if (!is_offload) {
488 rxd = (void *)msdu->data;
489
490 trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd));
491
492 skb_put(msdu, sizeof(*rxd));
493 skb_pull(msdu, sizeof(*rxd));
494 skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len));
495
496 if (!(__le32_to_cpu(rxd->attention.flags) &
497 RX_ATTENTION_FLAGS_MSDU_DONE)) {
498 ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n");
499 return -EIO;
500 }
501 }
502
503 msdu_desc++;
504 }
505
506 return 0;
507}
508
382int ath10k_htt_rx_alloc(struct ath10k_htt *htt) 509int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
383{ 510{
384 struct ath10k *ar = htt->ar; 511 struct ath10k *ar = htt->ar;
@@ -424,7 +551,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
424 551
425 htt->rx_ring.alloc_idx.vaddr = vaddr; 552 htt->rx_ring.alloc_idx.vaddr = vaddr;
426 htt->rx_ring.alloc_idx.paddr = paddr; 553 htt->rx_ring.alloc_idx.paddr = paddr;
427 htt->rx_ring.sw_rd_idx.msdu_payld = 0; 554 htt->rx_ring.sw_rd_idx.msdu_payld = htt->rx_ring.size_mask;
428 *htt->rx_ring.alloc_idx.vaddr = 0; 555 *htt->rx_ring.alloc_idx.vaddr = 0;
429 556
430 /* Initialize the Rx refill retry timer */ 557 /* Initialize the Rx refill retry timer */
@@ -433,14 +560,15 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
433 spin_lock_init(&htt->rx_ring.lock); 560 spin_lock_init(&htt->rx_ring.lock);
434 561
435 htt->rx_ring.fill_cnt = 0; 562 htt->rx_ring.fill_cnt = 0;
436 if (__ath10k_htt_rx_ring_fill_n(htt, htt->rx_ring.fill_level)) 563 htt->rx_ring.sw_rd_idx.msdu_payld = 0;
437 goto err_fill_ring; 564 hash_init(htt->rx_ring.skb_table);
438 565
439 tasklet_init(&htt->rx_replenish_task, ath10k_htt_rx_replenish_task, 566 tasklet_init(&htt->rx_replenish_task, ath10k_htt_rx_replenish_task,
440 (unsigned long)htt); 567 (unsigned long)htt);
441 568
442 skb_queue_head_init(&htt->tx_compl_q); 569 skb_queue_head_init(&htt->tx_compl_q);
443 skb_queue_head_init(&htt->rx_compl_q); 570 skb_queue_head_init(&htt->rx_compl_q);
571 skb_queue_head_init(&htt->rx_in_ord_compl_q);
444 572
445 tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task, 573 tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task,
446 (unsigned long)htt); 574 (unsigned long)htt);
@@ -449,12 +577,6 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
449 htt->rx_ring.size, htt->rx_ring.fill_level); 577 htt->rx_ring.size, htt->rx_ring.fill_level);
450 return 0; 578 return 0;
451 579
452err_fill_ring:
453 ath10k_htt_rx_ring_free(htt);
454 dma_free_coherent(htt->ar->dev,
455 sizeof(*htt->rx_ring.alloc_idx.vaddr),
456 htt->rx_ring.alloc_idx.vaddr,
457 htt->rx_ring.alloc_idx.paddr);
458err_dma_idx: 580err_dma_idx:
459 dma_free_coherent(htt->ar->dev, 581 dma_free_coherent(htt->ar->dev,
460 (htt->rx_ring.size * 582 (htt->rx_ring.size *
@@ -691,7 +813,7 @@ static void ath10k_htt_rx_h_mactime(struct ath10k *ar,
691 * 813 *
692 * FIXME: Can we get/compute 64bit TSF? 814 * FIXME: Can we get/compute 64bit TSF?
693 */ 815 */
694 status->mactime = __le32_to_cpu(rxd->ppdu_end.tsf_timestamp); 816 status->mactime = __le32_to_cpu(rxd->ppdu_end.common.tsf_timestamp);
695 status->flag |= RX_FLAG_MACTIME_END; 817 status->flag |= RX_FLAG_MACTIME_END;
696} 818}
697 819
@@ -1578,6 +1700,194 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
1578 spin_unlock_bh(&ar->data_lock); 1700 spin_unlock_bh(&ar->data_lock);
1579} 1701}
1580 1702
1703static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list,
1704 struct sk_buff_head *amsdu)
1705{
1706 struct sk_buff *msdu;
1707 struct htt_rx_desc *rxd;
1708
1709 if (skb_queue_empty(list))
1710 return -ENOBUFS;
1711
1712 if (WARN_ON(!skb_queue_empty(amsdu)))
1713 return -EINVAL;
1714
1715 while ((msdu = __skb_dequeue(list))) {
1716 __skb_queue_tail(amsdu, msdu);
1717
1718 rxd = (void *)msdu->data - sizeof(*rxd);
1719 if (rxd->msdu_end.info0 &
1720 __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))
1721 break;
1722 }
1723
1724 msdu = skb_peek_tail(amsdu);
1725 rxd = (void *)msdu->data - sizeof(*rxd);
1726 if (!(rxd->msdu_end.info0 &
1727 __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))) {
1728 skb_queue_splice_init(amsdu, list);
1729 return -EAGAIN;
1730 }
1731
1732 return 0;
1733}
1734
1735static void ath10k_htt_rx_h_rx_offload_prot(struct ieee80211_rx_status *status,
1736 struct sk_buff *skb)
1737{
1738 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1739
1740 if (!ieee80211_has_protected(hdr->frame_control))
1741 return;
1742
1743 /* Offloaded frames are already decrypted but firmware insists they are
1744 * protected in the 802.11 header. Strip the flag. Otherwise mac80211
1745 * will drop the frame.
1746 */
1747
1748 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
1749 status->flag |= RX_FLAG_DECRYPTED |
1750 RX_FLAG_IV_STRIPPED |
1751 RX_FLAG_MMIC_STRIPPED;
1752}
1753
1754static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar,
1755 struct sk_buff_head *list)
1756{
1757 struct ath10k_htt *htt = &ar->htt;
1758 struct ieee80211_rx_status *status = &htt->rx_status;
1759 struct htt_rx_offload_msdu *rx;
1760 struct sk_buff *msdu;
1761 size_t offset;
1762
1763 while ((msdu = __skb_dequeue(list))) {
1764 /* Offloaded frames don't have Rx descriptor. Instead they have
1765 * a short meta information header.
1766 */
1767
1768 rx = (void *)msdu->data;
1769
1770 skb_put(msdu, sizeof(*rx));
1771 skb_pull(msdu, sizeof(*rx));
1772
1773 if (skb_tailroom(msdu) < __le16_to_cpu(rx->msdu_len)) {
1774 ath10k_warn(ar, "dropping frame: offloaded rx msdu is too long!\n");
1775 dev_kfree_skb_any(msdu);
1776 continue;
1777 }
1778
1779 skb_put(msdu, __le16_to_cpu(rx->msdu_len));
1780
1781 /* Offloaded rx header length isn't multiple of 2 nor 4 so the
1782 * actual payload is unaligned. Align the frame. Otherwise
1783 * mac80211 complains. This shouldn't reduce performance much
1784 * because these offloaded frames are rare.
1785 */
1786 offset = 4 - ((unsigned long)msdu->data & 3);
1787 skb_put(msdu, offset);
1788 memmove(msdu->data + offset, msdu->data, msdu->len);
1789 skb_pull(msdu, offset);
1790
1791 /* FIXME: The frame is NWifi. Re-construct QoS Control
1792 * if possible later.
1793 */
1794
1795 memset(status, 0, sizeof(*status));
1796 status->flag |= RX_FLAG_NO_SIGNAL_VAL;
1797
1798 ath10k_htt_rx_h_rx_offload_prot(status, msdu);
1799 ath10k_htt_rx_h_channel(ar, status);
1800 ath10k_process_rx(ar, status, msdu);
1801 }
1802}
1803
1804static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
1805{
1806 struct ath10k_htt *htt = &ar->htt;
1807 struct htt_resp *resp = (void *)skb->data;
1808 struct ieee80211_rx_status *status = &htt->rx_status;
1809 struct sk_buff_head list;
1810 struct sk_buff_head amsdu;
1811 u16 peer_id;
1812 u16 msdu_count;
1813 u8 vdev_id;
1814 u8 tid;
1815 bool offload;
1816 bool frag;
1817 int ret;
1818
1819 lockdep_assert_held(&htt->rx_ring.lock);
1820
1821 if (htt->rx_confused)
1822 return;
1823
1824 skb_pull(skb, sizeof(resp->hdr));
1825 skb_pull(skb, sizeof(resp->rx_in_ord_ind));
1826
1827 peer_id = __le16_to_cpu(resp->rx_in_ord_ind.peer_id);
1828 msdu_count = __le16_to_cpu(resp->rx_in_ord_ind.msdu_count);
1829 vdev_id = resp->rx_in_ord_ind.vdev_id;
1830 tid = SM(resp->rx_in_ord_ind.info, HTT_RX_IN_ORD_IND_INFO_TID);
1831 offload = !!(resp->rx_in_ord_ind.info &
1832 HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK);
1833 frag = !!(resp->rx_in_ord_ind.info & HTT_RX_IN_ORD_IND_INFO_FRAG_MASK);
1834
1835 ath10k_dbg(ar, ATH10K_DBG_HTT,
1836 "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n",
1837 vdev_id, peer_id, tid, offload, frag, msdu_count);
1838
1839 if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) {
1840 ath10k_warn(ar, "dropping invalid in order rx indication\n");
1841 return;
1842 }
1843
1844 /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later
1845 * extracted and processed.
1846 */
1847 __skb_queue_head_init(&list);
1848 ret = ath10k_htt_rx_pop_paddr_list(htt, &resp->rx_in_ord_ind, &list);
1849 if (ret < 0) {
1850 ath10k_warn(ar, "failed to pop paddr list: %d\n", ret);
1851 htt->rx_confused = true;
1852 return;
1853 }
1854
1855 /* Offloaded frames are very different and need to be handled
1856 * separately.
1857 */
1858 if (offload)
1859 ath10k_htt_rx_h_rx_offload(ar, &list);
1860
1861 while (!skb_queue_empty(&list)) {
1862 __skb_queue_head_init(&amsdu);
1863 ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu);
1864 switch (ret) {
1865 case 0:
1866 /* Note: The in-order indication may report interleaved
1867 * frames from different PPDUs meaning reported rx rate
1868 * to mac80211 isn't accurate/reliable. It's still
1869 * better to report something than nothing though. This
1870 * should still give an idea about rx rate to the user.
1871 */
1872 ath10k_htt_rx_h_ppdu(ar, &amsdu, status);
1873 ath10k_htt_rx_h_filter(ar, &amsdu, status);
1874 ath10k_htt_rx_h_mpdu(ar, &amsdu, status);
1875 ath10k_htt_rx_h_deliver(ar, &amsdu, status);
1876 break;
1877 case -EAGAIN:
1878 /* fall through */
1879 default:
1880 /* Should not happen. */
1881 ath10k_warn(ar, "failed to extract amsdu: %d\n", ret);
1882 htt->rx_confused = true;
1883 __skb_queue_purge(&list);
1884 return;
1885 }
1886 }
1887
1888 tasklet_schedule(&htt->rx_replenish_task);
1889}
1890
1581void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) 1891void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
1582{ 1892{
1583 struct ath10k_htt *htt = &ar->htt; 1893 struct ath10k_htt *htt = &ar->htt;
@@ -1700,6 +2010,20 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
1700 */ 2010 */
1701 break; 2011 break;
1702 } 2012 }
2013 case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: {
2014 spin_lock_bh(&htt->rx_ring.lock);
2015 __skb_queue_tail(&htt->rx_in_ord_compl_q, skb);
2016 spin_unlock_bh(&htt->rx_ring.lock);
2017 tasklet_schedule(&htt->txrx_compl_task);
2018 return;
2019 }
2020 case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
2021 /* FIXME: This WMI-TLV event is overlapping with 10.2
2022 * CHAN_CHANGE - both being 0xF. Neither is being used in
2023 * practice so no immediate action is necessary. Nevertheless
2024 * HTT may need an abstraction layer like WMI has one day.
2025 */
2026 break;
1703 default: 2027 default:
1704 ath10k_warn(ar, "htt event (%d) not handled\n", 2028 ath10k_warn(ar, "htt event (%d) not handled\n",
1705 resp->hdr.msg_type); 2029 resp->hdr.msg_type);
@@ -1715,6 +2039,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
1715static void ath10k_htt_txrx_compl_task(unsigned long ptr) 2039static void ath10k_htt_txrx_compl_task(unsigned long ptr)
1716{ 2040{
1717 struct ath10k_htt *htt = (struct ath10k_htt *)ptr; 2041 struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
2042 struct ath10k *ar = htt->ar;
1718 struct htt_resp *resp; 2043 struct htt_resp *resp;
1719 struct sk_buff *skb; 2044 struct sk_buff *skb;
1720 2045
@@ -1731,5 +2056,10 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
1731 ath10k_htt_rx_handler(htt, &resp->rx_ind); 2056 ath10k_htt_rx_handler(htt, &resp->rx_ind);
1732 dev_kfree_skb_any(skb); 2057 dev_kfree_skb_any(skb);
1733 } 2058 }
2059
2060 while ((skb = __skb_dequeue(&htt->rx_in_ord_compl_q))) {
2061 ath10k_htt_rx_in_ord_ind(ar, skb);
2062 dev_kfree_skb_any(skb);
2063 }
1734 spin_unlock_bh(&htt->rx_ring.lock); 2064 spin_unlock_bh(&htt->rx_ring.lock);
1735} 2065}
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index 4bc51d8a14a3..cbd2bc9e6202 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -56,21 +56,18 @@ exit:
56 return ret; 56 return ret;
57} 57}
58 58
59int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt) 59int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb)
60{ 60{
61 struct ath10k *ar = htt->ar; 61 struct ath10k *ar = htt->ar;
62 int msdu_id; 62 int ret;
63 63
64 lockdep_assert_held(&htt->tx_lock); 64 lockdep_assert_held(&htt->tx_lock);
65 65
66 msdu_id = find_first_zero_bit(htt->used_msdu_ids, 66 ret = idr_alloc(&htt->pending_tx, skb, 0, 0x10000, GFP_ATOMIC);
67 htt->max_num_pending_tx); 67
68 if (msdu_id == htt->max_num_pending_tx) 68 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", ret);
69 return -ENOBUFS;
70 69
71 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id); 70 return ret;
72 __set_bit(msdu_id, htt->used_msdu_ids);
73 return msdu_id;
74} 71}
75 72
76void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) 73void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
@@ -79,79 +76,53 @@ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
79 76
80 lockdep_assert_held(&htt->tx_lock); 77 lockdep_assert_held(&htt->tx_lock);
81 78
82 if (!test_bit(msdu_id, htt->used_msdu_ids))
83 ath10k_warn(ar, "trying to free unallocated msdu_id %d\n",
84 msdu_id);
85
86 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id); 79 ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id);
87 __clear_bit(msdu_id, htt->used_msdu_ids); 80
81 idr_remove(&htt->pending_tx, msdu_id);
88} 82}
89 83
90int ath10k_htt_tx_alloc(struct ath10k_htt *htt) 84int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
91{ 85{
92 struct ath10k *ar = htt->ar; 86 struct ath10k *ar = htt->ar;
93 87
94 spin_lock_init(&htt->tx_lock);
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", 88 ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
102 htt->max_num_pending_tx); 89 htt->max_num_pending_tx);
103 90
104 htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) * 91 spin_lock_init(&htt->tx_lock);
105 htt->max_num_pending_tx, GFP_KERNEL); 92 idr_init(&htt->pending_tx);
106 if (!htt->pending_tx)
107 return -ENOMEM;
108
109 htt->used_msdu_ids = kzalloc(sizeof(unsigned long) *
110 BITS_TO_LONGS(htt->max_num_pending_tx),
111 GFP_KERNEL);
112 if (!htt->used_msdu_ids) {
113 kfree(htt->pending_tx);
114 return -ENOMEM;
115 }
116 93
117 htt->tx_pool = dma_pool_create("ath10k htt tx pool", htt->ar->dev, 94 htt->tx_pool = dma_pool_create("ath10k htt tx pool", htt->ar->dev,
118 sizeof(struct ath10k_htt_txbuf), 4, 0); 95 sizeof(struct ath10k_htt_txbuf), 4, 0);
119 if (!htt->tx_pool) { 96 if (!htt->tx_pool) {
120 kfree(htt->used_msdu_ids); 97 idr_destroy(&htt->pending_tx);
121 kfree(htt->pending_tx);
122 return -ENOMEM; 98 return -ENOMEM;
123 } 99 }
124 100
125 return 0; 101 return 0;
126} 102}
127 103
128static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt) 104static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
129{ 105{
130 struct ath10k *ar = htt->ar; 106 struct ath10k *ar = ctx;
107 struct ath10k_htt *htt = &ar->htt;
131 struct htt_tx_done tx_done = {0}; 108 struct htt_tx_done tx_done = {0};
132 int msdu_id;
133
134 spin_lock_bh(&htt->tx_lock);
135 for (msdu_id = 0; msdu_id < htt->max_num_pending_tx; msdu_id++) {
136 if (!test_bit(msdu_id, htt->used_msdu_ids))
137 continue;
138 109
139 ath10k_dbg(ar, ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", 110 ath10k_dbg(ar, ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", msdu_id);
140 msdu_id);
141 111
142 tx_done.discard = 1; 112 tx_done.discard = 1;
143 tx_done.msdu_id = msdu_id; 113 tx_done.msdu_id = msdu_id;
144 114
145 ath10k_txrx_tx_unref(htt, &tx_done); 115 spin_lock_bh(&htt->tx_lock);
146 } 116 ath10k_txrx_tx_unref(htt, &tx_done);
147 spin_unlock_bh(&htt->tx_lock); 117 spin_unlock_bh(&htt->tx_lock);
118
119 return 0;
148} 120}
149 121
150void ath10k_htt_tx_free(struct ath10k_htt *htt) 122void ath10k_htt_tx_free(struct ath10k_htt *htt)
151{ 123{
152 ath10k_htt_tx_free_pending(htt); 124 idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
153 kfree(htt->pending_tx); 125 idr_destroy(&htt->pending_tx);
154 kfree(htt->used_msdu_ids);
155 dma_pool_destroy(htt->tx_pool); 126 dma_pool_destroy(htt->tx_pool);
156} 127}
157 128
@@ -383,13 +354,12 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
383 len += sizeof(cmd->mgmt_tx); 354 len += sizeof(cmd->mgmt_tx);
384 355
385 spin_lock_bh(&htt->tx_lock); 356 spin_lock_bh(&htt->tx_lock);
386 res = ath10k_htt_tx_alloc_msdu_id(htt); 357 res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
387 if (res < 0) { 358 if (res < 0) {
388 spin_unlock_bh(&htt->tx_lock); 359 spin_unlock_bh(&htt->tx_lock);
389 goto err_tx_dec; 360 goto err_tx_dec;
390 } 361 }
391 msdu_id = res; 362 msdu_id = res;
392 htt->pending_tx[msdu_id] = msdu;
393 spin_unlock_bh(&htt->tx_lock); 363 spin_unlock_bh(&htt->tx_lock);
394 364
395 txdesc = ath10k_htc_alloc_skb(ar, len); 365 txdesc = ath10k_htc_alloc_skb(ar, len);
@@ -428,7 +398,6 @@ err_free_txdesc:
428 dev_kfree_skb_any(txdesc); 398 dev_kfree_skb_any(txdesc);
429err_free_msdu_id: 399err_free_msdu_id:
430 spin_lock_bh(&htt->tx_lock); 400 spin_lock_bh(&htt->tx_lock);
431 htt->pending_tx[msdu_id] = NULL;
432 ath10k_htt_tx_free_msdu_id(htt, msdu_id); 401 ath10k_htt_tx_free_msdu_id(htt, msdu_id);
433 spin_unlock_bh(&htt->tx_lock); 402 spin_unlock_bh(&htt->tx_lock);
434err_tx_dec: 403err_tx_dec:
@@ -460,13 +429,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
460 goto err; 429 goto err;
461 430
462 spin_lock_bh(&htt->tx_lock); 431 spin_lock_bh(&htt->tx_lock);
463 res = ath10k_htt_tx_alloc_msdu_id(htt); 432 res = ath10k_htt_tx_alloc_msdu_id(htt, msdu);
464 if (res < 0) { 433 if (res < 0) {
465 spin_unlock_bh(&htt->tx_lock); 434 spin_unlock_bh(&htt->tx_lock);
466 goto err_tx_dec; 435 goto err_tx_dec;
467 } 436 }
468 msdu_id = res; 437 msdu_id = res;
469 htt->pending_tx[msdu_id] = msdu;
470 spin_unlock_bh(&htt->tx_lock); 438 spin_unlock_bh(&htt->tx_lock);
471 439
472 prefetch_len = min(htt->prefetch_len, msdu->len); 440 prefetch_len = min(htt->prefetch_len, msdu->len);
@@ -480,10 +448,18 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
480 448
481 skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC, 449 skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC,
482 &paddr); 450 &paddr);
483 if (!skb_cb->htt.txbuf) 451 if (!skb_cb->htt.txbuf) {
452 res = -ENOMEM;
484 goto err_free_msdu_id; 453 goto err_free_msdu_id;
454 }
485 skb_cb->htt.txbuf_paddr = paddr; 455 skb_cb->htt.txbuf_paddr = paddr;
486 456
457 if ((ieee80211_is_action(hdr->frame_control) ||
458 ieee80211_is_deauth(hdr->frame_control) ||
459 ieee80211_is_disassoc(hdr->frame_control)) &&
460 ieee80211_has_protected(hdr->frame_control))
461 skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
462
487 skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, 463 skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
488 DMA_TO_DEVICE); 464 DMA_TO_DEVICE);
489 res = dma_mapping_error(dev, skb_cb->paddr); 465 res = dma_mapping_error(dev, skb_cb->paddr);
@@ -539,8 +515,10 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
539 515
540 flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID); 516 flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID);
541 flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID); 517 flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID);
542 flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD; 518 if (msdu->ip_summed == CHECKSUM_PARTIAL) {
543 flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD; 519 flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD;
520 flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD;
521 }
544 522
545 /* Prevent firmware from sending up tx inspection requests. There's 523 /* Prevent firmware from sending up tx inspection requests. There's
546 * nothing ath10k can do with frames requested for inspection so force 524 * nothing ath10k can do with frames requested for inspection so force
@@ -598,7 +576,6 @@ err_free_txbuf:
598 skb_cb->htt.txbuf_paddr); 576 skb_cb->htt.txbuf_paddr);
599err_free_msdu_id: 577err_free_msdu_id:
600 spin_lock_bh(&htt->tx_lock); 578 spin_lock_bh(&htt->tx_lock);
601 htt->pending_tx[msdu_id] = NULL;
602 ath10k_htt_tx_free_msdu_id(htt, msdu_id); 579 ath10k_htt_tx_free_msdu_id(htt, msdu_id);
603 spin_unlock_bh(&htt->tx_lock); 580 spin_unlock_bh(&htt->tx_lock);
604err_tx_dec: 581err_tx_dec:
diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c
new file mode 100644
index 000000000000..839a8791fb9e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -0,0 +1,58 @@
1/*
2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/types.h>
18#include "hw.h"
19
20const struct ath10k_hw_regs qca988x_regs = {
21 .rtc_state_cold_reset_mask = 0x00000400,
22 .rtc_soc_base_address = 0x00004000,
23 .rtc_wmac_base_address = 0x00005000,
24 .soc_core_base_address = 0x00009000,
25 .ce_wrapper_base_address = 0x00057000,
26 .ce0_base_address = 0x00057400,
27 .ce1_base_address = 0x00057800,
28 .ce2_base_address = 0x00057c00,
29 .ce3_base_address = 0x00058000,
30 .ce4_base_address = 0x00058400,
31 .ce5_base_address = 0x00058800,
32 .ce6_base_address = 0x00058c00,
33 .ce7_base_address = 0x00059000,
34 .soc_reset_control_si0_rst_mask = 0x00000001,
35 .soc_reset_control_ce_rst_mask = 0x00040000,
36 .soc_chip_id_address = 0x00ec,
37 .scratch_3_address = 0x0030,
38};
39
40const struct ath10k_hw_regs qca6174_regs = {
41 .rtc_state_cold_reset_mask = 0x00002000,
42 .rtc_soc_base_address = 0x00000800,
43 .rtc_wmac_base_address = 0x00001000,
44 .soc_core_base_address = 0x0003a000,
45 .ce_wrapper_base_address = 0x00034000,
46 .ce0_base_address = 0x00034400,
47 .ce1_base_address = 0x00034800,
48 .ce2_base_address = 0x00034c00,
49 .ce3_base_address = 0x00035000,
50 .ce4_base_address = 0x00035400,
51 .ce5_base_address = 0x00035800,
52 .ce6_base_address = 0x00035c00,
53 .ce7_base_address = 0x00036000,
54 .soc_reset_control_si0_rst_mask = 0x00000000,
55 .soc_reset_control_ce_rst_mask = 0x00000001,
56 .soc_chip_id_address = 0x000f0,
57 .scratch_3_address = 0x0028,
58};
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
index dfedfd0e0f34..460771fcfe9e 100644
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -34,9 +34,50 @@
34#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" 34#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
35#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 35#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
36 36
37/* QCA6174 target BMI version signatures */
38#define QCA6174_HW_1_0_VERSION 0x05000000
39#define QCA6174_HW_1_1_VERSION 0x05000001
40#define QCA6174_HW_1_3_VERSION 0x05000003
41#define QCA6174_HW_2_1_VERSION 0x05010000
42#define QCA6174_HW_3_0_VERSION 0x05020000
43#define QCA6174_HW_3_2_VERSION 0x05030000
44
45enum qca6174_pci_rev {
46 QCA6174_PCI_REV_1_1 = 0x11,
47 QCA6174_PCI_REV_1_3 = 0x13,
48 QCA6174_PCI_REV_2_0 = 0x20,
49 QCA6174_PCI_REV_3_0 = 0x30,
50};
51
52enum qca6174_chip_id_rev {
53 QCA6174_HW_1_0_CHIP_ID_REV = 0,
54 QCA6174_HW_1_1_CHIP_ID_REV = 1,
55 QCA6174_HW_1_3_CHIP_ID_REV = 2,
56 QCA6174_HW_2_1_CHIP_ID_REV = 4,
57 QCA6174_HW_2_2_CHIP_ID_REV = 5,
58 QCA6174_HW_3_0_CHIP_ID_REV = 8,
59 QCA6174_HW_3_1_CHIP_ID_REV = 9,
60 QCA6174_HW_3_2_CHIP_ID_REV = 10,
61};
62
63#define QCA6174_HW_2_1_FW_DIR "ath10k/QCA6174/hw2.1"
64#define QCA6174_HW_2_1_FW_FILE "firmware.bin"
65#define QCA6174_HW_2_1_OTP_FILE "otp.bin"
66#define QCA6174_HW_2_1_BOARD_DATA_FILE "board.bin"
67#define QCA6174_HW_2_1_PATCH_LOAD_ADDR 0x1234
68
69#define QCA6174_HW_3_0_FW_DIR "ath10k/QCA6174/hw3.0"
70#define QCA6174_HW_3_0_FW_FILE "firmware.bin"
71#define QCA6174_HW_3_0_OTP_FILE "otp.bin"
72#define QCA6174_HW_3_0_BOARD_DATA_FILE "board.bin"
73#define QCA6174_HW_3_0_PATCH_LOAD_ADDR 0x1234
74
37#define ATH10K_FW_API2_FILE "firmware-2.bin" 75#define ATH10K_FW_API2_FILE "firmware-2.bin"
38#define ATH10K_FW_API3_FILE "firmware-3.bin" 76#define ATH10K_FW_API3_FILE "firmware-3.bin"
39 77
78/* added support for ATH10K_FW_IE_WMI_OP_VERSION */
79#define ATH10K_FW_API4_FILE "firmware-4.bin"
80
40#define ATH10K_FW_UTF_FILE "utf.bin" 81#define ATH10K_FW_UTF_FILE "utf.bin"
41 82
42/* includes also the null byte */ 83/* includes also the null byte */
@@ -58,8 +99,57 @@ enum ath10k_fw_ie_type {
58 ATH10K_FW_IE_FEATURES = 2, 99 ATH10K_FW_IE_FEATURES = 2,
59 ATH10K_FW_IE_FW_IMAGE = 3, 100 ATH10K_FW_IE_FW_IMAGE = 3,
60 ATH10K_FW_IE_OTP_IMAGE = 4, 101 ATH10K_FW_IE_OTP_IMAGE = 4,
102
103 /* WMI "operations" interface version, 32 bit value. Supported from
104 * FW API 4 and above.
105 */
106 ATH10K_FW_IE_WMI_OP_VERSION = 5,
107};
108
109enum ath10k_fw_wmi_op_version {
110 ATH10K_FW_WMI_OP_VERSION_UNSET = 0,
111
112 ATH10K_FW_WMI_OP_VERSION_MAIN = 1,
113 ATH10K_FW_WMI_OP_VERSION_10_1 = 2,
114 ATH10K_FW_WMI_OP_VERSION_10_2 = 3,
115 ATH10K_FW_WMI_OP_VERSION_TLV = 4,
116 ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5,
117
118 /* keep last */
119 ATH10K_FW_WMI_OP_VERSION_MAX,
120};
121
122enum ath10k_hw_rev {
123 ATH10K_HW_QCA988X,
124 ATH10K_HW_QCA6174,
125};
126
127struct ath10k_hw_regs {
128 u32 rtc_state_cold_reset_mask;
129 u32 rtc_soc_base_address;
130 u32 rtc_wmac_base_address;
131 u32 soc_core_base_address;
132 u32 ce_wrapper_base_address;
133 u32 ce0_base_address;
134 u32 ce1_base_address;
135 u32 ce2_base_address;
136 u32 ce3_base_address;
137 u32 ce4_base_address;
138 u32 ce5_base_address;
139 u32 ce6_base_address;
140 u32 ce7_base_address;
141 u32 soc_reset_control_si0_rst_mask;
142 u32 soc_reset_control_ce_rst_mask;
143 u32 soc_chip_id_address;
144 u32 scratch_3_address;
61}; 145};
62 146
147extern const struct ath10k_hw_regs qca988x_regs;
148extern const struct ath10k_hw_regs qca6174_regs;
149
150#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X)
151#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
152
63/* Known pecularities: 153/* Known pecularities:
64 * - current FW doesn't support raw rx mode (last tested v599) 154 * - current FW doesn't support raw rx mode (last tested v599)
65 * - current FW dumps upon raw tx mode (last tested v599) 155 * - current FW dumps upon raw tx mode (last tested v599)
@@ -162,6 +252,18 @@ struct ath10k_pktlog_hdr {
162#define TARGET_10X_NUM_MSDU_DESC (1024 + 400) 252#define TARGET_10X_NUM_MSDU_DESC (1024 + 400)
163#define TARGET_10X_MAX_FRAG_ENTRIES 0 253#define TARGET_10X_MAX_FRAG_ENTRIES 0
164 254
255/* 10.2 parameters */
256#define TARGET_10_2_DMA_BURST_SIZE 1
257
258/* Target specific defines for WMI-TLV firmware */
259#define TARGET_TLV_NUM_VDEVS 3
260#define TARGET_TLV_NUM_STATIONS 32
261#define TARGET_TLV_NUM_PEERS ((TARGET_TLV_NUM_STATIONS) + \
262 (TARGET_TLV_NUM_VDEVS) + \
263 2)
264#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
265#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
266
165/* Number of Copy Engines supported */ 267/* Number of Copy Engines supported */
166#define CE_COUNT 8 268#define CE_COUNT 8
167 269
@@ -192,7 +294,7 @@ struct ath10k_pktlog_hdr {
192/* as of IP3.7.1 */ 294/* as of IP3.7.1 */
193#define RTC_STATE_V_ON 3 295#define RTC_STATE_V_ON 3
194 296
195#define RTC_STATE_COLD_RESET_MASK 0x00000400 297#define RTC_STATE_COLD_RESET_MASK ar->regs->rtc_state_cold_reset_mask
196#define RTC_STATE_V_LSB 0 298#define RTC_STATE_V_LSB 0
197#define RTC_STATE_V_MASK 0x00000007 299#define RTC_STATE_V_MASK 0x00000007
198#define RTC_STATE_ADDRESS 0x0000 300#define RTC_STATE_ADDRESS 0x0000
@@ -201,12 +303,12 @@ struct ath10k_pktlog_hdr {
201#define PCIE_SOC_WAKE_RESET 0x00000000 303#define PCIE_SOC_WAKE_RESET 0x00000000
202#define SOC_GLOBAL_RESET_ADDRESS 0x0008 304#define SOC_GLOBAL_RESET_ADDRESS 0x0008
203 305
204#define RTC_SOC_BASE_ADDRESS 0x00004000 306#define RTC_SOC_BASE_ADDRESS ar->regs->rtc_soc_base_address
205#define RTC_WMAC_BASE_ADDRESS 0x00005000 307#define RTC_WMAC_BASE_ADDRESS ar->regs->rtc_wmac_base_address
206#define MAC_COEX_BASE_ADDRESS 0x00006000 308#define MAC_COEX_BASE_ADDRESS 0x00006000
207#define BT_COEX_BASE_ADDRESS 0x00007000 309#define BT_COEX_BASE_ADDRESS 0x00007000
208#define SOC_PCIE_BASE_ADDRESS 0x00008000 310#define SOC_PCIE_BASE_ADDRESS 0x00008000
209#define SOC_CORE_BASE_ADDRESS 0x00009000 311#define SOC_CORE_BASE_ADDRESS ar->regs->soc_core_base_address
210#define WLAN_UART_BASE_ADDRESS 0x0000c000 312#define WLAN_UART_BASE_ADDRESS 0x0000c000
211#define WLAN_SI_BASE_ADDRESS 0x00010000 313#define WLAN_SI_BASE_ADDRESS 0x00010000
212#define WLAN_GPIO_BASE_ADDRESS 0x00014000 314#define WLAN_GPIO_BASE_ADDRESS 0x00014000
@@ -215,23 +317,23 @@ struct ath10k_pktlog_hdr {
215#define EFUSE_BASE_ADDRESS 0x00030000 317#define EFUSE_BASE_ADDRESS 0x00030000
216#define FPGA_REG_BASE_ADDRESS 0x00039000 318#define FPGA_REG_BASE_ADDRESS 0x00039000
217#define WLAN_UART2_BASE_ADDRESS 0x00054c00 319#define WLAN_UART2_BASE_ADDRESS 0x00054c00
218#define CE_WRAPPER_BASE_ADDRESS 0x00057000 320#define CE_WRAPPER_BASE_ADDRESS ar->regs->ce_wrapper_base_address
219#define CE0_BASE_ADDRESS 0x00057400 321#define CE0_BASE_ADDRESS ar->regs->ce0_base_address
220#define CE1_BASE_ADDRESS 0x00057800 322#define CE1_BASE_ADDRESS ar->regs->ce1_base_address
221#define CE2_BASE_ADDRESS 0x00057c00 323#define CE2_BASE_ADDRESS ar->regs->ce2_base_address
222#define CE3_BASE_ADDRESS 0x00058000 324#define CE3_BASE_ADDRESS ar->regs->ce3_base_address
223#define CE4_BASE_ADDRESS 0x00058400 325#define CE4_BASE_ADDRESS ar->regs->ce4_base_address
224#define CE5_BASE_ADDRESS 0x00058800 326#define CE5_BASE_ADDRESS ar->regs->ce5_base_address
225#define CE6_BASE_ADDRESS 0x00058c00 327#define CE6_BASE_ADDRESS ar->regs->ce6_base_address
226#define CE7_BASE_ADDRESS 0x00059000 328#define CE7_BASE_ADDRESS ar->regs->ce7_base_address
227#define DBI_BASE_ADDRESS 0x00060000 329#define DBI_BASE_ADDRESS 0x00060000
228#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 330#define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000
229#define PCIE_LOCAL_BASE_ADDRESS 0x00080000 331#define PCIE_LOCAL_BASE_ADDRESS 0x00080000
230 332
231#define SOC_RESET_CONTROL_ADDRESS 0x00000000 333#define SOC_RESET_CONTROL_ADDRESS 0x00000000
232#define SOC_RESET_CONTROL_OFFSET 0x00000000 334#define SOC_RESET_CONTROL_OFFSET 0x00000000
233#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 335#define SOC_RESET_CONTROL_SI0_RST_MASK ar->regs->soc_reset_control_si0_rst_mask
234#define SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 336#define SOC_RESET_CONTROL_CE_RST_MASK ar->regs->soc_reset_control_ce_rst_mask
235#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 337#define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040
236#define SOC_CPU_CLOCK_OFFSET 0x00000020 338#define SOC_CPU_CLOCK_OFFSET 0x00000020
237#define SOC_CPU_CLOCK_STANDARD_LSB 0 339#define SOC_CPU_CLOCK_STANDARD_LSB 0
@@ -245,7 +347,7 @@ struct ath10k_pktlog_hdr {
245#define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 347#define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050
246#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 348#define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004
247 349
248#define SOC_CHIP_ID_ADDRESS 0x000000ec 350#define SOC_CHIP_ID_ADDRESS ar->regs->soc_chip_id_address
249#define SOC_CHIP_ID_REV_LSB 8 351#define SOC_CHIP_ID_REV_LSB 8
250#define SOC_CHIP_ID_REV_MASK 0x00000f00 352#define SOC_CHIP_ID_REV_MASK 0x00000f00
251 353
@@ -301,7 +403,7 @@ struct ath10k_pktlog_hdr {
301#define PCIE_INTR_ENABLE_ADDRESS 0x0008 403#define PCIE_INTR_ENABLE_ADDRESS 0x0008
302#define PCIE_INTR_CAUSE_ADDRESS 0x000c 404#define PCIE_INTR_CAUSE_ADDRESS 0x000c
303#define PCIE_INTR_CLR_ADDRESS 0x0014 405#define PCIE_INTR_CLR_ADDRESS 0x0014
304#define SCRATCH_3_ADDRESS 0x0030 406#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address
305#define CPU_INTR_ADDRESS 0x0010 407#define CPU_INTR_ADDRESS 0x0010
306 408
307/* Firmware indications to the Host via SCRATCH_3 register. */ 409/* Firmware indications to the Host via SCRATCH_3 register. */
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index c4005670cba2..d6d2f0f00caa 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 */
@@ -35,7 +37,7 @@
35static int ath10k_send_key(struct ath10k_vif *arvif, 37static int ath10k_send_key(struct ath10k_vif *arvif,
36 struct ieee80211_key_conf *key, 38 struct ieee80211_key_conf *key,
37 enum set_key_cmd cmd, 39 enum set_key_cmd cmd,
38 const u8 *macaddr) 40 const u8 *macaddr, bool def_idx)
39{ 41{
40 struct ath10k *ar = arvif->ar; 42 struct ath10k *ar = arvif->ar;
41 struct wmi_vdev_install_key_arg arg = { 43 struct wmi_vdev_install_key_arg arg = {
@@ -56,10 +58,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
56 switch (key->cipher) { 58 switch (key->cipher) {
57 case WLAN_CIPHER_SUITE_CCMP: 59 case WLAN_CIPHER_SUITE_CCMP:
58 arg.key_cipher = WMI_CIPHER_AES_CCM; 60 arg.key_cipher = WMI_CIPHER_AES_CCM;
59 if (arvif->vdev_type == WMI_VDEV_TYPE_AP) 61 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
60 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
61 else
62 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
63 break; 62 break;
64 case WLAN_CIPHER_SUITE_TKIP: 63 case WLAN_CIPHER_SUITE_TKIP:
65 arg.key_cipher = WMI_CIPHER_TKIP; 64 arg.key_cipher = WMI_CIPHER_TKIP;
@@ -73,7 +72,13 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
73 * Otherwise pairwise key must be set */ 72 * Otherwise pairwise key must be set */
74 if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN)) 73 if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN))
75 arg.key_flags = WMI_KEY_PAIRWISE; 74 arg.key_flags = WMI_KEY_PAIRWISE;
75
76 if (def_idx)
77 arg.key_flags |= WMI_KEY_TX_USAGE;
76 break; 78 break;
79 case WLAN_CIPHER_SUITE_AES_CMAC:
80 /* this one needs to be done in software */
81 return 1;
77 default: 82 default:
78 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher); 83 ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
79 return -EOPNOTSUPP; 84 return -EOPNOTSUPP;
@@ -90,7 +95,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
90static int ath10k_install_key(struct ath10k_vif *arvif, 95static int ath10k_install_key(struct ath10k_vif *arvif,
91 struct ieee80211_key_conf *key, 96 struct ieee80211_key_conf *key,
92 enum set_key_cmd cmd, 97 enum set_key_cmd cmd,
93 const u8 *macaddr) 98 const u8 *macaddr, bool def_idx)
94{ 99{
95 struct ath10k *ar = arvif->ar; 100 struct ath10k *ar = arvif->ar;
96 int ret; 101 int ret;
@@ -99,7 +104,7 @@ static int ath10k_install_key(struct ath10k_vif *arvif,
99 104
100 reinit_completion(&ar->install_key_done); 105 reinit_completion(&ar->install_key_done);
101 106
102 ret = ath10k_send_key(arvif, key, cmd, macaddr); 107 ret = ath10k_send_key(arvif, key, cmd, macaddr, def_idx);
103 if (ret) 108 if (ret)
104 return ret; 109 return ret;
105 110
@@ -117,6 +122,7 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
117 struct ath10k_peer *peer; 122 struct ath10k_peer *peer;
118 int ret; 123 int ret;
119 int i; 124 int i;
125 bool def_idx;
120 126
121 lockdep_assert_held(&ar->conf_mutex); 127 lockdep_assert_held(&ar->conf_mutex);
122 128
@@ -130,9 +136,14 @@ static int ath10k_install_peer_wep_keys(struct ath10k_vif *arvif,
130 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) { 136 for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) {
131 if (arvif->wep_keys[i] == NULL) 137 if (arvif->wep_keys[i] == NULL)
132 continue; 138 continue;
139 /* set TX_USAGE flag for default key id */
140 if (arvif->def_wep_key_idx == i)
141 def_idx = true;
142 else
143 def_idx = false;
133 144
134 ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, 145 ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY,
135 addr); 146 addr, def_idx);
136 if (ret) 147 if (ret)
137 return ret; 148 return ret;
138 149
@@ -166,8 +177,9 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
166 if (peer->keys[i] == NULL) 177 if (peer->keys[i] == NULL)
167 continue; 178 continue;
168 179
180 /* key flags are not required to delete the key */
169 ret = ath10k_install_key(arvif, peer->keys[i], 181 ret = ath10k_install_key(arvif, peer->keys[i],
170 DISABLE_KEY, addr); 182 DISABLE_KEY, addr, false);
171 if (ret && first_errno == 0) 183 if (ret && first_errno == 0)
172 first_errno = ret; 184 first_errno = ret;
173 185
@@ -241,8 +253,8 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
241 253
242 if (i == ARRAY_SIZE(peer->keys)) 254 if (i == ARRAY_SIZE(peer->keys))
243 break; 255 break;
244 256 /* key flags are not required to delete the key */
245 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr); 257 ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, false);
246 if (ret && first_errno == 0) 258 if (ret && first_errno == 0)
247 first_errno = ret; 259 first_errno = ret;
248 260
@@ -267,7 +279,10 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
267 case IEEE80211_BAND_2GHZ: 279 case IEEE80211_BAND_2GHZ:
268 switch (chandef->width) { 280 switch (chandef->width) {
269 case NL80211_CHAN_WIDTH_20_NOHT: 281 case NL80211_CHAN_WIDTH_20_NOHT:
270 phymode = MODE_11G; 282 if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
283 phymode = MODE_11B;
284 else
285 phymode = MODE_11G;
271 break; 286 break;
272 case NL80211_CHAN_WIDTH_20: 287 case NL80211_CHAN_WIDTH_20:
273 phymode = MODE_11NG_HT20; 288 phymode = MODE_11NG_HT20;
@@ -519,10 +534,14 @@ void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif)
519 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr, 534 dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr,
520 arvif->beacon->len, DMA_TO_DEVICE); 535 arvif->beacon->len, DMA_TO_DEVICE);
521 536
537 if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED &&
538 arvif->beacon_state != ATH10K_BEACON_SENT))
539 return;
540
522 dev_kfree_skb_any(arvif->beacon); 541 dev_kfree_skb_any(arvif->beacon);
523 542
524 arvif->beacon = NULL; 543 arvif->beacon = NULL;
525 arvif->beacon_sent = false; 544 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
526} 545}
527 546
528static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif) 547static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif)
@@ -962,6 +981,143 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
962 return ret; 981 return ret;
963} 982}
964 983
984static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif,
985 struct sk_buff *bcn)
986{
987 struct ath10k *ar = arvif->ar;
988 struct ieee80211_mgmt *mgmt;
989 const u8 *p2p_ie;
990 int ret;
991
992 if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
993 return 0;
994
995 if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO)
996 return 0;
997
998 mgmt = (void *)bcn->data;
999 p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1000 mgmt->u.beacon.variable,
1001 bcn->len - (mgmt->u.beacon.variable -
1002 bcn->data));
1003 if (!p2p_ie)
1004 return -ENOENT;
1005
1006 ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie);
1007 if (ret) {
1008 ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n",
1009 arvif->vdev_id, ret);
1010 return ret;
1011 }
1012
1013 return 0;
1014}
1015
1016static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui,
1017 u8 oui_type, size_t ie_offset)
1018{
1019 size_t len;
1020 const u8 *next;
1021 const u8 *end;
1022 u8 *ie;
1023
1024 if (WARN_ON(skb->len < ie_offset))
1025 return -EINVAL;
1026
1027 ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type,
1028 skb->data + ie_offset,
1029 skb->len - ie_offset);
1030 if (!ie)
1031 return -ENOENT;
1032
1033 len = ie[1] + 2;
1034 end = skb->data + skb->len;
1035 next = ie + len;
1036
1037 if (WARN_ON(next > end))
1038 return -EINVAL;
1039
1040 memmove(ie, next, end - next);
1041 skb_trim(skb, skb->len - len);
1042
1043 return 0;
1044}
1045
1046static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif)
1047{
1048 struct ath10k *ar = arvif->ar;
1049 struct ieee80211_hw *hw = ar->hw;
1050 struct ieee80211_vif *vif = arvif->vif;
1051 struct ieee80211_mutable_offsets offs = {};
1052 struct sk_buff *bcn;
1053 int ret;
1054
1055 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1056 return 0;
1057
1058 bcn = ieee80211_beacon_get_template(hw, vif, &offs);
1059 if (!bcn) {
1060 ath10k_warn(ar, "failed to get beacon template from mac80211\n");
1061 return -EPERM;
1062 }
1063
1064 ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn);
1065 if (ret) {
1066 ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret);
1067 kfree_skb(bcn);
1068 return ret;
1069 }
1070
1071 /* P2P IE is inserted by firmware automatically (as configured above)
1072 * so remove it from the base beacon template to avoid duplicate P2P
1073 * IEs in beacon frames.
1074 */
1075 ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P,
1076 offsetof(struct ieee80211_mgmt,
1077 u.beacon.variable));
1078
1079 ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0,
1080 0, NULL, 0);
1081 kfree_skb(bcn);
1082
1083 if (ret) {
1084 ath10k_warn(ar, "failed to submit beacon template command: %d\n",
1085 ret);
1086 return ret;
1087 }
1088
1089 return 0;
1090}
1091
1092static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif)
1093{
1094 struct ath10k *ar = arvif->ar;
1095 struct ieee80211_hw *hw = ar->hw;
1096 struct ieee80211_vif *vif = arvif->vif;
1097 struct sk_buff *prb;
1098 int ret;
1099
1100 if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map))
1101 return 0;
1102
1103 prb = ieee80211_proberesp_get(hw, vif);
1104 if (!prb) {
1105 ath10k_warn(ar, "failed to get probe resp template from mac80211\n");
1106 return -EPERM;
1107 }
1108
1109 ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb);
1110 kfree_skb(prb);
1111
1112 if (ret) {
1113 ath10k_warn(ar, "failed to submit probe resp template command: %d\n",
1114 ret);
1115 return ret;
1116 }
1117
1118 return 0;
1119}
1120
965static void ath10k_control_beaconing(struct ath10k_vif *arvif, 1121static void ath10k_control_beaconing(struct ath10k_vif *arvif,
966 struct ieee80211_bss_conf *info) 1122 struct ieee80211_bss_conf *info)
967{ 1123{
@@ -1046,28 +1202,85 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
1046 arvif->vdev_id, ret); 1202 arvif->vdev_id, ret);
1047} 1203}
1048 1204
1049/* 1205static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
1050 * Review this when mac80211 gains per-interface powersave support. 1206{
1051 */ 1207 struct ath10k *ar = arvif->ar;
1208 u32 param;
1209 u32 value;
1210 int ret;
1211
1212 lockdep_assert_held(&arvif->ar->conf_mutex);
1213
1214 if (arvif->u.sta.uapsd)
1215 value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
1216 else
1217 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
1218
1219 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
1220 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
1221 if (ret) {
1222 ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
1223 value, arvif->vdev_id, ret);
1224 return ret;
1225 }
1226
1227 return 0;
1228}
1229
1230static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
1231{
1232 struct ath10k *ar = arvif->ar;
1233 u32 param;
1234 u32 value;
1235 int ret;
1236
1237 lockdep_assert_held(&arvif->ar->conf_mutex);
1238
1239 if (arvif->u.sta.uapsd)
1240 value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
1241 else
1242 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
1243
1244 param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
1245 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
1246 param, value);
1247 if (ret) {
1248 ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
1249 value, arvif->vdev_id, ret);
1250 return ret;
1251 }
1252
1253 return 0;
1254}
1255
1052static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) 1256static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1053{ 1257{
1054 struct ath10k *ar = arvif->ar; 1258 struct ath10k *ar = arvif->ar;
1259 struct ieee80211_vif *vif = arvif->vif;
1055 struct ieee80211_conf *conf = &ar->hw->conf; 1260 struct ieee80211_conf *conf = &ar->hw->conf;
1056 enum wmi_sta_powersave_param param; 1261 enum wmi_sta_powersave_param param;
1057 enum wmi_sta_ps_mode psmode; 1262 enum wmi_sta_ps_mode psmode;
1058 int ret; 1263 int ret;
1264 int ps_timeout;
1059 1265
1060 lockdep_assert_held(&arvif->ar->conf_mutex); 1266 lockdep_assert_held(&arvif->ar->conf_mutex);
1061 1267
1062 if (arvif->vif->type != NL80211_IFTYPE_STATION) 1268 if (arvif->vif->type != NL80211_IFTYPE_STATION)
1063 return 0; 1269 return 0;
1064 1270
1065 if (conf->flags & IEEE80211_CONF_PS) { 1271 if (vif->bss_conf.ps) {
1066 psmode = WMI_STA_PS_MODE_ENABLED; 1272 psmode = WMI_STA_PS_MODE_ENABLED;
1067 param = WMI_STA_PS_PARAM_INACTIVITY_TIME; 1273 param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
1068 1274
1275 ps_timeout = conf->dynamic_ps_timeout;
1276 if (ps_timeout == 0) {
1277 /* Firmware doesn't like 0 */
1278 ps_timeout = ieee80211_tu_to_usec(
1279 vif->bss_conf.beacon_int) / 1000;
1280 }
1281
1069 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, 1282 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
1070 conf->dynamic_ps_timeout); 1283 ps_timeout);
1071 if (ret) { 1284 if (ret) {
1072 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n", 1285 ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
1073 arvif->vdev_id, ret); 1286 arvif->vdev_id, ret);
@@ -1090,6 +1303,38 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
1090 return 0; 1303 return 0;
1091} 1304}
1092 1305
1306static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif)
1307{
1308 struct ath10k *ar = arvif->ar;
1309 struct wmi_sta_keepalive_arg arg = {};
1310 int ret;
1311
1312 lockdep_assert_held(&arvif->ar->conf_mutex);
1313
1314 if (arvif->vdev_type != WMI_VDEV_TYPE_STA)
1315 return 0;
1316
1317 if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map))
1318 return 0;
1319
1320 /* Some firmware revisions have a bug and ignore the `enabled` field.
1321 * Instead use the interval to disable the keepalive.
1322 */
1323 arg.vdev_id = arvif->vdev_id;
1324 arg.enabled = 1;
1325 arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME;
1326 arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE;
1327
1328 ret = ath10k_wmi_sta_keepalive(ar, &arg);
1329 if (ret) {
1330 ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n",
1331 arvif->vdev_id, ret);
1332 return ret;
1333 }
1334
1335 return 0;
1336}
1337
1093/**********************/ 1338/**********************/
1094/* Station management */ 1339/* Station management */
1095/**********************/ 1340/**********************/
@@ -1358,6 +1603,10 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
1358 return; 1603 return;
1359 1604
1360 arg->peer_flags |= WMI_PEER_VHT; 1605 arg->peer_flags |= WMI_PEER_VHT;
1606
1607 if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ)
1608 arg->peer_flags |= WMI_PEER_VHT_2G;
1609
1361 arg->peer_vht_caps = vht_cap->cap; 1610 arg->peer_vht_caps = vht_cap->cap;
1362 1611
1363 ampdu_factor = (vht_cap->cap & 1612 ampdu_factor = (vht_cap->cap &
@@ -1409,9 +1658,22 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
1409 if (vif->bss_conf.qos) 1658 if (vif->bss_conf.qos)
1410 arg->peer_flags |= WMI_PEER_QOS; 1659 arg->peer_flags |= WMI_PEER_QOS;
1411 break; 1660 break;
1661 case WMI_VDEV_TYPE_IBSS:
1662 if (sta->wme)
1663 arg->peer_flags |= WMI_PEER_QOS;
1664 break;
1412 default: 1665 default:
1413 break; 1666 break;
1414 } 1667 }
1668
1669 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
1670 sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
1671}
1672
1673static bool ath10k_mac_sta_has_11g_rates(struct ieee80211_sta *sta)
1674{
1675 /* First 4 rates in ath10k_rates are CCK (11b) rates. */
1676 return sta->supp_rates[IEEE80211_BAND_2GHZ] >> 4;
1415} 1677}
1416 1678
1417static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, 1679static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
@@ -1423,13 +1685,20 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
1423 1685
1424 switch (ar->hw->conf.chandef.chan->band) { 1686 switch (ar->hw->conf.chandef.chan->band) {
1425 case IEEE80211_BAND_2GHZ: 1687 case IEEE80211_BAND_2GHZ:
1426 if (sta->ht_cap.ht_supported) { 1688 if (sta->vht_cap.vht_supported) {
1689 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
1690 phymode = MODE_11AC_VHT40;
1691 else
1692 phymode = MODE_11AC_VHT20;
1693 } else if (sta->ht_cap.ht_supported) {
1427 if (sta->bandwidth == IEEE80211_STA_RX_BW_40) 1694 if (sta->bandwidth == IEEE80211_STA_RX_BW_40)
1428 phymode = MODE_11NG_HT40; 1695 phymode = MODE_11NG_HT40;
1429 else 1696 else
1430 phymode = MODE_11NG_HT20; 1697 phymode = MODE_11NG_HT20;
1431 } else { 1698 } else if (ath10k_mac_sta_has_11g_rates(sta)) {
1432 phymode = MODE_11G; 1699 phymode = MODE_11G;
1700 } else {
1701 phymode = MODE_11B;
1433 } 1702 }
1434 1703
1435 break; 1704 break;
@@ -1603,7 +1872,8 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
1603 ath10k_warn(ar, "faield to down vdev %i: %d\n", 1872 ath10k_warn(ar, "faield to down vdev %i: %d\n",
1604 arvif->vdev_id, ret); 1873 arvif->vdev_id, ret);
1605 1874
1606 arvif->def_wep_key_idx = 0; 1875 arvif->def_wep_key_idx = -1;
1876
1607 arvif->is_up = false; 1877 arvif->is_up = false;
1608} 1878}
1609 1879
@@ -1662,11 +1932,14 @@ static int ath10k_station_assoc(struct ath10k *ar,
1662 } 1932 }
1663 } 1933 }
1664 1934
1665 ret = ath10k_install_peer_wep_keys(arvif, sta->addr); 1935 /* Plumb cached keys only for static WEP */
1666 if (ret) { 1936 if (arvif->def_wep_key_idx != -1) {
1667 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", 1937 ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
1668 arvif->vdev_id, ret); 1938 if (ret) {
1669 return ret; 1939 ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
1940 arvif->vdev_id, ret);
1941 return ret;
1942 }
1670 } 1943 }
1671 } 1944 }
1672 1945
@@ -1931,75 +2204,13 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
1931 * used only for CQM purposes (e.g. hostapd station keepalive ping) so 2204 * used only for CQM purposes (e.g. hostapd station keepalive ping) so
1932 * it is safe to downgrade to NullFunc. 2205 * it is safe to downgrade to NullFunc.
1933 */ 2206 */
2207 hdr = (void *)skb->data;
1934 if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { 2208 if (ieee80211_is_qos_nullfunc(hdr->frame_control)) {
1935 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 2209 hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1936 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST; 2210 cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
1937 } 2211 }
1938} 2212}
1939 2213
1940static void ath10k_tx_wep_key_work(struct work_struct *work)
1941{
1942 struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
1943 wep_key_work);
1944 struct ath10k *ar = arvif->ar;
1945 int ret, keyidx = arvif->def_wep_key_newidx;
1946
1947 mutex_lock(&arvif->ar->conf_mutex);
1948
1949 if (arvif->ar->state != ATH10K_STATE_ON)
1950 goto unlock;
1951
1952 if (arvif->def_wep_key_idx == keyidx)
1953 goto unlock;
1954
1955 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
1956 arvif->vdev_id, keyidx);
1957
1958 ret = ath10k_wmi_vdev_set_param(arvif->ar,
1959 arvif->vdev_id,
1960 arvif->ar->wmi.vdev_param->def_keyid,
1961 keyidx);
1962 if (ret) {
1963 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
1964 arvif->vdev_id,
1965 ret);
1966 goto unlock;
1967 }
1968
1969 arvif->def_wep_key_idx = keyidx;
1970
1971unlock:
1972 mutex_unlock(&arvif->ar->conf_mutex);
1973}
1974
1975static void ath10k_tx_h_update_wep_key(struct ieee80211_vif *vif,
1976 struct ieee80211_key_conf *key,
1977 struct sk_buff *skb)
1978{
1979 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
1980 struct ath10k *ar = arvif->ar;
1981 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1982
1983 if (!ieee80211_has_protected(hdr->frame_control))
1984 return;
1985
1986 if (!key)
1987 return;
1988
1989 if (key->cipher != WLAN_CIPHER_SUITE_WEP40 &&
1990 key->cipher != WLAN_CIPHER_SUITE_WEP104)
1991 return;
1992
1993 if (key->keyidx == arvif->def_wep_key_idx)
1994 return;
1995
1996 /* FIXME: Most likely a few frames will be TXed with an old key. Simply
1997 * queueing frames until key index is updated is not an option because
1998 * sk_buff may need more processing to be done, e.g. offchannel */
1999 arvif->def_wep_key_newidx = key->keyidx;
2000 ieee80211_queue_work(ar->hw, &arvif->wep_key_work);
2001}
2002
2003static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, 2214static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
2004 struct ieee80211_vif *vif, 2215 struct ieee80211_vif *vif,
2005 struct sk_buff *skb) 2216 struct sk_buff *skb)
@@ -2151,7 +2362,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
2151 2362
2152 ret = wait_for_completion_timeout(&ar->offchan_tx_completed, 2363 ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
2153 3 * HZ); 2364 3 * HZ);
2154 if (ret <= 0) 2365 if (ret == 0)
2155 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n", 2366 ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
2156 skb); 2367 skb);
2157 2368
@@ -2213,6 +2424,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
2213 case ATH10K_SCAN_RUNNING: 2424 case ATH10K_SCAN_RUNNING:
2214 if (ar->scan.is_roc) 2425 if (ar->scan.is_roc)
2215 ieee80211_remain_on_channel_expired(ar->hw); 2426 ieee80211_remain_on_channel_expired(ar->hw);
2427 /* fall through */
2216 case ATH10K_SCAN_ABORTING: 2428 case ATH10K_SCAN_ABORTING:
2217 if (!ar->scan.is_roc) 2429 if (!ar->scan.is_roc)
2218 ieee80211_scan_completed(ar->hw, 2430 ieee80211_scan_completed(ar->hw,
@@ -2359,7 +2571,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
2359 struct ath10k *ar = hw->priv; 2571 struct ath10k *ar = hw->priv;
2360 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2572 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2361 struct ieee80211_vif *vif = info->control.vif; 2573 struct ieee80211_vif *vif = info->control.vif;
2362 struct ieee80211_key_conf *key = info->control.hw_key;
2363 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 2574 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2364 2575
2365 /* We should disable CCK RATE due to P2P */ 2576 /* We should disable CCK RATE due to P2P */
@@ -2373,7 +2584,6 @@ static void ath10k_tx(struct ieee80211_hw *hw,
2373 /* it makes no sense to process injected frames like that */ 2584 /* it makes no sense to process injected frames like that */
2374 if (vif && vif->type != NL80211_IFTYPE_MONITOR) { 2585 if (vif && vif->type != NL80211_IFTYPE_MONITOR) {
2375 ath10k_tx_h_nwifi(hw, skb); 2586 ath10k_tx_h_nwifi(hw, skb);
2376 ath10k_tx_h_update_wep_key(vif, key, skb);
2377 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb); 2587 ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb);
2378 ath10k_tx_h_seq_no(vif, skb); 2588 ath10k_tx_h_seq_no(vif, skb);
2379 } 2589 }
@@ -2871,6 +3081,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2871 int bit; 3081 int bit;
2872 u32 vdev_param; 3082 u32 vdev_param;
2873 3083
3084 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
3085
2874 mutex_lock(&ar->conf_mutex); 3086 mutex_lock(&ar->conf_mutex);
2875 3087
2876 memset(arvif, 0, sizeof(*arvif)); 3088 memset(arvif, 0, sizeof(*arvif));
@@ -2878,7 +3090,6 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2878 arvif->ar = ar; 3090 arvif->ar = ar;
2879 arvif->vif = vif; 3091 arvif->vif = vif;
2880 3092
2881 INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work);
2882 INIT_LIST_HEAD(&arvif->list); 3093 INIT_LIST_HEAD(&arvif->list);
2883 3094
2884 if (ar->free_vdev_map == 0) { 3095 if (ar->free_vdev_map == 0) {
@@ -2894,10 +3105,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2894 arvif->vdev_id = bit; 3105 arvif->vdev_id = bit;
2895 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; 3106 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
2896 3107
2897 if (ar->p2p)
2898 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
2899
2900 switch (vif->type) { 3108 switch (vif->type) {
3109 case NL80211_IFTYPE_P2P_DEVICE:
3110 arvif->vdev_type = WMI_VDEV_TYPE_STA;
3111 arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
3112 break;
2901 case NL80211_IFTYPE_UNSPECIFIED: 3113 case NL80211_IFTYPE_UNSPECIFIED:
2902 case NL80211_IFTYPE_STATION: 3114 case NL80211_IFTYPE_STATION:
2903 arvif->vdev_type = WMI_VDEV_TYPE_STA; 3115 arvif->vdev_type = WMI_VDEV_TYPE_STA;
@@ -2966,15 +3178,18 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
2966 ar->free_vdev_map &= ~(1LL << arvif->vdev_id); 3178 ar->free_vdev_map &= ~(1LL << arvif->vdev_id);
2967 list_add(&arvif->list, &ar->arvifs); 3179 list_add(&arvif->list, &ar->arvifs);
2968 3180
2969 vdev_param = ar->wmi.vdev_param->def_keyid; 3181 /* It makes no sense to have firmware do keepalives. mac80211 already
2970 ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, 3182 * takes care of this with idle connection polling.
2971 arvif->def_wep_key_idx); 3183 */
3184 ret = ath10k_mac_vif_disable_keepalive(arvif);
2972 if (ret) { 3185 if (ret) {
2973 ath10k_warn(ar, "failed to set vdev %i default key id: %d\n", 3186 ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n",
2974 arvif->vdev_id, ret); 3187 arvif->vdev_id, ret);
2975 goto err_vdev_delete; 3188 goto err_vdev_delete;
2976 } 3189 }
2977 3190
3191 arvif->def_wep_key_idx = -1;
3192
2978 vdev_param = ar->wmi.vdev_param->tx_encap_type; 3193 vdev_param = ar->wmi.vdev_param->tx_encap_type;
2979 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, 3194 ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
2980 ATH10K_HW_TXRX_NATIVE_WIFI); 3195 ATH10K_HW_TXRX_NATIVE_WIFI);
@@ -3026,22 +3241,16 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
3026 goto err_peer_delete; 3241 goto err_peer_delete;
3027 } 3242 }
3028 3243
3029 param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; 3244 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
3030 value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
3031 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
3032 param, value);
3033 if (ret) { 3245 if (ret) {
3034 ath10k_warn(ar, "failed to set vdev %i TX wake thresh: %d\n", 3246 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
3035 arvif->vdev_id, ret); 3247 arvif->vdev_id, ret);
3036 goto err_peer_delete; 3248 goto err_peer_delete;
3037 } 3249 }
3038 3250
3039 param = WMI_STA_PS_PARAM_PSPOLL_COUNT; 3251 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
3040 value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
3041 ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
3042 param, value);
3043 if (ret) { 3252 if (ret) {
3044 ath10k_warn(ar, "failed to set vdev %i PSPOLL count: %d\n", 3253 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
3045 arvif->vdev_id, ret); 3254 arvif->vdev_id, ret);
3046 goto err_peer_delete; 3255 goto err_peer_delete;
3047 } 3256 }
@@ -3099,8 +3308,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
3099 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 3308 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3100 int ret; 3309 int ret;
3101 3310
3102 cancel_work_sync(&arvif->wep_key_work);
3103
3104 mutex_lock(&ar->conf_mutex); 3311 mutex_lock(&ar->conf_mutex);
3105 3312
3106 spin_lock_bh(&ar->data_lock); 3313 spin_lock_bh(&ar->data_lock);
@@ -3211,9 +3418,21 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3211 if (ret) 3418 if (ret)
3212 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n", 3419 ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
3213 arvif->vdev_id, ret); 3420 arvif->vdev_id, ret);
3421
3422 ret = ath10k_mac_setup_bcn_tmpl(arvif);
3423 if (ret)
3424 ath10k_warn(ar, "failed to update beacon template: %d\n",
3425 ret);
3214 } 3426 }
3215 3427
3216 if (changed & BSS_CHANGED_BEACON_INFO) { 3428 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
3429 ret = ath10k_mac_setup_prb_tmpl(arvif);
3430 if (ret)
3431 ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n",
3432 arvif->vdev_id, ret);
3433 }
3434
3435 if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
3217 arvif->dtim_period = info->dtim_period; 3436 arvif->dtim_period = info->dtim_period;
3218 3437
3219 ath10k_dbg(ar, ATH10K_DBG_MAC, 3438 ath10k_dbg(ar, ATH10K_DBG_MAC,
@@ -3314,6 +3533,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
3314 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); 3533 ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
3315 } 3534 }
3316 3535
3536 if (changed & BSS_CHANGED_PS) {
3537 ret = ath10k_mac_vif_setup_ps(arvif);
3538 if (ret)
3539 ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
3540 arvif->vdev_id, ret);
3541 }
3542
3317 mutex_unlock(&ar->conf_mutex); 3543 mutex_unlock(&ar->conf_mutex);
3318} 3544}
3319 3545
@@ -3453,6 +3679,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3453 const u8 *peer_addr; 3679 const u8 *peer_addr;
3454 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 || 3680 bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
3455 key->cipher == WLAN_CIPHER_SUITE_WEP104; 3681 key->cipher == WLAN_CIPHER_SUITE_WEP104;
3682 bool def_idx = false;
3456 int ret = 0; 3683 int ret = 0;
3457 3684
3458 if (key->keyidx > WMI_MAX_KEY_INDEX) 3685 if (key->keyidx > WMI_MAX_KEY_INDEX)
@@ -3498,7 +3725,14 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3498 ath10k_clear_vdev_key(arvif, key); 3725 ath10k_clear_vdev_key(arvif, key);
3499 } 3726 }
3500 3727
3501 ret = ath10k_install_key(arvif, key, cmd, peer_addr); 3728 /* set TX_USAGE flag for all the keys incase of dot1x-WEP. For
3729 * static WEP, do not set this flag for the keys whose key id
3730 * is greater than default key id.
3731 */
3732 if (arvif->def_wep_key_idx == -1)
3733 def_idx = true;
3734
3735 ret = ath10k_install_key(arvif, key, cmd, peer_addr, def_idx);
3502 if (ret) { 3736 if (ret) {
3503 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", 3737 ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
3504 arvif->vdev_id, peer_addr, ret); 3738 arvif->vdev_id, peer_addr, ret);
@@ -3523,6 +3757,39 @@ exit:
3523 return ret; 3757 return ret;
3524} 3758}
3525 3759
3760static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw,
3761 struct ieee80211_vif *vif,
3762 int keyidx)
3763{
3764 struct ath10k *ar = hw->priv;
3765 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3766 int ret;
3767
3768 mutex_lock(&arvif->ar->conf_mutex);
3769
3770 if (arvif->ar->state != ATH10K_STATE_ON)
3771 goto unlock;
3772
3773 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
3774 arvif->vdev_id, keyidx);
3775
3776 ret = ath10k_wmi_vdev_set_param(arvif->ar,
3777 arvif->vdev_id,
3778 arvif->ar->wmi.vdev_param->def_keyid,
3779 keyidx);
3780
3781 if (ret) {
3782 ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
3783 arvif->vdev_id,
3784 ret);
3785 goto unlock;
3786 }
3787
3788 arvif->def_wep_key_idx = keyidx;
3789unlock:
3790 mutex_unlock(&arvif->ar->conf_mutex);
3791}
3792
3526static void ath10k_sta_rc_update_wk(struct work_struct *wk) 3793static void ath10k_sta_rc_update_wk(struct work_struct *wk)
3527{ 3794{
3528 struct ath10k *ar; 3795 struct ath10k *ar;
@@ -3583,8 +3850,9 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
3583 sta->addr, smps, err); 3850 sta->addr, smps, err);
3584 } 3851 }
3585 3852
3586 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { 3853 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
3587 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", 3854 changed & IEEE80211_RC_NSS_CHANGED) {
3855 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
3588 sta->addr); 3856 sta->addr);
3589 3857
3590 err = ath10k_station_assoc(ar, arvif->vif, sta, true); 3858 err = ath10k_station_assoc(ar, arvif->vif, sta, true);
@@ -3757,6 +4025,8 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
3757 u16 ac, bool enable) 4025 u16 ac, bool enable)
3758{ 4026{
3759 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 4027 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
4028 struct wmi_sta_uapsd_auto_trig_arg arg = {};
4029 u32 prio = 0, acc = 0;
3760 u32 value = 0; 4030 u32 value = 0;
3761 int ret = 0; 4031 int ret = 0;
3762 4032
@@ -3769,18 +4039,26 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
3769 case IEEE80211_AC_VO: 4039 case IEEE80211_AC_VO:
3770 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN | 4040 value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN |
3771 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN; 4041 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN;
4042 prio = 7;
4043 acc = 3;
3772 break; 4044 break;
3773 case IEEE80211_AC_VI: 4045 case IEEE80211_AC_VI:
3774 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN | 4046 value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN |
3775 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN; 4047 WMI_STA_PS_UAPSD_AC2_TRIGGER_EN;
4048 prio = 5;
4049 acc = 2;
3776 break; 4050 break;
3777 case IEEE80211_AC_BE: 4051 case IEEE80211_AC_BE:
3778 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN | 4052 value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN |
3779 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN; 4053 WMI_STA_PS_UAPSD_AC1_TRIGGER_EN;
4054 prio = 2;
4055 acc = 1;
3780 break; 4056 break;
3781 case IEEE80211_AC_BK: 4057 case IEEE80211_AC_BK:
3782 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN | 4058 value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN |
3783 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN; 4059 WMI_STA_PS_UAPSD_AC0_TRIGGER_EN;
4060 prio = 0;
4061 acc = 0;
3784 break; 4062 break;
3785 } 4063 }
3786 4064
@@ -3808,6 +4086,43 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
3808 if (ret) 4086 if (ret)
3809 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret); 4087 ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
3810 4088
4089 ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
4090 if (ret) {
4091 ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
4092 arvif->vdev_id, ret);
4093 return ret;
4094 }
4095
4096 ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
4097 if (ret) {
4098 ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
4099 arvif->vdev_id, ret);
4100 return ret;
4101 }
4102
4103 if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) ||
4104 test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) {
4105 /* Only userspace can make an educated decision when to send
4106 * trigger frame. The following effectively disables u-UAPSD
4107 * autotrigger in firmware (which is enabled by default
4108 * provided the autotrigger service is available).
4109 */
4110
4111 arg.wmm_ac = acc;
4112 arg.user_priority = prio;
4113 arg.service_interval = 0;
4114 arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
4115 arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC;
4116
4117 ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id,
4118 arvif->bssid, &arg, 1);
4119 if (ret) {
4120 ath10k_warn(ar, "failed to set uapsd auto trigger %d\n",
4121 ret);
4122 return ret;
4123 }
4124 }
4125
3811exit: 4126exit:
3812 return ret; 4127 return ret;
3813} 4128}
@@ -3817,6 +4132,7 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw,
3817 const struct ieee80211_tx_queue_params *params) 4132 const struct ieee80211_tx_queue_params *params)
3818{ 4133{
3819 struct ath10k *ar = hw->priv; 4134 struct ath10k *ar = hw->priv;
4135 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3820 struct wmi_wmm_params_arg *p = NULL; 4136 struct wmi_wmm_params_arg *p = NULL;
3821 int ret; 4137 int ret;
3822 4138
@@ -3824,16 +4140,16 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw,
3824 4140
3825 switch (ac) { 4141 switch (ac) {
3826 case IEEE80211_AC_VO: 4142 case IEEE80211_AC_VO:
3827 p = &ar->wmm_params.ac_vo; 4143 p = &arvif->wmm_params.ac_vo;
3828 break; 4144 break;
3829 case IEEE80211_AC_VI: 4145 case IEEE80211_AC_VI:
3830 p = &ar->wmm_params.ac_vi; 4146 p = &arvif->wmm_params.ac_vi;
3831 break; 4147 break;
3832 case IEEE80211_AC_BE: 4148 case IEEE80211_AC_BE:
3833 p = &ar->wmm_params.ac_be; 4149 p = &arvif->wmm_params.ac_be;
3834 break; 4150 break;
3835 case IEEE80211_AC_BK: 4151 case IEEE80211_AC_BK:
3836 p = &ar->wmm_params.ac_bk; 4152 p = &arvif->wmm_params.ac_bk;
3837 break; 4153 break;
3838 } 4154 }
3839 4155
@@ -3853,11 +4169,23 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw,
3853 */ 4169 */
3854 p->txop = params->txop * 32; 4170 p->txop = params->txop * 32;
3855 4171
3856 /* FIXME: FW accepts wmm params per hw, not per vif */ 4172 if (ar->wmi.ops->gen_vdev_wmm_conf) {
3857 ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params); 4173 ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id,
3858 if (ret) { 4174 &arvif->wmm_params);
3859 ath10k_warn(ar, "failed to set wmm params: %d\n", ret); 4175 if (ret) {
3860 goto exit; 4176 ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n",
4177 arvif->vdev_id, ret);
4178 goto exit;
4179 }
4180 } else {
4181 /* This won't work well with multi-interface cases but it's
4182 * better than nothing.
4183 */
4184 ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params);
4185 if (ret) {
4186 ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
4187 goto exit;
4188 }
3861 } 4189 }
3862 4190
3863 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd); 4191 ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
@@ -3989,29 +4317,6 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3989 return ret; 4317 return ret;
3990} 4318}
3991 4319
3992static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
3993{
3994 struct ath10k *ar = hw->priv;
3995 struct ath10k_vif *arvif;
3996 int ret = 0;
3997
3998 mutex_lock(&ar->conf_mutex);
3999 list_for_each_entry(arvif, &ar->arvifs, list) {
4000 ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n",
4001 arvif->vdev_id, value);
4002
4003 ret = ath10k_mac_set_frag(arvif, value);
4004 if (ret) {
4005 ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n",
4006 arvif->vdev_id, ret);
4007 break;
4008 }
4009 }
4010 mutex_unlock(&ar->conf_mutex);
4011
4012 return ret;
4013}
4014
4015static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4320static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4016 u32 queues, bool drop) 4321 u32 queues, bool drop)
4017{ 4322{
@@ -4650,12 +4955,12 @@ static const struct ieee80211_ops ath10k_ops = {
4650 .hw_scan = ath10k_hw_scan, 4955 .hw_scan = ath10k_hw_scan,
4651 .cancel_hw_scan = ath10k_cancel_hw_scan, 4956 .cancel_hw_scan = ath10k_cancel_hw_scan,
4652 .set_key = ath10k_set_key, 4957 .set_key = ath10k_set_key,
4958 .set_default_unicast_key = ath10k_set_default_unicast_key,
4653 .sta_state = ath10k_sta_state, 4959 .sta_state = ath10k_sta_state,
4654 .conf_tx = ath10k_conf_tx, 4960 .conf_tx = ath10k_conf_tx,
4655 .remain_on_channel = ath10k_remain_on_channel, 4961 .remain_on_channel = ath10k_remain_on_channel,
4656 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel, 4962 .cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
4657 .set_rts_threshold = ath10k_set_rts_threshold, 4963 .set_rts_threshold = ath10k_set_rts_threshold,
4658 .set_frag_threshold = ath10k_set_frag_threshold,
4659 .flush = ath10k_flush, 4964 .flush = ath10k_flush,
4660 .tx_last_beacon = ath10k_tx_last_beacon, 4965 .tx_last_beacon = ath10k_tx_last_beacon,
4661 .set_antenna = ath10k_set_antenna, 4966 .set_antenna = ath10k_set_antenna,
@@ -4676,6 +4981,9 @@ static const struct ieee80211_ops ath10k_ops = {
4676 .suspend = ath10k_suspend, 4981 .suspend = ath10k_suspend,
4677 .resume = ath10k_resume, 4982 .resume = ath10k_resume,
4678#endif 4983#endif
4984#ifdef CONFIG_MAC80211_DEBUGFS
4985 .sta_add_debugfs = ath10k_sta_add_debugfs,
4986#endif
4679}; 4987};
4680 4988
4681#define RATETAB_ENT(_rate, _rateid, _flags) { \ 4989#define RATETAB_ENT(_rate, _rateid, _flags) { \
@@ -4746,6 +5054,9 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
4746 CHAN5G(165, 5825, 0), 5054 CHAN5G(165, 5825, 0),
4747}; 5055};
4748 5056
5057/* Note: Be careful if you re-order these. There is code which depends on this
5058 * ordering.
5059 */
4749static struct ieee80211_rate ath10k_rates[] = { 5060static struct ieee80211_rate ath10k_rates[] = {
4750 /* CCK */ 5061 /* CCK */
4751 RATETAB_ENT(10, 0x82, 0), 5062 RATETAB_ENT(10, 0x82, 0),
@@ -4799,6 +5110,10 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
4799 .types = BIT(NL80211_IFTYPE_P2P_GO) 5110 .types = BIT(NL80211_IFTYPE_P2P_GO)
4800 }, 5111 },
4801 { 5112 {
5113 .max = 1,
5114 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
5115 },
5116 {
4802 .max = 7, 5117 .max = 7,
4803 .types = BIT(NL80211_IFTYPE_AP) 5118 .types = BIT(NL80211_IFTYPE_AP)
4804 }, 5119 },
@@ -4956,6 +5271,13 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
4956 5271
4957int ath10k_mac_register(struct ath10k *ar) 5272int ath10k_mac_register(struct ath10k *ar)
4958{ 5273{
5274 static const u32 cipher_suites[] = {
5275 WLAN_CIPHER_SUITE_WEP40,
5276 WLAN_CIPHER_SUITE_WEP104,
5277 WLAN_CIPHER_SUITE_TKIP,
5278 WLAN_CIPHER_SUITE_CCMP,
5279 WLAN_CIPHER_SUITE_AES_CMAC,
5280 };
4959 struct ieee80211_supported_band *band; 5281 struct ieee80211_supported_band *band;
4960 struct ieee80211_sta_vht_cap vht_cap; 5282 struct ieee80211_sta_vht_cap vht_cap;
4961 struct ieee80211_sta_ht_cap ht_cap; 5283 struct ieee80211_sta_ht_cap ht_cap;
@@ -4985,7 +5307,8 @@ int ath10k_mac_register(struct ath10k *ar)
4985 band->bitrates = ath10k_g_rates; 5307 band->bitrates = ath10k_g_rates;
4986 band->ht_cap = ht_cap; 5308 band->ht_cap = ht_cap;
4987 5309
4988 /* vht is not supported in 2.4 GHz */ 5310 /* Enable the VHT support at 2.4 GHz */
5311 band->vht_cap = vht_cap;
4989 5312
4990 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band; 5313 ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
4991 } 5314 }
@@ -5018,18 +5341,19 @@ int ath10k_mac_register(struct ath10k *ar)
5018 5341
5019 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) 5342 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
5020 ar->hw->wiphy->interface_modes |= 5343 ar->hw->wiphy->interface_modes |=
5344 BIT(NL80211_IFTYPE_P2P_DEVICE) |
5021 BIT(NL80211_IFTYPE_P2P_CLIENT) | 5345 BIT(NL80211_IFTYPE_P2P_CLIENT) |
5022 BIT(NL80211_IFTYPE_P2P_GO); 5346 BIT(NL80211_IFTYPE_P2P_GO);
5023 5347
5024 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | 5348 ar->hw->flags = IEEE80211_HW_SIGNAL_DBM |
5025 IEEE80211_HW_SUPPORTS_PS | 5349 IEEE80211_HW_SUPPORTS_PS |
5026 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 5350 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
5027 IEEE80211_HW_SUPPORTS_UAPSD |
5028 IEEE80211_HW_MFP_CAPABLE | 5351 IEEE80211_HW_MFP_CAPABLE |
5029 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 5352 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
5030 IEEE80211_HW_HAS_RATE_CONTROL | 5353 IEEE80211_HW_HAS_RATE_CONTROL |
5031 IEEE80211_HW_AP_LINK_PS | 5354 IEEE80211_HW_AP_LINK_PS |
5032 IEEE80211_HW_SPECTRUM_MGMT; 5355 IEEE80211_HW_SPECTRUM_MGMT |
5356 IEEE80211_HW_SW_CRYPTO_CONTROL;
5033 5357
5034 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; 5358 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
5035 5359
@@ -5049,6 +5373,19 @@ int ath10k_mac_register(struct ath10k *ar)
5049 5373
5050 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; 5374 ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
5051 5375
5376 if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) {
5377 ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
5378
5379 /* Firmware delivers WPS/P2P Probe Requests frames to driver so
5380 * that userspace (e.g. wpa_supplicant/hostapd) can generate
5381 * correct Probe Responses. This is more of a hack advert..
5382 */
5383 ar->hw->wiphy->probe_resp_offload |=
5384 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
5385 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
5386 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
5387 }
5388
5052 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 5389 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5053 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 5390 ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
5054 ar->hw->wiphy->max_remain_on_channel_duration = 5000; 5391 ar->hw->wiphy->max_remain_on_channel_duration = 5000;
@@ -5062,16 +5399,26 @@ int ath10k_mac_register(struct ath10k *ar)
5062 */ 5399 */
5063 ar->hw->queues = 4; 5400 ar->hw->queues = 4;
5064 5401
5065 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 5402 switch (ar->wmi.op_version) {
5066 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; 5403 case ATH10K_FW_WMI_OP_VERSION_MAIN:
5067 ar->hw->wiphy->n_iface_combinations = 5404 case ATH10K_FW_WMI_OP_VERSION_TLV:
5068 ARRAY_SIZE(ath10k_10x_if_comb);
5069 } else {
5070 ar->hw->wiphy->iface_combinations = ath10k_if_comb; 5405 ar->hw->wiphy->iface_combinations = ath10k_if_comb;
5071 ar->hw->wiphy->n_iface_combinations = 5406 ar->hw->wiphy->n_iface_combinations =
5072 ARRAY_SIZE(ath10k_if_comb); 5407 ARRAY_SIZE(ath10k_if_comb);
5073
5074 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 5408 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
5409 break;
5410 case ATH10K_FW_WMI_OP_VERSION_10_1:
5411 case ATH10K_FW_WMI_OP_VERSION_10_2:
5412 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
5413 ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
5414 ar->hw->wiphy->n_iface_combinations =
5415 ARRAY_SIZE(ath10k_10x_if_comb);
5416 break;
5417 case ATH10K_FW_WMI_OP_VERSION_UNSET:
5418 case ATH10K_FW_WMI_OP_VERSION_MAX:
5419 WARN_ON(1);
5420 ret = -EINVAL;
5421 goto err_free;
5075 } 5422 }
5076 5423
5077 ar->hw->netdev_features = NETIF_F_HW_CSUM; 5424 ar->hw->netdev_features = NETIF_F_HW_CSUM;
@@ -5093,6 +5440,9 @@ int ath10k_mac_register(struct ath10k *ar)
5093 goto err_free; 5440 goto err_free;
5094 } 5441 }
5095 5442
5443 ar->hw->wiphy->cipher_suites = cipher_suites;
5444 ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
5445
5096 ret = ieee80211_register_hw(ar->hw); 5446 ret = ieee80211_register_hw(ar->hw);
5097 if (ret) { 5447 if (ret) {
5098 ath10k_err(ar, "failed to register ieee80211: %d\n", ret); 5448 ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 7abb8367119a..e6972b09333e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -58,12 +58,27 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1: warm only (default: 0)");
58#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 58#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3
59 59
60#define QCA988X_2_0_DEVICE_ID (0x003c) 60#define QCA988X_2_0_DEVICE_ID (0x003c)
61#define QCA6174_2_1_DEVICE_ID (0x003e)
61 62
62static const struct pci_device_id ath10k_pci_id_table[] = { 63static const struct pci_device_id ath10k_pci_id_table[] = {
63 { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ 64 { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */
65 { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */
64 {0} 66 {0}
65}; 67};
66 68
69static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
70 /* QCA988X pre 2.0 chips are not supported because they need some nasty
71 * hacks. ath10k doesn't have them and these devices crash horribly
72 * because of that.
73 */
74 { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
75 { QCA6174_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV },
76 { QCA6174_2_1_DEVICE_ID, QCA6174_HW_2_2_CHIP_ID_REV },
77 { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_0_CHIP_ID_REV },
78 { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_1_CHIP_ID_REV },
79 { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV },
80};
81
67static void ath10k_pci_buffer_cleanup(struct ath10k *ar); 82static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
68static int ath10k_pci_cold_reset(struct ath10k *ar); 83static int ath10k_pci_cold_reset(struct ath10k *ar);
69static int ath10k_pci_warm_reset(struct ath10k *ar); 84static int ath10k_pci_warm_reset(struct ath10k *ar);
@@ -395,7 +410,7 @@ static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe)
395 return -EIO; 410 return -EIO;
396 } 411 }
397 412
398 ATH10K_SKB_CB(skb)->paddr = paddr; 413 ATH10K_SKB_RXCB(skb)->paddr = paddr;
399 414
400 ret = __ath10k_ce_rx_post_buf(ce_pipe, skb, paddr); 415 ret = __ath10k_ce_rx_post_buf(ce_pipe, skb, paddr);
401 if (ret) { 416 if (ret) {
@@ -864,7 +879,7 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
864 &flags) == 0) { 879 &flags) == 0) {
865 skb = transfer_context; 880 skb = transfer_context;
866 max_nbytes = skb->len + skb_tailroom(skb); 881 max_nbytes = skb->len + skb_tailroom(skb);
867 dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, 882 dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
868 max_nbytes, DMA_FROM_DEVICE); 883 max_nbytes, DMA_FROM_DEVICE);
869 884
870 if (unlikely(max_nbytes < nbytes)) { 885 if (unlikely(max_nbytes < nbytes)) {
@@ -1230,7 +1245,7 @@ static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
1230 1245
1231 ce_ring->per_transfer_context[i] = NULL; 1246 ce_ring->per_transfer_context[i] = NULL;
1232 1247
1233 dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, 1248 dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr,
1234 skb->len + skb_tailroom(skb), 1249 skb->len + skb_tailroom(skb),
1235 DMA_FROM_DEVICE); 1250 DMA_FROM_DEVICE);
1236 dev_kfree_skb_any(skb); 1251 dev_kfree_skb_any(skb);
@@ -1498,6 +1513,35 @@ static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
1498 return 0; 1513 return 0;
1499} 1514}
1500 1515
1516static int ath10k_pci_get_num_banks(struct ath10k *ar)
1517{
1518 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
1519
1520 switch (ar_pci->pdev->device) {
1521 case QCA988X_2_0_DEVICE_ID:
1522 return 1;
1523 case QCA6174_2_1_DEVICE_ID:
1524 switch (MS(ar->chip_id, SOC_CHIP_ID_REV)) {
1525 case QCA6174_HW_1_0_CHIP_ID_REV:
1526 case QCA6174_HW_1_1_CHIP_ID_REV:
1527 return 3;
1528 case QCA6174_HW_1_3_CHIP_ID_REV:
1529 return 2;
1530 case QCA6174_HW_2_1_CHIP_ID_REV:
1531 case QCA6174_HW_2_2_CHIP_ID_REV:
1532 return 6;
1533 case QCA6174_HW_3_0_CHIP_ID_REV:
1534 case QCA6174_HW_3_1_CHIP_ID_REV:
1535 case QCA6174_HW_3_2_CHIP_ID_REV:
1536 return 9;
1537 }
1538 break;
1539 }
1540
1541 ath10k_warn(ar, "unknown number of banks, assuming 1\n");
1542 return 1;
1543}
1544
1501static int ath10k_pci_init_config(struct ath10k *ar) 1545static int ath10k_pci_init_config(struct ath10k *ar)
1502{ 1546{
1503 u32 interconnect_targ_addr; 1547 u32 interconnect_targ_addr;
@@ -1608,7 +1652,8 @@ static int ath10k_pci_init_config(struct ath10k *ar)
1608 /* first bank is switched to IRAM */ 1652 /* first bank is switched to IRAM */
1609 ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) & 1653 ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) &
1610 HI_EARLY_ALLOC_MAGIC_MASK); 1654 HI_EARLY_ALLOC_MAGIC_MASK);
1611 ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & 1655 ealloc_value |= ((ath10k_pci_get_num_banks(ar) <<
1656 HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) &
1612 HI_EARLY_ALLOC_IRAM_BANKS_MASK); 1657 HI_EARLY_ALLOC_IRAM_BANKS_MASK);
1613 1658
1614 ret = ath10k_pci_diag_write32(ar, ealloc_targ_addr, ealloc_value); 1659 ret = ath10k_pci_diag_write32(ar, ealloc_targ_addr, ealloc_value);
@@ -1804,12 +1849,12 @@ static int ath10k_pci_warm_reset(struct ath10k *ar)
1804 return 0; 1849 return 0;
1805} 1850}
1806 1851
1807static int ath10k_pci_chip_reset(struct ath10k *ar) 1852static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar)
1808{ 1853{
1809 int i, ret; 1854 int i, ret;
1810 u32 val; 1855 u32 val;
1811 1856
1812 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset\n"); 1857 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot 988x chip reset\n");
1813 1858
1814 /* Some hardware revisions (e.g. CUS223v2) has issues with cold reset. 1859 /* Some hardware revisions (e.g. CUS223v2) has issues with cold reset.
1815 * It is thus preferred to use warm reset which is safer but may not be 1860 * It is thus preferred to use warm reset which is safer but may not be
@@ -1873,11 +1918,53 @@ static int ath10k_pci_chip_reset(struct ath10k *ar)
1873 return ret; 1918 return ret;
1874 } 1919 }
1875 1920
1876 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset complete (cold)\n"); 1921 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca988x chip reset complete (cold)\n");
1922
1923 return 0;
1924}
1925
1926static int ath10k_pci_qca6174_chip_reset(struct ath10k *ar)
1927{
1928 int ret;
1929
1930 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca6174 chip reset\n");
1931
1932 /* FIXME: QCA6174 requires cold + warm reset to work. */
1933
1934 ret = ath10k_pci_cold_reset(ar);
1935 if (ret) {
1936 ath10k_warn(ar, "failed to cold reset: %d\n", ret);
1937 return ret;
1938 }
1939
1940 ret = ath10k_pci_wait_for_target_init(ar);
1941 if (ret) {
1942 ath10k_warn(ar, "failed to wait for target after cold reset: %d\n",
1943 ret);
1944 return ret;
1945 }
1946
1947 ret = ath10k_pci_warm_reset(ar);
1948 if (ret) {
1949 ath10k_warn(ar, "failed to warm reset: %d\n", ret);
1950 return ret;
1951 }
1952
1953 ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca6174 chip reset complete (cold)\n");
1877 1954
1878 return 0; 1955 return 0;
1879} 1956}
1880 1957
1958static int ath10k_pci_chip_reset(struct ath10k *ar)
1959{
1960 if (QCA_REV_988X(ar))
1961 return ath10k_pci_qca988x_chip_reset(ar);
1962 else if (QCA_REV_6174(ar))
1963 return ath10k_pci_qca6174_chip_reset(ar);
1964 else
1965 return -ENOTSUPP;
1966}
1967
1881static int ath10k_pci_hif_power_up(struct ath10k *ar) 1968static int ath10k_pci_hif_power_up(struct ath10k *ar)
1882{ 1969{
1883 int ret; 1970 int ret;
@@ -1902,6 +1989,12 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar)
1902 */ 1989 */
1903 ret = ath10k_pci_chip_reset(ar); 1990 ret = ath10k_pci_chip_reset(ar);
1904 if (ret) { 1991 if (ret) {
1992 if (ath10k_pci_has_fw_crashed(ar)) {
1993 ath10k_warn(ar, "firmware crashed during chip reset\n");
1994 ath10k_pci_fw_crashed_clear(ar);
1995 ath10k_pci_fw_crashed_dump(ar);
1996 }
1997
1905 ath10k_err(ar, "failed to reset chip: %d\n", ret); 1998 ath10k_err(ar, "failed to reset chip: %d\n", ret);
1906 goto err_sleep; 1999 goto err_sleep;
1907 } 2000 }
@@ -2033,6 +2126,7 @@ static void ath10k_msi_err_tasklet(unsigned long data)
2033 return; 2126 return;
2034 } 2127 }
2035 2128
2129 ath10k_pci_irq_disable(ar);
2036 ath10k_pci_fw_crashed_clear(ar); 2130 ath10k_pci_fw_crashed_clear(ar);
2037 ath10k_pci_fw_crashed_dump(ar); 2131 ath10k_pci_fw_crashed_dump(ar);
2038} 2132}
@@ -2102,6 +2196,7 @@ static void ath10k_pci_tasklet(unsigned long data)
2102 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); 2196 struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
2103 2197
2104 if (ath10k_pci_has_fw_crashed(ar)) { 2198 if (ath10k_pci_has_fw_crashed(ar)) {
2199 ath10k_pci_irq_disable(ar);
2105 ath10k_pci_fw_crashed_clear(ar); 2200 ath10k_pci_fw_crashed_clear(ar);
2106 ath10k_pci_fw_crashed_dump(ar); 2201 ath10k_pci_fw_crashed_dump(ar);
2107 return; 2202 return;
@@ -2344,8 +2439,6 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar)
2344 2439
2345 if (val & FW_IND_EVENT_PENDING) { 2440 if (val & FW_IND_EVENT_PENDING) {
2346 ath10k_warn(ar, "device has crashed during init\n"); 2441 ath10k_warn(ar, "device has crashed during init\n");
2347 ath10k_pci_fw_crashed_clear(ar);
2348 ath10k_pci_fw_crashed_dump(ar);
2349 return -ECOMM; 2442 return -ECOMM;
2350 } 2443 }
2351 2444
@@ -2476,17 +2569,46 @@ static void ath10k_pci_release(struct ath10k *ar)
2476 pci_disable_device(pdev); 2569 pci_disable_device(pdev);
2477} 2570}
2478 2571
2572static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id)
2573{
2574 const struct ath10k_pci_supp_chip *supp_chip;
2575 int i;
2576 u32 rev_id = MS(chip_id, SOC_CHIP_ID_REV);
2577
2578 for (i = 0; i < ARRAY_SIZE(ath10k_pci_supp_chips); i++) {
2579 supp_chip = &ath10k_pci_supp_chips[i];
2580
2581 if (supp_chip->dev_id == dev_id &&
2582 supp_chip->rev_id == rev_id)
2583 return true;
2584 }
2585
2586 return false;
2587}
2588
2479static int ath10k_pci_probe(struct pci_dev *pdev, 2589static int ath10k_pci_probe(struct pci_dev *pdev,
2480 const struct pci_device_id *pci_dev) 2590 const struct pci_device_id *pci_dev)
2481{ 2591{
2482 int ret = 0; 2592 int ret = 0;
2483 struct ath10k *ar; 2593 struct ath10k *ar;
2484 struct ath10k_pci *ar_pci; 2594 struct ath10k_pci *ar_pci;
2595 enum ath10k_hw_rev hw_rev;
2485 u32 chip_id; 2596 u32 chip_id;
2486 2597
2487 ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, 2598 switch (pci_dev->device) {
2488 ATH10K_BUS_PCI, 2599 case QCA988X_2_0_DEVICE_ID:
2489 &ath10k_pci_hif_ops); 2600 hw_rev = ATH10K_HW_QCA988X;
2601 break;
2602 case QCA6174_2_1_DEVICE_ID:
2603 hw_rev = ATH10K_HW_QCA6174;
2604 break;
2605 default:
2606 WARN_ON(1);
2607 return -ENOTSUPP;
2608 }
2609
2610 ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, ATH10K_BUS_PCI,
2611 hw_rev, &ath10k_pci_hif_ops);
2490 if (!ar) { 2612 if (!ar) {
2491 dev_err(&pdev->dev, "failed to allocate core\n"); 2613 dev_err(&pdev->dev, "failed to allocate core\n");
2492 return -ENOMEM; 2614 return -ENOMEM;
@@ -2515,12 +2637,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2515 goto err_release; 2637 goto err_release;
2516 } 2638 }
2517 2639
2518 chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
2519 if (chip_id == 0xffffffff) {
2520 ath10k_err(ar, "failed to get chip id\n");
2521 goto err_sleep;
2522 }
2523
2524 ret = ath10k_pci_alloc_pipes(ar); 2640 ret = ath10k_pci_alloc_pipes(ar);
2525 if (ret) { 2641 if (ret) {
2526 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", 2642 ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
@@ -2547,6 +2663,24 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
2547 goto err_deinit_irq; 2663 goto err_deinit_irq;
2548 } 2664 }
2549 2665
2666 ret = ath10k_pci_chip_reset(ar);
2667 if (ret) {
2668 ath10k_err(ar, "failed to reset chip: %d\n", ret);
2669 goto err_free_irq;
2670 }
2671
2672 chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS);
2673 if (chip_id == 0xffffffff) {
2674 ath10k_err(ar, "failed to get chip id\n");
2675 goto err_free_irq;
2676 }
2677
2678 if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) {
2679 ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
2680 pdev->device, chip_id);
2681 goto err_sleep;
2682 }
2683
2550 ath10k_pci_sleep(ar); 2684 ath10k_pci_sleep(ar);
2551 2685
2552 ret = ath10k_core_register(ar, chip_id); 2686 ret = ath10k_core_register(ar, chip_id);
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h
index cf36511c7f4d..bddf54320160 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;
@@ -189,7 +194,7 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
189 194
190#define ATH10K_PCI_RX_POST_RETRY_MS 50 195#define ATH10K_PCI_RX_POST_RETRY_MS 50
191#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ 196#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */
192#define PCIE_WAKE_TIMEOUT 5000 /* 5ms */ 197#define PCIE_WAKE_TIMEOUT 10000 /* 10ms */
193 198
194#define BAR_NUM 0 199#define BAR_NUM 0
195 200
diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h
index e1ffdd57a18c..e9cc7787bf5f 100644
--- a/drivers/net/wireless/ath/ath10k/rx_desc.h
+++ b/drivers/net/wireless/ath/ath10k/rx_desc.h
@@ -850,7 +850,7 @@ struct rx_ppdu_start {
850 850
851#define RX_PPDU_END_INFO1_PPDU_DONE (1 << 15) 851#define RX_PPDU_END_INFO1_PPDU_DONE (1 << 15)
852 852
853struct rx_ppdu_end { 853struct rx_ppdu_end_common {
854 __le32 evm_p0; 854 __le32 evm_p0;
855 __le32 evm_p1; 855 __le32 evm_p1;
856 __le32 evm_p2; 856 __le32 evm_p2;
@@ -873,10 +873,33 @@ struct rx_ppdu_end {
873 u8 phy_err_code; 873 u8 phy_err_code;
874 __le16 flags; /* %RX_PPDU_END_FLAGS_ */ 874 __le16 flags; /* %RX_PPDU_END_FLAGS_ */
875 __le32 info0; /* %RX_PPDU_END_INFO0_ */ 875 __le32 info0; /* %RX_PPDU_END_INFO0_ */
876} __packed;
877
878struct rx_ppdu_end_qca988x {
876 __le16 bb_length; 879 __le16 bb_length;
877 __le16 info1; /* %RX_PPDU_END_INFO1_ */ 880 __le16 info1; /* %RX_PPDU_END_INFO1_ */
878} __packed; 881} __packed;
879 882
883#define RX_PPDU_END_RTT_CORRELATION_VALUE_MASK 0x00ffffff
884#define RX_PPDU_END_RTT_CORRELATION_VALUE_LSB 0
885#define RX_PPDU_END_RTT_UNUSED_MASK 0x7f000000
886#define RX_PPDU_END_RTT_UNUSED_LSB 24
887#define RX_PPDU_END_RTT_NORMAL_MODE BIT(31)
888
889struct rx_ppdu_end_qca6174 {
890 __le32 rtt; /* %RX_PPDU_END_RTT_ */
891 __le16 bb_length;
892 __le16 info1; /* %RX_PPDU_END_INFO1_ */
893} __packed;
894
895struct rx_ppdu_end {
896 struct rx_ppdu_end_common common;
897 union {
898 struct rx_ppdu_end_qca988x qca988x;
899 struct rx_ppdu_end_qca6174 qca6174;
900 } __packed;
901} __packed;
902
880/* 903/*
881 * evm_p0 904 * evm_p0
882 * EVM for pilot 0. Contain EVM for streams: 0, 1, 2 and 3. 905 * EVM for pilot 0. Contain EVM for streams: 0, 1, 2 and 3.
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/targaddrs.h b/drivers/net/wireless/ath/ath10k/targaddrs.h
index 9d0ae30f9ff1..a417aae52623 100644
--- a/drivers/net/wireless/ath/ath10k/targaddrs.h
+++ b/drivers/net/wireless/ath/ath10k/targaddrs.h
@@ -18,6 +18,8 @@
18#ifndef __TARGADDRS_H__ 18#ifndef __TARGADDRS_H__
19#define __TARGADDRS_H__ 19#define __TARGADDRS_H__
20 20
21#include "hw.h"
22
21/* 23/*
22 * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the 24 * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
23 * host_interest structure. It must match the address of the _host_interest 25 * host_interest structure. It must match the address of the _host_interest
@@ -445,4 +447,7 @@ Fw Mode/SubMode Mask
445#define QCA988X_BOARD_DATA_SZ 7168 447#define QCA988X_BOARD_DATA_SZ 7168
446#define QCA988X_BOARD_EXT_DATA_SZ 0 448#define QCA988X_BOARD_EXT_DATA_SZ 0
447 449
450#define QCA6174_BOARD_DATA_SZ 8192
451#define QCA6174_BOARD_EXT_DATA_SZ 0
452
448#endif /* __TARGADDRS_H__ */ 453#endif /* __TARGADDRS_H__ */
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..aede750809fe
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/thermal.c
@@ -0,0 +1,244 @@
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 /* display in millidegree celcius */
164 ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000);
165out:
166 mutex_unlock(&ar->conf_mutex);
167 return ret;
168}
169
170void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
171{
172 spin_lock_bh(&ar->data_lock);
173 ar->thermal.temperature = temperature;
174 spin_unlock_bh(&ar->data_lock);
175 complete(&ar->thermal.wmi_sync);
176}
177
178static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ath10k_thermal_show_temp,
179 NULL, 0);
180
181static struct attribute *ath10k_hwmon_attrs[] = {
182 &sensor_dev_attr_temp1_input.dev_attr.attr,
183 NULL,
184};
185ATTRIBUTE_GROUPS(ath10k_hwmon);
186
187int ath10k_thermal_register(struct ath10k *ar)
188{
189 struct thermal_cooling_device *cdev;
190 struct device *hwmon_dev;
191 int ret;
192
193 cdev = thermal_cooling_device_register("ath10k_thermal", ar,
194 &ath10k_thermal_ops);
195
196 if (IS_ERR(cdev)) {
197 ath10k_err(ar, "failed to setup thermal device result: %ld\n",
198 PTR_ERR(cdev));
199 return -EINVAL;
200 }
201
202 ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
203 "cooling_device");
204 if (ret) {
205 ath10k_err(ar, "failed to create thermal symlink\n");
206 goto err_cooling_destroy;
207 }
208
209 ar->thermal.cdev = cdev;
210
211 /* Do not register hwmon device when temperature reading is not
212 * supported by firmware
213 */
214 if (ar->wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4)
215 return 0;
216
217 /* Avoid linking error on devm_hwmon_device_register_with_groups, I
218 * guess linux/hwmon.h is missing proper stubs. */
219 if (!config_enabled(CONFIG_HWMON))
220 return 0;
221
222 hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
223 "ath10k_hwmon", ar,
224 ath10k_hwmon_groups);
225 if (IS_ERR(hwmon_dev)) {
226 ath10k_err(ar, "failed to register hwmon device: %ld\n",
227 PTR_ERR(hwmon_dev));
228 ret = -EINVAL;
229 goto err_remove_link;
230 }
231 return 0;
232
233err_remove_link:
234 sysfs_remove_link(&ar->dev->kobj, "thermal_sensor");
235err_cooling_destroy:
236 thermal_cooling_device_unregister(cdev);
237 return ret;
238}
239
240void ath10k_thermal_unregister(struct ath10k *ar)
241{
242 thermal_cooling_device_unregister(ar->thermal.cdev);
243 sysfs_remove_link(&ar->dev->kobj, "cooling_device");
244}
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/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index b289378b6e3e..5407887380ab 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -453,6 +453,74 @@ TRACE_EVENT(ath10k_htt_rx_desc,
453 ) 453 )
454); 454);
455 455
456TRACE_EVENT(ath10k_wmi_diag_container,
457 TP_PROTO(struct ath10k *ar,
458 u8 type,
459 u32 timestamp,
460 u32 code,
461 u16 len,
462 const void *data),
463
464 TP_ARGS(ar, type, timestamp, code, len, data),
465
466 TP_STRUCT__entry(
467 __string(device, dev_name(ar->dev))
468 __string(driver, dev_driver_string(ar->dev))
469 __field(u8, type)
470 __field(u32, timestamp)
471 __field(u32, code)
472 __field(u16, len)
473 __dynamic_array(u8, data, len)
474 ),
475
476 TP_fast_assign(
477 __assign_str(device, dev_name(ar->dev));
478 __assign_str(driver, dev_driver_string(ar->dev));
479 __entry->type = type;
480 __entry->timestamp = timestamp;
481 __entry->code = code;
482 __entry->len = len;
483 memcpy(__get_dynamic_array(data), data, len);
484 ),
485
486 TP_printk(
487 "%s %s diag container type %hhu timestamp %u code %u len %d",
488 __get_str(driver),
489 __get_str(device),
490 __entry->type,
491 __entry->timestamp,
492 __entry->code,
493 __entry->len
494 )
495);
496
497TRACE_EVENT(ath10k_wmi_diag,
498 TP_PROTO(struct ath10k *ar, const void *data, size_t len),
499
500 TP_ARGS(ar, data, len),
501
502 TP_STRUCT__entry(
503 __string(device, dev_name(ar->dev))
504 __string(driver, dev_driver_string(ar->dev))
505 __field(u16, len)
506 __dynamic_array(u8, data, len)
507 ),
508
509 TP_fast_assign(
510 __assign_str(device, dev_name(ar->dev));
511 __assign_str(driver, dev_driver_string(ar->dev));
512 __entry->len = len;
513 memcpy(__get_dynamic_array(data), data, len);
514 ),
515
516 TP_printk(
517 "%s %s tlv diag len %d",
518 __get_str(driver),
519 __get_str(device),
520 __entry->len
521 )
522);
523
456#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ 524#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
457 525
458/* we don't want to use include/trace/events */ 526/* we don't want to use include/trace/events */
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 7579de8e7a8c..3f00cec8aef5 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -64,7 +64,13 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
64 return; 64 return;
65 } 65 }
66 66
67 msdu = htt->pending_tx[tx_done->msdu_id]; 67 msdu = idr_find(&htt->pending_tx, tx_done->msdu_id);
68 if (!msdu) {
69 ath10k_warn(ar, "received tx completion for invalid msdu_id: %d\n",
70 tx_done->msdu_id);
71 return;
72 }
73
68 skb_cb = ATH10K_SKB_CB(msdu); 74 skb_cb = ATH10K_SKB_CB(msdu);
69 75
70 dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); 76 dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);
@@ -95,7 +101,6 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
95 /* we do not own the msdu anymore */ 101 /* we do not own the msdu anymore */
96 102
97exit: 103exit:
98 htt->pending_tx[tx_done->msdu_id] = NULL;
99 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); 104 ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id);
100 __ath10k_htt_tx_dec_pending(htt); 105 __ath10k_htt_tx_dec_pending(htt);
101 if (htt->num_pending_tx == 0) 106 if (htt->num_pending_tx == 0)
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..04dc4b9db04e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -0,0 +1,1064 @@
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_vdev_wmm_conf)(struct ath10k *ar, u32 vdev_id,
82 const struct wmi_wmm_params_all_arg *arg);
83 struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id,
84 const u8 peer_addr[ETH_ALEN]);
85 struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id,
86 const u8 peer_addr[ETH_ALEN]);
87 struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id,
88 const u8 peer_addr[ETH_ALEN],
89 u32 tid_bitmap);
90 struct sk_buff *(*gen_peer_set_param)(struct ath10k *ar, u32 vdev_id,
91 const u8 *peer_addr,
92 enum wmi_peer_param param_id,
93 u32 param_value);
94 struct sk_buff *(*gen_peer_assoc)(struct ath10k *ar,
95 const struct wmi_peer_assoc_complete_arg *arg);
96 struct sk_buff *(*gen_set_psmode)(struct ath10k *ar, u32 vdev_id,
97 enum wmi_sta_ps_mode psmode);
98 struct sk_buff *(*gen_set_sta_ps)(struct ath10k *ar, u32 vdev_id,
99 enum wmi_sta_powersave_param param_id,
100 u32 value);
101 struct sk_buff *(*gen_set_ap_ps)(struct ath10k *ar, u32 vdev_id,
102 const u8 *mac,
103 enum wmi_ap_ps_peer_param param_id,
104 u32 value);
105 struct sk_buff *(*gen_scan_chan_list)(struct ath10k *ar,
106 const struct wmi_scan_chan_list_arg *arg);
107 struct sk_buff *(*gen_beacon_dma)(struct ath10k *ar, u32 vdev_id,
108 const void *bcn, size_t bcn_len,
109 u32 bcn_paddr, bool dtim_zero,
110 bool deliver_cab);
111 struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
112 const struct wmi_wmm_params_all_arg *arg);
113 struct sk_buff *(*gen_request_stats)(struct ath10k *ar,
114 enum wmi_stats_id stats_id);
115 struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
116 enum wmi_force_fw_hang_type type,
117 u32 delay_ms);
118 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb);
119 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable,
120 u32 log_level);
121 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
122 struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar);
123 struct sk_buff *(*gen_pdev_set_quiet_mode)(struct ath10k *ar,
124 u32 period, u32 duration,
125 u32 next_offset,
126 u32 enabled);
127 struct sk_buff *(*gen_pdev_get_temperature)(struct ath10k *ar);
128 struct sk_buff *(*gen_addba_clear_resp)(struct ath10k *ar, u32 vdev_id,
129 const u8 *mac);
130 struct sk_buff *(*gen_addba_send)(struct ath10k *ar, u32 vdev_id,
131 const u8 *mac, u32 tid, u32 buf_size);
132 struct sk_buff *(*gen_addba_set_resp)(struct ath10k *ar, u32 vdev_id,
133 const u8 *mac, u32 tid,
134 u32 status);
135 struct sk_buff *(*gen_delba_send)(struct ath10k *ar, u32 vdev_id,
136 const u8 *mac, u32 tid, u32 initiator,
137 u32 reason);
138 struct sk_buff *(*gen_bcn_tmpl)(struct ath10k *ar, u32 vdev_id,
139 u32 tim_ie_offset, struct sk_buff *bcn,
140 u32 prb_caps, u32 prb_erp,
141 void *prb_ies, size_t prb_ies_len);
142 struct sk_buff *(*gen_prb_tmpl)(struct ath10k *ar, u32 vdev_id,
143 struct sk_buff *bcn);
144 struct sk_buff *(*gen_p2p_go_bcn_ie)(struct ath10k *ar, u32 vdev_id,
145 const u8 *p2p_ie);
146 struct sk_buff *(*gen_vdev_sta_uapsd)(struct ath10k *ar, u32 vdev_id,
147 const u8 peer_addr[ETH_ALEN],
148 const struct wmi_sta_uapsd_auto_trig_arg *args,
149 u32 num_ac);
150 struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar,
151 const struct wmi_sta_keepalive_arg *arg);
152};
153
154int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
155
156static inline int
157ath10k_wmi_rx(struct ath10k *ar, struct sk_buff *skb)
158{
159 if (WARN_ON_ONCE(!ar->wmi.ops->rx))
160 return -EOPNOTSUPP;
161
162 ar->wmi.ops->rx(ar, skb);
163 return 0;
164}
165
166static inline int
167ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out,
168 size_t len)
169{
170 if (!ar->wmi.ops->map_svc)
171 return -EOPNOTSUPP;
172
173 ar->wmi.ops->map_svc(in, out, len);
174 return 0;
175}
176
177static inline int
178ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb,
179 struct wmi_scan_ev_arg *arg)
180{
181 if (!ar->wmi.ops->pull_scan)
182 return -EOPNOTSUPP;
183
184 return ar->wmi.ops->pull_scan(ar, skb, arg);
185}
186
187static inline int
188ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb,
189 struct wmi_mgmt_rx_ev_arg *arg)
190{
191 if (!ar->wmi.ops->pull_mgmt_rx)
192 return -EOPNOTSUPP;
193
194 return ar->wmi.ops->pull_mgmt_rx(ar, skb, arg);
195}
196
197static inline int
198ath10k_wmi_pull_ch_info(struct ath10k *ar, struct sk_buff *skb,
199 struct wmi_ch_info_ev_arg *arg)
200{
201 if (!ar->wmi.ops->pull_ch_info)
202 return -EOPNOTSUPP;
203
204 return ar->wmi.ops->pull_ch_info(ar, skb, arg);
205}
206
207static inline int
208ath10k_wmi_pull_vdev_start(struct ath10k *ar, struct sk_buff *skb,
209 struct wmi_vdev_start_ev_arg *arg)
210{
211 if (!ar->wmi.ops->pull_vdev_start)
212 return -EOPNOTSUPP;
213
214 return ar->wmi.ops->pull_vdev_start(ar, skb, arg);
215}
216
217static inline int
218ath10k_wmi_pull_peer_kick(struct ath10k *ar, struct sk_buff *skb,
219 struct wmi_peer_kick_ev_arg *arg)
220{
221 if (!ar->wmi.ops->pull_peer_kick)
222 return -EOPNOTSUPP;
223
224 return ar->wmi.ops->pull_peer_kick(ar, skb, arg);
225}
226
227static inline int
228ath10k_wmi_pull_swba(struct ath10k *ar, struct sk_buff *skb,
229 struct wmi_swba_ev_arg *arg)
230{
231 if (!ar->wmi.ops->pull_swba)
232 return -EOPNOTSUPP;
233
234 return ar->wmi.ops->pull_swba(ar, skb, arg);
235}
236
237static inline int
238ath10k_wmi_pull_phyerr(struct ath10k *ar, struct sk_buff *skb,
239 struct wmi_phyerr_ev_arg *arg)
240{
241 if (!ar->wmi.ops->pull_phyerr)
242 return -EOPNOTSUPP;
243
244 return ar->wmi.ops->pull_phyerr(ar, skb, arg);
245}
246
247static inline int
248ath10k_wmi_pull_svc_rdy(struct ath10k *ar, struct sk_buff *skb,
249 struct wmi_svc_rdy_ev_arg *arg)
250{
251 if (!ar->wmi.ops->pull_svc_rdy)
252 return -EOPNOTSUPP;
253
254 return ar->wmi.ops->pull_svc_rdy(ar, skb, arg);
255}
256
257static inline int
258ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb,
259 struct wmi_rdy_ev_arg *arg)
260{
261 if (!ar->wmi.ops->pull_rdy)
262 return -EOPNOTSUPP;
263
264 return ar->wmi.ops->pull_rdy(ar, skb, arg);
265}
266
267static inline int
268ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
269 struct ath10k_fw_stats *stats)
270{
271 if (!ar->wmi.ops->pull_fw_stats)
272 return -EOPNOTSUPP;
273
274 return ar->wmi.ops->pull_fw_stats(ar, skb, stats);
275}
276
277static inline int
278ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
279{
280 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
281 struct sk_buff *skb;
282 int ret;
283
284 if (!ar->wmi.ops->gen_mgmt_tx)
285 return -EOPNOTSUPP;
286
287 skb = ar->wmi.ops->gen_mgmt_tx(ar, msdu);
288 if (IS_ERR(skb))
289 return PTR_ERR(skb);
290
291 ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid);
292 if (ret)
293 return ret;
294
295 /* FIXME There's no ACK event for Management Tx. This probably
296 * shouldn't be called here either. */
297 info->flags |= IEEE80211_TX_STAT_ACK;
298 ieee80211_tx_status_irqsafe(ar->hw, msdu);
299
300 return 0;
301}
302
303static inline int
304ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
305 u16 ctl2g, u16 ctl5g,
306 enum wmi_dfs_region dfs_reg)
307{
308 struct sk_buff *skb;
309
310 if (!ar->wmi.ops->gen_pdev_set_rd)
311 return -EOPNOTSUPP;
312
313 skb = ar->wmi.ops->gen_pdev_set_rd(ar, rd, rd2g, rd5g, ctl2g, ctl5g,
314 dfs_reg);
315 if (IS_ERR(skb))
316 return PTR_ERR(skb);
317
318 return ath10k_wmi_cmd_send(ar, skb,
319 ar->wmi.cmd->pdev_set_regdomain_cmdid);
320}
321
322static inline int
323ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
324{
325 struct sk_buff *skb;
326
327 if (!ar->wmi.ops->gen_pdev_suspend)
328 return -EOPNOTSUPP;
329
330 skb = ar->wmi.ops->gen_pdev_suspend(ar, suspend_opt);
331 if (IS_ERR(skb))
332 return PTR_ERR(skb);
333
334 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
335}
336
337static inline int
338ath10k_wmi_pdev_resume_target(struct ath10k *ar)
339{
340 struct sk_buff *skb;
341
342 if (!ar->wmi.ops->gen_pdev_resume)
343 return -EOPNOTSUPP;
344
345 skb = ar->wmi.ops->gen_pdev_resume(ar);
346 if (IS_ERR(skb))
347 return PTR_ERR(skb);
348
349 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid);
350}
351
352static inline int
353ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
354{
355 struct sk_buff *skb;
356
357 if (!ar->wmi.ops->gen_pdev_set_param)
358 return -EOPNOTSUPP;
359
360 skb = ar->wmi.ops->gen_pdev_set_param(ar, id, value);
361 if (IS_ERR(skb))
362 return PTR_ERR(skb);
363
364 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid);
365}
366
367static inline int
368ath10k_wmi_cmd_init(struct ath10k *ar)
369{
370 struct sk_buff *skb;
371
372 if (!ar->wmi.ops->gen_init)
373 return -EOPNOTSUPP;
374
375 skb = ar->wmi.ops->gen_init(ar);
376 if (IS_ERR(skb))
377 return PTR_ERR(skb);
378
379 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->init_cmdid);
380}
381
382static inline int
383ath10k_wmi_start_scan(struct ath10k *ar,
384 const struct wmi_start_scan_arg *arg)
385{
386 struct sk_buff *skb;
387
388 if (!ar->wmi.ops->gen_start_scan)
389 return -EOPNOTSUPP;
390
391 skb = ar->wmi.ops->gen_start_scan(ar, arg);
392 if (IS_ERR(skb))
393 return PTR_ERR(skb);
394
395 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid);
396}
397
398static inline int
399ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
400{
401 struct sk_buff *skb;
402
403 if (!ar->wmi.ops->gen_stop_scan)
404 return -EOPNOTSUPP;
405
406 skb = ar->wmi.ops->gen_stop_scan(ar, arg);
407 if (IS_ERR(skb))
408 return PTR_ERR(skb);
409
410 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid);
411}
412
413static inline int
414ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
415 enum wmi_vdev_type type,
416 enum wmi_vdev_subtype subtype,
417 const u8 macaddr[ETH_ALEN])
418{
419 struct sk_buff *skb;
420
421 if (!ar->wmi.ops->gen_vdev_create)
422 return -EOPNOTSUPP;
423
424 skb = ar->wmi.ops->gen_vdev_create(ar, vdev_id, type, subtype, macaddr);
425 if (IS_ERR(skb))
426 return PTR_ERR(skb);
427
428 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid);
429}
430
431static inline int
432ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
433{
434 struct sk_buff *skb;
435
436 if (!ar->wmi.ops->gen_vdev_delete)
437 return -EOPNOTSUPP;
438
439 skb = ar->wmi.ops->gen_vdev_delete(ar, vdev_id);
440 if (IS_ERR(skb))
441 return PTR_ERR(skb);
442
443 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
444}
445
446static inline int
447ath10k_wmi_vdev_start(struct ath10k *ar,
448 const struct wmi_vdev_start_request_arg *arg)
449{
450 struct sk_buff *skb;
451
452 if (!ar->wmi.ops->gen_vdev_start)
453 return -EOPNOTSUPP;
454
455 skb = ar->wmi.ops->gen_vdev_start(ar, arg, false);
456 if (IS_ERR(skb))
457 return PTR_ERR(skb);
458
459 return ath10k_wmi_cmd_send(ar, skb,
460 ar->wmi.cmd->vdev_start_request_cmdid);
461}
462
463static inline int
464ath10k_wmi_vdev_restart(struct ath10k *ar,
465 const struct wmi_vdev_start_request_arg *arg)
466{
467 struct sk_buff *skb;
468
469 if (!ar->wmi.ops->gen_vdev_start)
470 return -EOPNOTSUPP;
471
472 skb = ar->wmi.ops->gen_vdev_start(ar, arg, true);
473 if (IS_ERR(skb))
474 return PTR_ERR(skb);
475
476 return ath10k_wmi_cmd_send(ar, skb,
477 ar->wmi.cmd->vdev_restart_request_cmdid);
478}
479
480static inline int
481ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id)
482{
483 struct sk_buff *skb;
484
485 if (!ar->wmi.ops->gen_vdev_stop)
486 return -EOPNOTSUPP;
487
488 skb = ar->wmi.ops->gen_vdev_stop(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_stop_cmdid);
493}
494
495static inline int
496ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
497{
498 struct sk_buff *skb;
499
500 if (!ar->wmi.ops->gen_vdev_up)
501 return -EOPNOTSUPP;
502
503 skb = ar->wmi.ops->gen_vdev_up(ar, vdev_id, aid, bssid);
504 if (IS_ERR(skb))
505 return PTR_ERR(skb);
506
507 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid);
508}
509
510static inline int
511ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id)
512{
513 struct sk_buff *skb;
514
515 if (!ar->wmi.ops->gen_vdev_down)
516 return -EOPNOTSUPP;
517
518 skb = ar->wmi.ops->gen_vdev_down(ar, vdev_id);
519 if (IS_ERR(skb))
520 return PTR_ERR(skb);
521
522 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid);
523}
524
525static inline int
526ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, u32 param_id,
527 u32 param_value)
528{
529 struct sk_buff *skb;
530
531 if (!ar->wmi.ops->gen_vdev_set_param)
532 return -EOPNOTSUPP;
533
534 skb = ar->wmi.ops->gen_vdev_set_param(ar, vdev_id, param_id,
535 param_value);
536 if (IS_ERR(skb))
537 return PTR_ERR(skb);
538
539 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid);
540}
541
542static inline int
543ath10k_wmi_vdev_install_key(struct ath10k *ar,
544 const struct wmi_vdev_install_key_arg *arg)
545{
546 struct sk_buff *skb;
547
548 if (!ar->wmi.ops->gen_vdev_install_key)
549 return -EOPNOTSUPP;
550
551 skb = ar->wmi.ops->gen_vdev_install_key(ar, arg);
552 if (IS_ERR(skb))
553 return PTR_ERR(skb);
554
555 return ath10k_wmi_cmd_send(ar, skb,
556 ar->wmi.cmd->vdev_install_key_cmdid);
557}
558
559static inline int
560ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
561 const struct wmi_vdev_spectral_conf_arg *arg)
562{
563 struct sk_buff *skb;
564 u32 cmd_id;
565
566 skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
567 if (IS_ERR(skb))
568 return PTR_ERR(skb);
569
570 cmd_id = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid;
571 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
572}
573
574static inline int
575ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
576 u32 enable)
577{
578 struct sk_buff *skb;
579 u32 cmd_id;
580
581 skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
582 enable);
583 if (IS_ERR(skb))
584 return PTR_ERR(skb);
585
586 cmd_id = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid;
587 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
588}
589
590static inline int
591ath10k_wmi_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
592 const u8 peer_addr[ETH_ALEN],
593 const struct wmi_sta_uapsd_auto_trig_arg *args,
594 u32 num_ac)
595{
596 struct sk_buff *skb;
597 u32 cmd_id;
598
599 if (!ar->wmi.ops->gen_vdev_sta_uapsd)
600 return -EOPNOTSUPP;
601
602 skb = ar->wmi.ops->gen_vdev_sta_uapsd(ar, vdev_id, peer_addr, args,
603 num_ac);
604 if (IS_ERR(skb))
605 return PTR_ERR(skb);
606
607 cmd_id = ar->wmi.cmd->sta_uapsd_auto_trig_cmdid;
608 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
609}
610
611static inline int
612ath10k_wmi_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
613 const struct wmi_wmm_params_all_arg *arg)
614{
615 struct sk_buff *skb;
616 u32 cmd_id;
617
618 skb = ar->wmi.ops->gen_vdev_wmm_conf(ar, vdev_id, arg);
619 if (IS_ERR(skb))
620 return PTR_ERR(skb);
621
622 cmd_id = ar->wmi.cmd->vdev_set_wmm_params_cmdid;
623 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
624}
625
626static inline int
627ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
628 const u8 peer_addr[ETH_ALEN])
629{
630 struct sk_buff *skb;
631
632 if (!ar->wmi.ops->gen_peer_create)
633 return -EOPNOTSUPP;
634
635 skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr);
636 if (IS_ERR(skb))
637 return PTR_ERR(skb);
638
639 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid);
640}
641
642static inline int
643ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
644 const u8 peer_addr[ETH_ALEN])
645{
646 struct sk_buff *skb;
647
648 if (!ar->wmi.ops->gen_peer_delete)
649 return -EOPNOTSUPP;
650
651 skb = ar->wmi.ops->gen_peer_delete(ar, vdev_id, peer_addr);
652 if (IS_ERR(skb))
653 return PTR_ERR(skb);
654
655 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid);
656}
657
658static inline int
659ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
660 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
661{
662 struct sk_buff *skb;
663
664 if (!ar->wmi.ops->gen_peer_flush)
665 return -EOPNOTSUPP;
666
667 skb = ar->wmi.ops->gen_peer_flush(ar, vdev_id, peer_addr, tid_bitmap);
668 if (IS_ERR(skb))
669 return PTR_ERR(skb);
670
671 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid);
672}
673
674static inline int
675ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, const u8 *peer_addr,
676 enum wmi_peer_param param_id, u32 param_value)
677{
678 struct sk_buff *skb;
679
680 if (!ar->wmi.ops->gen_peer_set_param)
681 return -EOPNOTSUPP;
682
683 skb = ar->wmi.ops->gen_peer_set_param(ar, vdev_id, peer_addr, param_id,
684 param_value);
685 if (IS_ERR(skb))
686 return PTR_ERR(skb);
687
688 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid);
689}
690
691static inline int
692ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
693 enum wmi_sta_ps_mode psmode)
694{
695 struct sk_buff *skb;
696
697 if (!ar->wmi.ops->gen_set_psmode)
698 return -EOPNOTSUPP;
699
700 skb = ar->wmi.ops->gen_set_psmode(ar, vdev_id, psmode);
701 if (IS_ERR(skb))
702 return PTR_ERR(skb);
703
704 return ath10k_wmi_cmd_send(ar, skb,
705 ar->wmi.cmd->sta_powersave_mode_cmdid);
706}
707
708static inline int
709ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
710 enum wmi_sta_powersave_param param_id, u32 value)
711{
712 struct sk_buff *skb;
713
714 if (!ar->wmi.ops->gen_set_sta_ps)
715 return -EOPNOTSUPP;
716
717 skb = ar->wmi.ops->gen_set_sta_ps(ar, vdev_id, param_id, value);
718 if (IS_ERR(skb))
719 return PTR_ERR(skb);
720
721 return ath10k_wmi_cmd_send(ar, skb,
722 ar->wmi.cmd->sta_powersave_param_cmdid);
723}
724
725static inline int
726ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
727 enum wmi_ap_ps_peer_param param_id, u32 value)
728{
729 struct sk_buff *skb;
730
731 if (!ar->wmi.ops->gen_set_ap_ps)
732 return -EOPNOTSUPP;
733
734 skb = ar->wmi.ops->gen_set_ap_ps(ar, vdev_id, mac, param_id, value);
735 if (IS_ERR(skb))
736 return PTR_ERR(skb);
737
738 return ath10k_wmi_cmd_send(ar, skb,
739 ar->wmi.cmd->ap_ps_peer_param_cmdid);
740}
741
742static inline int
743ath10k_wmi_scan_chan_list(struct ath10k *ar,
744 const struct wmi_scan_chan_list_arg *arg)
745{
746 struct sk_buff *skb;
747
748 if (!ar->wmi.ops->gen_scan_chan_list)
749 return -EOPNOTSUPP;
750
751 skb = ar->wmi.ops->gen_scan_chan_list(ar, arg);
752 if (IS_ERR(skb))
753 return PTR_ERR(skb);
754
755 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid);
756}
757
758static inline int
759ath10k_wmi_peer_assoc(struct ath10k *ar,
760 const struct wmi_peer_assoc_complete_arg *arg)
761{
762 struct sk_buff *skb;
763
764 if (!ar->wmi.ops->gen_peer_assoc)
765 return -EOPNOTSUPP;
766
767 skb = ar->wmi.ops->gen_peer_assoc(ar, arg);
768 if (IS_ERR(skb))
769 return PTR_ERR(skb);
770
771 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
772}
773
774static inline int
775ath10k_wmi_beacon_send_ref_nowait(struct ath10k *ar, u32 vdev_id,
776 const void *bcn, size_t bcn_len,
777 u32 bcn_paddr, bool dtim_zero,
778 bool deliver_cab)
779{
780 struct sk_buff *skb;
781 int ret;
782
783 if (!ar->wmi.ops->gen_beacon_dma)
784 return -EOPNOTSUPP;
785
786 skb = ar->wmi.ops->gen_beacon_dma(ar, vdev_id, bcn, bcn_len, bcn_paddr,
787 dtim_zero, deliver_cab);
788 if (IS_ERR(skb))
789 return PTR_ERR(skb);
790
791 ret = ath10k_wmi_cmd_send_nowait(ar, skb,
792 ar->wmi.cmd->pdev_send_bcn_cmdid);
793 if (ret) {
794 dev_kfree_skb(skb);
795 return ret;
796 }
797
798 return 0;
799}
800
801static inline int
802ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
803 const struct wmi_wmm_params_all_arg *arg)
804{
805 struct sk_buff *skb;
806
807 if (!ar->wmi.ops->gen_pdev_set_wmm)
808 return -EOPNOTSUPP;
809
810 skb = ar->wmi.ops->gen_pdev_set_wmm(ar, arg);
811 if (IS_ERR(skb))
812 return PTR_ERR(skb);
813
814 return ath10k_wmi_cmd_send(ar, skb,
815 ar->wmi.cmd->pdev_set_wmm_params_cmdid);
816}
817
818static inline int
819ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
820{
821 struct sk_buff *skb;
822
823 if (!ar->wmi.ops->gen_request_stats)
824 return -EOPNOTSUPP;
825
826 skb = ar->wmi.ops->gen_request_stats(ar, stats_id);
827 if (IS_ERR(skb))
828 return PTR_ERR(skb);
829
830 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid);
831}
832
833static inline int
834ath10k_wmi_force_fw_hang(struct ath10k *ar,
835 enum wmi_force_fw_hang_type type, u32 delay_ms)
836{
837 struct sk_buff *skb;
838
839 if (!ar->wmi.ops->gen_force_fw_hang)
840 return -EOPNOTSUPP;
841
842 skb = ar->wmi.ops->gen_force_fw_hang(ar, type, delay_ms);
843 if (IS_ERR(skb))
844 return PTR_ERR(skb);
845
846 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
847}
848
849static inline int
850ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable, u32 log_level)
851{
852 struct sk_buff *skb;
853
854 if (!ar->wmi.ops->gen_dbglog_cfg)
855 return -EOPNOTSUPP;
856
857 skb = ar->wmi.ops->gen_dbglog_cfg(ar, module_enable, log_level);
858 if (IS_ERR(skb))
859 return PTR_ERR(skb);
860
861 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
862}
863
864static inline int
865ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 filter)
866{
867 struct sk_buff *skb;
868
869 if (!ar->wmi.ops->gen_pktlog_enable)
870 return -EOPNOTSUPP;
871
872 skb = ar->wmi.ops->gen_pktlog_enable(ar, filter);
873 if (IS_ERR(skb))
874 return PTR_ERR(skb);
875
876 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_pktlog_enable_cmdid);
877}
878
879static inline int
880ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar)
881{
882 struct sk_buff *skb;
883
884 if (!ar->wmi.ops->gen_pktlog_disable)
885 return -EOPNOTSUPP;
886
887 skb = ar->wmi.ops->gen_pktlog_disable(ar);
888 if (IS_ERR(skb))
889 return PTR_ERR(skb);
890
891 return ath10k_wmi_cmd_send(ar, skb,
892 ar->wmi.cmd->pdev_pktlog_disable_cmdid);
893}
894
895static inline int
896ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 period, u32 duration,
897 u32 next_offset, u32 enabled)
898{
899 struct sk_buff *skb;
900
901 if (!ar->wmi.ops->gen_pdev_set_quiet_mode)
902 return -EOPNOTSUPP;
903
904 skb = ar->wmi.ops->gen_pdev_set_quiet_mode(ar, period, duration,
905 next_offset, enabled);
906 if (IS_ERR(skb))
907 return PTR_ERR(skb);
908
909 return ath10k_wmi_cmd_send(ar, skb,
910 ar->wmi.cmd->pdev_set_quiet_mode_cmdid);
911}
912
913static inline int
914ath10k_wmi_pdev_get_temperature(struct ath10k *ar)
915{
916 struct sk_buff *skb;
917
918 if (!ar->wmi.ops->gen_pdev_get_temperature)
919 return -EOPNOTSUPP;
920
921 skb = ar->wmi.ops->gen_pdev_get_temperature(ar);
922 if (IS_ERR(skb))
923 return PTR_ERR(skb);
924
925 return ath10k_wmi_cmd_send(ar, skb,
926 ar->wmi.cmd->pdev_get_temperature_cmdid);
927}
928
929static inline int
930ath10k_wmi_addba_clear_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac)
931{
932 struct sk_buff *skb;
933
934 if (!ar->wmi.ops->gen_addba_clear_resp)
935 return -EOPNOTSUPP;
936
937 skb = ar->wmi.ops->gen_addba_clear_resp(ar, vdev_id, mac);
938 if (IS_ERR(skb))
939 return PTR_ERR(skb);
940
941 return ath10k_wmi_cmd_send(ar, skb,
942 ar->wmi.cmd->addba_clear_resp_cmdid);
943}
944
945static inline int
946ath10k_wmi_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
947 u32 tid, u32 buf_size)
948{
949 struct sk_buff *skb;
950
951 if (!ar->wmi.ops->gen_addba_send)
952 return -EOPNOTSUPP;
953
954 skb = ar->wmi.ops->gen_addba_send(ar, vdev_id, mac, tid, buf_size);
955 if (IS_ERR(skb))
956 return PTR_ERR(skb);
957
958 return ath10k_wmi_cmd_send(ar, skb,
959 ar->wmi.cmd->addba_send_cmdid);
960}
961
962static inline int
963ath10k_wmi_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac,
964 u32 tid, u32 status)
965{
966 struct sk_buff *skb;
967
968 if (!ar->wmi.ops->gen_addba_set_resp)
969 return -EOPNOTSUPP;
970
971 skb = ar->wmi.ops->gen_addba_set_resp(ar, vdev_id, mac, tid, status);
972 if (IS_ERR(skb))
973 return PTR_ERR(skb);
974
975 return ath10k_wmi_cmd_send(ar, skb,
976 ar->wmi.cmd->addba_set_resp_cmdid);
977}
978
979static inline int
980ath10k_wmi_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
981 u32 tid, u32 initiator, u32 reason)
982{
983 struct sk_buff *skb;
984
985 if (!ar->wmi.ops->gen_delba_send)
986 return -EOPNOTSUPP;
987
988 skb = ar->wmi.ops->gen_delba_send(ar, vdev_id, mac, tid, initiator,
989 reason);
990 if (IS_ERR(skb))
991 return PTR_ERR(skb);
992
993 return ath10k_wmi_cmd_send(ar, skb,
994 ar->wmi.cmd->delba_send_cmdid);
995}
996
997static inline int
998ath10k_wmi_bcn_tmpl(struct ath10k *ar, u32 vdev_id, u32 tim_ie_offset,
999 struct sk_buff *bcn, u32 prb_caps, u32 prb_erp,
1000 void *prb_ies, size_t prb_ies_len)
1001{
1002 struct sk_buff *skb;
1003
1004 if (!ar->wmi.ops->gen_bcn_tmpl)
1005 return -EOPNOTSUPP;
1006
1007 skb = ar->wmi.ops->gen_bcn_tmpl(ar, vdev_id, tim_ie_offset, bcn,
1008 prb_caps, prb_erp, prb_ies,
1009 prb_ies_len);
1010 if (IS_ERR(skb))
1011 return PTR_ERR(skb);
1012
1013 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->bcn_tmpl_cmdid);
1014}
1015
1016static inline int
1017ath10k_wmi_prb_tmpl(struct ath10k *ar, u32 vdev_id, struct sk_buff *prb)
1018{
1019 struct sk_buff *skb;
1020
1021 if (!ar->wmi.ops->gen_prb_tmpl)
1022 return -EOPNOTSUPP;
1023
1024 skb = ar->wmi.ops->gen_prb_tmpl(ar, vdev_id, prb);
1025 if (IS_ERR(skb))
1026 return PTR_ERR(skb);
1027
1028 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->prb_tmpl_cmdid);
1029}
1030
1031static inline int
1032ath10k_wmi_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, const u8 *p2p_ie)
1033{
1034 struct sk_buff *skb;
1035
1036 if (!ar->wmi.ops->gen_p2p_go_bcn_ie)
1037 return -EOPNOTSUPP;
1038
1039 skb = ar->wmi.ops->gen_p2p_go_bcn_ie(ar, vdev_id, p2p_ie);
1040 if (IS_ERR(skb))
1041 return PTR_ERR(skb);
1042
1043 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->p2p_go_set_beacon_ie);
1044}
1045
1046static inline int
1047ath10k_wmi_sta_keepalive(struct ath10k *ar,
1048 const struct wmi_sta_keepalive_arg *arg)
1049{
1050 struct sk_buff *skb;
1051 u32 cmd_id;
1052
1053 if (!ar->wmi.ops->gen_sta_keepalive)
1054 return -EOPNOTSUPP;
1055
1056 skb = ar->wmi.ops->gen_sta_keepalive(ar, arg);
1057 if (IS_ERR(skb))
1058 return PTR_ERR(skb);
1059
1060 cmd_id = ar->wmi.cmd->sta_keepalive_cmd;
1061 return ath10k_wmi_cmd_send(ar, skb, cmd_id);
1062}
1063
1064#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..71614ba1b145
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -0,0 +1,2696 @@
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 [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]
62 = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) },
63 [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]
64 = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) },
65};
66
67static int
68ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len,
69 int (*iter)(struct ath10k *ar, u16 tag, u16 len,
70 const void *ptr, void *data),
71 void *data)
72{
73 const void *begin = ptr;
74 const struct wmi_tlv *tlv;
75 u16 tlv_tag, tlv_len;
76 int ret;
77
78 while (len > 0) {
79 if (len < sizeof(*tlv)) {
80 ath10k_dbg(ar, ATH10K_DBG_WMI,
81 "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
82 ptr - begin, len, sizeof(*tlv));
83 return -EINVAL;
84 }
85
86 tlv = ptr;
87 tlv_tag = __le16_to_cpu(tlv->tag);
88 tlv_len = __le16_to_cpu(tlv->len);
89 ptr += sizeof(*tlv);
90 len -= sizeof(*tlv);
91
92 if (tlv_len > len) {
93 ath10k_dbg(ar, ATH10K_DBG_WMI,
94 "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n",
95 tlv_tag, ptr - begin, len, tlv_len);
96 return -EINVAL;
97 }
98
99 if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) &&
100 wmi_tlv_policies[tlv_tag].min_len &&
101 wmi_tlv_policies[tlv_tag].min_len > tlv_len) {
102 ath10k_dbg(ar, ATH10K_DBG_WMI,
103 "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n",
104 tlv_tag, ptr - begin, tlv_len,
105 wmi_tlv_policies[tlv_tag].min_len);
106 return -EINVAL;
107 }
108
109 ret = iter(ar, tlv_tag, tlv_len, ptr, data);
110 if (ret)
111 return ret;
112
113 ptr += tlv_len;
114 len -= tlv_len;
115 }
116
117 return 0;
118}
119
120static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len,
121 const void *ptr, void *data)
122{
123 const void **tb = data;
124
125 if (tag < WMI_TLV_TAG_MAX)
126 tb[tag] = ptr;
127
128 return 0;
129}
130
131static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb,
132 const void *ptr, size_t len)
133{
134 return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse,
135 (void *)tb);
136}
137
138static const void **
139ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr,
140 size_t len, gfp_t gfp)
141{
142 const void **tb;
143 int ret;
144
145 tb = kzalloc(sizeof(*tb) * WMI_TLV_TAG_MAX, gfp);
146 if (!tb)
147 return ERR_PTR(-ENOMEM);
148
149 ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len);
150 if (ret) {
151 kfree(tb);
152 return ERR_PTR(ret);
153 }
154
155 return tb;
156}
157
158static u16 ath10k_wmi_tlv_len(const void *ptr)
159{
160 return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len);
161}
162
163/**************/
164/* TLV events */
165/**************/
166static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar,
167 struct sk_buff *skb)
168{
169 const void **tb;
170 const struct wmi_tlv_bcn_tx_status_ev *ev;
171 u32 vdev_id, tx_status;
172 int ret;
173
174 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
175 if (IS_ERR(tb)) {
176 ret = PTR_ERR(tb);
177 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
178 return ret;
179 }
180
181 ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT];
182 if (!ev) {
183 kfree(tb);
184 return -EPROTO;
185 }
186
187 tx_status = __le32_to_cpu(ev->tx_status);
188 vdev_id = __le32_to_cpu(ev->vdev_id);
189
190 switch (tx_status) {
191 case WMI_TLV_BCN_TX_STATUS_OK:
192 break;
193 case WMI_TLV_BCN_TX_STATUS_XRETRY:
194 case WMI_TLV_BCN_TX_STATUS_DROP:
195 case WMI_TLV_BCN_TX_STATUS_FILTERED:
196 /* FIXME: It's probably worth telling mac80211 to stop the
197 * interface as it is crippled.
198 */
199 ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d",
200 vdev_id, tx_status);
201 break;
202 }
203
204 kfree(tb);
205 return 0;
206}
207
208static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar,
209 struct sk_buff *skb)
210{
211 const void **tb;
212 const struct wmi_tlv_diag_data_ev *ev;
213 const struct wmi_tlv_diag_item *item;
214 const void *data;
215 int ret, num_items, len;
216
217 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
218 if (IS_ERR(tb)) {
219 ret = PTR_ERR(tb);
220 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
221 return ret;
222 }
223
224 ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT];
225 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
226 if (!ev || !data) {
227 kfree(tb);
228 return -EPROTO;
229 }
230
231 num_items = __le32_to_cpu(ev->num_items);
232 len = ath10k_wmi_tlv_len(data);
233
234 while (num_items--) {
235 if (len == 0)
236 break;
237 if (len < sizeof(*item)) {
238 ath10k_warn(ar, "failed to parse diag data: can't fit item header\n");
239 break;
240 }
241
242 item = data;
243
244 if (len < sizeof(*item) + __le16_to_cpu(item->len)) {
245 ath10k_warn(ar, "failed to parse diag data: item is too long\n");
246 break;
247 }
248
249 trace_ath10k_wmi_diag_container(ar,
250 item->type,
251 __le32_to_cpu(item->timestamp),
252 __le32_to_cpu(item->code),
253 __le16_to_cpu(item->len),
254 item->payload);
255
256 len -= sizeof(*item);
257 len -= roundup(__le16_to_cpu(item->len), 4);
258
259 data += sizeof(*item);
260 data += roundup(__le16_to_cpu(item->len), 4);
261 }
262
263 if (num_items != -1 || len != 0)
264 ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n",
265 num_items, len);
266
267 kfree(tb);
268 return 0;
269}
270
271static int ath10k_wmi_tlv_event_diag(struct ath10k *ar,
272 struct sk_buff *skb)
273{
274 const void **tb;
275 const void *data;
276 int ret, len;
277
278 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
279 if (IS_ERR(tb)) {
280 ret = PTR_ERR(tb);
281 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
282 return ret;
283 }
284
285 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
286 if (!data) {
287 kfree(tb);
288 return -EPROTO;
289 }
290 len = ath10k_wmi_tlv_len(data);
291
292 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len);
293 trace_ath10k_wmi_diag(ar, data, len);
294
295 kfree(tb);
296 return 0;
297}
298
299/***********/
300/* TLV ops */
301/***********/
302
303static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
304{
305 struct wmi_cmd_hdr *cmd_hdr;
306 enum wmi_tlv_event_id id;
307
308 cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
309 id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
310
311 if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
312 return;
313
314 trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
315
316 switch (id) {
317 case WMI_TLV_MGMT_RX_EVENTID:
318 ath10k_wmi_event_mgmt_rx(ar, skb);
319 /* mgmt_rx() owns the skb now! */
320 return;
321 case WMI_TLV_SCAN_EVENTID:
322 ath10k_wmi_event_scan(ar, skb);
323 break;
324 case WMI_TLV_CHAN_INFO_EVENTID:
325 ath10k_wmi_event_chan_info(ar, skb);
326 break;
327 case WMI_TLV_ECHO_EVENTID:
328 ath10k_wmi_event_echo(ar, skb);
329 break;
330 case WMI_TLV_DEBUG_MESG_EVENTID:
331 ath10k_wmi_event_debug_mesg(ar, skb);
332 break;
333 case WMI_TLV_UPDATE_STATS_EVENTID:
334 ath10k_wmi_event_update_stats(ar, skb);
335 break;
336 case WMI_TLV_VDEV_START_RESP_EVENTID:
337 ath10k_wmi_event_vdev_start_resp(ar, skb);
338 break;
339 case WMI_TLV_VDEV_STOPPED_EVENTID:
340 ath10k_wmi_event_vdev_stopped(ar, skb);
341 break;
342 case WMI_TLV_PEER_STA_KICKOUT_EVENTID:
343 ath10k_wmi_event_peer_sta_kickout(ar, skb);
344 break;
345 case WMI_TLV_HOST_SWBA_EVENTID:
346 ath10k_wmi_event_host_swba(ar, skb);
347 break;
348 case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID:
349 ath10k_wmi_event_tbttoffset_update(ar, skb);
350 break;
351 case WMI_TLV_PHYERR_EVENTID:
352 ath10k_wmi_event_phyerr(ar, skb);
353 break;
354 case WMI_TLV_ROAM_EVENTID:
355 ath10k_wmi_event_roam(ar, skb);
356 break;
357 case WMI_TLV_PROFILE_MATCH:
358 ath10k_wmi_event_profile_match(ar, skb);
359 break;
360 case WMI_TLV_DEBUG_PRINT_EVENTID:
361 ath10k_wmi_event_debug_print(ar, skb);
362 break;
363 case WMI_TLV_PDEV_QVIT_EVENTID:
364 ath10k_wmi_event_pdev_qvit(ar, skb);
365 break;
366 case WMI_TLV_WLAN_PROFILE_DATA_EVENTID:
367 ath10k_wmi_event_wlan_profile_data(ar, skb);
368 break;
369 case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID:
370 ath10k_wmi_event_rtt_measurement_report(ar, skb);
371 break;
372 case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID:
373 ath10k_wmi_event_tsf_measurement_report(ar, skb);
374 break;
375 case WMI_TLV_RTT_ERROR_REPORT_EVENTID:
376 ath10k_wmi_event_rtt_error_report(ar, skb);
377 break;
378 case WMI_TLV_WOW_WAKEUP_HOST_EVENTID:
379 ath10k_wmi_event_wow_wakeup_host(ar, skb);
380 break;
381 case WMI_TLV_DCS_INTERFERENCE_EVENTID:
382 ath10k_wmi_event_dcs_interference(ar, skb);
383 break;
384 case WMI_TLV_PDEV_TPC_CONFIG_EVENTID:
385 ath10k_wmi_event_pdev_tpc_config(ar, skb);
386 break;
387 case WMI_TLV_PDEV_FTM_INTG_EVENTID:
388 ath10k_wmi_event_pdev_ftm_intg(ar, skb);
389 break;
390 case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID:
391 ath10k_wmi_event_gtk_offload_status(ar, skb);
392 break;
393 case WMI_TLV_GTK_REKEY_FAIL_EVENTID:
394 ath10k_wmi_event_gtk_rekey_fail(ar, skb);
395 break;
396 case WMI_TLV_TX_DELBA_COMPLETE_EVENTID:
397 ath10k_wmi_event_delba_complete(ar, skb);
398 break;
399 case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID:
400 ath10k_wmi_event_addba_complete(ar, skb);
401 break;
402 case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID:
403 ath10k_wmi_event_vdev_install_key_complete(ar, skb);
404 break;
405 case WMI_TLV_SERVICE_READY_EVENTID:
406 ath10k_wmi_event_service_ready(ar, skb);
407 break;
408 case WMI_TLV_READY_EVENTID:
409 ath10k_wmi_event_ready(ar, skb);
410 break;
411 case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
412 ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
413 break;
414 case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID:
415 ath10k_wmi_tlv_event_diag_data(ar, skb);
416 break;
417 case WMI_TLV_DIAG_EVENTID:
418 ath10k_wmi_tlv_event_diag(ar, skb);
419 break;
420 default:
421 ath10k_warn(ar, "Unknown eventid: %d\n", id);
422 break;
423 }
424
425 dev_kfree_skb(skb);
426}
427
428static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar,
429 struct sk_buff *skb,
430 struct wmi_scan_ev_arg *arg)
431{
432 const void **tb;
433 const struct wmi_scan_event *ev;
434 int ret;
435
436 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
437 if (IS_ERR(tb)) {
438 ret = PTR_ERR(tb);
439 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
440 return ret;
441 }
442
443 ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT];
444 if (!ev) {
445 kfree(tb);
446 return -EPROTO;
447 }
448
449 arg->event_type = ev->event_type;
450 arg->reason = ev->reason;
451 arg->channel_freq = ev->channel_freq;
452 arg->scan_req_id = ev->scan_req_id;
453 arg->scan_id = ev->scan_id;
454 arg->vdev_id = ev->vdev_id;
455
456 kfree(tb);
457 return 0;
458}
459
460static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar,
461 struct sk_buff *skb,
462 struct wmi_mgmt_rx_ev_arg *arg)
463{
464 const void **tb;
465 const struct wmi_tlv_mgmt_rx_ev *ev;
466 const u8 *frame;
467 u32 msdu_len;
468 int ret;
469
470 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
471 if (IS_ERR(tb)) {
472 ret = PTR_ERR(tb);
473 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
474 return ret;
475 }
476
477 ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR];
478 frame = tb[WMI_TLV_TAG_ARRAY_BYTE];
479
480 if (!ev || !frame) {
481 kfree(tb);
482 return -EPROTO;
483 }
484
485 arg->channel = ev->channel;
486 arg->buf_len = ev->buf_len;
487 arg->status = ev->status;
488 arg->snr = ev->snr;
489 arg->phy_mode = ev->phy_mode;
490 arg->rate = ev->rate;
491
492 msdu_len = __le32_to_cpu(arg->buf_len);
493
494 if (skb->len < (frame - skb->data) + msdu_len) {
495 kfree(tb);
496 return -EPROTO;
497 }
498
499 /* shift the sk_buff to point to `frame` */
500 skb_trim(skb, 0);
501 skb_put(skb, frame - skb->data);
502 skb_pull(skb, frame - skb->data);
503 skb_put(skb, msdu_len);
504
505 kfree(tb);
506 return 0;
507}
508
509static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar,
510 struct sk_buff *skb,
511 struct wmi_ch_info_ev_arg *arg)
512{
513 const void **tb;
514 const struct wmi_chan_info_event *ev;
515 int ret;
516
517 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
518 if (IS_ERR(tb)) {
519 ret = PTR_ERR(tb);
520 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
521 return ret;
522 }
523
524 ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT];
525 if (!ev) {
526 kfree(tb);
527 return -EPROTO;
528 }
529
530 arg->err_code = ev->err_code;
531 arg->freq = ev->freq;
532 arg->cmd_flags = ev->cmd_flags;
533 arg->noise_floor = ev->noise_floor;
534 arg->rx_clear_count = ev->rx_clear_count;
535 arg->cycle_count = ev->cycle_count;
536
537 kfree(tb);
538 return 0;
539}
540
541static int
542ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
543 struct wmi_vdev_start_ev_arg *arg)
544{
545 const void **tb;
546 const struct wmi_vdev_start_response_event *ev;
547 int ret;
548
549 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
550 if (IS_ERR(tb)) {
551 ret = PTR_ERR(tb);
552 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
553 return ret;
554 }
555
556 ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT];
557 if (!ev) {
558 kfree(tb);
559 return -EPROTO;
560 }
561
562 skb_pull(skb, sizeof(*ev));
563 arg->vdev_id = ev->vdev_id;
564 arg->req_id = ev->req_id;
565 arg->resp_type = ev->resp_type;
566 arg->status = ev->status;
567
568 kfree(tb);
569 return 0;
570}
571
572static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar,
573 struct sk_buff *skb,
574 struct wmi_peer_kick_ev_arg *arg)
575{
576 const void **tb;
577 const struct wmi_peer_sta_kickout_event *ev;
578 int ret;
579
580 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
581 if (IS_ERR(tb)) {
582 ret = PTR_ERR(tb);
583 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
584 return ret;
585 }
586
587 ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT];
588 if (!ev) {
589 kfree(tb);
590 return -EPROTO;
591 }
592
593 arg->mac_addr = ev->peer_macaddr.addr;
594
595 kfree(tb);
596 return 0;
597}
598
599struct wmi_tlv_swba_parse {
600 const struct wmi_host_swba_event *ev;
601 bool tim_done;
602 bool noa_done;
603 size_t n_tim;
604 size_t n_noa;
605 struct wmi_swba_ev_arg *arg;
606};
607
608static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len,
609 const void *ptr, void *data)
610{
611 struct wmi_tlv_swba_parse *swba = data;
612
613 if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO)
614 return -EPROTO;
615
616 if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info))
617 return -ENOBUFS;
618
619 swba->arg->tim_info[swba->n_tim++] = ptr;
620 return 0;
621}
622
623static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len,
624 const void *ptr, void *data)
625{
626 struct wmi_tlv_swba_parse *swba = data;
627
628 if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO)
629 return -EPROTO;
630
631 if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info))
632 return -ENOBUFS;
633
634 swba->arg->noa_info[swba->n_noa++] = ptr;
635 return 0;
636}
637
638static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len,
639 const void *ptr, void *data)
640{
641 struct wmi_tlv_swba_parse *swba = data;
642 int ret;
643
644 switch (tag) {
645 case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT:
646 swba->ev = ptr;
647 break;
648 case WMI_TLV_TAG_ARRAY_STRUCT:
649 if (!swba->tim_done) {
650 swba->tim_done = true;
651 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
652 ath10k_wmi_tlv_swba_tim_parse,
653 swba);
654 if (ret)
655 return ret;
656 } else if (!swba->noa_done) {
657 swba->noa_done = true;
658 ret = ath10k_wmi_tlv_iter(ar, ptr, len,
659 ath10k_wmi_tlv_swba_noa_parse,
660 swba);
661 if (ret)
662 return ret;
663 }
664 break;
665 default:
666 break;
667 }
668 return 0;
669}
670
671static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar,
672 struct sk_buff *skb,
673 struct wmi_swba_ev_arg *arg)
674{
675 struct wmi_tlv_swba_parse swba = { .arg = arg };
676 u32 map;
677 size_t n_vdevs;
678 int ret;
679
680 ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
681 ath10k_wmi_tlv_swba_parse, &swba);
682 if (ret) {
683 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
684 return ret;
685 }
686
687 if (!swba.ev)
688 return -EPROTO;
689
690 arg->vdev_map = swba.ev->vdev_map;
691
692 for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1)
693 if (map & BIT(0))
694 n_vdevs++;
695
696 if (n_vdevs != swba.n_tim ||
697 n_vdevs != swba.n_noa)
698 return -EPROTO;
699
700 return 0;
701}
702
703static int ath10k_wmi_tlv_op_pull_phyerr_ev(struct ath10k *ar,
704 struct sk_buff *skb,
705 struct wmi_phyerr_ev_arg *arg)
706{
707 const void **tb;
708 const struct wmi_tlv_phyerr_ev *ev;
709 const void *phyerrs;
710 int ret;
711
712 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
713 if (IS_ERR(tb)) {
714 ret = PTR_ERR(tb);
715 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
716 return ret;
717 }
718
719 ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR];
720 phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE];
721
722 if (!ev || !phyerrs) {
723 kfree(tb);
724 return -EPROTO;
725 }
726
727 arg->num_phyerrs = ev->num_phyerrs;
728 arg->tsf_l32 = ev->tsf_l32;
729 arg->tsf_u32 = ev->tsf_u32;
730 arg->buf_len = ev->buf_len;
731 arg->phyerrs = phyerrs;
732
733 kfree(tb);
734 return 0;
735}
736
737#define WMI_TLV_ABI_VER_NS0 0x5F414351
738#define WMI_TLV_ABI_VER_NS1 0x00004C4D
739#define WMI_TLV_ABI_VER_NS2 0x00000000
740#define WMI_TLV_ABI_VER_NS3 0x00000000
741
742#define WMI_TLV_ABI_VER0_MAJOR 1
743#define WMI_TLV_ABI_VER0_MINOR 0
744#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \
745 (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF))
746#define WMI_TLV_ABI_VER1 53
747
748static int
749ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
750 const void *ptr, void *data)
751{
752 struct wmi_svc_rdy_ev_arg *arg = data;
753 int i;
754
755 if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ)
756 return -EPROTO;
757
758 for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) {
759 if (!arg->mem_reqs[i]) {
760 arg->mem_reqs[i] = ptr;
761 return 0;
762 }
763 }
764
765 return -ENOMEM;
766}
767
768static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
769 struct sk_buff *skb,
770 struct wmi_svc_rdy_ev_arg *arg)
771{
772 const void **tb;
773 const struct hal_reg_capabilities *reg;
774 const struct wmi_tlv_svc_rdy_ev *ev;
775 const __le32 *svc_bmap;
776 const struct wlan_host_mem_req *mem_reqs;
777 int ret;
778
779 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
780 if (IS_ERR(tb)) {
781 ret = PTR_ERR(tb);
782 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
783 return ret;
784 }
785
786 ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
787 reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
788 svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
789 mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
790
791 if (!ev || !reg || !svc_bmap || !mem_reqs) {
792 kfree(tb);
793 return -EPROTO;
794 }
795
796 /* This is an internal ABI compatibility check for WMI TLV so check it
797 * here instead of the generic WMI code.
798 */
799 ath10k_dbg(ar, ATH10K_DBG_WMI,
800 "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n",
801 __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0,
802 __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0,
803 __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1,
804 __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2,
805 __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3);
806
807 if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 ||
808 __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 ||
809 __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
810 __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
811 __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
812 kfree(tb);
813 return -ENOTSUPP;
814 }
815
816 arg->min_tx_power = ev->hw_min_tx_power;
817 arg->max_tx_power = ev->hw_max_tx_power;
818 arg->ht_cap = ev->ht_cap_info;
819 arg->vht_cap = ev->vht_cap_info;
820 arg->sw_ver0 = ev->abi.abi_ver0;
821 arg->sw_ver1 = ev->abi.abi_ver1;
822 arg->fw_build = ev->fw_build_vers;
823 arg->phy_capab = ev->phy_capability;
824 arg->num_rf_chains = ev->num_rf_chains;
825 arg->eeprom_rd = reg->eeprom_rd;
826 arg->num_mem_reqs = ev->num_mem_reqs;
827 arg->service_map = svc_bmap;
828 arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap);
829
830 ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
831 ath10k_wmi_tlv_parse_mem_reqs, arg);
832 if (ret) {
833 kfree(tb);
834 ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
835 return ret;
836 }
837
838 kfree(tb);
839 return 0;
840}
841
842static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
843 struct sk_buff *skb,
844 struct wmi_rdy_ev_arg *arg)
845{
846 const void **tb;
847 const struct wmi_tlv_rdy_ev *ev;
848 int ret;
849
850 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
851 if (IS_ERR(tb)) {
852 ret = PTR_ERR(tb);
853 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
854 return ret;
855 }
856
857 ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT];
858 if (!ev) {
859 kfree(tb);
860 return -EPROTO;
861 }
862
863 arg->sw_version = ev->abi.abi_ver0;
864 arg->abi_version = ev->abi.abi_ver1;
865 arg->status = ev->status;
866 arg->mac_addr = ev->mac_addr.addr;
867
868 kfree(tb);
869 return 0;
870}
871
872static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
873 struct sk_buff *skb,
874 struct ath10k_fw_stats *stats)
875{
876 const void **tb;
877 const struct wmi_stats_event *ev;
878 const void *data;
879 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
880 size_t data_len;
881 int ret;
882
883 tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
884 if (IS_ERR(tb)) {
885 ret = PTR_ERR(tb);
886 ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
887 return ret;
888 }
889
890 ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT];
891 data = tb[WMI_TLV_TAG_ARRAY_BYTE];
892
893 if (!ev || !data) {
894 kfree(tb);
895 return -EPROTO;
896 }
897
898 data_len = ath10k_wmi_tlv_len(data);
899 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
900 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
901 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
902
903 WARN_ON(1); /* FIXME: not implemented yet */
904
905 kfree(tb);
906 return 0;
907}
908
909static struct sk_buff *
910ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt)
911{
912 struct wmi_tlv_pdev_suspend *cmd;
913 struct wmi_tlv *tlv;
914 struct sk_buff *skb;
915
916 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
917 if (!skb)
918 return ERR_PTR(-ENOMEM);
919
920 tlv = (void *)skb->data;
921 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD);
922 tlv->len = __cpu_to_le16(sizeof(*cmd));
923 cmd = (void *)tlv->value;
924 cmd->opt = __cpu_to_le32(opt);
925
926 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n");
927 return skb;
928}
929
930static struct sk_buff *
931ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar)
932{
933 struct wmi_tlv_resume_cmd *cmd;
934 struct wmi_tlv *tlv;
935 struct sk_buff *skb;
936
937 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
938 if (!skb)
939 return ERR_PTR(-ENOMEM);
940
941 tlv = (void *)skb->data;
942 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD);
943 tlv->len = __cpu_to_le16(sizeof(*cmd));
944 cmd = (void *)tlv->value;
945 cmd->reserved = __cpu_to_le32(0);
946
947 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n");
948 return skb;
949}
950
951static struct sk_buff *
952ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar,
953 u16 rd, u16 rd2g, u16 rd5g,
954 u16 ctl2g, u16 ctl5g,
955 enum wmi_dfs_region dfs_reg)
956{
957 struct wmi_tlv_pdev_set_rd_cmd *cmd;
958 struct wmi_tlv *tlv;
959 struct sk_buff *skb;
960
961 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
962 if (!skb)
963 return ERR_PTR(-ENOMEM);
964
965 tlv = (void *)skb->data;
966 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD);
967 tlv->len = __cpu_to_le16(sizeof(*cmd));
968 cmd = (void *)tlv->value;
969 cmd->regd = __cpu_to_le32(rd);
970 cmd->regd_2ghz = __cpu_to_le32(rd2g);
971 cmd->regd_5ghz = __cpu_to_le32(rd5g);
972 cmd->conform_limit_2ghz = __cpu_to_le32(rd2g);
973 cmd->conform_limit_5ghz = __cpu_to_le32(rd5g);
974
975 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n");
976 return skb;
977}
978
979static struct sk_buff *
980ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id,
981 u32 param_value)
982{
983 struct wmi_tlv_pdev_set_param_cmd *cmd;
984 struct wmi_tlv *tlv;
985 struct sk_buff *skb;
986
987 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
988 if (!skb)
989 return ERR_PTR(-ENOMEM);
990
991 tlv = (void *)skb->data;
992 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD);
993 tlv->len = __cpu_to_le16(sizeof(*cmd));
994 cmd = (void *)tlv->value;
995 cmd->param_id = __cpu_to_le32(param_id);
996 cmd->param_value = __cpu_to_le32(param_value);
997
998 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param\n");
999 return skb;
1000}
1001
1002static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
1003{
1004 struct sk_buff *skb;
1005 struct wmi_tlv *tlv;
1006 struct wmi_tlv_init_cmd *cmd;
1007 struct wmi_tlv_resource_config *cfg;
1008 struct wmi_host_mem_chunks *chunks;
1009 size_t len, chunks_len;
1010 void *ptr;
1011
1012 chunks_len = ar->wmi.num_mem_chunks * sizeof(struct host_memory_chunk);
1013 len = (sizeof(*tlv) + sizeof(*cmd)) +
1014 (sizeof(*tlv) + sizeof(*cfg)) +
1015 (sizeof(*tlv) + chunks_len);
1016
1017 skb = ath10k_wmi_alloc_skb(ar, len);
1018 if (!skb)
1019 return ERR_PTR(-ENOMEM);
1020
1021 ptr = skb->data;
1022
1023 tlv = ptr;
1024 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD);
1025 tlv->len = __cpu_to_le16(sizeof(*cmd));
1026 cmd = (void *)tlv->value;
1027 ptr += sizeof(*tlv);
1028 ptr += sizeof(*cmd);
1029
1030 tlv = ptr;
1031 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG);
1032 tlv->len = __cpu_to_le16(sizeof(*cfg));
1033 cfg = (void *)tlv->value;
1034 ptr += sizeof(*tlv);
1035 ptr += sizeof(*cfg);
1036
1037 tlv = ptr;
1038 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1039 tlv->len = __cpu_to_le16(chunks_len);
1040 chunks = (void *)tlv->value;
1041
1042 ptr += sizeof(*tlv);
1043 ptr += chunks_len;
1044
1045 cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0);
1046 cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1);
1047 cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0);
1048 cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1);
1049 cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2);
1050 cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3);
1051 cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks);
1052
1053 cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS);
1054 cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS);
1055
1056 if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) {
1057 cfg->num_offload_peers = __cpu_to_le32(3);
1058 cfg->num_offload_reorder_bufs = __cpu_to_le32(3);
1059 } else {
1060 cfg->num_offload_peers = __cpu_to_le32(0);
1061 cfg->num_offload_reorder_bufs = __cpu_to_le32(0);
1062 }
1063
1064 cfg->num_peer_keys = __cpu_to_le32(2);
1065 cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS);
1066 cfg->ast_skid_limit = __cpu_to_le32(0x10);
1067 cfg->tx_chain_mask = __cpu_to_le32(0x7);
1068 cfg->rx_chain_mask = __cpu_to_le32(0x7);
1069 cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64);
1070 cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64);
1071 cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64);
1072 cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28);
1073 cfg->rx_decap_mode = __cpu_to_le32(1);
1074 cfg->scan_max_pending_reqs = __cpu_to_le32(4);
1075 cfg->bmiss_offload_max_vdev = __cpu_to_le32(3);
1076 cfg->roam_offload_max_vdev = __cpu_to_le32(3);
1077 cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8);
1078 cfg->num_mcast_groups = __cpu_to_le32(0);
1079 cfg->num_mcast_table_elems = __cpu_to_le32(0);
1080 cfg->mcast2ucast_mode = __cpu_to_le32(0);
1081 cfg->tx_dbg_log_size = __cpu_to_le32(0x400);
1082 cfg->num_wds_entries = __cpu_to_le32(0x20);
1083 cfg->dma_burst_size = __cpu_to_le32(0);
1084 cfg->mac_aggr_delim = __cpu_to_le32(0);
1085 cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0);
1086 cfg->vow_config = __cpu_to_le32(0);
1087 cfg->gtk_offload_max_vdev = __cpu_to_le32(2);
1088 cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC);
1089 cfg->max_frag_entries = __cpu_to_le32(2);
1090 cfg->num_tdls_vdevs = __cpu_to_le32(1);
1091 cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
1092 cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
1093 cfg->num_multicast_filter_entries = __cpu_to_le32(5);
1094 cfg->num_wow_filters = __cpu_to_le32(0x16);
1095 cfg->num_keep_alive_pattern = __cpu_to_le32(6);
1096 cfg->keep_alive_pattern_size = __cpu_to_le32(0);
1097 cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
1098 cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1);
1099
1100 ath10k_wmi_put_host_mem_chunks(ar, chunks);
1101
1102 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n");
1103 return skb;
1104}
1105
1106static struct sk_buff *
1107ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar,
1108 const struct wmi_start_scan_arg *arg)
1109{
1110 struct wmi_tlv_start_scan_cmd *cmd;
1111 struct wmi_tlv *tlv;
1112 struct sk_buff *skb;
1113 size_t len, chan_len, ssid_len, bssid_len, ie_len;
1114 __le32 *chans;
1115 struct wmi_ssid *ssids;
1116 struct wmi_mac_addr *addrs;
1117 void *ptr;
1118 int i, ret;
1119
1120 ret = ath10k_wmi_start_scan_verify(arg);
1121 if (ret)
1122 return ERR_PTR(ret);
1123
1124 chan_len = arg->n_channels * sizeof(__le32);
1125 ssid_len = arg->n_ssids * sizeof(struct wmi_ssid);
1126 bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr);
1127 ie_len = roundup(arg->ie_len, 4);
1128 len = (sizeof(*tlv) + sizeof(*cmd)) +
1129 (arg->n_channels ? sizeof(*tlv) + chan_len : 0) +
1130 (arg->n_ssids ? sizeof(*tlv) + ssid_len : 0) +
1131 (arg->n_bssids ? sizeof(*tlv) + bssid_len : 0) +
1132 (arg->ie_len ? sizeof(*tlv) + ie_len : 0);
1133
1134 skb = ath10k_wmi_alloc_skb(ar, len);
1135 if (!skb)
1136 return ERR_PTR(-ENOMEM);
1137
1138 ptr = (void *)skb->data;
1139 tlv = ptr;
1140 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD);
1141 tlv->len = __cpu_to_le16(sizeof(*cmd));
1142 cmd = (void *)tlv->value;
1143
1144 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
1145 cmd->burst_duration_ms = __cpu_to_le32(0);
1146 cmd->num_channels = __cpu_to_le32(arg->n_channels);
1147 cmd->num_ssids = __cpu_to_le32(arg->n_ssids);
1148 cmd->num_bssids = __cpu_to_le32(arg->n_bssids);
1149 cmd->ie_len = __cpu_to_le32(arg->ie_len);
1150 cmd->num_probes = __cpu_to_le32(3);
1151
1152 /* FIXME: There are some scan flag inconsistencies across firmwares,
1153 * e.g. WMI-TLV inverts the logic behind the following flag.
1154 */
1155 cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ);
1156
1157 ptr += sizeof(*tlv);
1158 ptr += sizeof(*cmd);
1159
1160 tlv = ptr;
1161 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
1162 tlv->len = __cpu_to_le16(chan_len);
1163 chans = (void *)tlv->value;
1164 for (i = 0; i < arg->n_channels; i++)
1165 chans[i] = __cpu_to_le32(arg->channels[i]);
1166
1167 ptr += sizeof(*tlv);
1168 ptr += chan_len;
1169
1170 tlv = ptr;
1171 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1172 tlv->len = __cpu_to_le16(ssid_len);
1173 ssids = (void *)tlv->value;
1174 for (i = 0; i < arg->n_ssids; i++) {
1175 ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len);
1176 memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len);
1177 }
1178
1179 ptr += sizeof(*tlv);
1180 ptr += ssid_len;
1181
1182 tlv = ptr;
1183 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT);
1184 tlv->len = __cpu_to_le16(bssid_len);
1185 addrs = (void *)tlv->value;
1186 for (i = 0; i < arg->n_bssids; i++)
1187 ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid);
1188
1189 ptr += sizeof(*tlv);
1190 ptr += bssid_len;
1191
1192 tlv = ptr;
1193 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1194 tlv->len = __cpu_to_le16(ie_len);
1195 memcpy(tlv->value, arg->ie, arg->ie_len);
1196
1197 ptr += sizeof(*tlv);
1198 ptr += ie_len;
1199
1200 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n");
1201 return skb;
1202}
1203
1204static struct sk_buff *
1205ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar,
1206 const struct wmi_stop_scan_arg *arg)
1207{
1208 struct wmi_stop_scan_cmd *cmd;
1209 struct wmi_tlv *tlv;
1210 struct sk_buff *skb;
1211 u32 scan_id;
1212 u32 req_id;
1213
1214 if (arg->req_id > 0xFFF)
1215 return ERR_PTR(-EINVAL);
1216 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
1217 return ERR_PTR(-EINVAL);
1218
1219 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1220 if (!skb)
1221 return ERR_PTR(-ENOMEM);
1222
1223 scan_id = arg->u.scan_id;
1224 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
1225
1226 req_id = arg->req_id;
1227 req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX;
1228
1229 tlv = (void *)skb->data;
1230 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD);
1231 tlv->len = __cpu_to_le16(sizeof(*cmd));
1232 cmd = (void *)tlv->value;
1233 cmd->req_type = __cpu_to_le32(arg->req_type);
1234 cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id);
1235 cmd->scan_id = __cpu_to_le32(scan_id);
1236 cmd->scan_req_id = __cpu_to_le32(req_id);
1237
1238 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n");
1239 return skb;
1240}
1241
1242static struct sk_buff *
1243ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar,
1244 u32 vdev_id,
1245 enum wmi_vdev_type vdev_type,
1246 enum wmi_vdev_subtype vdev_subtype,
1247 const u8 mac_addr[ETH_ALEN])
1248{
1249 struct wmi_vdev_create_cmd *cmd;
1250 struct wmi_tlv *tlv;
1251 struct sk_buff *skb;
1252
1253 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1254 if (!skb)
1255 return ERR_PTR(-ENOMEM);
1256
1257 tlv = (void *)skb->data;
1258 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD);
1259 tlv->len = __cpu_to_le16(sizeof(*cmd));
1260 cmd = (void *)tlv->value;
1261 cmd->vdev_id = __cpu_to_le32(vdev_id);
1262 cmd->vdev_type = __cpu_to_le32(vdev_type);
1263 cmd->vdev_subtype = __cpu_to_le32(vdev_subtype);
1264 ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr);
1265
1266 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n");
1267 return skb;
1268}
1269
1270static struct sk_buff *
1271ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
1272{
1273 struct wmi_vdev_delete_cmd *cmd;
1274 struct wmi_tlv *tlv;
1275 struct sk_buff *skb;
1276
1277 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1278 if (!skb)
1279 return ERR_PTR(-ENOMEM);
1280
1281 tlv = (void *)skb->data;
1282 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD);
1283 tlv->len = __cpu_to_le16(sizeof(*cmd));
1284 cmd = (void *)tlv->value;
1285 cmd->vdev_id = __cpu_to_le32(vdev_id);
1286
1287 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n");
1288 return skb;
1289}
1290
1291static struct sk_buff *
1292ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar,
1293 const struct wmi_vdev_start_request_arg *arg,
1294 bool restart)
1295{
1296 struct wmi_tlv_vdev_start_cmd *cmd;
1297 struct wmi_channel *ch;
1298 struct wmi_p2p_noa_descriptor *noa;
1299 struct wmi_tlv *tlv;
1300 struct sk_buff *skb;
1301 size_t len;
1302 void *ptr;
1303 u32 flags = 0;
1304
1305 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
1306 return ERR_PTR(-EINVAL);
1307 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
1308 return ERR_PTR(-EINVAL);
1309 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
1310 return ERR_PTR(-EINVAL);
1311
1312 len = (sizeof(*tlv) + sizeof(*cmd)) +
1313 (sizeof(*tlv) + sizeof(*ch)) +
1314 (sizeof(*tlv) + 0);
1315 skb = ath10k_wmi_alloc_skb(ar, len);
1316 if (!skb)
1317 return ERR_PTR(-ENOMEM);
1318
1319 if (arg->hidden_ssid)
1320 flags |= WMI_VDEV_START_HIDDEN_SSID;
1321 if (arg->pmf_enabled)
1322 flags |= WMI_VDEV_START_PMF_ENABLED;
1323
1324 ptr = (void *)skb->data;
1325
1326 tlv = ptr;
1327 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD);
1328 tlv->len = __cpu_to_le16(sizeof(*cmd));
1329 cmd = (void *)tlv->value;
1330 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1331 cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval);
1332 cmd->dtim_period = __cpu_to_le32(arg->dtim_period);
1333 cmd->flags = __cpu_to_le32(flags);
1334 cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate);
1335 cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power);
1336 cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack);
1337
1338 if (arg->ssid) {
1339 cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len);
1340 memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len);
1341 }
1342
1343 ptr += sizeof(*tlv);
1344 ptr += sizeof(*cmd);
1345
1346 tlv = ptr;
1347 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1348 tlv->len = __cpu_to_le16(sizeof(*ch));
1349 ch = (void *)tlv->value;
1350 ath10k_wmi_put_wmi_channel(ch, &arg->channel);
1351
1352 ptr += sizeof(*tlv);
1353 ptr += sizeof(*ch);
1354
1355 tlv = ptr;
1356 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1357 tlv->len = 0;
1358 noa = (void *)tlv->value;
1359
1360 /* Note: This is a nested TLV containing:
1361 * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv]..
1362 */
1363
1364 ptr += sizeof(*tlv);
1365 ptr += 0;
1366
1367 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n");
1368 return skb;
1369}
1370
1371static struct sk_buff *
1372ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
1373{
1374 struct wmi_vdev_stop_cmd *cmd;
1375 struct wmi_tlv *tlv;
1376 struct sk_buff *skb;
1377
1378 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1379 if (!skb)
1380 return ERR_PTR(-ENOMEM);
1381
1382 tlv = (void *)skb->data;
1383 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD);
1384 tlv->len = __cpu_to_le16(sizeof(*cmd));
1385 cmd = (void *)tlv->value;
1386 cmd->vdev_id = __cpu_to_le32(vdev_id);
1387
1388 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n");
1389 return skb;
1390}
1391
1392static struct sk_buff *
1393ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
1394 const u8 *bssid)
1395
1396{
1397 struct wmi_vdev_up_cmd *cmd;
1398 struct wmi_tlv *tlv;
1399 struct sk_buff *skb;
1400
1401 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1402 if (!skb)
1403 return ERR_PTR(-ENOMEM);
1404
1405 tlv = (void *)skb->data;
1406 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD);
1407 tlv->len = __cpu_to_le16(sizeof(*cmd));
1408 cmd = (void *)tlv->value;
1409 cmd->vdev_id = __cpu_to_le32(vdev_id);
1410 cmd->vdev_assoc_id = __cpu_to_le32(aid);
1411 ether_addr_copy(cmd->vdev_bssid.addr, bssid);
1412
1413 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n");
1414 return skb;
1415}
1416
1417static struct sk_buff *
1418ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
1419{
1420 struct wmi_vdev_down_cmd *cmd;
1421 struct wmi_tlv *tlv;
1422 struct sk_buff *skb;
1423
1424 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1425 if (!skb)
1426 return ERR_PTR(-ENOMEM);
1427
1428 tlv = (void *)skb->data;
1429 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD);
1430 tlv->len = __cpu_to_le16(sizeof(*cmd));
1431 cmd = (void *)tlv->value;
1432 cmd->vdev_id = __cpu_to_le32(vdev_id);
1433
1434 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n");
1435 return skb;
1436}
1437
1438static struct sk_buff *
1439ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
1440 u32 param_id, u32 param_value)
1441{
1442 struct wmi_vdev_set_param_cmd *cmd;
1443 struct wmi_tlv *tlv;
1444 struct sk_buff *skb;
1445
1446 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1447 if (!skb)
1448 return ERR_PTR(-ENOMEM);
1449
1450 tlv = (void *)skb->data;
1451 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD);
1452 tlv->len = __cpu_to_le16(sizeof(*cmd));
1453 cmd = (void *)tlv->value;
1454 cmd->vdev_id = __cpu_to_le32(vdev_id);
1455 cmd->param_id = __cpu_to_le32(param_id);
1456 cmd->param_value = __cpu_to_le32(param_value);
1457
1458 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev set param\n");
1459 return skb;
1460}
1461
1462static struct sk_buff *
1463ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar,
1464 const struct wmi_vdev_install_key_arg *arg)
1465{
1466 struct wmi_vdev_install_key_cmd *cmd;
1467 struct wmi_tlv *tlv;
1468 struct sk_buff *skb;
1469 size_t len;
1470 void *ptr;
1471
1472 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
1473 return ERR_PTR(-EINVAL);
1474 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
1475 return ERR_PTR(-EINVAL);
1476
1477 len = sizeof(*tlv) + sizeof(*cmd) +
1478 sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32));
1479 skb = ath10k_wmi_alloc_skb(ar, len);
1480 if (!skb)
1481 return ERR_PTR(-ENOMEM);
1482
1483 ptr = (void *)skb->data;
1484 tlv = ptr;
1485 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD);
1486 tlv->len = __cpu_to_le16(sizeof(*cmd));
1487 cmd = (void *)tlv->value;
1488 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1489 cmd->key_idx = __cpu_to_le32(arg->key_idx);
1490 cmd->key_flags = __cpu_to_le32(arg->key_flags);
1491 cmd->key_cipher = __cpu_to_le32(arg->key_cipher);
1492 cmd->key_len = __cpu_to_le32(arg->key_len);
1493 cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len);
1494 cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
1495
1496 if (arg->macaddr)
1497 ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
1498
1499 ptr += sizeof(*tlv);
1500 ptr += sizeof(*cmd);
1501
1502 tlv = ptr;
1503 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1504 tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32)));
1505 if (arg->key_data)
1506 memcpy(tlv->value, arg->key_data, arg->key_len);
1507
1508 ptr += sizeof(*tlv);
1509 ptr += roundup(arg->key_len, sizeof(__le32));
1510
1511 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n");
1512 return skb;
1513}
1514
1515static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr,
1516 const struct wmi_sta_uapsd_auto_trig_arg *arg)
1517{
1518 struct wmi_sta_uapsd_auto_trig_param *ac;
1519 struct wmi_tlv *tlv;
1520
1521 tlv = ptr;
1522 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM);
1523 tlv->len = __cpu_to_le16(sizeof(*ac));
1524 ac = (void *)tlv->value;
1525
1526 ac->wmm_ac = __cpu_to_le32(arg->wmm_ac);
1527 ac->user_priority = __cpu_to_le32(arg->user_priority);
1528 ac->service_interval = __cpu_to_le32(arg->service_interval);
1529 ac->suspend_interval = __cpu_to_le32(arg->suspend_interval);
1530 ac->delay_interval = __cpu_to_le32(arg->delay_interval);
1531
1532 ath10k_dbg(ar, ATH10K_DBG_WMI,
1533 "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n",
1534 ac->wmm_ac, ac->user_priority, ac->service_interval,
1535 ac->suspend_interval, ac->delay_interval);
1536
1537 return ptr + sizeof(*tlv) + sizeof(*ac);
1538}
1539
1540static struct sk_buff *
1541ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id,
1542 const u8 peer_addr[ETH_ALEN],
1543 const struct wmi_sta_uapsd_auto_trig_arg *args,
1544 u32 num_ac)
1545{
1546 struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd;
1547 struct wmi_sta_uapsd_auto_trig_param *ac;
1548 struct wmi_tlv *tlv;
1549 struct sk_buff *skb;
1550 size_t len;
1551 size_t ac_tlv_len;
1552 void *ptr;
1553 int i;
1554
1555 ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac));
1556 len = sizeof(*tlv) + sizeof(*cmd) +
1557 sizeof(*tlv) + ac_tlv_len;
1558 skb = ath10k_wmi_alloc_skb(ar, len);
1559 if (!skb)
1560 return ERR_PTR(-ENOMEM);
1561
1562 ptr = (void *)skb->data;
1563 tlv = ptr;
1564 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD);
1565 tlv->len = __cpu_to_le16(sizeof(*cmd));
1566 cmd = (void *)tlv->value;
1567 cmd->vdev_id = __cpu_to_le32(vdev_id);
1568 cmd->num_ac = __cpu_to_le32(num_ac);
1569 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1570
1571 ptr += sizeof(*tlv);
1572 ptr += sizeof(*cmd);
1573
1574 tlv = ptr;
1575 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1576 tlv->len = __cpu_to_le16(ac_tlv_len);
1577 ac = (void *)tlv->value;
1578
1579 ptr += sizeof(*tlv);
1580 for (i = 0; i < num_ac; i++)
1581 ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]);
1582
1583 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n");
1584 return skb;
1585}
1586
1587static void *ath10k_wmi_tlv_put_wmm(void *ptr,
1588 const struct wmi_wmm_params_arg *arg)
1589{
1590 struct wmi_wmm_params *wmm;
1591 struct wmi_tlv *tlv;
1592
1593 tlv = ptr;
1594 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS);
1595 tlv->len = __cpu_to_le16(sizeof(*wmm));
1596 wmm = (void *)tlv->value;
1597 ath10k_wmi_set_wmm_param(wmm, arg);
1598
1599 return ptr + sizeof(*tlv) + sizeof(*wmm);
1600}
1601
1602static struct sk_buff *
1603ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id,
1604 const struct wmi_wmm_params_all_arg *arg)
1605{
1606 struct wmi_tlv_vdev_set_wmm_cmd *cmd;
1607 struct wmi_wmm_params *wmm;
1608 struct wmi_tlv *tlv;
1609 struct sk_buff *skb;
1610 size_t len;
1611 void *ptr;
1612
1613 len = (sizeof(*tlv) + sizeof(*cmd)) +
1614 (4 * (sizeof(*tlv) + sizeof(*wmm)));
1615 skb = ath10k_wmi_alloc_skb(ar, len);
1616 if (!skb)
1617 return ERR_PTR(-ENOMEM);
1618
1619 ptr = (void *)skb->data;
1620 tlv = ptr;
1621 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD);
1622 tlv->len = __cpu_to_le16(sizeof(*cmd));
1623 cmd = (void *)tlv->value;
1624 cmd->vdev_id = __cpu_to_le32(vdev_id);
1625
1626 ptr += sizeof(*tlv);
1627 ptr += sizeof(*cmd);
1628
1629 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
1630 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
1631 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
1632 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
1633
1634 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n");
1635 return skb;
1636}
1637
1638static struct sk_buff *
1639ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar,
1640 const struct wmi_sta_keepalive_arg *arg)
1641{
1642 struct wmi_tlv_sta_keepalive_cmd *cmd;
1643 struct wmi_sta_keepalive_arp_resp *arp;
1644 struct sk_buff *skb;
1645 struct wmi_tlv *tlv;
1646 void *ptr;
1647 size_t len;
1648
1649 len = sizeof(*tlv) + sizeof(*cmd) +
1650 sizeof(*tlv) + sizeof(*arp);
1651 skb = ath10k_wmi_alloc_skb(ar, len);
1652 if (!skb)
1653 return ERR_PTR(-ENOMEM);
1654
1655 ptr = (void *)skb->data;
1656 tlv = ptr;
1657 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD);
1658 tlv->len = __cpu_to_le16(sizeof(*cmd));
1659 cmd = (void *)tlv->value;
1660 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1661 cmd->enabled = __cpu_to_le32(arg->enabled);
1662 cmd->method = __cpu_to_le32(arg->method);
1663 cmd->interval = __cpu_to_le32(arg->interval);
1664
1665 ptr += sizeof(*tlv);
1666 ptr += sizeof(*cmd);
1667
1668 tlv = ptr;
1669 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE);
1670 tlv->len = __cpu_to_le16(sizeof(*arp));
1671 arp = (void *)tlv->value;
1672
1673 arp->src_ip4_addr = arg->src_ip4_addr;
1674 arp->dest_ip4_addr = arg->dest_ip4_addr;
1675 ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr);
1676
1677 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d inverval %d\n",
1678 arg->vdev_id, arg->enabled, arg->method, arg->interval);
1679 return skb;
1680}
1681
1682static struct sk_buff *
1683ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
1684 const u8 peer_addr[ETH_ALEN])
1685{
1686 struct wmi_tlv_peer_create_cmd *cmd;
1687 struct wmi_tlv *tlv;
1688 struct sk_buff *skb;
1689
1690 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1691 if (!skb)
1692 return ERR_PTR(-ENOMEM);
1693
1694 tlv = (void *)skb->data;
1695 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD);
1696 tlv->len = __cpu_to_le16(sizeof(*cmd));
1697 cmd = (void *)tlv->value;
1698 cmd->vdev_id = __cpu_to_le32(vdev_id);
1699 cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */
1700 ether_addr_copy(cmd->peer_addr.addr, peer_addr);
1701
1702 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n");
1703 return skb;
1704}
1705
1706static struct sk_buff *
1707ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
1708 const u8 peer_addr[ETH_ALEN])
1709{
1710 struct wmi_peer_delete_cmd *cmd;
1711 struct wmi_tlv *tlv;
1712 struct sk_buff *skb;
1713
1714 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1715 if (!skb)
1716 return ERR_PTR(-ENOMEM);
1717
1718 tlv = (void *)skb->data;
1719 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD);
1720 tlv->len = __cpu_to_le16(sizeof(*cmd));
1721 cmd = (void *)tlv->value;
1722 cmd->vdev_id = __cpu_to_le32(vdev_id);
1723 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1724
1725 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n");
1726 return skb;
1727}
1728
1729static struct sk_buff *
1730ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
1731 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
1732{
1733 struct wmi_peer_flush_tids_cmd *cmd;
1734 struct wmi_tlv *tlv;
1735 struct sk_buff *skb;
1736
1737 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1738 if (!skb)
1739 return ERR_PTR(-ENOMEM);
1740
1741 tlv = (void *)skb->data;
1742 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD);
1743 tlv->len = __cpu_to_le16(sizeof(*cmd));
1744 cmd = (void *)tlv->value;
1745 cmd->vdev_id = __cpu_to_le32(vdev_id);
1746 cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
1747 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1748
1749 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n");
1750 return skb;
1751}
1752
1753static struct sk_buff *
1754ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
1755 const u8 *peer_addr,
1756 enum wmi_peer_param param_id,
1757 u32 param_value)
1758{
1759 struct wmi_peer_set_param_cmd *cmd;
1760 struct wmi_tlv *tlv;
1761 struct sk_buff *skb;
1762
1763 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1764 if (!skb)
1765 return ERR_PTR(-ENOMEM);
1766
1767 tlv = (void *)skb->data;
1768 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD);
1769 tlv->len = __cpu_to_le16(sizeof(*cmd));
1770 cmd = (void *)tlv->value;
1771 cmd->vdev_id = __cpu_to_le32(vdev_id);
1772 cmd->param_id = __cpu_to_le32(param_id);
1773 cmd->param_value = __cpu_to_le32(param_value);
1774 ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
1775
1776 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer set param\n");
1777 return skb;
1778}
1779
1780static struct sk_buff *
1781ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar,
1782 const struct wmi_peer_assoc_complete_arg *arg)
1783{
1784 struct wmi_tlv_peer_assoc_cmd *cmd;
1785 struct wmi_vht_rate_set *vht_rate;
1786 struct wmi_tlv *tlv;
1787 struct sk_buff *skb;
1788 size_t len, legacy_rate_len, ht_rate_len;
1789 void *ptr;
1790
1791 if (arg->peer_mpdu_density > 16)
1792 return ERR_PTR(-EINVAL);
1793 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
1794 return ERR_PTR(-EINVAL);
1795 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
1796 return ERR_PTR(-EINVAL);
1797
1798 legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates,
1799 sizeof(__le32));
1800 ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32));
1801 len = (sizeof(*tlv) + sizeof(*cmd)) +
1802 (sizeof(*tlv) + legacy_rate_len) +
1803 (sizeof(*tlv) + ht_rate_len) +
1804 (sizeof(*tlv) + sizeof(*vht_rate));
1805 skb = ath10k_wmi_alloc_skb(ar, len);
1806 if (!skb)
1807 return ERR_PTR(-ENOMEM);
1808
1809 ptr = (void *)skb->data;
1810 tlv = ptr;
1811 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD);
1812 tlv->len = __cpu_to_le16(sizeof(*cmd));
1813 cmd = (void *)tlv->value;
1814
1815 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
1816 cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1);
1817 cmd->assoc_id = __cpu_to_le32(arg->peer_aid);
1818 cmd->flags = __cpu_to_le32(arg->peer_flags);
1819 cmd->caps = __cpu_to_le32(arg->peer_caps);
1820 cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval);
1821 cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps);
1822 cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu);
1823 cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density);
1824 cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps);
1825 cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams);
1826 cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps);
1827 cmd->phy_mode = __cpu_to_le32(arg->peer_phymode);
1828 cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates);
1829 cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates);
1830 ether_addr_copy(cmd->mac_addr.addr, arg->addr);
1831
1832 ptr += sizeof(*tlv);
1833 ptr += sizeof(*cmd);
1834
1835 tlv = ptr;
1836 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1837 tlv->len = __cpu_to_le16(legacy_rate_len);
1838 memcpy(tlv->value, arg->peer_legacy_rates.rates,
1839 arg->peer_legacy_rates.num_rates);
1840
1841 ptr += sizeof(*tlv);
1842 ptr += legacy_rate_len;
1843
1844 tlv = ptr;
1845 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
1846 tlv->len = __cpu_to_le16(ht_rate_len);
1847 memcpy(tlv->value, arg->peer_ht_rates.rates,
1848 arg->peer_ht_rates.num_rates);
1849
1850 ptr += sizeof(*tlv);
1851 ptr += ht_rate_len;
1852
1853 tlv = ptr;
1854 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET);
1855 tlv->len = __cpu_to_le16(sizeof(*vht_rate));
1856 vht_rate = (void *)tlv->value;
1857
1858 vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate);
1859 vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set);
1860 vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate);
1861 vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set);
1862
1863 ptr += sizeof(*tlv);
1864 ptr += sizeof(*vht_rate);
1865
1866 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n");
1867 return skb;
1868}
1869
1870static struct sk_buff *
1871ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
1872 enum wmi_sta_ps_mode psmode)
1873{
1874 struct wmi_sta_powersave_mode_cmd *cmd;
1875 struct wmi_tlv *tlv;
1876 struct sk_buff *skb;
1877
1878 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1879 if (!skb)
1880 return ERR_PTR(-ENOMEM);
1881
1882 tlv = (void *)skb->data;
1883 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD);
1884 tlv->len = __cpu_to_le16(sizeof(*cmd));
1885 cmd = (void *)tlv->value;
1886 cmd->vdev_id = __cpu_to_le32(vdev_id);
1887 cmd->sta_ps_mode = __cpu_to_le32(psmode);
1888
1889 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n");
1890 return skb;
1891}
1892
1893static struct sk_buff *
1894ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
1895 enum wmi_sta_powersave_param param_id,
1896 u32 param_value)
1897{
1898 struct wmi_sta_powersave_param_cmd *cmd;
1899 struct wmi_tlv *tlv;
1900 struct sk_buff *skb;
1901
1902 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
1903 if (!skb)
1904 return ERR_PTR(-ENOMEM);
1905
1906 tlv = (void *)skb->data;
1907 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD);
1908 tlv->len = __cpu_to_le16(sizeof(*cmd));
1909 cmd = (void *)tlv->value;
1910 cmd->vdev_id = __cpu_to_le32(vdev_id);
1911 cmd->param_id = __cpu_to_le32(param_id);
1912 cmd->param_value = __cpu_to_le32(param_value);
1913
1914 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n");
1915 return skb;
1916}
1917
1918static struct sk_buff *
1919ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
1920 enum wmi_ap_ps_peer_param param_id, u32 value)
1921{
1922 struct wmi_ap_ps_peer_cmd *cmd;
1923 struct wmi_tlv *tlv;
1924 struct sk_buff *skb;
1925
1926 if (!mac)
1927 return ERR_PTR(-EINVAL);
1928
1929 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
1930 if (!skb)
1931 return ERR_PTR(-ENOMEM);
1932
1933 tlv = (void *)skb->data;
1934 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD);
1935 tlv->len = __cpu_to_le16(sizeof(*cmd));
1936 cmd = (void *)tlv->value;
1937 cmd->vdev_id = __cpu_to_le32(vdev_id);
1938 cmd->param_id = __cpu_to_le32(param_id);
1939 cmd->param_value = __cpu_to_le32(value);
1940 ether_addr_copy(cmd->peer_macaddr.addr, mac);
1941
1942 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n");
1943 return skb;
1944}
1945
1946static struct sk_buff *
1947ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar,
1948 const struct wmi_scan_chan_list_arg *arg)
1949{
1950 struct wmi_tlv_scan_chan_list_cmd *cmd;
1951 struct wmi_channel *ci;
1952 struct wmi_channel_arg *ch;
1953 struct wmi_tlv *tlv;
1954 struct sk_buff *skb;
1955 size_t chans_len, len;
1956 int i;
1957 void *ptr, *chans;
1958
1959 chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci));
1960 len = (sizeof(*tlv) + sizeof(*cmd)) +
1961 (sizeof(*tlv) + chans_len);
1962
1963 skb = ath10k_wmi_alloc_skb(ar, len);
1964 if (!skb)
1965 return ERR_PTR(-ENOMEM);
1966
1967 ptr = (void *)skb->data;
1968 tlv = ptr;
1969 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD);
1970 tlv->len = __cpu_to_le16(sizeof(*cmd));
1971 cmd = (void *)tlv->value;
1972 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
1973
1974 ptr += sizeof(*tlv);
1975 ptr += sizeof(*cmd);
1976
1977 tlv = ptr;
1978 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT);
1979 tlv->len = __cpu_to_le16(chans_len);
1980 chans = (void *)tlv->value;
1981
1982 for (i = 0; i < arg->n_channels; i++) {
1983 ch = &arg->channels[i];
1984
1985 tlv = chans;
1986 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL);
1987 tlv->len = __cpu_to_le16(sizeof(*ci));
1988 ci = (void *)tlv->value;
1989
1990 ath10k_wmi_put_wmi_channel(ci, ch);
1991
1992 chans += sizeof(*tlv);
1993 chans += sizeof(*ci);
1994 }
1995
1996 ptr += sizeof(*tlv);
1997 ptr += chans_len;
1998
1999 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n");
2000 return skb;
2001}
2002
2003static struct sk_buff *
2004ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id,
2005 const void *bcn, size_t bcn_len,
2006 u32 bcn_paddr, bool dtim_zero,
2007 bool deliver_cab)
2008
2009{
2010 struct wmi_bcn_tx_ref_cmd *cmd;
2011 struct wmi_tlv *tlv;
2012 struct sk_buff *skb;
2013 struct ieee80211_hdr *hdr;
2014 u16 fc;
2015
2016 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2017 if (!skb)
2018 return ERR_PTR(-ENOMEM);
2019
2020 hdr = (struct ieee80211_hdr *)bcn;
2021 fc = le16_to_cpu(hdr->frame_control);
2022
2023 tlv = (void *)skb->data;
2024 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD);
2025 tlv->len = __cpu_to_le16(sizeof(*cmd));
2026 cmd = (void *)tlv->value;
2027 cmd->vdev_id = __cpu_to_le32(vdev_id);
2028 cmd->data_len = __cpu_to_le32(bcn_len);
2029 cmd->data_ptr = __cpu_to_le32(bcn_paddr);
2030 cmd->msdu_id = 0;
2031 cmd->frame_control = __cpu_to_le32(fc);
2032 cmd->flags = 0;
2033
2034 if (dtim_zero)
2035 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
2036
2037 if (deliver_cab)
2038 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
2039
2040 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n");
2041 return skb;
2042}
2043
2044static struct sk_buff *
2045ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar,
2046 const struct wmi_wmm_params_all_arg *arg)
2047{
2048 struct wmi_tlv_pdev_set_wmm_cmd *cmd;
2049 struct wmi_wmm_params *wmm;
2050 struct wmi_tlv *tlv;
2051 struct sk_buff *skb;
2052 size_t len;
2053 void *ptr;
2054
2055 len = (sizeof(*tlv) + sizeof(*cmd)) +
2056 (4 * (sizeof(*tlv) + sizeof(*wmm)));
2057 skb = ath10k_wmi_alloc_skb(ar, len);
2058 if (!skb)
2059 return ERR_PTR(-ENOMEM);
2060
2061 ptr = (void *)skb->data;
2062
2063 tlv = ptr;
2064 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD);
2065 tlv->len = __cpu_to_le16(sizeof(*cmd));
2066 cmd = (void *)tlv->value;
2067
2068 /* nothing to set here */
2069
2070 ptr += sizeof(*tlv);
2071 ptr += sizeof(*cmd);
2072
2073 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be);
2074 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk);
2075 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi);
2076 ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo);
2077
2078 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n");
2079 return skb;
2080}
2081
2082static struct sk_buff *
2083ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar,
2084 enum wmi_stats_id stats_id)
2085{
2086 struct wmi_request_stats_cmd *cmd;
2087 struct wmi_tlv *tlv;
2088 struct sk_buff *skb;
2089
2090 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2091 if (!skb)
2092 return ERR_PTR(-ENOMEM);
2093
2094 tlv = (void *)skb->data;
2095 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD);
2096 tlv->len = __cpu_to_le16(sizeof(*cmd));
2097 cmd = (void *)tlv->value;
2098 cmd->stats_id = __cpu_to_le32(stats_id);
2099
2100 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n");
2101 return skb;
2102}
2103
2104static struct sk_buff *
2105ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar,
2106 enum wmi_force_fw_hang_type type,
2107 u32 delay_ms)
2108{
2109 struct wmi_force_fw_hang_cmd *cmd;
2110 struct wmi_tlv *tlv;
2111 struct sk_buff *skb;
2112
2113 skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd));
2114 if (!skb)
2115 return ERR_PTR(-ENOMEM);
2116
2117 tlv = (void *)skb->data;
2118 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD);
2119 tlv->len = __cpu_to_le16(sizeof(*cmd));
2120 cmd = (void *)tlv->value;
2121 cmd->type = __cpu_to_le32(type);
2122 cmd->delay_ms = __cpu_to_le32(delay_ms);
2123
2124 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n");
2125 return skb;
2126}
2127
2128static struct sk_buff *
2129ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable,
2130 u32 log_level) {
2131 struct wmi_tlv_dbglog_cmd *cmd;
2132 struct wmi_tlv *tlv;
2133 struct sk_buff *skb;
2134 size_t len, bmap_len;
2135 u32 value;
2136 void *ptr;
2137
2138 if (module_enable) {
2139 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
2140 module_enable,
2141 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE);
2142 } else {
2143 value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(
2144 WMI_TLV_DBGLOG_ALL_MODULES,
2145 WMI_TLV_DBGLOG_LOG_LEVEL_WARN);
2146 }
2147
2148 bmap_len = 0;
2149 len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len;
2150 skb = ath10k_wmi_alloc_skb(ar, len);
2151 if (!skb)
2152 return ERR_PTR(-ENOMEM);
2153
2154 ptr = (void *)skb->data;
2155
2156 tlv = ptr;
2157 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD);
2158 tlv->len = __cpu_to_le16(sizeof(*cmd));
2159 cmd = (void *)tlv->value;
2160 cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL);
2161 cmd->value = __cpu_to_le32(value);
2162
2163 ptr += sizeof(*tlv);
2164 ptr += sizeof(*cmd);
2165
2166 tlv = ptr;
2167 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32);
2168 tlv->len = __cpu_to_le16(bmap_len);
2169
2170 /* nothing to do here */
2171
2172 ptr += sizeof(*tlv);
2173 ptr += sizeof(bmap_len);
2174
2175 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value);
2176 return skb;
2177}
2178
2179static struct sk_buff *
2180ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter)
2181{
2182 struct wmi_tlv_pktlog_enable *cmd;
2183 struct wmi_tlv *tlv;
2184 struct sk_buff *skb;
2185 void *ptr;
2186 size_t len;
2187
2188 len = sizeof(*tlv) + sizeof(*cmd);
2189 skb = ath10k_wmi_alloc_skb(ar, len);
2190 if (!skb)
2191 return ERR_PTR(-ENOMEM);
2192
2193 ptr = (void *)skb->data;
2194 tlv = ptr;
2195 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD);
2196 tlv->len = __cpu_to_le16(sizeof(*cmd));
2197 cmd = (void *)tlv->value;
2198 cmd->filter = __cpu_to_le32(filter);
2199
2200 ptr += sizeof(*tlv);
2201 ptr += sizeof(*cmd);
2202
2203 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n",
2204 filter);
2205 return skb;
2206}
2207
2208static struct sk_buff *
2209ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar)
2210{
2211 struct wmi_tlv_pktlog_disable *cmd;
2212 struct wmi_tlv *tlv;
2213 struct sk_buff *skb;
2214 void *ptr;
2215 size_t len;
2216
2217 len = sizeof(*tlv) + sizeof(*cmd);
2218 skb = ath10k_wmi_alloc_skb(ar, len);
2219 if (!skb)
2220 return ERR_PTR(-ENOMEM);
2221
2222 ptr = (void *)skb->data;
2223 tlv = ptr;
2224 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD);
2225 tlv->len = __cpu_to_le16(sizeof(*cmd));
2226 cmd = (void *)tlv->value;
2227
2228 ptr += sizeof(*tlv);
2229 ptr += sizeof(*cmd);
2230
2231 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n");
2232 return skb;
2233}
2234
2235static struct sk_buff *
2236ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id,
2237 u32 tim_ie_offset, struct sk_buff *bcn,
2238 u32 prb_caps, u32 prb_erp, void *prb_ies,
2239 size_t prb_ies_len)
2240{
2241 struct wmi_tlv_bcn_tmpl_cmd *cmd;
2242 struct wmi_tlv_bcn_prb_info *info;
2243 struct wmi_tlv *tlv;
2244 struct sk_buff *skb;
2245 void *ptr;
2246 size_t len;
2247
2248 if (WARN_ON(prb_ies_len > 0 && !prb_ies))
2249 return ERR_PTR(-EINVAL);
2250
2251 len = sizeof(*tlv) + sizeof(*cmd) +
2252 sizeof(*tlv) + sizeof(*info) + prb_ies_len +
2253 sizeof(*tlv) + roundup(bcn->len, 4);
2254 skb = ath10k_wmi_alloc_skb(ar, len);
2255 if (!skb)
2256 return ERR_PTR(-ENOMEM);
2257
2258 ptr = (void *)skb->data;
2259 tlv = ptr;
2260 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD);
2261 tlv->len = __cpu_to_le16(sizeof(*cmd));
2262 cmd = (void *)tlv->value;
2263 cmd->vdev_id = __cpu_to_le32(vdev_id);
2264 cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset);
2265 cmd->buf_len = __cpu_to_le32(bcn->len);
2266
2267 ptr += sizeof(*tlv);
2268 ptr += sizeof(*cmd);
2269
2270 /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but
2271 * then it is then impossible to pass original ie len.
2272 * This chunk is not used yet so if setting probe resp template yields
2273 * problems with beaconing or crashes firmware look here.
2274 */
2275 tlv = ptr;
2276 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
2277 tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len);
2278 info = (void *)tlv->value;
2279 info->caps = __cpu_to_le32(prb_caps);
2280 info->erp = __cpu_to_le32(prb_erp);
2281 memcpy(info->ies, prb_ies, prb_ies_len);
2282
2283 ptr += sizeof(*tlv);
2284 ptr += sizeof(*info);
2285 ptr += prb_ies_len;
2286
2287 tlv = ptr;
2288 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2289 tlv->len = __cpu_to_le16(roundup(bcn->len, 4));
2290 memcpy(tlv->value, bcn->data, bcn->len);
2291
2292 /* FIXME: Adjust TSF? */
2293
2294 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n",
2295 vdev_id);
2296 return skb;
2297}
2298
2299static struct sk_buff *
2300ath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id,
2301 struct sk_buff *prb)
2302{
2303 struct wmi_tlv_prb_tmpl_cmd *cmd;
2304 struct wmi_tlv_bcn_prb_info *info;
2305 struct wmi_tlv *tlv;
2306 struct sk_buff *skb;
2307 void *ptr;
2308 size_t len;
2309
2310 len = sizeof(*tlv) + sizeof(*cmd) +
2311 sizeof(*tlv) + sizeof(*info) +
2312 sizeof(*tlv) + roundup(prb->len, 4);
2313 skb = ath10k_wmi_alloc_skb(ar, len);
2314 if (!skb)
2315 return ERR_PTR(-ENOMEM);
2316
2317 ptr = (void *)skb->data;
2318 tlv = ptr;
2319 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD);
2320 tlv->len = __cpu_to_le16(sizeof(*cmd));
2321 cmd = (void *)tlv->value;
2322 cmd->vdev_id = __cpu_to_le32(vdev_id);
2323 cmd->buf_len = __cpu_to_le32(prb->len);
2324
2325 ptr += sizeof(*tlv);
2326 ptr += sizeof(*cmd);
2327
2328 tlv = ptr;
2329 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO);
2330 tlv->len = __cpu_to_le16(sizeof(*info));
2331 info = (void *)tlv->value;
2332 info->caps = 0;
2333 info->erp = 0;
2334
2335 ptr += sizeof(*tlv);
2336 ptr += sizeof(*info);
2337
2338 tlv = ptr;
2339 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2340 tlv->len = __cpu_to_le16(roundup(prb->len, 4));
2341 memcpy(tlv->value, prb->data, prb->len);
2342
2343 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n",
2344 vdev_id);
2345 return skb;
2346}
2347
2348static struct sk_buff *
2349ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id,
2350 const u8 *p2p_ie)
2351{
2352 struct wmi_tlv_p2p_go_bcn_ie *cmd;
2353 struct wmi_tlv *tlv;
2354 struct sk_buff *skb;
2355 void *ptr;
2356 size_t len;
2357
2358 len = sizeof(*tlv) + sizeof(*cmd) +
2359 sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4);
2360 skb = ath10k_wmi_alloc_skb(ar, len);
2361 if (!skb)
2362 return ERR_PTR(-ENOMEM);
2363
2364 ptr = (void *)skb->data;
2365 tlv = ptr;
2366 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE);
2367 tlv->len = __cpu_to_le16(sizeof(*cmd));
2368 cmd = (void *)tlv->value;
2369 cmd->vdev_id = __cpu_to_le32(vdev_id);
2370 cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2);
2371
2372 ptr += sizeof(*tlv);
2373 ptr += sizeof(*cmd);
2374
2375 tlv = ptr;
2376 tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE);
2377 tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4));
2378 memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2);
2379
2380 ptr += sizeof(*tlv);
2381 ptr += roundup(p2p_ie[1] + 2, 4);
2382
2383 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n",
2384 vdev_id);
2385 return skb;
2386}
2387
2388/****************/
2389/* TLV mappings */
2390/****************/
2391
2392static struct wmi_cmd_map wmi_tlv_cmd_map = {
2393 .init_cmdid = WMI_TLV_INIT_CMDID,
2394 .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID,
2395 .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID,
2396 .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID,
2397 .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID,
2398 .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID,
2399 .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID,
2400 .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID,
2401 .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID,
2402 .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID,
2403 .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID,
2404 .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID,
2405 .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID,
2406 .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID,
2407 .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID,
2408 .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID,
2409 .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID,
2410 .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID,
2411 .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID,
2412 .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID,
2413 .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID,
2414 .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID,
2415 .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID,
2416 .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID,
2417 .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID,
2418 .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID,
2419 .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID,
2420 .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID,
2421 .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID,
2422 .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID,
2423 .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID,
2424 .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID,
2425 .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID,
2426 .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID,
2427 .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID,
2428 .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID,
2429 .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID,
2430 .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID,
2431 .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID,
2432 .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID,
2433 .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID,
2434 .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID,
2435 .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID,
2436 .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID,
2437 .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID,
2438 .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID,
2439 .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID,
2440 .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID,
2441 .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID,
2442 .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID,
2443 .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID,
2444 .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID,
2445 .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID,
2446 .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE,
2447 .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD,
2448 .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD,
2449 .roam_scan_rssi_change_threshold =
2450 WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD,
2451 .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
2452 .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE,
2453 .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE,
2454 .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD,
2455 .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO,
2456 .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY,
2457 .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE,
2458 .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE,
2459 .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID,
2460 .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID,
2461 .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID,
2462 .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID,
2463 .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID,
2464 .wlan_profile_set_hist_intvl_cmdid =
2465 WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2466 .wlan_profile_get_profile_data_cmdid =
2467 WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
2468 .wlan_profile_enable_profile_id_cmdid =
2469 WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2470 .wlan_profile_list_profile_id_cmdid =
2471 WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID,
2472 .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID,
2473 .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID,
2474 .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID,
2475 .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID,
2476 .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID,
2477 .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID,
2478 .wow_enable_disable_wake_event_cmdid =
2479 WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID,
2480 .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID,
2481 .wow_hostwakeup_from_sleep_cmdid =
2482 WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID,
2483 .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID,
2484 .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID,
2485 .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID,
2486 .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID,
2487 .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID,
2488 .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID,
2489 .network_list_offload_config_cmdid =
2490 WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID,
2491 .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID,
2492 .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID,
2493 .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID,
2494 .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID,
2495 .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID,
2496 .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID,
2497 .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID,
2498 .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID,
2499 .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID,
2500 .echo_cmdid = WMI_TLV_ECHO_CMDID,
2501 .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID,
2502 .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID,
2503 .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID,
2504 .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID,
2505 .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID,
2506 .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID,
2507 .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID,
2508 .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID,
2509 .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID,
2510 .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED,
2511 .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID,
2512};
2513
2514static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = {
2515 .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK,
2516 .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK,
2517 .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G,
2518 .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G,
2519 .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE,
2520 .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE,
2521 .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE,
2522 .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE,
2523 .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE,
2524 .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW,
2525 .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH,
2526 .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH,
2527 .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH,
2528 .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING,
2529 .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE,
2530 .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE,
2531 .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK,
2532 .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI,
2533 .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO,
2534 .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT,
2535 .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE,
2536 .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE,
2537 .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT,
2538 .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE,
2539 .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE,
2540 .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH,
2541 .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2542 .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN,
2543 .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE,
2544 .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD,
2545 .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD,
2546 .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD,
2547 .bcnflt_stats_update_period =
2548 WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD,
2549 .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS,
2550 .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE,
2551 .dcs = WMI_TLV_PDEV_PARAM_DCS,
2552 .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE,
2553 .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD,
2554 .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD,
2555 .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL,
2556 .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL,
2557 .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN,
2558 .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA,
2559 .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG,
2560 .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP,
2561 .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED,
2562 .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR,
2563 .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE,
2564 .cal_period = WMI_PDEV_PARAM_UNSUPPORTED,
2565};
2566
2567static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
2568 .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD,
2569 .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD,
2570 .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL,
2571 .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL,
2572 .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE,
2573 .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE,
2574 .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME,
2575 .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE,
2576 .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME,
2577 .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD,
2578 .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME,
2579 .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL,
2580 .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD,
2581 .wmi_vdev_oc_scheduler_air_time_limit =
2582 WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT,
2583 .wds = WMI_TLV_VDEV_PARAM_WDS,
2584 .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW,
2585 .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX,
2586 .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT,
2587 .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT,
2588 .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM,
2589 .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH,
2590 .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET,
2591 .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION,
2592 .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT,
2593 .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE,
2594 .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE,
2595 .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE,
2596 .sgi = WMI_TLV_VDEV_PARAM_SGI,
2597 .ldpc = WMI_TLV_VDEV_PARAM_LDPC,
2598 .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC,
2599 .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC,
2600 .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD,
2601 .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID,
2602 .nss = WMI_TLV_VDEV_PARAM_NSS,
2603 .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE,
2604 .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE,
2605 .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE,
2606 .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE,
2607 .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE,
2608 .ap_keepalive_min_idle_inactive_time_secs =
2609 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS,
2610 .ap_keepalive_max_idle_inactive_time_secs =
2611 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS,
2612 .ap_keepalive_max_unresponsive_time_secs =
2613 WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS,
2614 .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS,
2615 .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2616 .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS,
2617 .txbf = WMI_TLV_VDEV_PARAM_TXBF,
2618 .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE,
2619 .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY,
2620 .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE,
2621 .ap_detect_out_of_sync_sleeping_sta_time_secs =
2622 WMI_TLV_VDEV_PARAM_UNSUPPORTED,
2623};
2624
2625static const struct wmi_ops wmi_tlv_ops = {
2626 .rx = ath10k_wmi_tlv_op_rx,
2627 .map_svc = wmi_tlv_svc_map,
2628
2629 .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
2630 .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
2631 .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev,
2632 .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev,
2633 .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev,
2634 .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev,
2635 .pull_phyerr = ath10k_wmi_tlv_op_pull_phyerr_ev,
2636 .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
2637 .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
2638 .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
2639
2640 .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend,
2641 .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume,
2642 .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd,
2643 .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param,
2644 .gen_init = ath10k_wmi_tlv_op_gen_init,
2645 .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan,
2646 .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan,
2647 .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create,
2648 .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete,
2649 .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start,
2650 .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop,
2651 .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up,
2652 .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down,
2653 .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param,
2654 .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key,
2655 .gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf,
2656 .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create,
2657 .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete,
2658 .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush,
2659 .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param,
2660 .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc,
2661 .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode,
2662 .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps,
2663 .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps,
2664 .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list,
2665 .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma,
2666 .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm,
2667 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
2668 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
2669 /* .gen_mgmt_tx = not implemented; HTT is used */
2670 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
2671 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
2672 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
2673 /* .gen_pdev_set_quiet_mode not implemented */
2674 /* .gen_pdev_get_temperature not implemented */
2675 /* .gen_addba_clear_resp not implemented */
2676 /* .gen_addba_send not implemented */
2677 /* .gen_addba_set_resp not implemented */
2678 /* .gen_delba_send not implemented */
2679 .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl,
2680 .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl,
2681 .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie,
2682 .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd,
2683 .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive,
2684};
2685
2686/************/
2687/* TLV init */
2688/************/
2689
2690void ath10k_wmi_tlv_attach(struct ath10k *ar)
2691{
2692 ar->wmi.cmd = &wmi_tlv_cmd_map;
2693 ar->wmi.vdev_param = &wmi_tlv_vdev_param_map;
2694 ar->wmi.pdev_param = &wmi_tlv_pdev_param_map;
2695 ar->wmi.ops = &wmi_tlv_ops;
2696}
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..de68fe76eae6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
@@ -0,0 +1,1444 @@
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_vdev_set_wmm_cmd {
1306 __le32 vdev_id;
1307} __packed;
1308
1309struct wmi_tlv_phyerr_ev {
1310 __le32 num_phyerrs;
1311 __le32 tsf_l32;
1312 __le32 tsf_u32;
1313 __le32 buf_len;
1314} __packed;
1315
1316enum wmi_tlv_dbglog_param {
1317 WMI_TLV_DBGLOG_PARAM_LOG_LEVEL = 1,
1318 WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE,
1319 WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE,
1320 WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE_BITMAP,
1321 WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE_BITMAP,
1322};
1323
1324enum wmi_tlv_dbglog_log_level {
1325 WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE = 0,
1326 WMI_TLV_DBGLOG_LOG_LEVEL_INFO,
1327 WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_1,
1328 WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_2,
1329 WMI_TLV_DBGLOG_LOG_LEVEL_WARN,
1330 WMI_TLV_DBGLOG_LOG_LEVEL_ERR,
1331};
1332
1333#define WMI_TLV_DBGLOG_BITMAP_MAX_IDS 512
1334#define WMI_TLV_DBGLOG_BITMAP_MAX_WORDS (WMI_TLV_DBGLOG_BITMAP_MAX_IDS / \
1335 sizeof(__le32))
1336#define WMI_TLV_DBGLOG_ALL_MODULES 0xffff
1337#define WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(module_id, log_level) \
1338 (((module_id << 16) & 0xffff0000) | \
1339 ((log_level << 0) & 0x000000ff))
1340
1341struct wmi_tlv_dbglog_cmd {
1342 __le32 param;
1343 __le32 value;
1344} __packed;
1345
1346struct wmi_tlv_resume_cmd {
1347 __le32 reserved;
1348} __packed;
1349
1350struct wmi_tlv_req_stats_cmd {
1351 __le32 stats_id; /* wmi_stats_id */
1352 __le32 vdev_id;
1353 struct wmi_mac_addr peer_macaddr;
1354} __packed;
1355
1356struct wmi_tlv_vdev_stats {
1357 __le32 vdev_id;
1358 __le32 beacon_snr;
1359 __le32 data_snr;
1360 __le32 num_tx_frames[4]; /* per-AC */
1361 __le32 num_rx_frames;
1362 __le32 num_tx_frames_retries[4];
1363 __le32 num_tx_frames_failures[4];
1364 __le32 num_rts_fail;
1365 __le32 num_rts_success;
1366 __le32 num_rx_err;
1367 __le32 num_rx_discard;
1368 __le32 num_tx_not_acked;
1369 __le32 tx_rate_history[10];
1370 __le32 beacon_rssi_history[10];
1371} __packed;
1372
1373struct wmi_tlv_pktlog_enable {
1374 __le32 reserved;
1375 __le32 filter;
1376} __packed;
1377
1378struct wmi_tlv_pktlog_disable {
1379 __le32 reserved;
1380} __packed;
1381
1382enum wmi_tlv_bcn_tx_status {
1383 WMI_TLV_BCN_TX_STATUS_OK,
1384 WMI_TLV_BCN_TX_STATUS_XRETRY,
1385 WMI_TLV_BCN_TX_STATUS_DROP,
1386 WMI_TLV_BCN_TX_STATUS_FILTERED,
1387};
1388
1389struct wmi_tlv_bcn_tx_status_ev {
1390 __le32 vdev_id;
1391 __le32 tx_status;
1392} __packed;
1393
1394struct wmi_tlv_bcn_prb_info {
1395 __le32 caps;
1396 __le32 erp;
1397 u8 ies[0];
1398} __packed;
1399
1400struct wmi_tlv_bcn_tmpl_cmd {
1401 __le32 vdev_id;
1402 __le32 tim_ie_offset;
1403 __le32 buf_len;
1404} __packed;
1405
1406struct wmi_tlv_prb_tmpl_cmd {
1407 __le32 vdev_id;
1408 __le32 buf_len;
1409} __packed;
1410
1411struct wmi_tlv_p2p_go_bcn_ie {
1412 __le32 vdev_id;
1413 __le32 ie_len;
1414} __packed;
1415
1416enum wmi_tlv_diag_item_type {
1417 WMI_TLV_DIAG_ITEM_TYPE_FW_EVENT,
1418 WMI_TLV_DIAG_ITEM_TYPE_FW_LOG,
1419 WMI_TLV_DIAG_ITEM_TYPE_FW_DEBUG_MSG,
1420};
1421
1422struct wmi_tlv_diag_item {
1423 u8 type;
1424 u8 reserved;
1425 __le16 len;
1426 __le32 timestamp;
1427 __le32 code;
1428 u8 payload[0];
1429} __packed;
1430
1431struct wmi_tlv_diag_data_ev {
1432 __le32 num_items;
1433} __packed;
1434
1435struct wmi_tlv_sta_keepalive_cmd {
1436 __le32 vdev_id;
1437 __le32 enabled;
1438 __le32 method; /* WMI_STA_KEEPALIVE_METHOD_ */
1439 __le32 interval; /* in seconds */
1440} __packed;
1441
1442void ath10k_wmi_tlv_attach(struct ath10k *ar);
1443
1444#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index c0f3e4d09263..aeea1c793943 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;
@@ -717,23 +956,45 @@ err_pull:
717 956
718static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) 957static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif)
719{ 958{
959 struct ath10k *ar = arvif->ar;
960 struct ath10k_skb_cb *cb;
961 struct sk_buff *bcn;
720 int ret; 962 int ret;
721 963
722 lockdep_assert_held(&arvif->ar->data_lock); 964 spin_lock_bh(&ar->data_lock);
723 965
724 if (arvif->beacon == NULL) 966 bcn = arvif->beacon;
725 return;
726 967
727 if (arvif->beacon_sent) 968 if (!bcn)
728 return; 969 goto unlock;
729 970
730 ret = ath10k_wmi_beacon_send_ref_nowait(arvif); 971 cb = ATH10K_SKB_CB(bcn);
731 if (ret) 972
732 return; 973 switch (arvif->beacon_state) {
974 case ATH10K_BEACON_SENDING:
975 case ATH10K_BEACON_SENT:
976 break;
977 case ATH10K_BEACON_SCHEDULED:
978 arvif->beacon_state = ATH10K_BEACON_SENDING;
979 spin_unlock_bh(&ar->data_lock);
980
981 ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar,
982 arvif->vdev_id,
983 bcn->data, bcn->len,
984 cb->paddr,
985 cb->bcn.dtim_zero,
986 cb->bcn.deliver_cab);
987
988 spin_lock_bh(&ar->data_lock);
989
990 if (ret == 0)
991 arvif->beacon_state = ATH10K_BEACON_SENT;
992 else
993 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
994 }
733 995
734 /* We need to retain the arvif->beacon reference for DMA unmapping and 996unlock:
735 * freeing the skbuff later. */ 997 spin_unlock_bh(&ar->data_lock);
736 arvif->beacon_sent = true;
737} 998}
738 999
739static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, 1000static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
@@ -746,12 +1007,10 @@ static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac,
746 1007
747static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) 1008static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar)
748{ 1009{
749 spin_lock_bh(&ar->data_lock);
750 ieee80211_iterate_active_interfaces_atomic(ar->hw, 1010 ieee80211_iterate_active_interfaces_atomic(ar->hw,
751 IEEE80211_IFACE_ITER_NORMAL, 1011 IEEE80211_IFACE_ITER_NORMAL,
752 ath10k_wmi_tx_beacons_iter, 1012 ath10k_wmi_tx_beacons_iter,
753 NULL); 1013 NULL);
754 spin_unlock_bh(&ar->data_lock);
755} 1014}
756 1015
757static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) 1016static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar)
@@ -792,24 +1051,23 @@ int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
792 return ret; 1051 return ret;
793} 1052}
794 1053
795int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) 1054static struct sk_buff *
1055ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
796{ 1056{
797 int ret = 0;
798 struct wmi_mgmt_tx_cmd *cmd; 1057 struct wmi_mgmt_tx_cmd *cmd;
799 struct ieee80211_hdr *hdr; 1058 struct ieee80211_hdr *hdr;
800 struct sk_buff *wmi_skb; 1059 struct sk_buff *skb;
801 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
802 int len; 1060 int len;
803 u32 buf_len = skb->len; 1061 u32 buf_len = msdu->len;
804 u16 fc; 1062 u16 fc;
805 1063
806 hdr = (struct ieee80211_hdr *)skb->data; 1064 hdr = (struct ieee80211_hdr *)msdu->data;
807 fc = le16_to_cpu(hdr->frame_control); 1065 fc = le16_to_cpu(hdr->frame_control);
808 1066
809 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) 1067 if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control)))
810 return -EINVAL; 1068 return ERR_PTR(-EINVAL);
811 1069
812 len = sizeof(cmd->hdr) + skb->len; 1070 len = sizeof(cmd->hdr) + msdu->len;
813 1071
814 if ((ieee80211_is_action(hdr->frame_control) || 1072 if ((ieee80211_is_action(hdr->frame_control) ||
815 ieee80211_is_deauth(hdr->frame_control) || 1073 ieee80211_is_deauth(hdr->frame_control) ||
@@ -821,36 +1079,27 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
821 1079
822 len = round_up(len, 4); 1080 len = round_up(len, 4);
823 1081
824 wmi_skb = ath10k_wmi_alloc_skb(ar, len); 1082 skb = ath10k_wmi_alloc_skb(ar, len);
825 if (!wmi_skb) 1083 if (!skb)
826 return -ENOMEM; 1084 return ERR_PTR(-ENOMEM);
827 1085
828 cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data; 1086 cmd = (struct wmi_mgmt_tx_cmd *)skb->data;
829 1087
830 cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); 1088 cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id);
831 cmd->hdr.tx_rate = 0; 1089 cmd->hdr.tx_rate = 0;
832 cmd->hdr.tx_power = 0; 1090 cmd->hdr.tx_power = 0;
833 cmd->hdr.buf_len = __cpu_to_le32(buf_len); 1091 cmd->hdr.buf_len = __cpu_to_le32(buf_len);
834 1092
835 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); 1093 ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
836 memcpy(cmd->buf, skb->data, skb->len); 1094 memcpy(cmd->buf, msdu->data, msdu->len);
837 1095
838 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", 1096 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, 1097 msdu, skb->len, fc & IEEE80211_FCTL_FTYPE,
840 fc & IEEE80211_FCTL_STYPE); 1098 fc & IEEE80211_FCTL_STYPE);
841 trace_ath10k_tx_hdr(ar, skb->data, skb->len); 1099 trace_ath10k_tx_hdr(ar, skb->data, skb->len);
842 trace_ath10k_tx_payload(ar, skb->data, skb->len); 1100 trace_ath10k_tx_payload(ar, skb->data, skb->len);
843 1101
844 /* Send the management frame buffer to the target */ 1102 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} 1103}
855 1104
856static void ath10k_wmi_event_scan_started(struct ath10k *ar) 1105static void ath10k_wmi_event_scan_started(struct ath10k *ar)
@@ -977,22 +1226,48 @@ ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type,
977 } 1226 }
978} 1227}
979 1228
980static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) 1229static int ath10k_wmi_op_pull_scan_ev(struct ath10k *ar, struct sk_buff *skb,
1230 struct wmi_scan_ev_arg *arg)
981{ 1231{
982 struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; 1232 struct wmi_scan_event *ev = (void *)skb->data;
1233
1234 if (skb->len < sizeof(*ev))
1235 return -EPROTO;
1236
1237 skb_pull(skb, sizeof(*ev));
1238 arg->event_type = ev->event_type;
1239 arg->reason = ev->reason;
1240 arg->channel_freq = ev->channel_freq;
1241 arg->scan_req_id = ev->scan_req_id;
1242 arg->scan_id = ev->scan_id;
1243 arg->vdev_id = ev->vdev_id;
1244
1245 return 0;
1246}
1247
1248int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb)
1249{
1250 struct wmi_scan_ev_arg arg = {};
983 enum wmi_scan_event_type event_type; 1251 enum wmi_scan_event_type event_type;
984 enum wmi_scan_completion_reason reason; 1252 enum wmi_scan_completion_reason reason;
985 u32 freq; 1253 u32 freq;
986 u32 req_id; 1254 u32 req_id;
987 u32 scan_id; 1255 u32 scan_id;
988 u32 vdev_id; 1256 u32 vdev_id;
1257 int ret;
1258
1259 ret = ath10k_wmi_pull_scan(ar, skb, &arg);
1260 if (ret) {
1261 ath10k_warn(ar, "failed to parse scan event: %d\n", ret);
1262 return ret;
1263 }
989 1264
990 event_type = __le32_to_cpu(event->event_type); 1265 event_type = __le32_to_cpu(arg.event_type);
991 reason = __le32_to_cpu(event->reason); 1266 reason = __le32_to_cpu(arg.reason);
992 freq = __le32_to_cpu(event->channel_freq); 1267 freq = __le32_to_cpu(arg.channel_freq);
993 req_id = __le32_to_cpu(event->scan_req_id); 1268 req_id = __le32_to_cpu(arg.scan_req_id);
994 scan_id = __le32_to_cpu(event->scan_id); 1269 scan_id = __le32_to_cpu(arg.scan_id);
995 vdev_id = __le32_to_cpu(event->vdev_id); 1270 vdev_id = __le32_to_cpu(arg.vdev_id);
996 1271
997 spin_lock_bh(&ar->data_lock); 1272 spin_lock_bh(&ar->data_lock);
998 1273
@@ -1147,11 +1422,51 @@ static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar,
1147 } 1422 }
1148} 1423}
1149 1424
1150static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) 1425static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb,
1426 struct wmi_mgmt_rx_ev_arg *arg)
1151{ 1427{
1152 struct wmi_mgmt_rx_event_v1 *ev_v1; 1428 struct wmi_mgmt_rx_event_v1 *ev_v1;
1153 struct wmi_mgmt_rx_event_v2 *ev_v2; 1429 struct wmi_mgmt_rx_event_v2 *ev_v2;
1154 struct wmi_mgmt_rx_hdr_v1 *ev_hdr; 1430 struct wmi_mgmt_rx_hdr_v1 *ev_hdr;
1431 size_t pull_len;
1432 u32 msdu_len;
1433
1434 if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) {
1435 ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data;
1436 ev_hdr = &ev_v2->hdr.v1;
1437 pull_len = sizeof(*ev_v2);
1438 } else {
1439 ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data;
1440 ev_hdr = &ev_v1->hdr;
1441 pull_len = sizeof(*ev_v1);
1442 }
1443
1444 if (skb->len < pull_len)
1445 return -EPROTO;
1446
1447 skb_pull(skb, pull_len);
1448 arg->channel = ev_hdr->channel;
1449 arg->buf_len = ev_hdr->buf_len;
1450 arg->status = ev_hdr->status;
1451 arg->snr = ev_hdr->snr;
1452 arg->phy_mode = ev_hdr->phy_mode;
1453 arg->rate = ev_hdr->rate;
1454
1455 msdu_len = __le32_to_cpu(arg->buf_len);
1456 if (skb->len < msdu_len)
1457 return -EPROTO;
1458
1459 /* the WMI buffer might've ended up being padded to 4 bytes due to HTC
1460 * trailer with credit update. Trim the excess garbage.
1461 */
1462 skb_trim(skb, msdu_len);
1463
1464 return 0;
1465}
1466
1467int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1468{
1469 struct wmi_mgmt_rx_ev_arg arg = {};
1155 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 1470 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1156 struct ieee80211_hdr *hdr; 1471 struct ieee80211_hdr *hdr;
1157 u32 rx_status; 1472 u32 rx_status;
@@ -1161,24 +1476,20 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1161 u32 rate; 1476 u32 rate;
1162 u32 buf_len; 1477 u32 buf_len;
1163 u16 fc; 1478 u16 fc;
1164 int pull_len; 1479 int ret;
1165 1480
1166 if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { 1481 ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
1167 ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; 1482 if (ret) {
1168 ev_hdr = &ev_v2->hdr.v1; 1483 ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
1169 pull_len = sizeof(*ev_v2); 1484 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 } 1485 }
1175 1486
1176 channel = __le32_to_cpu(ev_hdr->channel); 1487 channel = __le32_to_cpu(arg.channel);
1177 buf_len = __le32_to_cpu(ev_hdr->buf_len); 1488 buf_len = __le32_to_cpu(arg.buf_len);
1178 rx_status = __le32_to_cpu(ev_hdr->status); 1489 rx_status = __le32_to_cpu(arg.status);
1179 snr = __le32_to_cpu(ev_hdr->snr); 1490 snr = __le32_to_cpu(arg.snr);
1180 phy_mode = __le32_to_cpu(ev_hdr->phy_mode); 1491 phy_mode = __le32_to_cpu(arg.phy_mode);
1181 rate = __le32_to_cpu(ev_hdr->rate); 1492 rate = __le32_to_cpu(arg.rate);
1182 1493
1183 memset(status, 0, sizeof(*status)); 1494 memset(status, 0, sizeof(*status));
1184 1495
@@ -1232,8 +1543,6 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1232 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; 1543 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;
1233 status->rate_idx = get_rate_idx(rate, status->band); 1544 status->rate_idx = get_rate_idx(rate, status->band);
1234 1545
1235 skb_pull(skb, pull_len);
1236
1237 hdr = (struct ieee80211_hdr *)skb->data; 1546 hdr = (struct ieee80211_hdr *)skb->data;
1238 fc = le16_to_cpu(hdr->frame_control); 1547 fc = le16_to_cpu(hdr->frame_control);
1239 1548
@@ -1266,12 +1575,6 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
1266 status->freq, status->band, status->signal, 1575 status->freq, status->band, status->signal,
1267 status->rate_idx); 1576 status->rate_idx);
1268 1577
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); 1578 ieee80211_rx(ar->hw, skb);
1276 return 0; 1579 return 0;
1277} 1580}
@@ -1295,21 +1598,44 @@ exit:
1295 return idx; 1598 return idx;
1296} 1599}
1297 1600
1298static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) 1601static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb,
1602 struct wmi_ch_info_ev_arg *arg)
1299{ 1603{
1300 struct wmi_chan_info_event *ev; 1604 struct wmi_chan_info_event *ev = (void *)skb->data;
1605
1606 if (skb->len < sizeof(*ev))
1607 return -EPROTO;
1608
1609 skb_pull(skb, sizeof(*ev));
1610 arg->err_code = ev->err_code;
1611 arg->freq = ev->freq;
1612 arg->cmd_flags = ev->cmd_flags;
1613 arg->noise_floor = ev->noise_floor;
1614 arg->rx_clear_count = ev->rx_clear_count;
1615 arg->cycle_count = ev->cycle_count;
1616
1617 return 0;
1618}
1619
1620void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
1621{
1622 struct wmi_ch_info_ev_arg arg = {};
1301 struct survey_info *survey; 1623 struct survey_info *survey;
1302 u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count; 1624 u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count;
1303 int idx; 1625 int idx, ret;
1304 1626
1305 ev = (struct wmi_chan_info_event *)skb->data; 1627 ret = ath10k_wmi_pull_ch_info(ar, skb, &arg);
1628 if (ret) {
1629 ath10k_warn(ar, "failed to parse chan info event: %d\n", ret);
1630 return;
1631 }
1306 1632
1307 err_code = __le32_to_cpu(ev->err_code); 1633 err_code = __le32_to_cpu(arg.err_code);
1308 freq = __le32_to_cpu(ev->freq); 1634 freq = __le32_to_cpu(arg.freq);
1309 cmd_flags = __le32_to_cpu(ev->cmd_flags); 1635 cmd_flags = __le32_to_cpu(arg.cmd_flags);
1310 noise_floor = __le32_to_cpu(ev->noise_floor); 1636 noise_floor = __le32_to_cpu(arg.noise_floor);
1311 rx_clear_count = __le32_to_cpu(ev->rx_clear_count); 1637 rx_clear_count = __le32_to_cpu(arg.rx_clear_count);
1312 cycle_count = __le32_to_cpu(ev->cycle_count); 1638 cycle_count = __le32_to_cpu(arg.cycle_count);
1313 1639
1314 ath10k_dbg(ar, ATH10K_DBG_WMI, 1640 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", 1641 "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n",
@@ -1344,11 +1670,11 @@ static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
1344 rx_clear_count -= ar->survey_last_rx_clear_count; 1670 rx_clear_count -= ar->survey_last_rx_clear_count;
1345 1671
1346 survey = &ar->survey[idx]; 1672 survey = &ar->survey[idx];
1347 survey->channel_time = WMI_CHAN_INFO_MSEC(cycle_count); 1673 survey->time = WMI_CHAN_INFO_MSEC(cycle_count);
1348 survey->channel_time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count); 1674 survey->time_rx = WMI_CHAN_INFO_MSEC(rx_clear_count);
1349 survey->noise = noise_floor; 1675 survey->noise = noise_floor;
1350 survey->filled = SURVEY_INFO_CHANNEL_TIME | 1676 survey->filled = SURVEY_INFO_TIME |
1351 SURVEY_INFO_CHANNEL_TIME_RX | 1677 SURVEY_INFO_TIME_RX |
1352 SURVEY_INFO_NOISE_DBM; 1678 SURVEY_INFO_NOISE_DBM;
1353 } 1679 }
1354 1680
@@ -1359,12 +1685,12 @@ exit:
1359 spin_unlock_bh(&ar->data_lock); 1685 spin_unlock_bh(&ar->data_lock);
1360} 1686}
1361 1687
1362static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) 1688void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb)
1363{ 1689{
1364 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); 1690 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");
1365} 1691}
1366 1692
1367static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) 1693int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
1368{ 1694{
1369 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", 1695 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
1370 skb->len); 1696 skb->len);
@@ -1374,12 +1700,9 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
1374 return 0; 1700 return 0;
1375} 1701}
1376 1702
1377static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src, 1703void ath10k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src,
1378 struct ath10k_fw_stats_pdev *dst) 1704 struct ath10k_fw_stats_pdev *dst)
1379{ 1705{
1380 const struct wal_dbg_tx_stats *tx = &src->wal.tx;
1381 const struct wal_dbg_rx_stats *rx = &src->wal.rx;
1382
1383 dst->ch_noise_floor = __le32_to_cpu(src->chan_nf); 1706 dst->ch_noise_floor = __le32_to_cpu(src->chan_nf);
1384 dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count); 1707 dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count);
1385 dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count); 1708 dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count);
@@ -1387,57 +1710,76 @@ static void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src,
1387 dst->cycle_count = __le32_to_cpu(src->cycle_count); 1710 dst->cycle_count = __le32_to_cpu(src->cycle_count);
1388 dst->phy_err_count = __le32_to_cpu(src->phy_err_count); 1711 dst->phy_err_count = __le32_to_cpu(src->phy_err_count);
1389 dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr); 1712 dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr);
1713}
1390 1714
1391 dst->comp_queued = __le32_to_cpu(tx->comp_queued); 1715void ath10k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
1392 dst->comp_delivered = __le32_to_cpu(tx->comp_delivered); 1716 struct ath10k_fw_stats_pdev *dst)
1393 dst->msdu_enqued = __le32_to_cpu(tx->msdu_enqued); 1717{
1394 dst->mpdu_enqued = __le32_to_cpu(tx->mpdu_enqued); 1718 dst->comp_queued = __le32_to_cpu(src->comp_queued);
1395 dst->wmm_drop = __le32_to_cpu(tx->wmm_drop); 1719 dst->comp_delivered = __le32_to_cpu(src->comp_delivered);
1396 dst->local_enqued = __le32_to_cpu(tx->local_enqued); 1720 dst->msdu_enqued = __le32_to_cpu(src->msdu_enqued);
1397 dst->local_freed = __le32_to_cpu(tx->local_freed); 1721 dst->mpdu_enqued = __le32_to_cpu(src->mpdu_enqued);
1398 dst->hw_queued = __le32_to_cpu(tx->hw_queued); 1722 dst->wmm_drop = __le32_to_cpu(src->wmm_drop);
1399 dst->hw_reaped = __le32_to_cpu(tx->hw_reaped); 1723 dst->local_enqued = __le32_to_cpu(src->local_enqued);
1400 dst->underrun = __le32_to_cpu(tx->underrun); 1724 dst->local_freed = __le32_to_cpu(src->local_freed);
1401 dst->tx_abort = __le32_to_cpu(tx->tx_abort); 1725 dst->hw_queued = __le32_to_cpu(src->hw_queued);
1402 dst->mpdus_requed = __le32_to_cpu(tx->mpdus_requed); 1726 dst->hw_reaped = __le32_to_cpu(src->hw_reaped);
1403 dst->tx_ko = __le32_to_cpu(tx->tx_ko); 1727 dst->underrun = __le32_to_cpu(src->underrun);
1404 dst->data_rc = __le32_to_cpu(tx->data_rc); 1728 dst->tx_abort = __le32_to_cpu(src->tx_abort);
1405 dst->self_triggers = __le32_to_cpu(tx->self_triggers); 1729 dst->mpdus_requed = __le32_to_cpu(src->mpdus_requed);
1406 dst->sw_retry_failure = __le32_to_cpu(tx->sw_retry_failure); 1730 dst->tx_ko = __le32_to_cpu(src->tx_ko);
1407 dst->illgl_rate_phy_err = __le32_to_cpu(tx->illgl_rate_phy_err); 1731 dst->data_rc = __le32_to_cpu(src->data_rc);
1408 dst->pdev_cont_xretry = __le32_to_cpu(tx->pdev_cont_xretry); 1732 dst->self_triggers = __le32_to_cpu(src->self_triggers);
1409 dst->pdev_tx_timeout = __le32_to_cpu(tx->pdev_tx_timeout); 1733 dst->sw_retry_failure = __le32_to_cpu(src->sw_retry_failure);
1410 dst->pdev_resets = __le32_to_cpu(tx->pdev_resets); 1734 dst->illgl_rate_phy_err = __le32_to_cpu(src->illgl_rate_phy_err);
1411 dst->phy_underrun = __le32_to_cpu(tx->phy_underrun); 1735 dst->pdev_cont_xretry = __le32_to_cpu(src->pdev_cont_xretry);
1412 dst->txop_ovf = __le32_to_cpu(tx->txop_ovf); 1736 dst->pdev_tx_timeout = __le32_to_cpu(src->pdev_tx_timeout);
1413 1737 dst->pdev_resets = __le32_to_cpu(src->pdev_resets);
1414 dst->mid_ppdu_route_change = __le32_to_cpu(rx->mid_ppdu_route_change); 1738 dst->phy_underrun = __le32_to_cpu(src->phy_underrun);
1415 dst->status_rcvd = __le32_to_cpu(rx->status_rcvd); 1739 dst->txop_ovf = __le32_to_cpu(src->txop_ovf);
1416 dst->r0_frags = __le32_to_cpu(rx->r0_frags); 1740}
1417 dst->r1_frags = __le32_to_cpu(rx->r1_frags); 1741
1418 dst->r2_frags = __le32_to_cpu(rx->r2_frags); 1742void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
1419 dst->r3_frags = __le32_to_cpu(rx->r3_frags); 1743 struct ath10k_fw_stats_pdev *dst)
1420 dst->htt_msdus = __le32_to_cpu(rx->htt_msdus); 1744{
1421 dst->htt_mpdus = __le32_to_cpu(rx->htt_mpdus); 1745 dst->mid_ppdu_route_change = __le32_to_cpu(src->mid_ppdu_route_change);
1422 dst->loc_msdus = __le32_to_cpu(rx->loc_msdus); 1746 dst->status_rcvd = __le32_to_cpu(src->status_rcvd);
1423 dst->loc_mpdus = __le32_to_cpu(rx->loc_mpdus); 1747 dst->r0_frags = __le32_to_cpu(src->r0_frags);
1424 dst->oversize_amsdu = __le32_to_cpu(rx->oversize_amsdu); 1748 dst->r1_frags = __le32_to_cpu(src->r1_frags);
1425 dst->phy_errs = __le32_to_cpu(rx->phy_errs); 1749 dst->r2_frags = __le32_to_cpu(src->r2_frags);
1426 dst->phy_err_drop = __le32_to_cpu(rx->phy_err_drop); 1750 dst->r3_frags = __le32_to_cpu(src->r3_frags);
1427 dst->mpdu_errs = __le32_to_cpu(rx->mpdu_errs); 1751 dst->htt_msdus = __le32_to_cpu(src->htt_msdus);
1428} 1752 dst->htt_mpdus = __le32_to_cpu(src->htt_mpdus);
1429 1753 dst->loc_msdus = __le32_to_cpu(src->loc_msdus);
1430static void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, 1754 dst->loc_mpdus = __le32_to_cpu(src->loc_mpdus);
1431 struct ath10k_fw_stats_peer *dst) 1755 dst->oversize_amsdu = __le32_to_cpu(src->oversize_amsdu);
1756 dst->phy_errs = __le32_to_cpu(src->phy_errs);
1757 dst->phy_err_drop = __le32_to_cpu(src->phy_err_drop);
1758 dst->mpdu_errs = __le32_to_cpu(src->mpdu_errs);
1759}
1760
1761void ath10k_wmi_pull_pdev_stats_extra(const struct wmi_pdev_stats_extra *src,
1762 struct ath10k_fw_stats_pdev *dst)
1763{
1764 dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad);
1765 dst->rts_bad = __le32_to_cpu(src->rts_bad);
1766 dst->rts_good = __le32_to_cpu(src->rts_good);
1767 dst->fcs_bad = __le32_to_cpu(src->fcs_bad);
1768 dst->no_beacons = __le32_to_cpu(src->no_beacons);
1769 dst->mib_int_count = __le32_to_cpu(src->mib_int_count);
1770}
1771
1772void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
1773 struct ath10k_fw_stats_peer *dst)
1432{ 1774{
1433 ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); 1775 ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr);
1434 dst->peer_rssi = __le32_to_cpu(src->peer_rssi); 1776 dst->peer_rssi = __le32_to_cpu(src->peer_rssi);
1435 dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate); 1777 dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate);
1436} 1778}
1437 1779
1438static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar, 1780static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar,
1439 struct sk_buff *skb, 1781 struct sk_buff *skb,
1440 struct ath10k_fw_stats *stats) 1782 struct ath10k_fw_stats *stats)
1441{ 1783{
1442 const struct wmi_stats_event *ev = (void *)skb->data; 1784 const struct wmi_stats_event *ev = (void *)skb->data;
1443 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1785 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
@@ -1462,7 +1804,10 @@ static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar,
1462 if (!dst) 1804 if (!dst)
1463 continue; 1805 continue;
1464 1806
1465 ath10k_wmi_pull_pdev_stats(src, dst); 1807 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
1808 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
1809 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
1810
1466 list_add_tail(&dst->list, &stats->pdevs); 1811 list_add_tail(&dst->list, &stats->pdevs);
1467 } 1812 }
1468 1813
@@ -1487,9 +1832,9 @@ static int ath10k_wmi_main_pull_fw_stats(struct ath10k *ar,
1487 return 0; 1832 return 0;
1488} 1833}
1489 1834
1490static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar, 1835static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
1491 struct sk_buff *skb, 1836 struct sk_buff *skb,
1492 struct ath10k_fw_stats *stats) 1837 struct ath10k_fw_stats *stats)
1493{ 1838{
1494 const struct wmi_stats_event *ev = (void *)skb->data; 1839 const struct wmi_stats_event *ev = (void *)skb->data;
1495 u32 num_pdev_stats, num_vdev_stats, num_peer_stats; 1840 u32 num_pdev_stats, num_vdev_stats, num_peer_stats;
@@ -1514,14 +1859,10 @@ static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar,
1514 if (!dst) 1859 if (!dst)
1515 continue; 1860 continue;
1516 1861
1517 ath10k_wmi_pull_pdev_stats(&src->old, dst); 1862 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
1518 1863 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
1519 dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); 1864 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
1520 dst->rts_bad = __le32_to_cpu(src->rts_bad); 1865 ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
1521 dst->rts_good = __le32_to_cpu(src->rts_good);
1522 dst->fcs_bad = __le32_to_cpu(src->fcs_bad);
1523 dst->no_beacons = __le32_to_cpu(src->no_beacons);
1524 dst->mib_int_count = __le32_to_cpu(src->mib_int_count);
1525 1866
1526 list_add_tail(&dst->list, &stats->pdevs); 1867 list_add_tail(&dst->list, &stats->pdevs);
1527 } 1868 }
@@ -1550,61 +1891,250 @@ static int ath10k_wmi_10x_pull_fw_stats(struct ath10k *ar,
1550 return 0; 1891 return 0;
1551} 1892}
1552 1893
1553int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, 1894static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar,
1554 struct ath10k_fw_stats *stats) 1895 struct sk_buff *skb,
1896 struct ath10k_fw_stats *stats)
1555{ 1897{
1556 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) 1898 const struct wmi_10_2_stats_event *ev = (void *)skb->data;
1557 return ath10k_wmi_10x_pull_fw_stats(ar, skb, stats); 1899 u32 num_pdev_stats;
1558 else 1900 u32 num_pdev_ext_stats;
1559 return ath10k_wmi_main_pull_fw_stats(ar, skb, stats); 1901 u32 num_vdev_stats;
1902 u32 num_peer_stats;
1903 int i;
1904
1905 if (!skb_pull(skb, sizeof(*ev)))
1906 return -EPROTO;
1907
1908 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
1909 num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
1910 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
1911 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
1912
1913 for (i = 0; i < num_pdev_stats; i++) {
1914 const struct wmi_10_2_pdev_stats *src;
1915 struct ath10k_fw_stats_pdev *dst;
1916
1917 src = (void *)skb->data;
1918 if (!skb_pull(skb, sizeof(*src)))
1919 return -EPROTO;
1920
1921 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1922 if (!dst)
1923 continue;
1924
1925 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
1926 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
1927 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
1928 ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
1929 /* FIXME: expose 10.2 specific values */
1930
1931 list_add_tail(&dst->list, &stats->pdevs);
1932 }
1933
1934 for (i = 0; i < num_pdev_ext_stats; i++) {
1935 const struct wmi_10_2_pdev_ext_stats *src;
1936
1937 src = (void *)skb->data;
1938 if (!skb_pull(skb, sizeof(*src)))
1939 return -EPROTO;
1940
1941 /* FIXME: expose values to userspace
1942 *
1943 * Note: Even though this loop seems to do nothing it is
1944 * required to parse following sub-structures properly.
1945 */
1946 }
1947
1948 /* fw doesn't implement vdev stats */
1949
1950 for (i = 0; i < num_peer_stats; i++) {
1951 const struct wmi_10_2_peer_stats *src;
1952 struct ath10k_fw_stats_peer *dst;
1953
1954 src = (void *)skb->data;
1955 if (!skb_pull(skb, sizeof(*src)))
1956 return -EPROTO;
1957
1958 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
1959 if (!dst)
1960 continue;
1961
1962 ath10k_wmi_pull_peer_stats(&src->old, dst);
1963
1964 dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
1965 /* FIXME: expose 10.2 specific values */
1966
1967 list_add_tail(&dst->list, &stats->peers);
1968 }
1969
1970 return 0;
1971}
1972
1973static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
1974 struct sk_buff *skb,
1975 struct ath10k_fw_stats *stats)
1976{
1977 const struct wmi_10_2_stats_event *ev = (void *)skb->data;
1978 u32 num_pdev_stats;
1979 u32 num_pdev_ext_stats;
1980 u32 num_vdev_stats;
1981 u32 num_peer_stats;
1982 int i;
1983
1984 if (!skb_pull(skb, sizeof(*ev)))
1985 return -EPROTO;
1986
1987 num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
1988 num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
1989 num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
1990 num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
1991
1992 for (i = 0; i < num_pdev_stats; i++) {
1993 const struct wmi_10_2_pdev_stats *src;
1994 struct ath10k_fw_stats_pdev *dst;
1995
1996 src = (void *)skb->data;
1997 if (!skb_pull(skb, sizeof(*src)))
1998 return -EPROTO;
1999
2000 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
2001 if (!dst)
2002 continue;
2003
2004 ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
2005 ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
2006 ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
2007 ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
2008 /* FIXME: expose 10.2 specific values */
2009
2010 list_add_tail(&dst->list, &stats->pdevs);
2011 }
2012
2013 for (i = 0; i < num_pdev_ext_stats; i++) {
2014 const struct wmi_10_2_pdev_ext_stats *src;
2015
2016 src = (void *)skb->data;
2017 if (!skb_pull(skb, sizeof(*src)))
2018 return -EPROTO;
2019
2020 /* FIXME: expose values to userspace
2021 *
2022 * Note: Even though this loop seems to do nothing it is
2023 * required to parse following sub-structures properly.
2024 */
2025 }
2026
2027 /* fw doesn't implement vdev stats */
2028
2029 for (i = 0; i < num_peer_stats; i++) {
2030 const struct wmi_10_2_4_peer_stats *src;
2031 struct ath10k_fw_stats_peer *dst;
2032
2033 src = (void *)skb->data;
2034 if (!skb_pull(skb, sizeof(*src)))
2035 return -EPROTO;
2036
2037 dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
2038 if (!dst)
2039 continue;
2040
2041 ath10k_wmi_pull_peer_stats(&src->common.old, dst);
2042
2043 dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate);
2044 /* FIXME: expose 10.2 specific values */
2045
2046 list_add_tail(&dst->list, &stats->peers);
2047 }
2048
2049 return 0;
1560} 2050}
1561 2051
1562static void ath10k_wmi_event_update_stats(struct ath10k *ar, 2052void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb)
1563 struct sk_buff *skb)
1564{ 2053{
1565 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); 2054 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
1566 ath10k_debug_fw_stats_process(ar, skb); 2055 ath10k_debug_fw_stats_process(ar, skb);
1567} 2056}
1568 2057
1569static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, 2058static int
1570 struct sk_buff *skb) 2059ath10k_wmi_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb,
2060 struct wmi_vdev_start_ev_arg *arg)
2061{
2062 struct wmi_vdev_start_response_event *ev = (void *)skb->data;
2063
2064 if (skb->len < sizeof(*ev))
2065 return -EPROTO;
2066
2067 skb_pull(skb, sizeof(*ev));
2068 arg->vdev_id = ev->vdev_id;
2069 arg->req_id = ev->req_id;
2070 arg->resp_type = ev->resp_type;
2071 arg->status = ev->status;
2072
2073 return 0;
2074}
2075
2076void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb)
1571{ 2077{
1572 struct wmi_vdev_start_response_event *ev; 2078 struct wmi_vdev_start_ev_arg arg = {};
2079 int ret;
1573 2080
1574 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); 2081 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n");
1575 2082
1576 ev = (struct wmi_vdev_start_response_event *)skb->data; 2083 ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg);
2084 if (ret) {
2085 ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret);
2086 return;
2087 }
1577 2088
1578 if (WARN_ON(__le32_to_cpu(ev->status))) 2089 if (WARN_ON(__le32_to_cpu(arg.status)))
1579 return; 2090 return;
1580 2091
1581 complete(&ar->vdev_setup_done); 2092 complete(&ar->vdev_setup_done);
1582} 2093}
1583 2094
1584static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, 2095void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb)
1585 struct sk_buff *skb)
1586{ 2096{
1587 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); 2097 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n");
1588 complete(&ar->vdev_setup_done); 2098 complete(&ar->vdev_setup_done);
1589} 2099}
1590 2100
1591static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, 2101static int
1592 struct sk_buff *skb) 2102ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb,
2103 struct wmi_peer_kick_ev_arg *arg)
1593{ 2104{
1594 struct wmi_peer_sta_kickout_event *ev; 2105 struct wmi_peer_sta_kickout_event *ev = (void *)skb->data;
2106
2107 if (skb->len < sizeof(*ev))
2108 return -EPROTO;
2109
2110 skb_pull(skb, sizeof(*ev));
2111 arg->mac_addr = ev->peer_macaddr.addr;
2112
2113 return 0;
2114}
2115
2116void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb)
2117{
2118 struct wmi_peer_kick_ev_arg arg = {};
1595 struct ieee80211_sta *sta; 2119 struct ieee80211_sta *sta;
2120 int ret;
1596 2121
1597 ev = (struct wmi_peer_sta_kickout_event *)skb->data; 2122 ret = ath10k_wmi_pull_peer_kick(ar, skb, &arg);
2123 if (ret) {
2124 ath10k_warn(ar, "failed to parse peer kickout event: %d\n",
2125 ret);
2126 return;
2127 }
1598 2128
1599 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", 2129 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n",
1600 ev->peer_macaddr.addr); 2130 arg.mac_addr);
1601 2131
1602 rcu_read_lock(); 2132 rcu_read_lock();
1603 2133
1604 sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); 2134 sta = ieee80211_find_sta_by_ifaddr(ar->hw, arg.mac_addr, NULL);
1605 if (!sta) { 2135 if (!sta) {
1606 ath10k_warn(ar, "Spurious quick kickout for STA %pM\n", 2136 ath10k_warn(ar, "Spurious quick kickout for STA %pM\n",
1607 ev->peer_macaddr.addr); 2137 arg.mac_addr);
1608 goto exit; 2138 goto exit;
1609 } 2139 }
1610 2140
@@ -1641,7 +2171,7 @@ exit:
1641static void ath10k_wmi_update_tim(struct ath10k *ar, 2171static void ath10k_wmi_update_tim(struct ath10k *ar,
1642 struct ath10k_vif *arvif, 2172 struct ath10k_vif *arvif,
1643 struct sk_buff *bcn, 2173 struct sk_buff *bcn,
1644 struct wmi_bcn_info *bcn_info) 2174 const struct wmi_tim_info *tim_info)
1645{ 2175{
1646 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; 2176 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data;
1647 struct ieee80211_tim_ie *tim; 2177 struct ieee80211_tim_ie *tim;
@@ -1652,14 +2182,14 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1652 2182
1653 /* if next SWBA has no tim_changed the tim_bitmap is garbage. 2183 /* if next SWBA has no tim_changed the tim_bitmap is garbage.
1654 * we must copy the bitmap upon change and reuse it later */ 2184 * we must copy the bitmap upon change and reuse it later */
1655 if (__le32_to_cpu(bcn_info->tim_info.tim_changed)) { 2185 if (__le32_to_cpu(tim_info->tim_changed)) {
1656 int i; 2186 int i;
1657 2187
1658 BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != 2188 BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) !=
1659 sizeof(bcn_info->tim_info.tim_bitmap)); 2189 sizeof(tim_info->tim_bitmap));
1660 2190
1661 for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { 2191 for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) {
1662 t = bcn_info->tim_info.tim_bitmap[i / 4]; 2192 t = tim_info->tim_bitmap[i / 4];
1663 v = __le32_to_cpu(t); 2193 v = __le32_to_cpu(t);
1664 arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; 2194 arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
1665 } 2195 }
@@ -1711,13 +2241,13 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1711 return; 2241 return;
1712 } 2242 }
1713 2243
1714 tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast); 2244 tim->bitmap_ctrl = !!__le32_to_cpu(tim_info->tim_mcast);
1715 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); 2245 memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len);
1716 2246
1717 if (tim->dtim_count == 0) { 2247 if (tim->dtim_count == 0) {
1718 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true; 2248 ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true;
1719 2249
1720 if (__le32_to_cpu(bcn_info->tim_info.tim_mcast) == 1) 2250 if (__le32_to_cpu(tim_info->tim_mcast) == 1)
1721 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; 2251 ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true;
1722 } 2252 }
1723 2253
@@ -1727,7 +2257,7 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
1727} 2257}
1728 2258
1729static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len, 2259static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
1730 struct wmi_p2p_noa_info *noa) 2260 const struct wmi_p2p_noa_info *noa)
1731{ 2261{
1732 struct ieee80211_p2p_noa_attr *noa_attr; 2262 struct ieee80211_p2p_noa_attr *noa_attr;
1733 u8 ctwindow_oppps = noa->ctwindow_oppps; 2263 u8 ctwindow_oppps = noa->ctwindow_oppps;
@@ -1769,7 +2299,7 @@ static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len,
1769 *noa_attr_len = __cpu_to_le16(attr_len); 2299 *noa_attr_len = __cpu_to_le16(attr_len);
1770} 2300}
1771 2301
1772static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa) 2302static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa)
1773{ 2303{
1774 u32 len = 0; 2304 u32 len = 0;
1775 u8 noa_descriptors = noa->num_descriptors; 2305 u8 noa_descriptors = noa->num_descriptors;
@@ -1789,9 +2319,8 @@ static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa)
1789 2319
1790static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, 2320static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
1791 struct sk_buff *bcn, 2321 struct sk_buff *bcn,
1792 struct wmi_bcn_info *bcn_info) 2322 const struct wmi_p2p_noa_info *noa)
1793{ 2323{
1794 struct wmi_p2p_noa_info *noa = &bcn_info->p2p_noa_info;
1795 u8 *new_data, *old_data = arvif->u.ap.noa_data; 2324 u8 *new_data, *old_data = arvif->u.ap.noa_data;
1796 u32 new_len; 2325 u32 new_len;
1797 2326
@@ -1832,22 +2361,59 @@ cleanup:
1832 kfree(old_data); 2361 kfree(old_data);
1833} 2362}
1834 2363
1835static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) 2364static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb,
2365 struct wmi_swba_ev_arg *arg)
1836{ 2366{
1837 struct wmi_host_swba_event *ev; 2367 struct wmi_host_swba_event *ev = (void *)skb->data;
2368 u32 map;
2369 size_t i;
2370
2371 if (skb->len < sizeof(*ev))
2372 return -EPROTO;
2373
2374 skb_pull(skb, sizeof(*ev));
2375 arg->vdev_map = ev->vdev_map;
2376
2377 for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) {
2378 if (!(map & BIT(0)))
2379 continue;
2380
2381 /* If this happens there were some changes in firmware and
2382 * ath10k should update the max size of tim_info array.
2383 */
2384 if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info)))
2385 break;
2386
2387 arg->tim_info[i] = &ev->bcn_info[i].tim_info;
2388 arg->noa_info[i] = &ev->bcn_info[i].p2p_noa_info;
2389 i++;
2390 }
2391
2392 return 0;
2393}
2394
2395void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
2396{
2397 struct wmi_swba_ev_arg arg = {};
1838 u32 map; 2398 u32 map;
1839 int i = -1; 2399 int i = -1;
1840 struct wmi_bcn_info *bcn_info; 2400 const struct wmi_tim_info *tim_info;
2401 const struct wmi_p2p_noa_info *noa_info;
1841 struct ath10k_vif *arvif; 2402 struct ath10k_vif *arvif;
1842 struct sk_buff *bcn; 2403 struct sk_buff *bcn;
1843 dma_addr_t paddr; 2404 dma_addr_t paddr;
1844 int ret, vdev_id = 0; 2405 int ret, vdev_id = 0;
1845 2406
1846 ev = (struct wmi_host_swba_event *)skb->data; 2407 ret = ath10k_wmi_pull_swba(ar, skb, &arg);
1847 map = __le32_to_cpu(ev->vdev_map); 2408 if (ret) {
2409 ath10k_warn(ar, "failed to parse swba event: %d\n", ret);
2410 return;
2411 }
2412
2413 map = __le32_to_cpu(arg.vdev_map);
1848 2414
1849 ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", 2415 ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n",
1850 ev->vdev_map); 2416 map);
1851 2417
1852 for (; map; map >>= 1, vdev_id++) { 2418 for (; map; map >>= 1, vdev_id++) {
1853 if (!(map & 0x1)) 2419 if (!(map & 0x1))
@@ -1860,19 +2426,20 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1860 break; 2426 break;
1861 } 2427 }
1862 2428
1863 bcn_info = &ev->bcn_info[i]; 2429 tim_info = arg.tim_info[i];
2430 noa_info = arg.noa_info[i];
1864 2431
1865 ath10k_dbg(ar, ATH10K_DBG_MGMT, 2432 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", 2433 "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, 2434 i,
1868 __le32_to_cpu(bcn_info->tim_info.tim_len), 2435 __le32_to_cpu(tim_info->tim_len),
1869 __le32_to_cpu(bcn_info->tim_info.tim_mcast), 2436 __le32_to_cpu(tim_info->tim_mcast),
1870 __le32_to_cpu(bcn_info->tim_info.tim_changed), 2437 __le32_to_cpu(tim_info->tim_changed),
1871 __le32_to_cpu(bcn_info->tim_info.tim_num_ps_pending), 2438 __le32_to_cpu(tim_info->tim_num_ps_pending),
1872 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[3]), 2439 __le32_to_cpu(tim_info->tim_bitmap[3]),
1873 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[2]), 2440 __le32_to_cpu(tim_info->tim_bitmap[2]),
1874 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[1]), 2441 __le32_to_cpu(tim_info->tim_bitmap[1]),
1875 __le32_to_cpu(bcn_info->tim_info.tim_bitmap[0])); 2442 __le32_to_cpu(tim_info->tim_bitmap[0]));
1876 2443
1877 arvif = ath10k_get_arvif(ar, vdev_id); 2444 arvif = ath10k_get_arvif(ar, vdev_id);
1878 if (arvif == NULL) { 2445 if (arvif == NULL) {
@@ -1899,15 +2466,25 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1899 } 2466 }
1900 2467
1901 ath10k_tx_h_seq_no(arvif->vif, bcn); 2468 ath10k_tx_h_seq_no(arvif->vif, bcn);
1902 ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info); 2469 ath10k_wmi_update_tim(ar, arvif, bcn, tim_info);
1903 ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); 2470 ath10k_wmi_update_noa(ar, arvif, bcn, noa_info);
1904 2471
1905 spin_lock_bh(&ar->data_lock); 2472 spin_lock_bh(&ar->data_lock);
1906 2473
1907 if (arvif->beacon) { 2474 if (arvif->beacon) {
1908 if (!arvif->beacon_sent) 2475 switch (arvif->beacon_state) {
1909 ath10k_warn(ar, "SWBA overrun on vdev %d\n", 2476 case ATH10K_BEACON_SENT:
2477 break;
2478 case ATH10K_BEACON_SCHEDULED:
2479 ath10k_warn(ar, "SWBA overrun on vdev %d, skipped old beacon\n",
2480 arvif->vdev_id);
2481 break;
2482 case ATH10K_BEACON_SENDING:
2483 ath10k_warn(ar, "SWBA overrun on vdev %d, skipped new beacon\n",
1910 arvif->vdev_id); 2484 arvif->vdev_id);
2485 dev_kfree_skb(bcn);
2486 goto skip;
2487 }
1911 2488
1912 ath10k_mac_vif_beacon_free(arvif); 2489 ath10k_mac_vif_beacon_free(arvif);
1913 } 2490 }
@@ -1935,19 +2512,19 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
1935 } 2512 }
1936 2513
1937 arvif->beacon = bcn; 2514 arvif->beacon = bcn;
1938 arvif->beacon_sent = false; 2515 arvif->beacon_state = ATH10K_BEACON_SCHEDULED;
1939 2516
1940 trace_ath10k_tx_hdr(ar, bcn->data, bcn->len); 2517 trace_ath10k_tx_hdr(ar, bcn->data, bcn->len);
1941 trace_ath10k_tx_payload(ar, bcn->data, bcn->len); 2518 trace_ath10k_tx_payload(ar, bcn->data, bcn->len);
1942 2519
1943 ath10k_wmi_tx_beacon_nowait(arvif);
1944skip: 2520skip:
1945 spin_unlock_bh(&ar->data_lock); 2521 spin_unlock_bh(&ar->data_lock);
1946 } 2522 }
2523
2524 ath10k_wmi_tx_beacons_nowait(ar);
1947} 2525}
1948 2526
1949static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, 2527void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb)
1950 struct sk_buff *skb)
1951{ 2528{
1952 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); 2529 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
1953} 2530}
@@ -2068,9 +2645,9 @@ static int ath10k_dfs_fft_report(struct ath10k *ar,
2068 return 0; 2645 return 0;
2069} 2646}
2070 2647
2071static void ath10k_wmi_event_dfs(struct ath10k *ar, 2648void ath10k_wmi_event_dfs(struct ath10k *ar,
2072 const struct wmi_phyerr *phyerr, 2649 const struct wmi_phyerr *phyerr,
2073 u64 tsf) 2650 u64 tsf)
2074{ 2651{
2075 int buf_len, tlv_len, res, i = 0; 2652 int buf_len, tlv_len, res, i = 0;
2076 const struct phyerr_tlv *tlv; 2653 const struct phyerr_tlv *tlv;
@@ -2133,10 +2710,9 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar,
2133 } 2710 }
2134} 2711}
2135 2712
2136static void 2713void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
2137ath10k_wmi_event_spectral_scan(struct ath10k *ar, 2714 const struct wmi_phyerr *phyerr,
2138 const struct wmi_phyerr *phyerr, 2715 u64 tsf)
2139 u64 tsf)
2140{ 2716{
2141 int buf_len, tlv_len, res, i = 0; 2717 int buf_len, tlv_len, res, i = 0;
2142 struct phyerr_tlv *tlv; 2718 struct phyerr_tlv *tlv;
@@ -2188,37 +2764,53 @@ ath10k_wmi_event_spectral_scan(struct ath10k *ar,
2188 } 2764 }
2189} 2765}
2190 2766
2191static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) 2767static int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, struct sk_buff *skb,
2768 struct wmi_phyerr_ev_arg *arg)
2192{ 2769{
2193 const struct wmi_phyerr_event *ev; 2770 struct wmi_phyerr_event *ev = (void *)skb->data;
2771
2772 if (skb->len < sizeof(*ev))
2773 return -EPROTO;
2774
2775 arg->num_phyerrs = ev->num_phyerrs;
2776 arg->tsf_l32 = ev->tsf_l32;
2777 arg->tsf_u32 = ev->tsf_u32;
2778 arg->buf_len = __cpu_to_le32(skb->len - sizeof(*ev));
2779 arg->phyerrs = ev->phyerrs;
2780
2781 return 0;
2782}
2783
2784void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
2785{
2786 struct wmi_phyerr_ev_arg arg = {};
2194 const struct wmi_phyerr *phyerr; 2787 const struct wmi_phyerr *phyerr;
2195 u32 count, i, buf_len, phy_err_code; 2788 u32 count, i, buf_len, phy_err_code;
2196 u64 tsf; 2789 u64 tsf;
2197 int left_len = skb->len; 2790 int left_len, ret;
2198 2791
2199 ATH10K_DFS_STAT_INC(ar, phy_errors); 2792 ATH10K_DFS_STAT_INC(ar, phy_errors);
2200 2793
2201 /* Check if combined event available */ 2794 ret = ath10k_wmi_pull_phyerr(ar, skb, &arg);
2202 if (left_len < sizeof(*ev)) { 2795 if (ret) {
2203 ath10k_warn(ar, "wmi phyerr combined event wrong len\n"); 2796 ath10k_warn(ar, "failed to parse phyerr event: %d\n", ret);
2204 return; 2797 return;
2205 } 2798 }
2206 2799
2207 left_len -= sizeof(*ev); 2800 left_len = __le32_to_cpu(arg.buf_len);
2208 2801
2209 /* Check number of included events */ 2802 /* Check number of included events */
2210 ev = (const struct wmi_phyerr_event *)skb->data; 2803 count = __le32_to_cpu(arg.num_phyerrs);
2211 count = __le32_to_cpu(ev->num_phyerrs);
2212 2804
2213 tsf = __le32_to_cpu(ev->tsf_u32); 2805 tsf = __le32_to_cpu(arg.tsf_u32);
2214 tsf <<= 32; 2806 tsf <<= 32;
2215 tsf |= __le32_to_cpu(ev->tsf_l32); 2807 tsf |= __le32_to_cpu(arg.tsf_l32);
2216 2808
2217 ath10k_dbg(ar, ATH10K_DBG_WMI, 2809 ath10k_dbg(ar, ATH10K_DBG_WMI,
2218 "wmi event phyerr count %d tsf64 0x%llX\n", 2810 "wmi event phyerr count %d tsf64 0x%llX\n",
2219 count, tsf); 2811 count, tsf);
2220 2812
2221 phyerr = ev->phyerrs; 2813 phyerr = arg.phyerrs;
2222 for (i = 0; i < count; i++) { 2814 for (i = 0; i < count; i++) {
2223 /* Check if we can read event header */ 2815 /* Check if we can read event header */
2224 if (left_len < sizeof(*phyerr)) { 2816 if (left_len < sizeof(*phyerr)) {
@@ -2258,19 +2850,17 @@ static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb)
2258 } 2850 }
2259} 2851}
2260 2852
2261static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) 2853void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
2262{ 2854{
2263 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); 2855 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n");
2264} 2856}
2265 2857
2266static void ath10k_wmi_event_profile_match(struct ath10k *ar, 2858void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb)
2267 struct sk_buff *skb)
2268{ 2859{
2269 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); 2860 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
2270} 2861}
2271 2862
2272static void ath10k_wmi_event_debug_print(struct ath10k *ar, 2863void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb)
2273 struct sk_buff *skb)
2274{ 2864{
2275 char buf[101], c; 2865 char buf[101], c;
2276 int i; 2866 int i;
@@ -2303,103 +2893,90 @@ static void ath10k_wmi_event_debug_print(struct ath10k *ar,
2303 ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf); 2893 ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf);
2304} 2894}
2305 2895
2306static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) 2896void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)
2307{ 2897{
2308 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); 2898 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n");
2309} 2899}
2310 2900
2311static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, 2901void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb)
2312 struct sk_buff *skb)
2313{ 2902{
2314 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); 2903 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n");
2315} 2904}
2316 2905
2317static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, 2906void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
2318 struct sk_buff *skb) 2907 struct sk_buff *skb)
2319{ 2908{
2320 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); 2909 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
2321} 2910}
2322 2911
2323static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, 2912void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
2324 struct sk_buff *skb) 2913 struct sk_buff *skb)
2325{ 2914{
2326 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); 2915 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
2327} 2916}
2328 2917
2329static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, 2918void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb)
2330 struct sk_buff *skb)
2331{ 2919{
2332 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); 2920 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n");
2333} 2921}
2334 2922
2335static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, 2923void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb)
2336 struct sk_buff *skb)
2337{ 2924{
2338 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); 2925 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n");
2339} 2926}
2340 2927
2341static void ath10k_wmi_event_dcs_interference(struct ath10k *ar, 2928void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb)
2342 struct sk_buff *skb)
2343{ 2929{
2344 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); 2930 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n");
2345} 2931}
2346 2932
2347static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, 2933void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
2348 struct sk_buff *skb)
2349{ 2934{
2350 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); 2935 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n");
2351} 2936}
2352 2937
2353static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, 2938void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb)
2354 struct sk_buff *skb)
2355{ 2939{
2356 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); 2940 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n");
2357} 2941}
2358 2942
2359static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, 2943void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, struct sk_buff *skb)
2360 struct sk_buff *skb)
2361{ 2944{
2362 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); 2945 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
2363} 2946}
2364 2947
2365static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, 2948void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb)
2366 struct sk_buff *skb)
2367{ 2949{
2368 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); 2950 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n");
2369} 2951}
2370 2952
2371static void ath10k_wmi_event_delba_complete(struct ath10k *ar, 2953void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb)
2372 struct sk_buff *skb)
2373{ 2954{
2374 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); 2955 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n");
2375} 2956}
2376 2957
2377static void ath10k_wmi_event_addba_complete(struct ath10k *ar, 2958void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb)
2378 struct sk_buff *skb)
2379{ 2959{
2380 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); 2960 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n");
2381} 2961}
2382 2962
2383static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, 2963void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
2384 struct sk_buff *skb) 2964 struct sk_buff *skb)
2385{ 2965{
2386 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); 2966 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
2387} 2967}
2388 2968
2389static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, 2969void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb)
2390 struct sk_buff *skb)
2391{ 2970{
2392 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); 2971 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n");
2393} 2972}
2394 2973
2395static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, 2974void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb)
2396 struct sk_buff *skb)
2397{ 2975{
2398 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); 2976 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n");
2399} 2977}
2400 2978
2401static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, 2979void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb)
2402 struct sk_buff *skb)
2403{ 2980{
2404 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); 2981 ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n");
2405} 2982}
@@ -2435,8 +3012,9 @@ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
2435 return 0; 3012 return 0;
2436} 3013}
2437 3014
2438static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb, 3015static int
2439 struct wmi_svc_rdy_ev_arg *arg) 3016ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
3017 struct wmi_svc_rdy_ev_arg *arg)
2440{ 3018{
2441 struct wmi_service_ready_event *ev; 3019 struct wmi_service_ready_event *ev;
2442 size_t i, n; 3020 size_t i, n;
@@ -2471,8 +3049,9 @@ static int ath10k_wmi_main_pull_svc_rdy_ev(struct sk_buff *skb,
2471 return 0; 3049 return 0;
2472} 3050}
2473 3051
2474static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb, 3052static int
2475 struct wmi_svc_rdy_ev_arg *arg) 3053ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
3054 struct wmi_svc_rdy_ev_arg *arg)
2476{ 3055{
2477 struct wmi_10x_service_ready_event *ev; 3056 struct wmi_10x_service_ready_event *ev;
2478 int i, n; 3057 int i, n;
@@ -2506,30 +3085,22 @@ static int ath10k_wmi_10x_pull_svc_rdy_ev(struct sk_buff *skb,
2506 return 0; 3085 return 0;
2507} 3086}
2508 3087
2509static void ath10k_wmi_event_service_ready(struct ath10k *ar, 3088void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb)
2510 struct sk_buff *skb)
2511{ 3089{
2512 struct wmi_svc_rdy_ev_arg arg = {}; 3090 struct wmi_svc_rdy_ev_arg arg = {};
2513 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; 3091 u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
2514 int ret; 3092 int ret;
2515 3093
2516 memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map)); 3094 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) { 3095 if (ret) {
2529 ath10k_warn(ar, "failed to parse service ready: %d\n", ret); 3096 ath10k_warn(ar, "failed to parse service ready: %d\n", ret);
2530 return; 3097 return;
2531 } 3098 }
2532 3099
3100 memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
3101 ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map,
3102 arg.service_map_len);
3103
2533 ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power); 3104 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); 3105 ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power);
2535 ar->ht_cap_info = __le32_to_cpu(arg.ht_cap); 3106 ar->ht_cap_info = __le32_to_cpu(arg.ht_cap);
@@ -2607,13 +3178,14 @@ static void ath10k_wmi_event_service_ready(struct ath10k *ar,
2607 } 3178 }
2608 3179
2609 ath10k_dbg(ar, ATH10K_DBG_WMI, 3180 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", 3181 "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), 3182 __le32_to_cpu(arg.min_tx_power),
2612 __le32_to_cpu(arg.max_tx_power), 3183 __le32_to_cpu(arg.max_tx_power),
2613 __le32_to_cpu(arg.ht_cap), 3184 __le32_to_cpu(arg.ht_cap),
2614 __le32_to_cpu(arg.vht_cap), 3185 __le32_to_cpu(arg.vht_cap),
2615 __le32_to_cpu(arg.sw_ver0), 3186 __le32_to_cpu(arg.sw_ver0),
2616 __le32_to_cpu(arg.sw_ver1), 3187 __le32_to_cpu(arg.sw_ver1),
3188 __le32_to_cpu(arg.fw_build),
2617 __le32_to_cpu(arg.phy_capab), 3189 __le32_to_cpu(arg.phy_capab),
2618 __le32_to_cpu(arg.num_rf_chains), 3190 __le32_to_cpu(arg.num_rf_chains),
2619 __le32_to_cpu(arg.eeprom_rd), 3191 __le32_to_cpu(arg.eeprom_rd),
@@ -2622,27 +3194,59 @@ static void ath10k_wmi_event_service_ready(struct ath10k *ar,
2622 complete(&ar->wmi.service_ready); 3194 complete(&ar->wmi.service_ready);
2623} 3195}
2624 3196
2625static int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) 3197static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb,
3198 struct wmi_rdy_ev_arg *arg)
2626{ 3199{
2627 struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; 3200 struct wmi_ready_event *ev = (void *)skb->data;
2628 3201
2629 if (WARN_ON(skb->len < sizeof(*ev))) 3202 if (skb->len < sizeof(*ev))
2630 return -EINVAL; 3203 return -EPROTO;
2631 3204
2632 ether_addr_copy(ar->mac_addr, ev->mac_addr.addr); 3205 skb_pull(skb, sizeof(*ev));
3206 arg->sw_version = ev->sw_version;
3207 arg->abi_version = ev->abi_version;
3208 arg->status = ev->status;
3209 arg->mac_addr = ev->mac_addr.addr;
3210
3211 return 0;
3212}
3213
3214int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
3215{
3216 struct wmi_rdy_ev_arg arg = {};
3217 int ret;
3218
3219 ret = ath10k_wmi_pull_rdy(ar, skb, &arg);
3220 if (ret) {
3221 ath10k_warn(ar, "failed to parse ready event: %d\n", ret);
3222 return ret;
3223 }
2633 3224
2634 ath10k_dbg(ar, ATH10K_DBG_WMI, 3225 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", 3226 "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n",
2636 __le32_to_cpu(ev->sw_version), 3227 __le32_to_cpu(arg.sw_version),
2637 __le32_to_cpu(ev->abi_version), 3228 __le32_to_cpu(arg.abi_version),
2638 ev->mac_addr.addr, 3229 arg.mac_addr,
2639 __le32_to_cpu(ev->status), skb->len, sizeof(*ev)); 3230 __le32_to_cpu(arg.status));
2640 3231
3232 ether_addr_copy(ar->mac_addr, arg.mac_addr);
2641 complete(&ar->wmi.unified_ready); 3233 complete(&ar->wmi.unified_ready);
2642 return 0; 3234 return 0;
2643} 3235}
2644 3236
2645static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) 3237static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
3238{
3239 const struct wmi_pdev_temperature_event *ev;
3240
3241 ev = (struct wmi_pdev_temperature_event *)skb->data;
3242 if (WARN_ON(skb->len < sizeof(*ev)))
3243 return -EPROTO;
3244
3245 ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature));
3246 return 0;
3247}
3248
3249static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
2646{ 3250{
2647 struct wmi_cmd_hdr *cmd_hdr; 3251 struct wmi_cmd_hdr *cmd_hdr;
2648 enum wmi_event_id id; 3252 enum wmi_event_id id;
@@ -2758,7 +3362,7 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
2758 dev_kfree_skb(skb); 3362 dev_kfree_skb(skb);
2759} 3363}
2760 3364
2761static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) 3365static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
2762{ 3366{
2763 struct wmi_cmd_hdr *cmd_hdr; 3367 struct wmi_cmd_hdr *cmd_hdr;
2764 enum wmi_10x_event_id id; 3368 enum wmi_10x_event_id id;
@@ -2882,7 +3486,7 @@ out:
2882 dev_kfree_skb(skb); 3486 dev_kfree_skb(skb);
2883} 3487}
2884 3488
2885static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) 3489static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
2886{ 3490{
2887 struct wmi_cmd_hdr *cmd_hdr; 3491 struct wmi_cmd_hdr *cmd_hdr;
2888 enum wmi_10_2_event_id id; 3492 enum wmi_10_2_event_id id;
@@ -2981,6 +3585,9 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
2981 case WMI_10_2_READY_EVENTID: 3585 case WMI_10_2_READY_EVENTID:
2982 ath10k_wmi_event_ready(ar, skb); 3586 ath10k_wmi_event_ready(ar, skb);
2983 break; 3587 break;
3588 case WMI_10_2_PDEV_TEMPERATURE_EVENTID:
3589 ath10k_wmi_event_temperature(ar, skb);
3590 break;
2984 case WMI_10_2_RTT_KEEPALIVE_EVENTID: 3591 case WMI_10_2_RTT_KEEPALIVE_EVENTID:
2985 case WMI_10_2_GPIO_INPUT_EVENTID: 3592 case WMI_10_2_GPIO_INPUT_EVENTID:
2986 case WMI_10_2_PEER_RATECODE_LIST_EVENTID: 3593 case WMI_10_2_PEER_RATECODE_LIST_EVENTID:
@@ -3001,14 +3608,11 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
3001 3608
3002static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) 3609static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb)
3003{ 3610{
3004 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 3611 int ret;
3005 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 3612
3006 ath10k_wmi_10_2_process_rx(ar, skb); 3613 ret = ath10k_wmi_rx(ar, skb);
3007 else 3614 if (ret)
3008 ath10k_wmi_10x_process_rx(ar, skb); 3615 ath10k_warn(ar, "failed to process wmi rx: %d\n", ret);
3009 } else {
3010 ath10k_wmi_main_process_rx(ar, skb);
3011 }
3012} 3616}
3013 3617
3014int ath10k_wmi_connect(struct ath10k *ar) 3618int ath10k_wmi_connect(struct ath10k *ar)
@@ -3039,16 +3643,17 @@ int ath10k_wmi_connect(struct ath10k *ar)
3039 return 0; 3643 return 0;
3040} 3644}
3041 3645
3042static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd, 3646static struct sk_buff *
3043 u16 rd2g, u16 rd5g, u16 ctl2g, 3647ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
3044 u16 ctl5g) 3648 u16 ctl2g, u16 ctl5g,
3649 enum wmi_dfs_region dfs_reg)
3045{ 3650{
3046 struct wmi_pdev_set_regdomain_cmd *cmd; 3651 struct wmi_pdev_set_regdomain_cmd *cmd;
3047 struct sk_buff *skb; 3652 struct sk_buff *skb;
3048 3653
3049 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3654 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3050 if (!skb) 3655 if (!skb)
3051 return -ENOMEM; 3656 return ERR_PTR(-ENOMEM);
3052 3657
3053 cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data; 3658 cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data;
3054 cmd->reg_domain = __cpu_to_le32(rd); 3659 cmd->reg_domain = __cpu_to_le32(rd);
@@ -3060,22 +3665,20 @@ static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd,
3060 ath10k_dbg(ar, ATH10K_DBG_WMI, 3665 ath10k_dbg(ar, ATH10K_DBG_WMI,
3061 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", 3666 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n",
3062 rd, rd2g, rd5g, ctl2g, ctl5g); 3667 rd, rd2g, rd5g, ctl2g, ctl5g);
3063 3668 return skb;
3064 return ath10k_wmi_cmd_send(ar, skb,
3065 ar->wmi.cmd->pdev_set_regdomain_cmdid);
3066} 3669}
3067 3670
3068static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd, 3671static struct sk_buff *
3069 u16 rd2g, u16 rd5g, 3672ath10k_wmi_10x_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16
3070 u16 ctl2g, u16 ctl5g, 3673 rd5g, u16 ctl2g, u16 ctl5g,
3071 enum wmi_dfs_region dfs_reg) 3674 enum wmi_dfs_region dfs_reg)
3072{ 3675{
3073 struct wmi_pdev_set_regdomain_cmd_10x *cmd; 3676 struct wmi_pdev_set_regdomain_cmd_10x *cmd;
3074 struct sk_buff *skb; 3677 struct sk_buff *skb;
3075 3678
3076 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3679 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3077 if (!skb) 3680 if (!skb)
3078 return -ENOMEM; 3681 return ERR_PTR(-ENOMEM);
3079 3682
3080 cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data; 3683 cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data;
3081 cmd->reg_domain = __cpu_to_le32(rd); 3684 cmd->reg_domain = __cpu_to_le32(rd);
@@ -3088,50 +3691,39 @@ static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd,
3088 ath10k_dbg(ar, ATH10K_DBG_WMI, 3691 ath10k_dbg(ar, ATH10K_DBG_WMI,
3089 "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", 3692 "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); 3693 rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg);
3091 3694 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} 3695}
3107 3696
3108int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) 3697static struct sk_buff *
3698ath10k_wmi_op_gen_pdev_suspend(struct ath10k *ar, u32 suspend_opt)
3109{ 3699{
3110 struct wmi_pdev_suspend_cmd *cmd; 3700 struct wmi_pdev_suspend_cmd *cmd;
3111 struct sk_buff *skb; 3701 struct sk_buff *skb;
3112 3702
3113 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3703 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3114 if (!skb) 3704 if (!skb)
3115 return -ENOMEM; 3705 return ERR_PTR(-ENOMEM);
3116 3706
3117 cmd = (struct wmi_pdev_suspend_cmd *)skb->data; 3707 cmd = (struct wmi_pdev_suspend_cmd *)skb->data;
3118 cmd->suspend_opt = __cpu_to_le32(suspend_opt); 3708 cmd->suspend_opt = __cpu_to_le32(suspend_opt);
3119 3709
3120 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); 3710 return skb;
3121} 3711}
3122 3712
3123int ath10k_wmi_pdev_resume_target(struct ath10k *ar) 3713static struct sk_buff *
3714ath10k_wmi_op_gen_pdev_resume(struct ath10k *ar)
3124{ 3715{
3125 struct sk_buff *skb; 3716 struct sk_buff *skb;
3126 3717
3127 skb = ath10k_wmi_alloc_skb(ar, 0); 3718 skb = ath10k_wmi_alloc_skb(ar, 0);
3128 if (skb == NULL) 3719 if (!skb)
3129 return -ENOMEM; 3720 return ERR_PTR(-ENOMEM);
3130 3721
3131 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); 3722 return skb;
3132} 3723}
3133 3724
3134int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) 3725static struct sk_buff *
3726ath10k_wmi_op_gen_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3135{ 3727{
3136 struct wmi_pdev_set_param_cmd *cmd; 3728 struct wmi_pdev_set_param_cmd *cmd;
3137 struct sk_buff *skb; 3729 struct sk_buff *skb;
@@ -3139,12 +3731,12 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3139 if (id == WMI_PDEV_PARAM_UNSUPPORTED) { 3731 if (id == WMI_PDEV_PARAM_UNSUPPORTED) {
3140 ath10k_warn(ar, "pdev param %d not supported by firmware\n", 3732 ath10k_warn(ar, "pdev param %d not supported by firmware\n",
3141 id); 3733 id);
3142 return -EOPNOTSUPP; 3734 return ERR_PTR(-EOPNOTSUPP);
3143 } 3735 }
3144 3736
3145 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 3737 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3146 if (!skb) 3738 if (!skb)
3147 return -ENOMEM; 3739 return ERR_PTR(-ENOMEM);
3148 3740
3149 cmd = (struct wmi_pdev_set_param_cmd *)skb->data; 3741 cmd = (struct wmi_pdev_set_param_cmd *)skb->data;
3150 cmd->param_id = __cpu_to_le32(id); 3742 cmd->param_id = __cpu_to_le32(id);
@@ -3152,11 +3744,11 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
3152 3744
3153 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", 3745 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n",
3154 id, value); 3746 id, value);
3155 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); 3747 return skb;
3156} 3748}
3157 3749
3158static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, 3750void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
3159 struct wmi_host_mem_chunks *chunks) 3751 struct wmi_host_mem_chunks *chunks)
3160{ 3752{
3161 struct host_memory_chunk *chunk; 3753 struct host_memory_chunk *chunk;
3162 int i; 3754 int i;
@@ -3177,7 +3769,7 @@ static void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
3177 } 3769 }
3178} 3770}
3179 3771
3180static int ath10k_wmi_main_cmd_init(struct ath10k *ar) 3772static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar)
3181{ 3773{
3182 struct wmi_init_cmd *cmd; 3774 struct wmi_init_cmd *cmd;
3183 struct sk_buff *buf; 3775 struct sk_buff *buf;
@@ -3240,7 +3832,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
3240 3832
3241 buf = ath10k_wmi_alloc_skb(ar, len); 3833 buf = ath10k_wmi_alloc_skb(ar, len);
3242 if (!buf) 3834 if (!buf)
3243 return -ENOMEM; 3835 return ERR_PTR(-ENOMEM);
3244 3836
3245 cmd = (struct wmi_init_cmd *)buf->data; 3837 cmd = (struct wmi_init_cmd *)buf->data;
3246 3838
@@ -3248,10 +3840,10 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar)
3248 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3840 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3249 3841
3250 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); 3842 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n");
3251 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3843 return buf;
3252} 3844}
3253 3845
3254static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) 3846static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar)
3255{ 3847{
3256 struct wmi_init_cmd_10x *cmd; 3848 struct wmi_init_cmd_10x *cmd;
3257 struct sk_buff *buf; 3849 struct sk_buff *buf;
@@ -3306,7 +3898,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
3306 3898
3307 buf = ath10k_wmi_alloc_skb(ar, len); 3899 buf = ath10k_wmi_alloc_skb(ar, len);
3308 if (!buf) 3900 if (!buf)
3309 return -ENOMEM; 3901 return ERR_PTR(-ENOMEM);
3310 3902
3311 cmd = (struct wmi_init_cmd_10x *)buf->data; 3903 cmd = (struct wmi_init_cmd_10x *)buf->data;
3312 3904
@@ -3314,15 +3906,15 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar)
3314 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3906 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3315 3907
3316 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); 3908 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n");
3317 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3909 return buf;
3318} 3910}
3319 3911
3320static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) 3912static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar)
3321{ 3913{
3322 struct wmi_init_cmd_10_2 *cmd; 3914 struct wmi_init_cmd_10_2 *cmd;
3323 struct sk_buff *buf; 3915 struct sk_buff *buf;
3324 struct wmi_resource_config_10x config = {}; 3916 struct wmi_resource_config_10x config = {};
3325 u32 len, val; 3917 u32 len, val, features;
3326 3918
3327 config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); 3919 config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS);
3328 config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); 3920 config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS);
@@ -3356,7 +3948,7 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
3356 config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); 3948 config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE);
3357 config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); 3949 config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE);
3358 config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); 3950 config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES);
3359 config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); 3951 config.dma_burst_size = __cpu_to_le32(TARGET_10_2_DMA_BURST_SIZE);
3360 config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); 3952 config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM);
3361 3953
3362 val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; 3954 val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK;
@@ -3372,34 +3964,21 @@ static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar)
3372 3964
3373 buf = ath10k_wmi_alloc_skb(ar, len); 3965 buf = ath10k_wmi_alloc_skb(ar, len);
3374 if (!buf) 3966 if (!buf)
3375 return -ENOMEM; 3967 return ERR_PTR(-ENOMEM);
3376 3968
3377 cmd = (struct wmi_init_cmd_10_2 *)buf->data; 3969 cmd = (struct wmi_init_cmd_10_2 *)buf->data;
3378 3970
3971 features = WMI_10_2_RX_BATCH_MODE;
3972 cmd->resource_config.feature_mask = __cpu_to_le32(features);
3973
3379 memcpy(&cmd->resource_config.common, &config, sizeof(config)); 3974 memcpy(&cmd->resource_config.common, &config, sizeof(config));
3380 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); 3975 ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks);
3381 3976
3382 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); 3977 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n");
3383 return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); 3978 return buf;
3384} 3979}
3385 3980
3386int ath10k_wmi_cmd_init(struct ath10k *ar) 3981int 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{ 3982{
3404 if (arg->ie_len && !arg->ie) 3983 if (arg->ie_len && !arg->ie)
3405 return -EINVAL; 3984 return -EINVAL;
@@ -3450,9 +4029,8 @@ ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg)
3450 return len; 4029 return len;
3451} 4030}
3452 4031
3453static void 4032void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
3454ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, 4033 const struct wmi_start_scan_arg *arg)
3455 const struct wmi_start_scan_arg *arg)
3456{ 4034{
3457 u32 scan_id; 4035 u32 scan_id;
3458 u32 scan_req_id; 4036 u32 scan_req_id;
@@ -3546,46 +4124,60 @@ ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs,
3546 } 4124 }
3547} 4125}
3548 4126
3549int ath10k_wmi_start_scan(struct ath10k *ar, 4127static struct sk_buff *
3550 const struct wmi_start_scan_arg *arg) 4128ath10k_wmi_op_gen_start_scan(struct ath10k *ar,
4129 const struct wmi_start_scan_arg *arg)
3551{ 4130{
4131 struct wmi_start_scan_cmd *cmd;
3552 struct sk_buff *skb; 4132 struct sk_buff *skb;
3553 size_t len; 4133 size_t len;
3554 int ret; 4134 int ret;
3555 4135
3556 ret = ath10k_wmi_start_scan_verify(arg); 4136 ret = ath10k_wmi_start_scan_verify(arg);
3557 if (ret) 4137 if (ret)
3558 return ret; 4138 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 4139
4140 len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
3567 skb = ath10k_wmi_alloc_skb(ar, len); 4141 skb = ath10k_wmi_alloc_skb(ar, len);
3568 if (!skb) 4142 if (!skb)
3569 return -ENOMEM; 4143 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 4144
3574 cmd = (struct wmi_10x_start_scan_cmd *)skb->data; 4145 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 4146
3580 cmd = (struct wmi_start_scan_cmd *)skb->data; 4147 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
3581 cmd->burst_duration_ms = __cpu_to_le32(0); 4148 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3582 4149
3583 ath10k_wmi_put_start_scan_common(&cmd->common, arg); 4150 cmd->burst_duration_ms = __cpu_to_le32(0);
3584 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
3585 }
3586 4151
3587 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); 4152 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n");
3588 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); 4153 return skb;
4154}
4155
4156static struct sk_buff *
4157ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar,
4158 const struct wmi_start_scan_arg *arg)
4159{
4160 struct wmi_10x_start_scan_cmd *cmd;
4161 struct sk_buff *skb;
4162 size_t len;
4163 int ret;
4164
4165 ret = ath10k_wmi_start_scan_verify(arg);
4166 if (ret)
4167 return ERR_PTR(ret);
4168
4169 len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg);
4170 skb = ath10k_wmi_alloc_skb(ar, len);
4171 if (!skb)
4172 return ERR_PTR(-ENOMEM);
4173
4174 cmd = (struct wmi_10x_start_scan_cmd *)skb->data;
4175
4176 ath10k_wmi_put_start_scan_common(&cmd->common, arg);
4177 ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg);
4178
4179 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n");
4180 return skb;
3589} 4181}
3590 4182
3591void ath10k_wmi_start_scan_init(struct ath10k *ar, 4183void ath10k_wmi_start_scan_init(struct ath10k *ar,
@@ -3614,7 +4206,9 @@ void ath10k_wmi_start_scan_init(struct ath10k *ar,
3614 arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF"; 4206 arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF";
3615} 4207}
3616 4208
3617int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) 4209static struct sk_buff *
4210ath10k_wmi_op_gen_stop_scan(struct ath10k *ar,
4211 const struct wmi_stop_scan_arg *arg)
3618{ 4212{
3619 struct wmi_stop_scan_cmd *cmd; 4213 struct wmi_stop_scan_cmd *cmd;
3620 struct sk_buff *skb; 4214 struct sk_buff *skb;
@@ -3622,13 +4216,13 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
3622 u32 req_id; 4216 u32 req_id;
3623 4217
3624 if (arg->req_id > 0xFFF) 4218 if (arg->req_id > 0xFFF)
3625 return -EINVAL; 4219 return ERR_PTR(-EINVAL);
3626 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) 4220 if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF)
3627 return -EINVAL; 4221 return ERR_PTR(-EINVAL);
3628 4222
3629 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4223 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3630 if (!skb) 4224 if (!skb)
3631 return -ENOMEM; 4225 return ERR_PTR(-ENOMEM);
3632 4226
3633 scan_id = arg->u.scan_id; 4227 scan_id = arg->u.scan_id;
3634 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; 4228 scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX;
@@ -3645,20 +4239,21 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
3645 ath10k_dbg(ar, ATH10K_DBG_WMI, 4239 ath10k_dbg(ar, ATH10K_DBG_WMI,
3646 "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", 4240 "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n",
3647 arg->req_id, arg->req_type, arg->u.scan_id); 4241 arg->req_id, arg->req_type, arg->u.scan_id);
3648 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); 4242 return skb;
3649} 4243}
3650 4244
3651int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, 4245static struct sk_buff *
3652 enum wmi_vdev_type type, 4246ath10k_wmi_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id,
3653 enum wmi_vdev_subtype subtype, 4247 enum wmi_vdev_type type,
3654 const u8 macaddr[ETH_ALEN]) 4248 enum wmi_vdev_subtype subtype,
4249 const u8 macaddr[ETH_ALEN])
3655{ 4250{
3656 struct wmi_vdev_create_cmd *cmd; 4251 struct wmi_vdev_create_cmd *cmd;
3657 struct sk_buff *skb; 4252 struct sk_buff *skb;
3658 4253
3659 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4254 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3660 if (!skb) 4255 if (!skb)
3661 return -ENOMEM; 4256 return ERR_PTR(-ENOMEM);
3662 4257
3663 cmd = (struct wmi_vdev_create_cmd *)skb->data; 4258 cmd = (struct wmi_vdev_create_cmd *)skb->data;
3664 cmd->vdev_id = __cpu_to_le32(vdev_id); 4259 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3669,58 +4264,52 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
3669 ath10k_dbg(ar, ATH10K_DBG_WMI, 4264 ath10k_dbg(ar, ATH10K_DBG_WMI,
3670 "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", 4265 "WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
3671 vdev_id, type, subtype, macaddr); 4266 vdev_id, type, subtype, macaddr);
3672 4267 return skb;
3673 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid);
3674} 4268}
3675 4269
3676int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) 4270static struct sk_buff *
4271ath10k_wmi_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id)
3677{ 4272{
3678 struct wmi_vdev_delete_cmd *cmd; 4273 struct wmi_vdev_delete_cmd *cmd;
3679 struct sk_buff *skb; 4274 struct sk_buff *skb;
3680 4275
3681 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4276 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3682 if (!skb) 4277 if (!skb)
3683 return -ENOMEM; 4278 return ERR_PTR(-ENOMEM);
3684 4279
3685 cmd = (struct wmi_vdev_delete_cmd *)skb->data; 4280 cmd = (struct wmi_vdev_delete_cmd *)skb->data;
3686 cmd->vdev_id = __cpu_to_le32(vdev_id); 4281 cmd->vdev_id = __cpu_to_le32(vdev_id);
3687 4282
3688 ath10k_dbg(ar, ATH10K_DBG_WMI, 4283 ath10k_dbg(ar, ATH10K_DBG_WMI,
3689 "WMI vdev delete id %d\n", vdev_id); 4284 "WMI vdev delete id %d\n", vdev_id);
3690 4285 return skb;
3691 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
3692} 4286}
3693 4287
3694static int 4288static struct sk_buff *
3695ath10k_wmi_vdev_start_restart(struct ath10k *ar, 4289ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
3696 const struct wmi_vdev_start_request_arg *arg, 4290 const struct wmi_vdev_start_request_arg *arg,
3697 u32 cmd_id) 4291 bool restart)
3698{ 4292{
3699 struct wmi_vdev_start_request_cmd *cmd; 4293 struct wmi_vdev_start_request_cmd *cmd;
3700 struct sk_buff *skb; 4294 struct sk_buff *skb;
3701 const char *cmdname; 4295 const char *cmdname;
3702 u32 flags = 0; 4296 u32 flags = 0;
3703 4297
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)) 4298 if (WARN_ON(arg->ssid && arg->ssid_len == 0))
3708 return -EINVAL; 4299 return ERR_PTR(-EINVAL);
3709 if (WARN_ON(arg->hidden_ssid && !arg->ssid)) 4300 if (WARN_ON(arg->hidden_ssid && !arg->ssid))
3710 return -EINVAL; 4301 return ERR_PTR(-EINVAL);
3711 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) 4302 if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
3712 return -EINVAL; 4303 return ERR_PTR(-EINVAL);
3713 4304
3714 if (cmd_id == ar->wmi.cmd->vdev_start_request_cmdid) 4305 if (restart)
3715 cmdname = "start";
3716 else if (cmd_id == ar->wmi.cmd->vdev_restart_request_cmdid)
3717 cmdname = "restart"; 4306 cmdname = "restart";
3718 else 4307 else
3719 return -EINVAL; /* should not happen, we already check cmd_id */ 4308 cmdname = "start";
3720 4309
3721 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4310 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3722 if (!skb) 4311 if (!skb)
3723 return -ENOMEM; 4312 return ERR_PTR(-ENOMEM);
3724 4313
3725 if (arg->hidden_ssid) 4314 if (arg->hidden_ssid)
3726 flags |= WMI_VDEV_START_HIDDEN_SSID; 4315 flags |= WMI_VDEV_START_HIDDEN_SSID;
@@ -3749,50 +4338,36 @@ ath10k_wmi_vdev_start_restart(struct ath10k *ar,
3749 flags, arg->channel.freq, arg->channel.mode, 4338 flags, arg->channel.freq, arg->channel.mode,
3750 cmd->chan.flags, arg->channel.max_power); 4339 cmd->chan.flags, arg->channel.max_power);
3751 4340
3752 return ath10k_wmi_cmd_send(ar, skb, cmd_id); 4341 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} 4342}
3770 4343
3771int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) 4344static struct sk_buff *
4345ath10k_wmi_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id)
3772{ 4346{
3773 struct wmi_vdev_stop_cmd *cmd; 4347 struct wmi_vdev_stop_cmd *cmd;
3774 struct sk_buff *skb; 4348 struct sk_buff *skb;
3775 4349
3776 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4350 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3777 if (!skb) 4351 if (!skb)
3778 return -ENOMEM; 4352 return ERR_PTR(-ENOMEM);
3779 4353
3780 cmd = (struct wmi_vdev_stop_cmd *)skb->data; 4354 cmd = (struct wmi_vdev_stop_cmd *)skb->data;
3781 cmd->vdev_id = __cpu_to_le32(vdev_id); 4355 cmd->vdev_id = __cpu_to_le32(vdev_id);
3782 4356
3783 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); 4357 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id);
3784 4358 return skb;
3785 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid);
3786} 4359}
3787 4360
3788int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) 4361static struct sk_buff *
4362ath10k_wmi_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
4363 const u8 *bssid)
3789{ 4364{
3790 struct wmi_vdev_up_cmd *cmd; 4365 struct wmi_vdev_up_cmd *cmd;
3791 struct sk_buff *skb; 4366 struct sk_buff *skb;
3792 4367
3793 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4368 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3794 if (!skb) 4369 if (!skb)
3795 return -ENOMEM; 4370 return ERR_PTR(-ENOMEM);
3796 4371
3797 cmd = (struct wmi_vdev_up_cmd *)skb->data; 4372 cmd = (struct wmi_vdev_up_cmd *)skb->data;
3798 cmd->vdev_id = __cpu_to_le32(vdev_id); 4373 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3802,30 +4377,30 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
3802 ath10k_dbg(ar, ATH10K_DBG_WMI, 4377 ath10k_dbg(ar, ATH10K_DBG_WMI,
3803 "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", 4378 "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
3804 vdev_id, aid, bssid); 4379 vdev_id, aid, bssid);
3805 4380 return skb;
3806 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid);
3807} 4381}
3808 4382
3809int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) 4383static struct sk_buff *
4384ath10k_wmi_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id)
3810{ 4385{
3811 struct wmi_vdev_down_cmd *cmd; 4386 struct wmi_vdev_down_cmd *cmd;
3812 struct sk_buff *skb; 4387 struct sk_buff *skb;
3813 4388
3814 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4389 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3815 if (!skb) 4390 if (!skb)
3816 return -ENOMEM; 4391 return ERR_PTR(-ENOMEM);
3817 4392
3818 cmd = (struct wmi_vdev_down_cmd *)skb->data; 4393 cmd = (struct wmi_vdev_down_cmd *)skb->data;
3819 cmd->vdev_id = __cpu_to_le32(vdev_id); 4394 cmd->vdev_id = __cpu_to_le32(vdev_id);
3820 4395
3821 ath10k_dbg(ar, ATH10K_DBG_WMI, 4396 ath10k_dbg(ar, ATH10K_DBG_WMI,
3822 "wmi mgmt vdev down id 0x%x\n", vdev_id); 4397 "wmi mgmt vdev down id 0x%x\n", vdev_id);
3823 4398 return skb;
3824 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid);
3825} 4399}
3826 4400
3827int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, 4401static struct sk_buff *
3828 u32 param_id, u32 param_value) 4402ath10k_wmi_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id,
4403 u32 param_id, u32 param_value)
3829{ 4404{
3830 struct wmi_vdev_set_param_cmd *cmd; 4405 struct wmi_vdev_set_param_cmd *cmd;
3831 struct sk_buff *skb; 4406 struct sk_buff *skb;
@@ -3834,12 +4409,12 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
3834 ath10k_dbg(ar, ATH10K_DBG_WMI, 4409 ath10k_dbg(ar, ATH10K_DBG_WMI,
3835 "vdev param %d not supported by firmware\n", 4410 "vdev param %d not supported by firmware\n",
3836 param_id); 4411 param_id);
3837 return -EOPNOTSUPP; 4412 return ERR_PTR(-EOPNOTSUPP);
3838 } 4413 }
3839 4414
3840 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4415 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3841 if (!skb) 4416 if (!skb)
3842 return -ENOMEM; 4417 return ERR_PTR(-ENOMEM);
3843 4418
3844 cmd = (struct wmi_vdev_set_param_cmd *)skb->data; 4419 cmd = (struct wmi_vdev_set_param_cmd *)skb->data;
3845 cmd->vdev_id = __cpu_to_le32(vdev_id); 4420 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3849,24 +4424,24 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
3849 ath10k_dbg(ar, ATH10K_DBG_WMI, 4424 ath10k_dbg(ar, ATH10K_DBG_WMI,
3850 "wmi vdev id 0x%x set param %d value %d\n", 4425 "wmi vdev id 0x%x set param %d value %d\n",
3851 vdev_id, param_id, param_value); 4426 vdev_id, param_id, param_value);
3852 4427 return skb;
3853 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid);
3854} 4428}
3855 4429
3856int ath10k_wmi_vdev_install_key(struct ath10k *ar, 4430static struct sk_buff *
3857 const struct wmi_vdev_install_key_arg *arg) 4431ath10k_wmi_op_gen_vdev_install_key(struct ath10k *ar,
4432 const struct wmi_vdev_install_key_arg *arg)
3858{ 4433{
3859 struct wmi_vdev_install_key_cmd *cmd; 4434 struct wmi_vdev_install_key_cmd *cmd;
3860 struct sk_buff *skb; 4435 struct sk_buff *skb;
3861 4436
3862 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) 4437 if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL)
3863 return -EINVAL; 4438 return ERR_PTR(-EINVAL);
3864 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) 4439 if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL)
3865 return -EINVAL; 4440 return ERR_PTR(-EINVAL);
3866 4441
3867 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len); 4442 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len);
3868 if (!skb) 4443 if (!skb)
3869 return -ENOMEM; 4444 return ERR_PTR(-ENOMEM);
3870 4445
3871 cmd = (struct wmi_vdev_install_key_cmd *)skb->data; 4446 cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
3872 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4447 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
@@ -3885,20 +4460,19 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar,
3885 ath10k_dbg(ar, ATH10K_DBG_WMI, 4460 ath10k_dbg(ar, ATH10K_DBG_WMI,
3886 "wmi vdev install key idx %d cipher %d len %d\n", 4461 "wmi vdev install key idx %d cipher %d len %d\n",
3887 arg->key_idx, arg->key_cipher, arg->key_len); 4462 arg->key_idx, arg->key_cipher, arg->key_len);
3888 return ath10k_wmi_cmd_send(ar, skb, 4463 return skb;
3889 ar->wmi.cmd->vdev_install_key_cmdid);
3890} 4464}
3891 4465
3892int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, 4466static struct sk_buff *
3893 const struct wmi_vdev_spectral_conf_arg *arg) 4467ath10k_wmi_op_gen_vdev_spectral_conf(struct ath10k *ar,
4468 const struct wmi_vdev_spectral_conf_arg *arg)
3894{ 4469{
3895 struct wmi_vdev_spectral_conf_cmd *cmd; 4470 struct wmi_vdev_spectral_conf_cmd *cmd;
3896 struct sk_buff *skb; 4471 struct sk_buff *skb;
3897 u32 cmdid;
3898 4472
3899 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4473 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3900 if (!skb) 4474 if (!skb)
3901 return -ENOMEM; 4475 return ERR_PTR(-ENOMEM);
3902 4476
3903 cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; 4477 cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data;
3904 cmd->vdev_id = __cpu_to_le32(arg->vdev_id); 4478 cmd->vdev_id = __cpu_to_le32(arg->vdev_id);
@@ -3921,39 +4495,38 @@ int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
3921 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); 4495 cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj);
3922 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); 4496 cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask);
3923 4497
3924 cmdid = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid; 4498 return skb;
3925 return ath10k_wmi_cmd_send(ar, skb, cmdid);
3926} 4499}
3927 4500
3928int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, 4501static struct sk_buff *
3929 u32 enable) 4502ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id,
4503 u32 trigger, u32 enable)
3930{ 4504{
3931 struct wmi_vdev_spectral_enable_cmd *cmd; 4505 struct wmi_vdev_spectral_enable_cmd *cmd;
3932 struct sk_buff *skb; 4506 struct sk_buff *skb;
3933 u32 cmdid;
3934 4507
3935 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4508 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3936 if (!skb) 4509 if (!skb)
3937 return -ENOMEM; 4510 return ERR_PTR(-ENOMEM);
3938 4511
3939 cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; 4512 cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data;
3940 cmd->vdev_id = __cpu_to_le32(vdev_id); 4513 cmd->vdev_id = __cpu_to_le32(vdev_id);
3941 cmd->trigger_cmd = __cpu_to_le32(trigger); 4514 cmd->trigger_cmd = __cpu_to_le32(trigger);
3942 cmd->enable_cmd = __cpu_to_le32(enable); 4515 cmd->enable_cmd = __cpu_to_le32(enable);
3943 4516
3944 cmdid = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid; 4517 return skb;
3945 return ath10k_wmi_cmd_send(ar, skb, cmdid);
3946} 4518}
3947 4519
3948int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, 4520static struct sk_buff *
3949 const u8 peer_addr[ETH_ALEN]) 4521ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id,
4522 const u8 peer_addr[ETH_ALEN])
3950{ 4523{
3951 struct wmi_peer_create_cmd *cmd; 4524 struct wmi_peer_create_cmd *cmd;
3952 struct sk_buff *skb; 4525 struct sk_buff *skb;
3953 4526
3954 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4527 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3955 if (!skb) 4528 if (!skb)
3956 return -ENOMEM; 4529 return ERR_PTR(-ENOMEM);
3957 4530
3958 cmd = (struct wmi_peer_create_cmd *)skb->data; 4531 cmd = (struct wmi_peer_create_cmd *)skb->data;
3959 cmd->vdev_id = __cpu_to_le32(vdev_id); 4532 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3962,18 +4535,19 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
3962 ath10k_dbg(ar, ATH10K_DBG_WMI, 4535 ath10k_dbg(ar, ATH10K_DBG_WMI,
3963 "wmi peer create vdev_id %d peer_addr %pM\n", 4536 "wmi peer create vdev_id %d peer_addr %pM\n",
3964 vdev_id, peer_addr); 4537 vdev_id, peer_addr);
3965 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); 4538 return skb;
3966} 4539}
3967 4540
3968int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, 4541static struct sk_buff *
3969 const u8 peer_addr[ETH_ALEN]) 4542ath10k_wmi_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id,
4543 const u8 peer_addr[ETH_ALEN])
3970{ 4544{
3971 struct wmi_peer_delete_cmd *cmd; 4545 struct wmi_peer_delete_cmd *cmd;
3972 struct sk_buff *skb; 4546 struct sk_buff *skb;
3973 4547
3974 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4548 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3975 if (!skb) 4549 if (!skb)
3976 return -ENOMEM; 4550 return ERR_PTR(-ENOMEM);
3977 4551
3978 cmd = (struct wmi_peer_delete_cmd *)skb->data; 4552 cmd = (struct wmi_peer_delete_cmd *)skb->data;
3979 cmd->vdev_id = __cpu_to_le32(vdev_id); 4553 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -3982,18 +4556,19 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
3982 ath10k_dbg(ar, ATH10K_DBG_WMI, 4556 ath10k_dbg(ar, ATH10K_DBG_WMI,
3983 "wmi peer delete vdev_id %d peer_addr %pM\n", 4557 "wmi peer delete vdev_id %d peer_addr %pM\n",
3984 vdev_id, peer_addr); 4558 vdev_id, peer_addr);
3985 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); 4559 return skb;
3986} 4560}
3987 4561
3988int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, 4562static struct sk_buff *
3989 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) 4563ath10k_wmi_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id,
4564 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
3990{ 4565{
3991 struct wmi_peer_flush_tids_cmd *cmd; 4566 struct wmi_peer_flush_tids_cmd *cmd;
3992 struct sk_buff *skb; 4567 struct sk_buff *skb;
3993 4568
3994 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4569 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
3995 if (!skb) 4570 if (!skb)
3996 return -ENOMEM; 4571 return ERR_PTR(-ENOMEM);
3997 4572
3998 cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; 4573 cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
3999 cmd->vdev_id = __cpu_to_le32(vdev_id); 4574 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4003,19 +4578,21 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
4003 ath10k_dbg(ar, ATH10K_DBG_WMI, 4578 ath10k_dbg(ar, ATH10K_DBG_WMI,
4004 "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", 4579 "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
4005 vdev_id, peer_addr, tid_bitmap); 4580 vdev_id, peer_addr, tid_bitmap);
4006 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); 4581 return skb;
4007} 4582}
4008 4583
4009int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, 4584static struct sk_buff *
4010 const u8 *peer_addr, enum wmi_peer_param param_id, 4585ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
4011 u32 param_value) 4586 const u8 *peer_addr,
4587 enum wmi_peer_param param_id,
4588 u32 param_value)
4012{ 4589{
4013 struct wmi_peer_set_param_cmd *cmd; 4590 struct wmi_peer_set_param_cmd *cmd;
4014 struct sk_buff *skb; 4591 struct sk_buff *skb;
4015 4592
4016 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4593 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4017 if (!skb) 4594 if (!skb)
4018 return -ENOMEM; 4595 return ERR_PTR(-ENOMEM);
4019 4596
4020 cmd = (struct wmi_peer_set_param_cmd *)skb->data; 4597 cmd = (struct wmi_peer_set_param_cmd *)skb->data;
4021 cmd->vdev_id = __cpu_to_le32(vdev_id); 4598 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4026,19 +4603,19 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
4026 ath10k_dbg(ar, ATH10K_DBG_WMI, 4603 ath10k_dbg(ar, ATH10K_DBG_WMI,
4027 "wmi vdev %d peer 0x%pM set param %d value %d\n", 4604 "wmi vdev %d peer 0x%pM set param %d value %d\n",
4028 vdev_id, peer_addr, param_id, param_value); 4605 vdev_id, peer_addr, param_id, param_value);
4029 4606 return skb;
4030 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid);
4031} 4607}
4032 4608
4033int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, 4609static struct sk_buff *
4034 enum wmi_sta_ps_mode psmode) 4610ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
4611 enum wmi_sta_ps_mode psmode)
4035{ 4612{
4036 struct wmi_sta_powersave_mode_cmd *cmd; 4613 struct wmi_sta_powersave_mode_cmd *cmd;
4037 struct sk_buff *skb; 4614 struct sk_buff *skb;
4038 4615
4039 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4616 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4040 if (!skb) 4617 if (!skb)
4041 return -ENOMEM; 4618 return ERR_PTR(-ENOMEM);
4042 4619
4043 cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data; 4620 cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data;
4044 cmd->vdev_id = __cpu_to_le32(vdev_id); 4621 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4047,21 +4624,20 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
4047 ath10k_dbg(ar, ATH10K_DBG_WMI, 4624 ath10k_dbg(ar, ATH10K_DBG_WMI,
4048 "wmi set powersave id 0x%x mode %d\n", 4625 "wmi set powersave id 0x%x mode %d\n",
4049 vdev_id, psmode); 4626 vdev_id, psmode);
4050 4627 return skb;
4051 return ath10k_wmi_cmd_send(ar, skb,
4052 ar->wmi.cmd->sta_powersave_mode_cmdid);
4053} 4628}
4054 4629
4055int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, 4630static struct sk_buff *
4056 enum wmi_sta_powersave_param param_id, 4631ath10k_wmi_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id,
4057 u32 value) 4632 enum wmi_sta_powersave_param param_id,
4633 u32 value)
4058{ 4634{
4059 struct wmi_sta_powersave_param_cmd *cmd; 4635 struct wmi_sta_powersave_param_cmd *cmd;
4060 struct sk_buff *skb; 4636 struct sk_buff *skb;
4061 4637
4062 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4638 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4063 if (!skb) 4639 if (!skb)
4064 return -ENOMEM; 4640 return ERR_PTR(-ENOMEM);
4065 4641
4066 cmd = (struct wmi_sta_powersave_param_cmd *)skb->data; 4642 cmd = (struct wmi_sta_powersave_param_cmd *)skb->data;
4067 cmd->vdev_id = __cpu_to_le32(vdev_id); 4643 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4071,22 +4647,22 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
4071 ath10k_dbg(ar, ATH10K_DBG_WMI, 4647 ath10k_dbg(ar, ATH10K_DBG_WMI,
4072 "wmi sta ps param vdev_id 0x%x param %d value %d\n", 4648 "wmi sta ps param vdev_id 0x%x param %d value %d\n",
4073 vdev_id, param_id, value); 4649 vdev_id, param_id, value);
4074 return ath10k_wmi_cmd_send(ar, skb, 4650 return skb;
4075 ar->wmi.cmd->sta_powersave_param_cmdid);
4076} 4651}
4077 4652
4078int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, 4653static struct sk_buff *
4079 enum wmi_ap_ps_peer_param param_id, u32 value) 4654ath10k_wmi_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac,
4655 enum wmi_ap_ps_peer_param param_id, u32 value)
4080{ 4656{
4081 struct wmi_ap_ps_peer_cmd *cmd; 4657 struct wmi_ap_ps_peer_cmd *cmd;
4082 struct sk_buff *skb; 4658 struct sk_buff *skb;
4083 4659
4084 if (!mac) 4660 if (!mac)
4085 return -EINVAL; 4661 return ERR_PTR(-EINVAL);
4086 4662
4087 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4663 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4088 if (!skb) 4664 if (!skb)
4089 return -ENOMEM; 4665 return ERR_PTR(-ENOMEM);
4090 4666
4091 cmd = (struct wmi_ap_ps_peer_cmd *)skb->data; 4667 cmd = (struct wmi_ap_ps_peer_cmd *)skb->data;
4092 cmd->vdev_id = __cpu_to_le32(vdev_id); 4668 cmd->vdev_id = __cpu_to_le32(vdev_id);
@@ -4097,13 +4673,12 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
4097 ath10k_dbg(ar, ATH10K_DBG_WMI, 4673 ath10k_dbg(ar, ATH10K_DBG_WMI,
4098 "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", 4674 "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
4099 vdev_id, param_id, value, mac); 4675 vdev_id, param_id, value, mac);
4100 4676 return skb;
4101 return ath10k_wmi_cmd_send(ar, skb,
4102 ar->wmi.cmd->ap_ps_peer_param_cmdid);
4103} 4677}
4104 4678
4105int ath10k_wmi_scan_chan_list(struct ath10k *ar, 4679static struct sk_buff *
4106 const struct wmi_scan_chan_list_arg *arg) 4680ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar,
4681 const struct wmi_scan_chan_list_arg *arg)
4107{ 4682{
4108 struct wmi_scan_chan_list_cmd *cmd; 4683 struct wmi_scan_chan_list_cmd *cmd;
4109 struct sk_buff *skb; 4684 struct sk_buff *skb;
@@ -4116,7 +4691,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
4116 4691
4117 skb = ath10k_wmi_alloc_skb(ar, len); 4692 skb = ath10k_wmi_alloc_skb(ar, len);
4118 if (!skb) 4693 if (!skb)
4119 return -EINVAL; 4694 return ERR_PTR(-EINVAL);
4120 4695
4121 cmd = (struct wmi_scan_chan_list_cmd *)skb->data; 4696 cmd = (struct wmi_scan_chan_list_cmd *)skb->data;
4122 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); 4697 cmd->num_scan_chans = __cpu_to_le32(arg->n_channels);
@@ -4128,7 +4703,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar,
4128 ath10k_wmi_put_wmi_channel(ci, ch); 4703 ath10k_wmi_put_wmi_channel(ci, ch);
4129 } 4704 }
4130 4705
4131 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); 4706 return skb;
4132} 4707}
4133 4708
4134static void 4709static void
@@ -4209,12 +4784,9 @@ ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf,
4209 cmd->info0 = __cpu_to_le32(info0); 4784 cmd->info0 = __cpu_to_le32(info0);
4210} 4785}
4211 4786
4212int ath10k_wmi_peer_assoc(struct ath10k *ar, 4787static int
4213 const struct wmi_peer_assoc_complete_arg *arg) 4788ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg)
4214{ 4789{
4215 struct sk_buff *skb;
4216 int len;
4217
4218 if (arg->peer_mpdu_density > 16) 4790 if (arg->peer_mpdu_density > 16)
4219 return -EINVAL; 4791 return -EINVAL;
4220 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) 4792 if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES)
@@ -4222,79 +4794,135 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar,
4222 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) 4794 if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES)
4223 return -EINVAL; 4795 return -EINVAL;
4224 4796
4225 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 4797 return 0;
4226 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 4798}
4227 len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); 4799
4228 else 4800static struct sk_buff *
4229 len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); 4801ath10k_wmi_op_gen_peer_assoc(struct ath10k *ar,
4230 } else { 4802 const struct wmi_peer_assoc_complete_arg *arg)
4231 len = sizeof(struct wmi_main_peer_assoc_complete_cmd); 4803{
4232 } 4804 size_t len = sizeof(struct wmi_main_peer_assoc_complete_cmd);
4805 struct sk_buff *skb;
4806 int ret;
4807
4808 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4809 if (ret)
4810 return ERR_PTR(ret);
4233 4811
4234 skb = ath10k_wmi_alloc_skb(ar, len); 4812 skb = ath10k_wmi_alloc_skb(ar, len);
4235 if (!skb) 4813 if (!skb)
4236 return -ENOMEM; 4814 return ERR_PTR(-ENOMEM);
4237 4815
4238 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 4816 ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg);
4239 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 4817
4240 ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); 4818 ath10k_dbg(ar, ATH10K_DBG_WMI,
4241 else 4819 "wmi peer assoc vdev %d addr %pM (%s)\n",
4242 ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); 4820 arg->vdev_id, arg->addr,
4243 } else { 4821 arg->peer_reassoc ? "reassociate" : "new");
4244 ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); 4822 return skb;
4245 } 4823}
4824
4825static struct sk_buff *
4826ath10k_wmi_10_1_op_gen_peer_assoc(struct ath10k *ar,
4827 const struct wmi_peer_assoc_complete_arg *arg)
4828{
4829 size_t len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd);
4830 struct sk_buff *skb;
4831 int ret;
4832
4833 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4834 if (ret)
4835 return ERR_PTR(ret);
4836
4837 skb = ath10k_wmi_alloc_skb(ar, len);
4838 if (!skb)
4839 return ERR_PTR(-ENOMEM);
4840
4841 ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg);
4842
4843 ath10k_dbg(ar, ATH10K_DBG_WMI,
4844 "wmi peer assoc vdev %d addr %pM (%s)\n",
4845 arg->vdev_id, arg->addr,
4846 arg->peer_reassoc ? "reassociate" : "new");
4847 return skb;
4848}
4849
4850static struct sk_buff *
4851ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar,
4852 const struct wmi_peer_assoc_complete_arg *arg)
4853{
4854 size_t len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd);
4855 struct sk_buff *skb;
4856 int ret;
4857
4858 ret = ath10k_wmi_peer_assoc_check_arg(arg);
4859 if (ret)
4860 return ERR_PTR(ret);
4861
4862 skb = ath10k_wmi_alloc_skb(ar, len);
4863 if (!skb)
4864 return ERR_PTR(-ENOMEM);
4865
4866 ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg);
4246 4867
4247 ath10k_dbg(ar, ATH10K_DBG_WMI, 4868 ath10k_dbg(ar, ATH10K_DBG_WMI,
4248 "wmi peer assoc vdev %d addr %pM (%s)\n", 4869 "wmi peer assoc vdev %d addr %pM (%s)\n",
4249 arg->vdev_id, arg->addr, 4870 arg->vdev_id, arg->addr,
4250 arg->peer_reassoc ? "reassociate" : "new"); 4871 arg->peer_reassoc ? "reassociate" : "new");
4251 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); 4872 return skb;
4873}
4874
4875static struct sk_buff *
4876ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar)
4877{
4878 struct sk_buff *skb;
4879
4880 skb = ath10k_wmi_alloc_skb(ar, 0);
4881 if (!skb)
4882 return ERR_PTR(-ENOMEM);
4883
4884 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature\n");
4885 return skb;
4252} 4886}
4253 4887
4254/* This function assumes the beacon is already DMA mapped */ 4888/* This function assumes the beacon is already DMA mapped */
4255int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) 4889static struct sk_buff *
4890ath10k_wmi_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, const void *bcn,
4891 size_t bcn_len, u32 bcn_paddr, bool dtim_zero,
4892 bool deliver_cab)
4256{ 4893{
4257 struct wmi_bcn_tx_ref_cmd *cmd; 4894 struct wmi_bcn_tx_ref_cmd *cmd;
4258 struct sk_buff *skb; 4895 struct sk_buff *skb;
4259 struct sk_buff *beacon = arvif->beacon;
4260 struct ath10k *ar = arvif->ar;
4261 struct ieee80211_hdr *hdr; 4896 struct ieee80211_hdr *hdr;
4262 int ret;
4263 u16 fc; 4897 u16 fc;
4264 4898
4265 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4899 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4266 if (!skb) 4900 if (!skb)
4267 return -ENOMEM; 4901 return ERR_PTR(-ENOMEM);
4268 4902
4269 hdr = (struct ieee80211_hdr *)beacon->data; 4903 hdr = (struct ieee80211_hdr *)bcn;
4270 fc = le16_to_cpu(hdr->frame_control); 4904 fc = le16_to_cpu(hdr->frame_control);
4271 4905
4272 cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data; 4906 cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data;
4273 cmd->vdev_id = __cpu_to_le32(arvif->vdev_id); 4907 cmd->vdev_id = __cpu_to_le32(vdev_id);
4274 cmd->data_len = __cpu_to_le32(beacon->len); 4908 cmd->data_len = __cpu_to_le32(bcn_len);
4275 cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr); 4909 cmd->data_ptr = __cpu_to_le32(bcn_paddr);
4276 cmd->msdu_id = 0; 4910 cmd->msdu_id = 0;
4277 cmd->frame_control = __cpu_to_le32(fc); 4911 cmd->frame_control = __cpu_to_le32(fc);
4278 cmd->flags = 0; 4912 cmd->flags = 0;
4279 cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA); 4913 cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA);
4280 4914
4281 if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) 4915 if (dtim_zero)
4282 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); 4916 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO);
4283 4917
4284 if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab) 4918 if (deliver_cab)
4285 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); 4919 cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB);
4286 4920
4287 ret = ath10k_wmi_cmd_send_nowait(ar, skb, 4921 return skb;
4288 ar->wmi.cmd->pdev_send_bcn_cmdid);
4289
4290 if (ret)
4291 dev_kfree_skb(skb);
4292
4293 return ret;
4294} 4922}
4295 4923
4296static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, 4924void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params,
4297 const struct wmi_wmm_params_arg *arg) 4925 const struct wmi_wmm_params_arg *arg)
4298{ 4926{
4299 params->cwmin = __cpu_to_le32(arg->cwmin); 4927 params->cwmin = __cpu_to_le32(arg->cwmin);
4300 params->cwmax = __cpu_to_le32(arg->cwmax); 4928 params->cwmax = __cpu_to_le32(arg->cwmax);
@@ -4304,52 +4932,54 @@ static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
4304 params->no_ack = __cpu_to_le32(arg->no_ack); 4932 params->no_ack = __cpu_to_le32(arg->no_ack);
4305} 4933}
4306 4934
4307int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 4935static struct sk_buff *
4308 const struct wmi_pdev_set_wmm_params_arg *arg) 4936ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar,
4937 const struct wmi_wmm_params_all_arg *arg)
4309{ 4938{
4310 struct wmi_pdev_set_wmm_params *cmd; 4939 struct wmi_pdev_set_wmm_params *cmd;
4311 struct sk_buff *skb; 4940 struct sk_buff *skb;
4312 4941
4313 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4942 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4314 if (!skb) 4943 if (!skb)
4315 return -ENOMEM; 4944 return ERR_PTR(-ENOMEM);
4316 4945
4317 cmd = (struct wmi_pdev_set_wmm_params *)skb->data; 4946 cmd = (struct wmi_pdev_set_wmm_params *)skb->data;
4318 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be); 4947 ath10k_wmi_set_wmm_param(&cmd->ac_be, &arg->ac_be);
4319 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_bk, &arg->ac_bk); 4948 ath10k_wmi_set_wmm_param(&cmd->ac_bk, &arg->ac_bk);
4320 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); 4949 ath10k_wmi_set_wmm_param(&cmd->ac_vi, &arg->ac_vi);
4321 ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); 4950 ath10k_wmi_set_wmm_param(&cmd->ac_vo, &arg->ac_vo);
4322 4951
4323 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); 4952 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n");
4324 return ath10k_wmi_cmd_send(ar, skb, 4953 return skb;
4325 ar->wmi.cmd->pdev_set_wmm_params_cmdid);
4326} 4954}
4327 4955
4328int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) 4956static struct sk_buff *
4957ath10k_wmi_op_gen_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
4329{ 4958{
4330 struct wmi_request_stats_cmd *cmd; 4959 struct wmi_request_stats_cmd *cmd;
4331 struct sk_buff *skb; 4960 struct sk_buff *skb;
4332 4961
4333 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4962 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4334 if (!skb) 4963 if (!skb)
4335 return -ENOMEM; 4964 return ERR_PTR(-ENOMEM);
4336 4965
4337 cmd = (struct wmi_request_stats_cmd *)skb->data; 4966 cmd = (struct wmi_request_stats_cmd *)skb->data;
4338 cmd->stats_id = __cpu_to_le32(stats_id); 4967 cmd->stats_id = __cpu_to_le32(stats_id);
4339 4968
4340 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); 4969 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); 4970 return skb;
4342} 4971}
4343 4972
4344int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4973static struct sk_buff *
4345 enum wmi_force_fw_hang_type type, u32 delay_ms) 4974ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar,
4975 enum wmi_force_fw_hang_type type, u32 delay_ms)
4346{ 4976{
4347 struct wmi_force_fw_hang_cmd *cmd; 4977 struct wmi_force_fw_hang_cmd *cmd;
4348 struct sk_buff *skb; 4978 struct sk_buff *skb;
4349 4979
4350 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 4980 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4351 if (!skb) 4981 if (!skb)
4352 return -ENOMEM; 4982 return ERR_PTR(-ENOMEM);
4353 4983
4354 cmd = (struct wmi_force_fw_hang_cmd *)skb->data; 4984 cmd = (struct wmi_force_fw_hang_cmd *)skb->data;
4355 cmd->type = __cpu_to_le32(type); 4985 cmd->type = __cpu_to_le32(type);
@@ -4357,10 +4987,12 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar,
4357 4987
4358 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", 4988 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n",
4359 type, delay_ms); 4989 type, delay_ms);
4360 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); 4990 return skb;
4361} 4991}
4362 4992
4363int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) 4993static struct sk_buff *
4994ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable,
4995 u32 log_level)
4364{ 4996{
4365 struct wmi_dbglog_cfg_cmd *cmd; 4997 struct wmi_dbglog_cfg_cmd *cmd;
4366 struct sk_buff *skb; 4998 struct sk_buff *skb;
@@ -4368,12 +5000,12 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
4368 5000
4369 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 5001 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4370 if (!skb) 5002 if (!skb)
4371 return -ENOMEM; 5003 return ERR_PTR(-ENOMEM);
4372 5004
4373 cmd = (struct wmi_dbglog_cfg_cmd *)skb->data; 5005 cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;
4374 5006
4375 if (module_enable) { 5007 if (module_enable) {
4376 cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE, 5008 cfg = SM(log_level,
4377 ATH10K_DBGLOG_CFG_LOG_LVL); 5009 ATH10K_DBGLOG_CFG_LOG_LVL);
4378 } else { 5010 } else {
4379 /* set back defaults, all modules with WARN level */ 5011 /* set back defaults, all modules with WARN level */
@@ -4393,57 +5025,449 @@ int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
4393 __le32_to_cpu(cmd->module_valid), 5025 __le32_to_cpu(cmd->module_valid),
4394 __le32_to_cpu(cmd->config_enable), 5026 __le32_to_cpu(cmd->config_enable),
4395 __le32_to_cpu(cmd->config_valid)); 5027 __le32_to_cpu(cmd->config_valid));
4396 5028 return skb;
4397 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
4398} 5029}
4399 5030
4400int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) 5031static struct sk_buff *
5032ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap)
4401{ 5033{
4402 struct wmi_pdev_pktlog_enable_cmd *cmd; 5034 struct wmi_pdev_pktlog_enable_cmd *cmd;
4403 struct sk_buff *skb; 5035 struct sk_buff *skb;
4404 5036
4405 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); 5037 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
4406 if (!skb) 5038 if (!skb)
4407 return -ENOMEM; 5039 return ERR_PTR(-ENOMEM);
4408 5040
4409 ev_bitmap &= ATH10K_PKTLOG_ANY; 5041 ev_bitmap &= ATH10K_PKTLOG_ANY;
4410 ath10k_dbg(ar, ATH10K_DBG_WMI,
4411 "wmi enable pktlog filter:%x\n", ev_bitmap);
4412 5042
4413 cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data; 5043 cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data;
4414 cmd->ev_bitmap = __cpu_to_le32(ev_bitmap); 5044 cmd->ev_bitmap = __cpu_to_le32(ev_bitmap);
4415 return ath10k_wmi_cmd_send(ar, skb, 5045
4416 ar->wmi.cmd->pdev_pktlog_enable_cmdid); 5046 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi enable pktlog filter 0x%08x\n",
5047 ev_bitmap);
5048 return skb;
4417} 5049}
4418 5050
4419int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar) 5051static struct sk_buff *
5052ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar)
4420{ 5053{
4421 struct sk_buff *skb; 5054 struct sk_buff *skb;
4422 5055
4423 skb = ath10k_wmi_alloc_skb(ar, 0); 5056 skb = ath10k_wmi_alloc_skb(ar, 0);
4424 if (!skb) 5057 if (!skb)
4425 return -ENOMEM; 5058 return ERR_PTR(-ENOMEM);
4426 5059
4427 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n"); 5060 ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n");
5061 return skb;
5062}
5063
5064static struct sk_buff *
5065ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period,
5066 u32 duration, u32 next_offset,
5067 u32 enabled)
5068{
5069 struct wmi_pdev_set_quiet_cmd *cmd;
5070 struct sk_buff *skb;
5071
5072 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
5073 if (!skb)
5074 return ERR_PTR(-ENOMEM);
5075
5076 cmd = (struct wmi_pdev_set_quiet_cmd *)skb->data;
5077 cmd->period = __cpu_to_le32(period);
5078 cmd->duration = __cpu_to_le32(duration);
5079 cmd->next_start = __cpu_to_le32(next_offset);
5080 cmd->enabled = __cpu_to_le32(enabled);
4428 5081
4429 return ath10k_wmi_cmd_send(ar, skb, 5082 ath10k_dbg(ar, ATH10K_DBG_WMI,
4430 ar->wmi.cmd->pdev_pktlog_disable_cmdid); 5083 "wmi quiet param: period %u duration %u enabled %d\n",
5084 period, duration, enabled);
5085 return skb;
4431} 5086}
4432 5087
4433int ath10k_wmi_attach(struct ath10k *ar) 5088static struct sk_buff *
5089ath10k_wmi_op_gen_addba_clear_resp(struct ath10k *ar, u32 vdev_id,
5090 const u8 *mac)
4434{ 5091{
4435 if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { 5092 struct wmi_addba_clear_resp_cmd *cmd;
4436 if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) 5093 struct sk_buff *skb;
4437 ar->wmi.cmd = &wmi_10_2_cmd_map; 5094
4438 else 5095 if (!mac)
4439 ar->wmi.cmd = &wmi_10x_cmd_map; 5096 return ERR_PTR(-EINVAL);
5097
5098 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
5099 if (!skb)
5100 return ERR_PTR(-ENOMEM);
5101
5102 cmd = (struct wmi_addba_clear_resp_cmd *)skb->data;
5103 cmd->vdev_id = __cpu_to_le32(vdev_id);
5104 ether_addr_copy(cmd->peer_macaddr.addr, mac);
5105
5106 ath10k_dbg(ar, ATH10K_DBG_WMI,
5107 "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n",
5108 vdev_id, mac);
5109 return skb;
5110}
5111
5112static struct sk_buff *
5113ath10k_wmi_op_gen_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
5114 u32 tid, u32 buf_size)
5115{
5116 struct wmi_addba_send_cmd *cmd;
5117 struct sk_buff *skb;
5118
5119 if (!mac)
5120 return ERR_PTR(-EINVAL);
5121
5122 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
5123 if (!skb)
5124 return ERR_PTR(-ENOMEM);
5125
5126 cmd = (struct wmi_addba_send_cmd *)skb->data;
5127 cmd->vdev_id = __cpu_to_le32(vdev_id);
5128 ether_addr_copy(cmd->peer_macaddr.addr, mac);
5129 cmd->tid = __cpu_to_le32(tid);
5130 cmd->buffersize = __cpu_to_le32(buf_size);
5131
5132 ath10k_dbg(ar, ATH10K_DBG_WMI,
5133 "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n",
5134 vdev_id, mac, tid, buf_size);
5135 return skb;
5136}
5137
5138static struct sk_buff *
5139ath10k_wmi_op_gen_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac,
5140 u32 tid, u32 status)
5141{
5142 struct wmi_addba_setresponse_cmd *cmd;
5143 struct sk_buff *skb;
5144
5145 if (!mac)
5146 return ERR_PTR(-EINVAL);
5147
5148 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
5149 if (!skb)
5150 return ERR_PTR(-ENOMEM);
5151
5152 cmd = (struct wmi_addba_setresponse_cmd *)skb->data;
5153 cmd->vdev_id = __cpu_to_le32(vdev_id);
5154 ether_addr_copy(cmd->peer_macaddr.addr, mac);
5155 cmd->tid = __cpu_to_le32(tid);
5156 cmd->statuscode = __cpu_to_le32(status);
5157
5158 ath10k_dbg(ar, ATH10K_DBG_WMI,
5159 "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n",
5160 vdev_id, mac, tid, status);
5161 return skb;
5162}
5163
5164static struct sk_buff *
5165ath10k_wmi_op_gen_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac,
5166 u32 tid, u32 initiator, u32 reason)
5167{
5168 struct wmi_delba_send_cmd *cmd;
5169 struct sk_buff *skb;
5170
5171 if (!mac)
5172 return ERR_PTR(-EINVAL);
5173
5174 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
5175 if (!skb)
5176 return ERR_PTR(-ENOMEM);
5177
5178 cmd = (struct wmi_delba_send_cmd *)skb->data;
5179 cmd->vdev_id = __cpu_to_le32(vdev_id);
5180 ether_addr_copy(cmd->peer_macaddr.addr, mac);
5181 cmd->tid = __cpu_to_le32(tid);
5182 cmd->initiator = __cpu_to_le32(initiator);
5183 cmd->reasoncode = __cpu_to_le32(reason);
5184
5185 ath10k_dbg(ar, ATH10K_DBG_WMI,
5186 "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n",
5187 vdev_id, mac, tid, initiator, reason);
5188 return skb;
5189}
5190
5191static const struct wmi_ops wmi_ops = {
5192 .rx = ath10k_wmi_op_rx,
5193 .map_svc = wmi_main_svc_map,
5194
5195 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5196 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5197 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5198 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5199 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5200 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5201 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5202 .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
5203 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5204 .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats,
5205
5206 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5207 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5208 .gen_pdev_set_rd = ath10k_wmi_op_gen_pdev_set_rd,
5209 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5210 .gen_init = ath10k_wmi_op_gen_init,
5211 .gen_start_scan = ath10k_wmi_op_gen_start_scan,
5212 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5213 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5214 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5215 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5216 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5217 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5218 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5219 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5220 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5221 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5222 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5223 /* .gen_vdev_wmm_conf not implemented */
5224 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5225 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5226 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5227 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5228 .gen_peer_assoc = ath10k_wmi_op_gen_peer_assoc,
5229 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5230 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5231 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5232 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5233 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5234 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5235 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5236 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5237 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5238 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5239 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5240 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5241 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5242 /* .gen_pdev_get_temperature not implemented */
5243 .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
5244 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5245 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5246 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5247 /* .gen_bcn_tmpl not implemented */
5248 /* .gen_prb_tmpl not implemented */
5249 /* .gen_p2p_go_bcn_ie not implemented */
5250};
5251
5252static const struct wmi_ops wmi_10_1_ops = {
5253 .rx = ath10k_wmi_10_1_op_rx,
5254 .map_svc = wmi_10x_svc_map,
5255 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
5256 .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
5257 .gen_init = ath10k_wmi_10_1_op_gen_init,
5258 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
5259 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
5260 .gen_peer_assoc = ath10k_wmi_10_1_op_gen_peer_assoc,
5261 /* .gen_pdev_get_temperature not implemented */
5262
5263 /* shared with main branch */
5264 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5265 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5266 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5267 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5268 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5269 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5270 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5271 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5272
5273 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5274 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5275 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5276 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5277 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5278 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5279 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5280 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5281 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5282 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5283 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5284 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5285 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5286 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5287 /* .gen_vdev_wmm_conf not implemented */
5288 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5289 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5290 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5291 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5292 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5293 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5294 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5295 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5296 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5297 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5298 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5299 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5300 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5301 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5302 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5303 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5304 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5305 .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
5306 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5307 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5308 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5309 /* .gen_bcn_tmpl not implemented */
5310 /* .gen_prb_tmpl not implemented */
5311 /* .gen_p2p_go_bcn_ie not implemented */
5312};
5313
5314static const struct wmi_ops wmi_10_2_ops = {
5315 .rx = ath10k_wmi_10_2_op_rx,
5316 .pull_fw_stats = ath10k_wmi_10_2_op_pull_fw_stats,
5317 .gen_init = ath10k_wmi_10_2_op_gen_init,
5318 .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
5319 /* .gen_pdev_get_temperature not implemented */
5320
5321 /* shared with 10.1 */
5322 .map_svc = wmi_10x_svc_map,
5323 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
5324 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
5325 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
5326
5327 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5328 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5329 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5330 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5331 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5332 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5333 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5334 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5335
5336 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5337 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5338 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5339 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5340 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5341 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5342 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5343 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5344 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5345 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5346 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5347 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5348 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5349 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5350 /* .gen_vdev_wmm_conf not implemented */
5351 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5352 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5353 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5354 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5355 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5356 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5357 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5358 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5359 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5360 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5361 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5362 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5363 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5364 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5365 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5366 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5367 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5368 .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
5369 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5370 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5371 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5372};
4440 5373
5374static const struct wmi_ops wmi_10_2_4_ops = {
5375 .rx = ath10k_wmi_10_2_op_rx,
5376 .pull_fw_stats = ath10k_wmi_10_2_4_op_pull_fw_stats,
5377 .gen_init = ath10k_wmi_10_2_op_gen_init,
5378 .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
5379 .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
5380
5381 /* shared with 10.1 */
5382 .map_svc = wmi_10x_svc_map,
5383 .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
5384 .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
5385 .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
5386
5387 .pull_scan = ath10k_wmi_op_pull_scan_ev,
5388 .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev,
5389 .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev,
5390 .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev,
5391 .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev,
5392 .pull_swba = ath10k_wmi_op_pull_swba_ev,
5393 .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
5394 .pull_rdy = ath10k_wmi_op_pull_rdy_ev,
5395
5396 .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
5397 .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume,
5398 .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param,
5399 .gen_stop_scan = ath10k_wmi_op_gen_stop_scan,
5400 .gen_vdev_create = ath10k_wmi_op_gen_vdev_create,
5401 .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete,
5402 .gen_vdev_start = ath10k_wmi_op_gen_vdev_start,
5403 .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop,
5404 .gen_vdev_up = ath10k_wmi_op_gen_vdev_up,
5405 .gen_vdev_down = ath10k_wmi_op_gen_vdev_down,
5406 .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param,
5407 .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key,
5408 .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf,
5409 .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable,
5410 .gen_peer_create = ath10k_wmi_op_gen_peer_create,
5411 .gen_peer_delete = ath10k_wmi_op_gen_peer_delete,
5412 .gen_peer_flush = ath10k_wmi_op_gen_peer_flush,
5413 .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param,
5414 .gen_set_psmode = ath10k_wmi_op_gen_set_psmode,
5415 .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps,
5416 .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps,
5417 .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list,
5418 .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma,
5419 .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm,
5420 .gen_request_stats = ath10k_wmi_op_gen_request_stats,
5421 .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang,
5422 .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx,
5423 .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg,
5424 .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable,
5425 .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable,
5426 .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode,
5427 .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp,
5428 .gen_addba_send = ath10k_wmi_op_gen_addba_send,
5429 .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp,
5430 .gen_delba_send = ath10k_wmi_op_gen_delba_send,
5431 /* .gen_bcn_tmpl not implemented */
5432 /* .gen_prb_tmpl not implemented */
5433 /* .gen_p2p_go_bcn_ie not implemented */
5434};
5435
5436int ath10k_wmi_attach(struct ath10k *ar)
5437{
5438 switch (ar->wmi.op_version) {
5439 case ATH10K_FW_WMI_OP_VERSION_10_2_4:
5440 ar->wmi.cmd = &wmi_10_2_4_cmd_map;
5441 ar->wmi.ops = &wmi_10_2_4_ops;
5442 ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map;
5443 ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map;
5444 break;
5445 case ATH10K_FW_WMI_OP_VERSION_10_2:
5446 ar->wmi.cmd = &wmi_10_2_cmd_map;
5447 ar->wmi.ops = &wmi_10_2_ops;
4441 ar->wmi.vdev_param = &wmi_10x_vdev_param_map; 5448 ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
4442 ar->wmi.pdev_param = &wmi_10x_pdev_param_map; 5449 ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
4443 } else { 5450 break;
5451 case ATH10K_FW_WMI_OP_VERSION_10_1:
5452 ar->wmi.cmd = &wmi_10x_cmd_map;
5453 ar->wmi.ops = &wmi_10_1_ops;
5454 ar->wmi.vdev_param = &wmi_10x_vdev_param_map;
5455 ar->wmi.pdev_param = &wmi_10x_pdev_param_map;
5456 break;
5457 case ATH10K_FW_WMI_OP_VERSION_MAIN:
4444 ar->wmi.cmd = &wmi_cmd_map; 5458 ar->wmi.cmd = &wmi_cmd_map;
5459 ar->wmi.ops = &wmi_ops;
4445 ar->wmi.vdev_param = &wmi_vdev_param_map; 5460 ar->wmi.vdev_param = &wmi_vdev_param_map;
4446 ar->wmi.pdev_param = &wmi_pdev_param_map; 5461 ar->wmi.pdev_param = &wmi_pdev_param_map;
5462 break;
5463 case ATH10K_FW_WMI_OP_VERSION_TLV:
5464 ath10k_wmi_tlv_attach(ar);
5465 break;
5466 case ATH10K_FW_WMI_OP_VERSION_UNSET:
5467 case ATH10K_FW_WMI_OP_VERSION_MAX:
5468 ath10k_err(ar, "unsupported WMI op version: %d\n",
5469 ar->wmi.op_version);
5470 return -EINVAL;
4447 } 5471 }
4448 5472
4449 init_completion(&ar->wmi.service_ready); 5473 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..20ce3603e64b 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,8 @@ 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;
554 u32 vdev_set_wmm_params_cmdid;
475}; 555};
476 556
477/* 557/*
@@ -1076,6 +1156,11 @@ enum wmi_10_2_cmd_id {
1076 WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID, 1156 WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID,
1077 WMI_10_2_PDEV_RATEPWR_TABLE_CMDID, 1157 WMI_10_2_PDEV_RATEPWR_TABLE_CMDID,
1078 WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID, 1158 WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID,
1159 WMI_10_2_PDEV_GET_INFO,
1160 WMI_10_2_VDEV_GET_INFO,
1161 WMI_10_2_VDEV_ATF_REQUEST_CMDID,
1162 WMI_10_2_PEER_ATF_REQUEST_CMDID,
1163 WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
1079 WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1, 1164 WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
1080}; 1165};
1081 1166
@@ -1117,6 +1202,8 @@ enum wmi_10_2_event_id {
1117 WMI_10_2_MCAST_BUF_RELEASE_EVENTID, 1202 WMI_10_2_MCAST_BUF_RELEASE_EVENTID,
1118 WMI_10_2_MCAST_LIST_AGEOUT_EVENTID, 1203 WMI_10_2_MCAST_LIST_AGEOUT_EVENTID,
1119 WMI_10_2_WDS_PEER_EVENTID, 1204 WMI_10_2_WDS_PEER_EVENTID,
1205 WMI_10_2_PEER_STA_PS_STATECHG_EVENTID,
1206 WMI_10_2_PDEV_TEMPERATURE_EVENTID,
1120 WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1, 1207 WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1,
1121}; 1208};
1122 1209
@@ -1862,6 +1949,11 @@ struct wmi_resource_config_10x {
1862 __le32 max_frag_entries; 1949 __le32 max_frag_entries;
1863} __packed; 1950} __packed;
1864 1951
1952enum wmi_10_2_feature_mask {
1953 WMI_10_2_RX_BATCH_MODE = BIT(0),
1954 WMI_10_2_ATF_CONFIG = BIT(1),
1955};
1956
1865struct wmi_resource_config_10_2 { 1957struct wmi_resource_config_10_2 {
1866 struct wmi_resource_config_10x common; 1958 struct wmi_resource_config_10x common;
1867 __le32 max_peer_ext_stats; 1959 __le32 max_peer_ext_stats;
@@ -1870,7 +1962,7 @@ struct wmi_resource_config_10_2 {
1870 __le32 be_min_free; 1962 __le32 be_min_free;
1871 __le32 vi_min_free; 1963 __le32 vi_min_free;
1872 __le32 vo_min_free; 1964 __le32 vo_min_free;
1873 __le32 rx_batchmode; /* 0-disable, 1-enable */ 1965 __le32 feature_mask;
1874} __packed; 1966} __packed;
1875 1967
1876#define NUM_UNITS_IS_NUM_VDEVS 0x1 1968#define NUM_UNITS_IS_NUM_VDEVS 0x1
@@ -2505,6 +2597,7 @@ struct wmi_pdev_param_map {
2505 u32 fast_channel_reset; 2597 u32 fast_channel_reset;
2506 u32 burst_dur; 2598 u32 burst_dur;
2507 u32 burst_enable; 2599 u32 burst_enable;
2600 u32 cal_period;
2508}; 2601};
2509 2602
2510#define WMI_PDEV_PARAM_UNSUPPORTED 0 2603#define WMI_PDEV_PARAM_UNSUPPORTED 0
@@ -2715,6 +2808,9 @@ enum wmi_10x_pdev_param {
2715 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE, 2808 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE,
2716 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, 2809 WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER,
2717 WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, 2810 WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
2811 WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE,
2812 WMI_10X_PDEV_PARAM_RTS_FIXED_RATE,
2813 WMI_10X_PDEV_PARAM_CAL_PERIOD
2718}; 2814};
2719 2815
2720struct wmi_pdev_set_param_cmd { 2816struct wmi_pdev_set_param_cmd {
@@ -2722,6 +2818,9 @@ struct wmi_pdev_set_param_cmd {
2722 __le32 param_value; 2818 __le32 param_value;
2723} __packed; 2819} __packed;
2724 2820
2821/* valid period is 1 ~ 60000ms, unit in millisecond */
2822#define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000
2823
2725struct wmi_pdev_get_tpc_config_cmd { 2824struct wmi_pdev_get_tpc_config_cmd {
2726 /* parameter */ 2825 /* parameter */
2727 __le32 param; 2826 __le32 param;
@@ -2841,14 +2940,14 @@ struct wmi_wmm_params_arg {
2841 u32 no_ack; 2940 u32 no_ack;
2842}; 2941};
2843 2942
2844struct wmi_pdev_set_wmm_params_arg { 2943struct wmi_wmm_params_all_arg {
2845 struct wmi_wmm_params_arg ac_be; 2944 struct wmi_wmm_params_arg ac_be;
2846 struct wmi_wmm_params_arg ac_bk; 2945 struct wmi_wmm_params_arg ac_bk;
2847 struct wmi_wmm_params_arg ac_vi; 2946 struct wmi_wmm_params_arg ac_vi;
2848 struct wmi_wmm_params_arg ac_vo; 2947 struct wmi_wmm_params_arg ac_vo;
2849}; 2948};
2850 2949
2851struct wal_dbg_tx_stats { 2950struct wmi_pdev_stats_tx {
2852 /* Num HTT cookies queued to dispatch list */ 2951 /* Num HTT cookies queued to dispatch list */
2853 __le32 comp_queued; 2952 __le32 comp_queued;
2854 2953
@@ -2918,7 +3017,7 @@ struct wal_dbg_tx_stats {
2918 __le32 txop_ovf; 3017 __le32 txop_ovf;
2919} __packed; 3018} __packed;
2920 3019
2921struct wal_dbg_rx_stats { 3020struct wmi_pdev_stats_rx {
2922 /* Cnts any change in ring routing mid-ppdu */ 3021 /* Cnts any change in ring routing mid-ppdu */
2923 __le32 mid_ppdu_route_change; 3022 __le32 mid_ppdu_route_change;
2924 3023
@@ -2952,17 +3051,11 @@ struct wal_dbg_rx_stats {
2952 __le32 mpdu_errs; 3051 __le32 mpdu_errs;
2953} __packed; 3052} __packed;
2954 3053
2955struct wal_dbg_peer_stats { 3054struct wmi_pdev_stats_peer {
2956 /* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */ 3055 /* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */
2957 __le32 dummy; 3056 __le32 dummy;
2958} __packed; 3057} __packed;
2959 3058
2960struct wal_dbg_stats {
2961 struct wal_dbg_tx_stats tx;
2962 struct wal_dbg_rx_stats rx;
2963 struct wal_dbg_peer_stats peer;
2964} __packed;
2965
2966enum wmi_stats_id { 3059enum wmi_stats_id {
2967 WMI_REQUEST_PEER_STAT = 0x01, 3060 WMI_REQUEST_PEER_STAT = 0x01,
2968 WMI_REQUEST_AP_STAT = 0x02 3061 WMI_REQUEST_AP_STAT = 0x02
@@ -3029,23 +3122,38 @@ struct wmi_stats_event {
3029 u8 data[0]; 3122 u8 data[0];
3030} __packed; 3123} __packed;
3031 3124
3125struct wmi_10_2_stats_event {
3126 __le32 stats_id; /* %WMI_REQUEST_ */
3127 __le32 num_pdev_stats;
3128 __le32 num_pdev_ext_stats;
3129 __le32 num_vdev_stats;
3130 __le32 num_peer_stats;
3131 __le32 num_bcnflt_stats;
3132 u8 data[0];
3133} __packed;
3134
3032/* 3135/*
3033 * PDEV statistics 3136 * PDEV statistics
3034 * TODO: add all PDEV stats here 3137 * TODO: add all PDEV stats here
3035 */ 3138 */
3139struct wmi_pdev_stats_base {
3140 __le32 chan_nf;
3141 __le32 tx_frame_count;
3142 __le32 rx_frame_count;
3143 __le32 rx_clear_count;
3144 __le32 cycle_count;
3145 __le32 phy_err_count;
3146 __le32 chan_tx_pwr;
3147} __packed;
3148
3036struct wmi_pdev_stats { 3149struct wmi_pdev_stats {
3037 __le32 chan_nf; /* Channel noise floor */ 3150 struct wmi_pdev_stats_base base;
3038 __le32 tx_frame_count; /* TX frame count */ 3151 struct wmi_pdev_stats_tx tx;
3039 __le32 rx_frame_count; /* RX frame count */ 3152 struct wmi_pdev_stats_rx rx;
3040 __le32 rx_clear_count; /* rx clear count */ 3153 struct wmi_pdev_stats_peer peer;
3041 __le32 cycle_count; /* cycle count */
3042 __le32 phy_err_count; /* Phy error count */
3043 __le32 chan_tx_pwr; /* channel tx power */
3044 struct wal_dbg_stats wal; /* WAL dbg stats */
3045} __packed; 3154} __packed;
3046 3155
3047struct wmi_10x_pdev_stats { 3156struct wmi_pdev_stats_extra {
3048 struct wmi_pdev_stats old;
3049 __le32 ack_rx_bad; 3157 __le32 ack_rx_bad;
3050 __le32 rts_bad; 3158 __le32 rts_bad;
3051 __le32 rts_good; 3159 __le32 rts_good;
@@ -3054,6 +3162,30 @@ struct wmi_10x_pdev_stats {
3054 __le32 mib_int_count; 3162 __le32 mib_int_count;
3055} __packed; 3163} __packed;
3056 3164
3165struct wmi_10x_pdev_stats {
3166 struct wmi_pdev_stats_base base;
3167 struct wmi_pdev_stats_tx tx;
3168 struct wmi_pdev_stats_rx rx;
3169 struct wmi_pdev_stats_peer peer;
3170 struct wmi_pdev_stats_extra extra;
3171} __packed;
3172
3173struct wmi_pdev_stats_mem {
3174 __le32 dram_free;
3175 __le32 iram_free;
3176} __packed;
3177
3178struct wmi_10_2_pdev_stats {
3179 struct wmi_pdev_stats_base base;
3180 struct wmi_pdev_stats_tx tx;
3181 __le32 mc_drop;
3182 struct wmi_pdev_stats_rx rx;
3183 __le32 pdev_rx_timeout;
3184 struct wmi_pdev_stats_mem mem;
3185 struct wmi_pdev_stats_peer peer;
3186 struct wmi_pdev_stats_extra extra;
3187} __packed;
3188
3057/* 3189/*
3058 * VDEV statistics 3190 * VDEV statistics
3059 * TODO: add all VDEV stats here 3191 * TODO: add all VDEV stats here
@@ -3077,6 +3209,32 @@ struct wmi_10x_peer_stats {
3077 __le32 peer_rx_rate; 3209 __le32 peer_rx_rate;
3078} __packed; 3210} __packed;
3079 3211
3212struct wmi_10_2_peer_stats {
3213 struct wmi_peer_stats old;
3214 __le32 peer_rx_rate;
3215 __le32 current_per;
3216 __le32 retries;
3217 __le32 tx_rate_count;
3218 __le32 max_4ms_frame_len;
3219 __le32 total_sub_frames;
3220 __le32 tx_bytes;
3221 __le32 num_pkt_loss_overflow[4];
3222 __le32 num_pkt_loss_excess_retry[4];
3223} __packed;
3224
3225struct wmi_10_2_4_peer_stats {
3226 struct wmi_10_2_peer_stats common;
3227 __le32 unknown_value; /* FIXME: what is this word? */
3228} __packed;
3229
3230struct wmi_10_2_pdev_ext_stats {
3231 __le32 rx_rssi_comb;
3232 __le32 rx_rssi[4];
3233 __le32 rx_mcs[10];
3234 __le32 tx_mcs[10];
3235 __le32 ack_rssi;
3236} __packed;
3237
3080struct wmi_vdev_create_cmd { 3238struct wmi_vdev_create_cmd {
3081 __le32 vdev_id; 3239 __le32 vdev_id;
3082 __le32 vdev_type; 3240 __le32 vdev_type;
@@ -3930,6 +4088,13 @@ enum wmi_sta_ps_param_pspoll_count {
3930 * Values greater than 0 indicate the maximum numer of PS-Poll frames 4088 * Values greater than 0 indicate the maximum numer of PS-Poll frames
3931 * FW will send before waking up. 4089 * FW will send before waking up.
3932 */ 4090 */
4091
4092 /* When u-APSD is enabled the firmware will be very reluctant to exit
4093 * STA PS. This could result in very poor Rx performance with STA doing
4094 * PS-Poll for each and every buffered frame. This value is a bit
4095 * arbitrary.
4096 */
4097 WMI_STA_PS_PSPOLL_COUNT_UAPSD = 3,
3933}; 4098};
3934 4099
3935/* 4100/*
@@ -3955,6 +4120,30 @@ enum wmi_sta_ps_param_uapsd {
3955 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7), 4120 WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7),
3956}; 4121};
3957 4122
4123#define WMI_STA_UAPSD_MAX_INTERVAL_MSEC UINT_MAX
4124
4125struct wmi_sta_uapsd_auto_trig_param {
4126 __le32 wmm_ac;
4127 __le32 user_priority;
4128 __le32 service_interval;
4129 __le32 suspend_interval;
4130 __le32 delay_interval;
4131};
4132
4133struct wmi_sta_uapsd_auto_trig_cmd_fixed_param {
4134 __le32 vdev_id;
4135 struct wmi_mac_addr peer_macaddr;
4136 __le32 num_ac;
4137};
4138
4139struct wmi_sta_uapsd_auto_trig_arg {
4140 u32 wmm_ac;
4141 u32 user_priority;
4142 u32 service_interval;
4143 u32 suspend_interval;
4144 u32 delay_interval;
4145};
4146
3958enum wmi_sta_powersave_param { 4147enum wmi_sta_powersave_param {
3959 /* 4148 /*
3960 * Controls how frames are retrievd from AP while STA is sleeping 4149 * Controls how frames are retrievd from AP while STA is sleeping
@@ -4120,7 +4309,7 @@ struct wmi_bcn_info {
4120 4309
4121struct wmi_host_swba_event { 4310struct wmi_host_swba_event {
4122 __le32 vdev_map; 4311 __le32 vdev_map;
4123 struct wmi_bcn_info bcn_info[1]; 4312 struct wmi_bcn_info bcn_info[0];
4124} __packed; 4313} __packed;
4125 4314
4126#define WMI_MAX_AP_VDEV 16 4315#define WMI_MAX_AP_VDEV 16
@@ -4325,7 +4514,7 @@ struct wmi_peer_set_q_empty_callback_cmd {
4325#define WMI_PEER_SPATIAL_MUX 0x00200000 4514#define WMI_PEER_SPATIAL_MUX 0x00200000
4326#define WMI_PEER_VHT 0x02000000 4515#define WMI_PEER_VHT 0x02000000
4327#define WMI_PEER_80MHZ 0x04000000 4516#define WMI_PEER_80MHZ 0x04000000
4328#define WMI_PEER_PMF 0x08000000 4517#define WMI_PEER_VHT_2G 0x08000000
4329 4518
4330/* 4519/*
4331 * Peer rate capabilities. 4520 * Peer rate capabilities.
@@ -4476,6 +4665,11 @@ enum wmi_sta_keepalive_method {
4476 WMI_STA_KEEPALIVE_METHOD_UNSOLICITATED_ARP_RESPONSE = 2, 4665 WMI_STA_KEEPALIVE_METHOD_UNSOLICITATED_ARP_RESPONSE = 2,
4477}; 4666};
4478 4667
4668#define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0
4669
4670/* Firmware crashes if keepalive interval exceeds this limit */
4671#define WMI_STA_KEEPALIVE_INTERVAL_MAX_SECONDS 0xffff
4672
4479/* note: ip4 addresses are in network byte order, i.e. big endian */ 4673/* note: ip4 addresses are in network byte order, i.e. big endian */
4480struct wmi_sta_keepalive_arp_resp { 4674struct wmi_sta_keepalive_arp_resp {
4481 __be32 src_ip4_addr; 4675 __be32 src_ip4_addr;
@@ -4491,6 +4685,16 @@ struct wmi_sta_keepalive_cmd {
4491 struct wmi_sta_keepalive_arp_resp arp_resp; 4685 struct wmi_sta_keepalive_arp_resp arp_resp;
4492} __packed; 4686} __packed;
4493 4687
4688struct wmi_sta_keepalive_arg {
4689 u32 vdev_id;
4690 u32 enabled;
4691 u32 method;
4692 u32 interval;
4693 __be32 src_ip4_addr;
4694 __be32 dest_ip4_addr;
4695 const u8 dest_mac_addr[ETH_ALEN];
4696};
4697
4494enum wmi_force_fw_hang_type { 4698enum wmi_force_fw_hang_type {
4495 WMI_FORCE_FW_HANG_ASSERT = 1, 4699 WMI_FORCE_FW_HANG_ASSERT = 1,
4496 WMI_FORCE_FW_HANG_NO_DETECT, 4700 WMI_FORCE_FW_HANG_NO_DETECT,
@@ -4567,6 +4771,58 @@ struct wmi_dbglog_cfg_cmd {
4567 4771
4568#define WMI_MAX_MEM_REQS 16 4772#define WMI_MAX_MEM_REQS 16
4569 4773
4774struct wmi_scan_ev_arg {
4775 __le32 event_type; /* %WMI_SCAN_EVENT_ */
4776 __le32 reason; /* %WMI_SCAN_REASON_ */
4777 __le32 channel_freq; /* only valid for WMI_SCAN_EVENT_FOREIGN_CHANNEL */
4778 __le32 scan_req_id;
4779 __le32 scan_id;
4780 __le32 vdev_id;
4781};
4782
4783struct wmi_mgmt_rx_ev_arg {
4784 __le32 channel;
4785 __le32 snr;
4786 __le32 rate;
4787 __le32 phy_mode;
4788 __le32 buf_len;
4789 __le32 status; /* %WMI_RX_STATUS_ */
4790};
4791
4792struct wmi_ch_info_ev_arg {
4793 __le32 err_code;
4794 __le32 freq;
4795 __le32 cmd_flags;
4796 __le32 noise_floor;
4797 __le32 rx_clear_count;
4798 __le32 cycle_count;
4799};
4800
4801struct wmi_vdev_start_ev_arg {
4802 __le32 vdev_id;
4803 __le32 req_id;
4804 __le32 resp_type; /* %WMI_VDEV_RESP_ */
4805 __le32 status;
4806};
4807
4808struct wmi_peer_kick_ev_arg {
4809 const u8 *mac_addr;
4810};
4811
4812struct wmi_swba_ev_arg {
4813 __le32 vdev_map;
4814 const struct wmi_tim_info *tim_info[WMI_MAX_AP_VDEV];
4815 const struct wmi_p2p_noa_info *noa_info[WMI_MAX_AP_VDEV];
4816};
4817
4818struct wmi_phyerr_ev_arg {
4819 __le32 num_phyerrs;
4820 __le32 tsf_l32;
4821 __le32 tsf_u32;
4822 __le32 buf_len;
4823 const struct wmi_phyerr *phyerrs;
4824};
4825
4570struct wmi_svc_rdy_ev_arg { 4826struct wmi_svc_rdy_ev_arg {
4571 __le32 min_tx_power; 4827 __le32 min_tx_power;
4572 __le32 max_tx_power; 4828 __le32 max_tx_power;
@@ -4574,6 +4830,7 @@ struct wmi_svc_rdy_ev_arg {
4574 __le32 vht_cap; 4830 __le32 vht_cap;
4575 __le32 sw_ver0; 4831 __le32 sw_ver0;
4576 __le32 sw_ver1; 4832 __le32 sw_ver1;
4833 __le32 fw_build;
4577 __le32 phy_capab; 4834 __le32 phy_capab;
4578 __le32 num_rf_chains; 4835 __le32 num_rf_chains;
4579 __le32 eeprom_rd; 4836 __le32 eeprom_rd;
@@ -4583,83 +4840,99 @@ struct wmi_svc_rdy_ev_arg {
4583 const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; 4840 const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS];
4584}; 4841};
4585 4842
4843struct wmi_rdy_ev_arg {
4844 __le32 sw_version;
4845 __le32 abi_version;
4846 __le32 status;
4847 const u8 *mac_addr;
4848};
4849
4850struct wmi_pdev_temperature_event {
4851 /* temperature value in Celcius degree */
4852 __le32 temperature;
4853} __packed;
4854
4586struct ath10k; 4855struct ath10k;
4587struct ath10k_vif; 4856struct ath10k_vif;
4588struct ath10k_fw_stats; 4857struct ath10k_fw_stats_pdev;
4858struct ath10k_fw_stats_peer;
4589 4859
4590int ath10k_wmi_attach(struct ath10k *ar); 4860int ath10k_wmi_attach(struct ath10k *ar);
4591void ath10k_wmi_detach(struct ath10k *ar); 4861void ath10k_wmi_detach(struct ath10k *ar);
4592int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); 4862int ath10k_wmi_wait_for_service_ready(struct ath10k *ar);
4593int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); 4863int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
4594 4864
4865struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);
4595int ath10k_wmi_connect(struct ath10k *ar); 4866int ath10k_wmi_connect(struct ath10k *ar);
4596 4867
4597struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); 4868struct 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); 4869int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
4599 4870int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
4600int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); 4871 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 *); 4872void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *);
4609int ath10k_wmi_stop_scan(struct ath10k *ar, 4873
4610 const struct wmi_stop_scan_arg *arg); 4874void ath10k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src,
4611int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, 4875 struct ath10k_fw_stats_pdev *dst);
4612 enum wmi_vdev_type type, 4876void ath10k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src,
4613 enum wmi_vdev_subtype subtype, 4877 struct ath10k_fw_stats_pdev *dst);
4614 const u8 macaddr[ETH_ALEN]); 4878void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src,
4615int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id); 4879 struct ath10k_fw_stats_pdev *dst);
4616int ath10k_wmi_vdev_start(struct ath10k *ar, 4880void ath10k_wmi_pull_pdev_stats_extra(const struct wmi_pdev_stats_extra *src,
4617 const struct wmi_vdev_start_request_arg *); 4881 struct ath10k_fw_stats_pdev *dst);
4618int ath10k_wmi_vdev_restart(struct ath10k *ar, 4882void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
4619 const struct wmi_vdev_start_request_arg *); 4883 struct ath10k_fw_stats_peer *dst);
4620int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id); 4884void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
4621int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, 4885 struct wmi_host_mem_chunks *chunks);
4622 const u8 *bssid); 4886void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
4623int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id); 4887 const struct wmi_start_scan_arg *arg);
4624int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, 4888void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params,
4625 u32 param_id, u32 param_value); 4889 const struct wmi_wmm_params_arg *arg);
4626int ath10k_wmi_vdev_install_key(struct ath10k *ar, 4890void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
4627 const struct wmi_vdev_install_key_arg *arg); 4891 const struct wmi_channel_arg *arg);
4628int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, 4892int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
4629 const struct wmi_vdev_spectral_conf_arg *arg); 4893
4630int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, 4894int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb);
4631 u32 enable); 4895int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb);
4632int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, 4896void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb);
4633 const u8 peer_addr[ETH_ALEN]); 4897void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb);
4634int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, 4898int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb);
4635 const u8 peer_addr[ETH_ALEN]); 4899void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb);
4636int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, 4900void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb);
4637 const u8 peer_addr[ETH_ALEN], u32 tid_bitmap); 4901void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb);
4638int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, 4902void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb);
4639 const u8 *peer_addr, 4903void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb);
4640 enum wmi_peer_param param_id, u32 param_value); 4904void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb);
4641int ath10k_wmi_peer_assoc(struct ath10k *ar, 4905void ath10k_wmi_event_dfs(struct ath10k *ar,
4642 const struct wmi_peer_assoc_complete_arg *arg); 4906 const struct wmi_phyerr *phyerr, u64 tsf);
4643int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, 4907void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
4644 enum wmi_sta_ps_mode psmode); 4908 const struct wmi_phyerr *phyerr,
4645int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, 4909 u64 tsf);
4646 enum wmi_sta_powersave_param param_id, 4910void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb);
4647 u32 value); 4911void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb);
4648int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, 4912void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb);
4649 enum wmi_ap_ps_peer_param param_id, u32 value); 4913void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb);
4650int ath10k_wmi_scan_chan_list(struct ath10k *ar, 4914void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb);
4651 const struct wmi_scan_chan_list_arg *arg); 4915void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb);
4652int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif); 4916void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
4653int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, 4917 struct sk_buff *skb);
4654 const struct wmi_pdev_set_wmm_params_arg *arg); 4918void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
4655int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); 4919 struct sk_buff *skb);
4656int ath10k_wmi_force_fw_hang(struct ath10k *ar, 4920void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb);
4657 enum wmi_force_fw_hang_type type, u32 delay_ms); 4921void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb);
4658int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); 4922void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb);
4659int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); 4923void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb);
4660int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, 4924void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb);
4661 struct ath10k_fw_stats *stats); 4925void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
4662int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list); 4926 struct sk_buff *skb);
4663int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar); 4927void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb);
4928void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb);
4929void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb);
4930void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
4931 struct sk_buff *skb);
4932void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb);
4933void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb);
4934void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb);
4935void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb);
4936int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb);
4664 4937
4665#endif /* _WMI_H_ */ 4938#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/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 19eab2a69ad5..3b4a6463d87a 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -672,10 +672,10 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
672 spin_lock_bh(&common->cc_lock); 672 spin_lock_bh(&common->cc_lock);
673 ath_hw_cycle_counters_update(common); 673 ath_hw_cycle_counters_update(common);
674 if (cc->cycles > 0) { 674 if (cc->cycles > 0) {
675 ah->survey.channel_time += cc->cycles / div; 675 ah->survey.time += cc->cycles / div;
676 ah->survey.channel_time_busy += cc->rx_busy / div; 676 ah->survey.time_busy += cc->rx_busy / div;
677 ah->survey.channel_time_rx += cc->rx_frame / div; 677 ah->survey.time_rx += cc->rx_frame / div;
678 ah->survey.channel_time_tx += cc->tx_frame / div; 678 ah->survey.time_tx += cc->tx_frame / div;
679 } 679 }
680 memset(cc, 0, sizeof(*cc)); 680 memset(cc, 0, sizeof(*cc));
681 spin_unlock_bh(&common->cc_lock); 681 spin_unlock_bh(&common->cc_lock);
@@ -686,10 +686,10 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
686 survey->noise = ah->ah_noise_floor; 686 survey->noise = ah->ah_noise_floor;
687 survey->filled = SURVEY_INFO_NOISE_DBM | 687 survey->filled = SURVEY_INFO_NOISE_DBM |
688 SURVEY_INFO_IN_USE | 688 SURVEY_INFO_IN_USE |
689 SURVEY_INFO_CHANNEL_TIME | 689 SURVEY_INFO_TIME |
690 SURVEY_INFO_CHANNEL_TIME_BUSY | 690 SURVEY_INFO_TIME_BUSY |
691 SURVEY_INFO_CHANNEL_TIME_RX | 691 SURVEY_INFO_TIME_RX |
692 SURVEY_INFO_CHANNEL_TIME_TX; 692 SURVEY_INFO_TIME_TX;
693 693
694 return 0; 694 return 0;
695} 695}
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/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index a3399c4f13a9..b9b651ea9851 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -478,7 +478,7 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah, u32 flags)
478 regval = ioread32(reg); 478 regval = ioread32(reg);
479 iowrite32(regval | val, reg); 479 iowrite32(regval | val, reg);
480 regval = ioread32(reg); 480 regval = ioread32(reg);
481 usleep_range(100, 150); 481 udelay(100); /* NB: should be atomic */
482 482
483 /* Bring BB/MAC out of reset */ 483 /* Bring BB/MAC out of reset */
484 iowrite32(regval & ~val, reg); 484 iowrite32(regval & ~val, reg);
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 7a5337877a0c..85da63a67faf 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1799,20 +1799,20 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1799 1799
1800 if (vif->target_stats.rx_byte) { 1800 if (vif->target_stats.rx_byte) {
1801 sinfo->rx_bytes = vif->target_stats.rx_byte; 1801 sinfo->rx_bytes = vif->target_stats.rx_byte;
1802 sinfo->filled |= STATION_INFO_RX_BYTES64; 1802 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES64);
1803 sinfo->rx_packets = vif->target_stats.rx_pkt; 1803 sinfo->rx_packets = vif->target_stats.rx_pkt;
1804 sinfo->filled |= STATION_INFO_RX_PACKETS; 1804 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
1805 } 1805 }
1806 1806
1807 if (vif->target_stats.tx_byte) { 1807 if (vif->target_stats.tx_byte) {
1808 sinfo->tx_bytes = vif->target_stats.tx_byte; 1808 sinfo->tx_bytes = vif->target_stats.tx_byte;
1809 sinfo->filled |= STATION_INFO_TX_BYTES64; 1809 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES64);
1810 sinfo->tx_packets = vif->target_stats.tx_pkt; 1810 sinfo->tx_packets = vif->target_stats.tx_pkt;
1811 sinfo->filled |= STATION_INFO_TX_PACKETS; 1811 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
1812 } 1812 }
1813 1813
1814 sinfo->signal = vif->target_stats.cs_rssi; 1814 sinfo->signal = vif->target_stats.cs_rssi;
1815 sinfo->filled |= STATION_INFO_SIGNAL; 1815 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1816 1816
1817 rate = vif->target_stats.tx_ucast_rate; 1817 rate = vif->target_stats.tx_ucast_rate;
1818 1818
@@ -1827,6 +1827,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1827 } 1827 }
1828 1828
1829 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 1829 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1830 sinfo->txrate.bw = RATE_INFO_BW_20;
1830 } else if (is_rate_ht40(rate, &mcs, &sgi)) { 1831 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1831 if (sgi) { 1832 if (sgi) {
1832 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; 1833 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
@@ -1835,7 +1836,7 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1835 sinfo->txrate.mcs = mcs; 1836 sinfo->txrate.mcs = mcs;
1836 } 1837 }
1837 1838
1838 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 1839 sinfo->txrate.bw = RATE_INFO_BW_40;
1839 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; 1840 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1840 } else { 1841 } else {
1841 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, 1842 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
@@ -1844,12 +1845,12 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1844 return 0; 1845 return 0;
1845 } 1846 }
1846 1847
1847 sinfo->filled |= STATION_INFO_TX_BITRATE; 1848 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
1848 1849
1849 if (test_bit(CONNECTED, &vif->flags) && 1850 if (test_bit(CONNECTED, &vif->flags) &&
1850 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) && 1851 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1851 vif->nw_type == INFRA_NETWORK) { 1852 vif->nw_type == INFRA_NETWORK) {
1852 sinfo->filled |= STATION_INFO_BSS_PARAM; 1853 sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
1853 sinfo->bss_param.flags = 0; 1854 sinfo->bss_param.flags = 0;
1854 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period; 1855 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1855 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int; 1856 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 933aef025698..b42ba46b5030 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -488,7 +488,6 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
488 488
489 sinfo.assoc_req_ies = ies; 489 sinfo.assoc_req_ies = ies;
490 sinfo.assoc_req_ies_len = ies_len; 490 sinfo.assoc_req_ies_len = ies_len;
491 sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
492 491
493 cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL); 492 cfg80211_new_sta(vif->ndev, mac_addr, &sinfo, GFP_KERNEL);
494 493
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_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 06ab71db6e80..174442beb952 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1203,24 +1203,41 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
1203static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) 1203static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
1204{ 1204{
1205 int offset[8] = {0}, total = 0, test; 1205 int offset[8] = {0}, total = 0, test;
1206 int agc_out, i; 1206 int agc_out, i, peak_detect_threshold;
1207 1207
1208 if (AR_SREV_9550(ah) || AR_SREV_9531(ah))
1209 peak_detect_threshold = 8;
1210 else
1211 peak_detect_threshold = 0;
1212
1213 /*
1214 * Turn off LNA/SW.
1215 */
1208 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1216 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1209 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); 1217 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1);
1210 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1218 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1211 AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); 1219 AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0);
1212 if (is_2g)
1213 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1214 AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
1215 else
1216 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1217 AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
1218 1220
1221 if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9330_11(ah)) {
1222 if (is_2g)
1223 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1224 AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0);
1225 else
1226 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1227 AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0);
1228 }
1229
1230 /*
1231 * Turn off RXON.
1232 */
1219 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1233 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1220 AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); 1234 AR_PHY_65NM_RXTX2_RXON_OVR, 0x1);
1221 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1235 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1222 AR_PHY_65NM_RXTX2_RXON, 0x0); 1236 AR_PHY_65NM_RXTX2_RXON, 0x0);
1223 1237
1238 /*
1239 * Turn on AGC for cal.
1240 */
1224 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1241 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1225 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); 1242 AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1);
1226 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1243 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
@@ -1228,16 +1245,19 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
1228 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1245 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1229 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); 1246 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1);
1230 1247
1231 if (AR_SREV_9330_11(ah)) { 1248 if (AR_SREV_9330_11(ah))
1232 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1249 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1233 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0); 1250 AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
1234 } else { 1251
1252 if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
1235 if (is_2g) 1253 if (is_2g)
1236 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1254 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1237 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0); 1255 AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR,
1256 peak_detect_threshold);
1238 else 1257 else
1239 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1258 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1240 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); 1259 AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR,
1260 peak_detect_threshold);
1241 } 1261 }
1242 1262
1243 for (i = 6; i > 0; i--) { 1263 for (i = 6; i > 0; i--) {
@@ -1266,10 +1286,19 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g)
1266 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1286 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1267 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); 1287 AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total);
1268 1288
1289 /*
1290 * Turn on LNA.
1291 */
1269 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), 1292 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain),
1270 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); 1293 AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0);
1294 /*
1295 * Turn off RXON.
1296 */
1271 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), 1297 REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain),
1272 AR_PHY_65NM_RXTX2_RXON_OVR, 0); 1298 AR_PHY_65NM_RXTX2_RXON_OVR, 0);
1299 /*
1300 * Turn off peak detect calibration.
1301 */
1273 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), 1302 REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
1274 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); 1303 AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0);
1275} 1304}
@@ -1611,8 +1640,14 @@ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
1611 1640
1612skip_tx_iqcal: 1641skip_tx_iqcal:
1613 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { 1642 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1614 if (AR_SREV_9330_11(ah)) 1643 if (AR_SREV_9330_11(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
1615 ar9003_hw_manual_peak_cal(ah, 0, IS_CHAN_2GHZ(chan)); 1644 for (i = 0; i < AR9300_MAX_CHAINS; i++) {
1645 if (!(ah->rxchainmask & (1 << i)))
1646 continue;
1647 ar9003_hw_manual_peak_cal(ah, i,
1648 IS_CHAN_2GHZ(chan));
1649 }
1650 }
1616 1651
1617 /* 1652 /*
1618 * For non-AR9550 chips, we just trigger AGC calibration 1653 * For non-AR9550 chips, we just trigger AGC calibration
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/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
index 81c88dd606dc..86bfc9604dca 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_wow.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -17,23 +17,9 @@
17#include <linux/export.h> 17#include <linux/export.h>
18#include "ath9k.h" 18#include "ath9k.h"
19#include "reg.h" 19#include "reg.h"
20#include "reg_wow.h"
20#include "hw-ops.h" 21#include "hw-ops.h"
21 22
22const char *ath9k_hw_wow_event_to_string(u32 wow_event)
23{
24 if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
25 return "Magic pattern";
26 if (wow_event & AH_WOW_USER_PATTERN_EN)
27 return "User pattern";
28 if (wow_event & AH_WOW_LINK_CHANGE)
29 return "Link change";
30 if (wow_event & AH_WOW_BEACON_MISS)
31 return "Beacon miss";
32
33 return "unknown reason";
34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36
37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 23static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
38{ 24{
39 struct ath_common *common = ath9k_hw_common(ah); 25 struct ath_common *common = ath9k_hw_common(ah);
@@ -49,6 +35,15 @@ static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
49 return; 35 return;
50 } 36 }
51 37
38 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
39 if (!REG_READ(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL))
40 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE);
41 } else if (AR_SREV_9485(ah)){
42 if (!(REG_READ(ah, AR_NDP2_TIMER_MODE) &
43 AR_GEN_TIMERS2_MODE_ENABLE_MASK))
44 REG_CLR_BIT(ah, AR_DIRECT_CONNECT, AR_DC_TSF2_ENABLE);
45 }
46
52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); 47 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
53} 48}
54 49
@@ -67,11 +62,15 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
67 /* set the transmit buffer */ 62 /* set the transmit buffer */
68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); 63 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
69 ctl[1] = 0; 64 ctl[1] = 0;
70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
71 ctl[4] = 0; 65 ctl[4] = 0;
72 ctl[7] = (ah->txchainmask) << 2; 66 ctl[7] = (ah->txchainmask) << 2;
73 ctl[2] = 0xf << 16; /* tx_tries 0 */ 67 ctl[2] = 0xf << 16; /* tx_tries 0 */
74 68
69 if (IS_CHAN_2GHZ(ah->curchan))
70 ctl[3] = 0x1b; /* CCK_1M */
71 else
72 ctl[3] = 0xb; /* OFDM_6M */
73
75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++) 74 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); 75 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
77 76
@@ -103,21 +102,22 @@ static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
103 102
104} 103}
105 104
106void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 105int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
107 u8 *user_mask, int pattern_count, 106 u8 *user_mask, int pattern_count,
108 int pattern_len) 107 int pattern_len)
109{ 108{
110 int i; 109 int i;
111 u32 pattern_val, mask_val; 110 u32 pattern_val, mask_val;
112 u32 set, clr; 111 u32 set, clr;
113 112
114 /* FIXME: should check count by querying the hardware capability */ 113 if (pattern_count >= ah->wow.max_patterns)
115 if (pattern_count >= MAX_NUM_PATTERN) 114 return -ENOSPC;
116 return;
117 115
118 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); 116 if (pattern_count < MAX_NUM_PATTERN_LEGACY)
117 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
118 else
119 REG_SET_BIT(ah, AR_MAC_PCU_WOW4, BIT(pattern_count - 8));
119 120
120 /* set the registers for pattern */
121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { 121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
122 memcpy(&pattern_val, user_pattern, 4); 122 memcpy(&pattern_val, user_pattern, 4);
123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), 123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
@@ -125,49 +125,42 @@ void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
125 user_pattern += 4; 125 user_pattern += 4;
126 } 126 }
127 127
128 /* set the registers for mask */
129 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { 128 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
130 memcpy(&mask_val, user_mask, 4); 129 memcpy(&mask_val, user_mask, 4);
131 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); 130 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
132 user_mask += 4; 131 user_mask += 4;
133 } 132 }
134 133
135 /* set the pattern length to be matched 134 if (pattern_count < MAX_NUM_PATTERN_LEGACY)
136 * 135 ah->wow.wow_event_mask |=
137 * AR_WOW_LENGTH1_REG1 136 BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
138 * bit 31:24 pattern 0 length 137 else
139 * bit 23:16 pattern 1 length 138 ah->wow.wow_event_mask2 |=
140 * bit 15:8 pattern 2 length 139 BIT((pattern_count - 8) + AR_WOW_PAT_FOUND_SHIFT);
141 * bit 7:0 pattern 3 length
142 *
143 * AR_WOW_LENGTH1_REG2
144 * bit 31:24 pattern 4 length
145 * bit 23:16 pattern 5 length
146 * bit 15:8 pattern 6 length
147 * bit 7:0 pattern 7 length
148 *
149 * the below logic writes out the new
150 * pattern length for the corresponding
151 * pattern_count, while masking out the
152 * other fields
153 */
154
155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
156 140
157 if (pattern_count < 4) { 141 if (pattern_count < 4) {
158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
159 set = (pattern_len & AR_WOW_LENGTH_MAX) << 142 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
160 AR_WOW_LEN1_SHIFT(pattern_count); 143 AR_WOW_LEN1_SHIFT(pattern_count);
161 clr = AR_WOW_LENGTH1_MASK(pattern_count); 144 clr = AR_WOW_LENGTH1_MASK(pattern_count);
162 REG_RMW(ah, AR_WOW_LENGTH1, set, clr); 145 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
163 } else { 146 } else if (pattern_count < 8) {
164 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
165 set = (pattern_len & AR_WOW_LENGTH_MAX) << 147 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
166 AR_WOW_LEN2_SHIFT(pattern_count); 148 AR_WOW_LEN2_SHIFT(pattern_count);
167 clr = AR_WOW_LENGTH2_MASK(pattern_count); 149 clr = AR_WOW_LENGTH2_MASK(pattern_count);
168 REG_RMW(ah, AR_WOW_LENGTH2, set, clr); 150 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
151 } else if (pattern_count < 12) {
152 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
153 AR_WOW_LEN3_SHIFT(pattern_count);
154 clr = AR_WOW_LENGTH3_MASK(pattern_count);
155 REG_RMW(ah, AR_WOW_LENGTH3, set, clr);
156 } else if (pattern_count < MAX_NUM_PATTERN) {
157 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
158 AR_WOW_LEN4_SHIFT(pattern_count);
159 clr = AR_WOW_LENGTH4_MASK(pattern_count);
160 REG_RMW(ah, AR_WOW_LENGTH4, set, clr);
169 } 161 }
170 162
163 return 0;
171} 164}
172EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); 165EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
173 166
@@ -189,7 +182,7 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
189 * register. This mask will clean it up. 182 * register. This mask will clean it up.
190 */ 183 */
191 184
192 val &= ah->wow_event_mask; 185 val &= ah->wow.wow_event_mask;
193 186
194 if (val) { 187 if (val) {
195 if (val & AR_WOW_MAGIC_PAT_FOUND) 188 if (val & AR_WOW_MAGIC_PAT_FOUND)
@@ -233,190 +226,192 @@ u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
233 if (ah->is_pciexpress) 226 if (ah->is_pciexpress)
234 ath9k_hw_configpcipowersave(ah, false); 227 ath9k_hw_configpcipowersave(ah, false);
235 228
236 ah->wow_event_mask = 0; 229 ah->wow.wow_event_mask = 0;
237 230
238 return wow_status; 231 return wow_status;
239} 232}
240EXPORT_SYMBOL(ath9k_hw_wow_wakeup); 233EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
241 234
242void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) 235static void ath9k_hw_wow_set_arwr_reg(struct ath_hw *ah)
243{ 236{
244 u32 wow_event_mask; 237 u32 wa_reg;
245 u32 set, clr;
246 238
247 /* 239 if (!ah->is_pciexpress)
248 * wow_event_mask is a mask to the AR_WOW_PATTERN register to 240 return;
249 * indicate which WoW events we have enabled. The WoW events
250 * are from the 'pattern_enable' in this function and
251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
252 */
253 wow_event_mask = ah->wow_event_mask;
254 241
255 /* 242 /*
256 * Untie Power-on-Reset from the PCI-E-Reset. When we are in 243 * We need to untie the internal POR (power-on-reset)
257 * WOW sleep, we do want the Reset from the PCI-E to disturb 244 * to the external PCI-E reset. We also need to tie
258 * our hw state 245 * the PCI-E Phy reset to the PCI-E reset.
259 */ 246 */
260 if (ah->is_pciexpress) { 247 wa_reg = REG_READ(ah, AR_WA);
261 /* 248 wa_reg &= ~AR_WA_UNTIE_RESET_EN;
262 * we need to untie the internal POR (power-on-reset) 249 wa_reg |= AR_WA_RESET_EN;
263 * to the external PCI-E reset. We also need to tie 250 wa_reg |= AR_WA_POR_SHORT;
264 * the PCI-E Phy reset to the PCI-E reset.
265 */
266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
268 REG_RMW(ah, AR_WA, set, clr);
269 }
270 251
271 /* 252 REG_WRITE(ah, AR_WA, wa_reg);
272 * set the power states appropriately and enable PME 253}
273 */ 254
274 set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA | 255void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
275 AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR; 256{
257 u32 wow_event_mask;
258 u32 keep_alive, magic_pattern, host_pm_ctrl;
259
260 wow_event_mask = ah->wow.wow_event_mask;
276 261
277 /* 262 /*
278 * set and clear WOW_PME_CLEAR registers for the chip 263 * AR_PMCTRL_HOST_PME_EN - Override PME enable in configuration
264 * space and allow MAC to generate WoW anyway.
265 *
266 * AR_PMCTRL_PWR_PM_CTRL_ENA - ???
267 *
268 * AR_PMCTRL_AUX_PWR_DET - PCI core SYS_AUX_PWR_DET signal,
269 * needs to be set for WoW in PCI mode.
270 *
271 * AR_PMCTRL_WOW_PME_CLR - WoW Clear Signal going to the MAC.
272 *
273 * Set the power states appropriately and enable PME.
274 *
275 * Set and clear WOW_PME_CLEAR for the chip
279 * to generate next wow signal. 276 * to generate next wow signal.
280 */ 277 */
281 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 278 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_HOST_PME_EN |
282 clr = AR_PMCTRL_WOW_PME_CLR; 279 AR_PMCTRL_PWR_PM_CTRL_ENA |
283 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 280 AR_PMCTRL_AUX_PWR_DET |
281 AR_PMCTRL_WOW_PME_CLR);
282 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR);
284 283
285 /* 284 /*
286 * Setup for: 285 * Random Backoff.
287 * - beacon misses 286 *
288 * - magic pattern 287 * 31:28 in AR_WOW_PATTERN : Indicates the number of bits used in the
289 * - keep alive timeout 288 * contention window. For value N,
290 * - pattern matching 289 * the random backoff will be selected between
290 * 0 and (2 ^ N) - 1.
291 */ 291 */
292 REG_SET_BIT(ah, AR_WOW_PATTERN,
293 AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF));
292 294
293 /* 295 /*
294 * Program default values for pattern backoff, aifs/slot/KAL count, 296 * AIFS time, Slot time, Keep Alive count.
295 * beacon miss timeout, KAL timeout, etc. 297 */
298 REG_SET_BIT(ah, AR_WOW_COUNT, AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
299 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
300 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT));
301 /*
302 * Beacon timeout.
296 */ 303 */
297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
299
300 set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
301 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
302 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
303 REG_SET_BIT(ah, AR_WOW_COUNT, set);
304
305 if (pattern_enable & AH_WOW_BEACON_MISS) 304 if (pattern_enable & AH_WOW_BEACON_MISS)
306 set = AR_WOW_BEACON_TIMO; 305 REG_WRITE(ah, AR_WOW_BCN_TIMO, AR_WOW_BEACON_TIMO);
307 /* We are not using beacon miss, program a large value */
308 else 306 else
309 set = AR_WOW_BEACON_TIMO_MAX; 307 REG_WRITE(ah, AR_WOW_BCN_TIMO, AR_WOW_BEACON_TIMO_MAX);
310
311 REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
312 308
313 /* 309 /*
314 * Keep alive timo in ms except AR9280 310 * Keep alive timeout in ms.
315 */ 311 */
316 if (!pattern_enable) 312 if (!pattern_enable)
317 set = AR_WOW_KEEP_ALIVE_NEVER; 313 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, AR_WOW_KEEP_ALIVE_NEVER);
318 else 314 else
319 set = KAL_TIMEOUT * 32; 315 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, KAL_TIMEOUT * 32);
320
321 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
322 316
323 /* 317 /*
324 * Keep alive delay in us. based on 'power on clock', 318 * Keep alive delay in us.
325 * therefore in usec
326 */ 319 */
327 set = KAL_DELAY * 1000; 320 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, KAL_DELAY * 1000);
328 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
329 321
330 /* 322 /*
331 * Create keep alive pattern to respond to beacons 323 * Create keep alive pattern to respond to beacons.
332 */ 324 */
333 ath9k_wow_create_keep_alive_pattern(ah); 325 ath9k_wow_create_keep_alive_pattern(ah);
334 326
335 /* 327 /*
336 * Configure MAC WoW Registers 328 * Configure keep alive register.
337 */ 329 */
338 set = 0; 330 keep_alive = REG_READ(ah, AR_WOW_KEEP_ALIVE);
331
339 /* Send keep alive timeouts anyway */ 332 /* Send keep alive timeouts anyway */
340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; 333 keep_alive &= ~AR_WOW_KEEP_ALIVE_AUTO_DIS;
341 334
342 if (pattern_enable & AH_WOW_LINK_CHANGE) 335 if (pattern_enable & AH_WOW_LINK_CHANGE) {
336 keep_alive &= ~AR_WOW_KEEP_ALIVE_FAIL_DIS;
343 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL; 337 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
344 else 338 } else {
345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 339 keep_alive |= AR_WOW_KEEP_ALIVE_FAIL_DIS;
340 }
346 341
347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 342 REG_WRITE(ah, AR_WOW_KEEP_ALIVE, keep_alive);
348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
349 343
350 /* 344 /*
351 * we are relying on a bmiss failure. ensure we have 345 * We are relying on a bmiss failure, ensure we have
352 * enough threshold to prevent false positives 346 * enough threshold to prevent false positives.
353 */ 347 */
354 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 348 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
355 AR_WOW_BMISSTHRESHOLD); 349 AR_WOW_BMISSTHRESHOLD);
356 350
357 set = 0;
358 clr = 0;
359
360 if (pattern_enable & AH_WOW_BEACON_MISS) { 351 if (pattern_enable & AH_WOW_BEACON_MISS) {
361 set = AR_WOW_BEACON_FAIL_EN;
362 wow_event_mask |= AR_WOW_BEACON_FAIL; 352 wow_event_mask |= AR_WOW_BEACON_FAIL;
353 REG_SET_BIT(ah, AR_WOW_BCN_EN, AR_WOW_BEACON_FAIL_EN);
363 } else { 354 } else {
364 clr = AR_WOW_BEACON_FAIL_EN; 355 REG_CLR_BIT(ah, AR_WOW_BCN_EN, AR_WOW_BEACON_FAIL_EN);
365 } 356 }
366 357
367 REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
368
369 set = 0;
370 clr = 0;
371 /* 358 /*
372 * Enable the magic packet registers 359 * Enable the magic packet registers.
373 */ 360 */
361 magic_pattern = REG_READ(ah, AR_WOW_PATTERN);
362 magic_pattern |= AR_WOW_MAC_INTR_EN;
363
374 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) { 364 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
375 set = AR_WOW_MAGIC_EN; 365 magic_pattern |= AR_WOW_MAGIC_EN;
376 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND; 366 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
377 } else { 367 } else {
378 clr = AR_WOW_MAGIC_EN; 368 magic_pattern &= ~AR_WOW_MAGIC_EN;
379 } 369 }
380 set |= AR_WOW_MAC_INTR_EN;
381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
382 370
371 REG_WRITE(ah, AR_WOW_PATTERN, magic_pattern);
372
373 /*
374 * Enable pattern matching for packets which are less
375 * than 256 bytes.
376 */
383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, 377 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
384 AR_WOW_PATTERN_SUPPORTED); 378 AR_WOW_PATTERN_SUPPORTED);
385 379
386 /* 380 /*
387 * Set the power states appropriately and enable PME 381 * Set the power states appropriately and enable PME.
388 */ 382 */
389 clr = 0; 383 host_pm_ctrl = REG_READ(ah, AR_PCIE_PM_CTRL);
390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | 384 host_pm_ctrl |= AR_PMCTRL_PWR_STATE_D1D3 |
391 AR_PMCTRL_PWR_PM_CTRL_ENA; 385 AR_PMCTRL_HOST_PME_EN |
386 AR_PMCTRL_PWR_PM_CTRL_ENA;
387 host_pm_ctrl &= ~AR_PCIE_PM_CTRL_ENA;
392 388
393 clr = AR_PCIE_PM_CTRL_ENA; 389 if (AR_SREV_9462(ah)) {
394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 390 /*
391 * This is needed to prevent the chip waking up
392 * the host within 3-4 seconds with certain
393 * platform/BIOS.
394 */
395 host_pm_ctrl &= ~AR_PMCTRL_PWR_STATE_D1D3;
396 host_pm_ctrl |= AR_PMCTRL_PWR_STATE_D1D3_REAL;
397 }
398
399 REG_WRITE(ah, AR_PCIE_PM_CTRL, host_pm_ctrl);
395 400
396 /* 401 /*
397 * this is needed to prevent the chip waking up 402 * Enable sequence number generation when asleep.
398 * the host within 3-4 seconds with certain
399 * platform/BIOS. The fix is to enable
400 * D1 & D3 to match original definition and
401 * also match the OTP value. Anyway this
402 * is more related to SW WOW.
403 */ 403 */
404 clr = AR_PMCTRL_PWR_STATE_D1D3; 404 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
406 405
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL; 406 /* To bring down WOW power low margin */
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 407 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, BIT(13));
409 408
410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 409 ath9k_hw_wow_set_arwr_reg(ah);
411 410
412 /* to bring down WOW power low margin */
413 set = BIT(13);
414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
415 /* HW WoW */ 411 /* HW WoW */
416 clr = BIT(5); 412 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, BIT(5));
417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
418 413
419 ath9k_hw_set_powermode_wow_sleep(ah); 414 ath9k_hw_set_powermode_wow_sleep(ah);
420 ah->wow_event_mask = wow_event_mask; 415 ah->wow.wow_event_mask = wow_event_mask;
421} 416}
422EXPORT_SYMBOL(ath9k_hw_wow_enable); 417EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
index 159cc6fd2362..6fc0d07e5ec6 100644
--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -358,7 +358,7 @@ static const u32 qca953x_1p0_baseband_postamble[][5] = {
358 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 358 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
359 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 359 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
360 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, 360 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
361 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10822, 0xcfa10822}, 361 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10820, 0xcfa10820},
362 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, 362 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
363 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, 363 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
364 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 364 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
@@ -378,7 +378,7 @@ static const u32 qca953x_1p0_baseband_postamble[][5] = {
378 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, 378 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
379 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 379 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
380 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 380 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
381 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 381 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
382 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33}, 382 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
383 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982}, 383 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
384 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 384 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
diff --git a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
index fd6a84ccd49e..148562addd38 100644
--- a/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar955x_1p0_initvals.h
@@ -63,7 +63,7 @@ static const u32 ar955x_1p0_baseband_postamble[][5] = {
63 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, 63 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
64 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, 64 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
65 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, 65 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
66 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10822, 0xcfa10822}, 66 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcfa10820, 0xcfa10820},
67 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, 67 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
68 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, 68 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
69 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, 69 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
@@ -83,7 +83,7 @@ static const u32 ar955x_1p0_baseband_postamble[][5] = {
83 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010}, 83 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
84 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 84 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
85 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 85 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
86 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 86 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18},
87 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33}, 87 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
88 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982}, 88 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
89 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 89 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
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/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1a9fe0983a6b..0f8e9464e4ab 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -34,7 +34,7 @@ struct ath_vif;
34 34
35extern struct ieee80211_ops ath9k_ops; 35extern struct ieee80211_ops ath9k_ops;
36extern int ath9k_modparam_nohwcrypt; 36extern int ath9k_modparam_nohwcrypt;
37extern int led_blink; 37extern int ath9k_led_blink;
38extern bool is_ath9k_unloaded; 38extern bool is_ath9k_unloaded;
39extern int ath9k_use_chanctx; 39extern int ath9k_use_chanctx;
40 40
@@ -830,14 +830,9 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
830/* Wake on Wireless LAN */ 830/* Wake on Wireless LAN */
831/************************/ 831/************************/
832 832
833struct ath9k_wow_pattern {
834 u8 pattern_bytes[MAX_PATTERN_SIZE];
835 u8 mask_bytes[MAX_PATTERN_SIZE];
836 u32 pattern_len;
837};
838
839#ifdef CONFIG_ATH9K_WOW 833#ifdef CONFIG_ATH9K_WOW
840void ath9k_init_wow(struct ieee80211_hw *hw); 834void ath9k_init_wow(struct ieee80211_hw *hw);
835void ath9k_deinit_wow(struct ieee80211_hw *hw);
841int ath9k_suspend(struct ieee80211_hw *hw, 836int ath9k_suspend(struct ieee80211_hw *hw,
842 struct cfg80211_wowlan *wowlan); 837 struct cfg80211_wowlan *wowlan);
843int ath9k_resume(struct ieee80211_hw *hw); 838int ath9k_resume(struct ieee80211_hw *hw);
@@ -846,6 +841,9 @@ void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
846static inline void ath9k_init_wow(struct ieee80211_hw *hw) 841static inline void ath9k_init_wow(struct ieee80211_hw *hw)
847{ 842{
848} 843}
844static inline void ath9k_deinit_wow(struct ieee80211_hw *hw)
845{
846}
849static inline int ath9k_suspend(struct ieee80211_hw *hw, 847static inline int ath9k_suspend(struct ieee80211_hw *hw,
850 struct cfg80211_wowlan *wowlan) 848 struct cfg80211_wowlan *wowlan)
851{ 849{
@@ -1039,9 +1037,8 @@ struct ath_softc {
1039 s16 tx99_power; 1037 s16 tx99_power;
1040 1038
1041#ifdef CONFIG_ATH9K_WOW 1039#ifdef CONFIG_ATH9K_WOW
1042 atomic_t wow_got_bmiss_intr;
1043 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
1044 u32 wow_intr_before_sleep; 1040 u32 wow_intr_before_sleep;
1041 bool force_wow;
1045#endif 1042#endif
1046}; 1043};
1047 1044
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index ec93ddf0863a..5cee231cca1f 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -582,7 +582,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
582 582
583void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv) 583void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
584{ 584{
585 if (config_enabled(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) { 585 if (config_enabled(CONFIG_ATH9K_DEBUGFS)) {
586 relay_close(spec_priv->rfs_chan_spec_scan); 586 relay_close(spec_priv->rfs_chan_spec_scan);
587 spec_priv->rfs_chan_spec_scan = NULL; 587 spec_priv->rfs_chan_spec_scan = NULL;
588 } 588 }
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 871e969409bf..50a2e0ac3b8b 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);
@@ -1115,6 +1043,133 @@ static const struct file_operations fops_ackto = {
1115}; 1043};
1116#endif 1044#endif
1117 1045
1046#ifdef CONFIG_ATH9K_WOW
1047
1048static ssize_t read_file_wow(struct file *file, char __user *user_buf,
1049 size_t count, loff_t *ppos)
1050{
1051 struct ath_softc *sc = file->private_data;
1052 unsigned int len = 0, size = 32;
1053 ssize_t retval;
1054 char *buf;
1055
1056 buf = kzalloc(size, GFP_KERNEL);
1057 if (!buf)
1058 return -ENOMEM;
1059
1060 len += scnprintf(buf + len, size - len, "WOW: %s\n",
1061 sc->force_wow ? "ENABLED" : "DISABLED");
1062
1063 if (len > size)
1064 len = size;
1065
1066 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1067 kfree(buf);
1068
1069 return retval;
1070}
1071
1072static ssize_t write_file_wow(struct file *file, const char __user *user_buf,
1073 size_t count, loff_t *ppos)
1074{
1075 struct ath_softc *sc = file->private_data;
1076 unsigned long val;
1077 char buf[32];
1078 ssize_t len;
1079
1080 len = min(count, sizeof(buf) - 1);
1081 if (copy_from_user(buf, user_buf, len))
1082 return -EFAULT;
1083
1084 buf[len] = '\0';
1085 if (kstrtoul(buf, 0, &val))
1086 return -EINVAL;
1087
1088 if (val != 1)
1089 return -EINVAL;
1090
1091 if (!sc->force_wow) {
1092 sc->force_wow = true;
1093 ath9k_init_wow(sc->hw);
1094 }
1095
1096 return count;
1097}
1098
1099static const struct file_operations fops_wow = {
1100 .read = read_file_wow,
1101 .write = write_file_wow,
1102 .open = simple_open,
1103 .owner = THIS_MODULE,
1104 .llseek = default_llseek,
1105};
1106
1107#endif
1108
1109static ssize_t read_file_tpc(struct file *file, char __user *user_buf,
1110 size_t count, loff_t *ppos)
1111{
1112 struct ath_softc *sc = file->private_data;
1113 struct ath_hw *ah = sc->sc_ah;
1114 unsigned int len = 0, size = 32;
1115 ssize_t retval;
1116 char *buf;
1117
1118 buf = kzalloc(size, GFP_KERNEL);
1119 if (!buf)
1120 return -ENOMEM;
1121
1122 len += scnprintf(buf + len, size - len, "%s\n",
1123 ah->tpc_enabled ? "ENABLED" : "DISABLED");
1124
1125 if (len > size)
1126 len = size;
1127
1128 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1129 kfree(buf);
1130
1131 return retval;
1132}
1133
1134static ssize_t write_file_tpc(struct file *file, const char __user *user_buf,
1135 size_t count, loff_t *ppos)
1136{
1137 struct ath_softc *sc = file->private_data;
1138 struct ath_hw *ah = sc->sc_ah;
1139 unsigned long val;
1140 char buf[32];
1141 ssize_t len;
1142 bool tpc_enabled;
1143
1144 len = min(count, sizeof(buf) - 1);
1145 if (copy_from_user(buf, user_buf, len))
1146 return -EFAULT;
1147
1148 buf[len] = '\0';
1149 if (kstrtoul(buf, 0, &val))
1150 return -EINVAL;
1151
1152 if (val < 0 || val > 1)
1153 return -EINVAL;
1154
1155 tpc_enabled = !!val;
1156
1157 if (tpc_enabled != ah->tpc_enabled) {
1158 ah->tpc_enabled = tpc_enabled;
1159 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
1160 }
1161
1162 return count;
1163}
1164
1165static const struct file_operations fops_tpc = {
1166 .read = read_file_tpc,
1167 .write = write_file_tpc,
1168 .open = simple_open,
1169 .owner = THIS_MODULE,
1170 .llseek = default_llseek,
1171};
1172
1118/* Ethtool support for get-stats */ 1173/* Ethtool support for get-stats */
1119 1174
1120#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 1175#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
@@ -1260,14 +1315,14 @@ int ath9k_init_debug(struct ath_hw *ah)
1260 ath9k_tx99_init_debug(sc); 1315 ath9k_tx99_init_debug(sc);
1261 ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy); 1316 ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
1262 1317
1263 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1318 debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
1264 &fops_dma); 1319 read_file_dma);
1265 debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc, 1320 debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
1266 &fops_interrupt); 1321 read_file_interrupt);
1267 debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, 1322 debugfs_create_devm_seqfile(sc->dev, "xmit", sc->debug.debugfs_phy,
1268 &fops_xmit); 1323 read_file_xmit);
1269 debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, 1324 debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy,
1270 &fops_queues); 1325 read_file_queues);
1271 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1326 debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1272 &sc->tx.txq_max_pending[IEEE80211_AC_BK]); 1327 &sc->tx.txq_max_pending[IEEE80211_AC_BK]);
1273 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1328 debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
@@ -1276,10 +1331,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1276 &sc->tx.txq_max_pending[IEEE80211_AC_VI]); 1331 &sc->tx.txq_max_pending[IEEE80211_AC_VI]);
1277 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1332 debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1278 &sc->tx.txq_max_pending[IEEE80211_AC_VO]); 1333 &sc->tx.txq_max_pending[IEEE80211_AC_VO]);
1279 debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, 1334 debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy,
1280 &fops_misc); 1335 read_file_misc);
1281 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, 1336 debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy,
1282 &fops_reset); 1337 read_file_reset);
1283 1338
1284 ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); 1339 ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
1285 ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats); 1340 ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
@@ -1301,8 +1356,9 @@ int ath9k_init_debug(struct ath_hw *ah)
1301 &ah->config.cwm_ignore_extcca); 1356 &ah->config.cwm_ignore_extcca);
1302 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc, 1357 debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
1303 &fops_regdump); 1358 &fops_regdump);
1304 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc, 1359 debugfs_create_devm_seqfile(sc->dev, "dump_nfcal",
1305 &fops_dump_nfcal); 1360 sc->debug.debugfs_phy,
1361 read_file_dump_nfcal);
1306 1362
1307 ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah); 1363 ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
1308 ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah); 1364 ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
@@ -1320,10 +1376,17 @@ int ath9k_init_debug(struct ath_hw *ah)
1320 &fops_btcoex); 1376 &fops_btcoex);
1321#endif 1377#endif
1322 1378
1379#ifdef CONFIG_ATH9K_WOW
1380 debugfs_create_file("wow", S_IRUSR | S_IWUSR,
1381 sc->debug.debugfs_phy, sc, &fops_wow);
1382#endif
1383
1323#ifdef CONFIG_ATH9K_DYNACK 1384#ifdef CONFIG_ATH9K_DYNACK
1324 debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, 1385 debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1325 sc, &fops_ackto); 1386 sc, &fops_ackto);
1326#endif 1387#endif
1388 debugfs_create_file("tpc", S_IRUSR | S_IWUSR,
1389 sc->debug.debugfs_phy, sc, &fops_tpc);
1327 1390
1328 return 0; 1391 return 0;
1329} 1392}
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/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 2fef7a480fec..da344b27326c 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -49,7 +49,7 @@ void ath_init_leds(struct ath_softc *sc)
49 if (AR_SREV_9100(sc->sc_ah)) 49 if (AR_SREV_9100(sc->sc_ah))
50 return; 50 return;
51 51
52 if (!led_blink) 52 if (!ath9k_led_blink)
53 sc->led_cdev.default_trigger = 53 sc->led_cdev.default_trigger =
54 ieee80211_get_radio_led_name(sc->hw); 54 ieee80211_get_radio_led_name(sc->hw);
55 55
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 9dde265d3f84..300d3671d0ef 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 ath9k_htc_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..2aabcbdaba4e 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 (!ath9k_htc_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..fd229409f676 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 ath9k_htc_led_blink = 1;
43module_param_named(blink, ath9k_htc_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 6d4b273469b1..60aa8d71e753 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,6 +424,8 @@ 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
427 ah->tpc_enabled = true;
428
425 ah->ani_function = ATH9K_ANI_ALL; 429 ah->ani_function = ATH9K_ANI_ALL;
426 if (!AR_SREV_9300_20_OR_LATER(ah)) 430 if (!AR_SREV_9300_20_OR_LATER(ah))
427 ah->ani_function &= ~ATH9K_ANI_MRC_CCK; 431 ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
@@ -536,6 +540,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
536 case AR_SREV_VERSION_9550: 540 case AR_SREV_VERSION_9550:
537 case AR_SREV_VERSION_9565: 541 case AR_SREV_VERSION_9565:
538 case AR_SREV_VERSION_9531: 542 case AR_SREV_VERSION_9531:
543 case AR_SREV_VERSION_9561:
539 break; 544 break;
540 default: 545 default:
541 ath_err(common, 546 ath_err(common,
@@ -636,6 +641,7 @@ int ath9k_hw_init(struct ath_hw *ah)
636 case AR9485_DEVID_AR1111: 641 case AR9485_DEVID_AR1111:
637 case AR9300_DEVID_AR9565: 642 case AR9300_DEVID_AR9565:
638 case AR9300_DEVID_AR953X: 643 case AR9300_DEVID_AR953X:
644 case AR9300_DEVID_QCA956X:
639 break; 645 break;
640 default: 646 default:
641 if (common->bus_ops->ath_bus_type == ATH_USB) 647 if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -776,7 +782,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
776 /* program BB PLL phase_shift */ 782 /* program BB PLL phase_shift */
777 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, 783 REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
778 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1); 784 AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x1);
779 } 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)) {
780 u32 regval, pll2_divint, pll2_divfrac, refdiv; 787 u32 regval, pll2_divint, pll2_divfrac, refdiv;
781 788
782 REG_WRITE(ah, AR_RTC_PLL_CONTROL, 789 REG_WRITE(ah, AR_RTC_PLL_CONTROL,
@@ -787,7 +794,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
787 udelay(100); 794 udelay(100);
788 795
789 if (ah->is_clk_25mhz) { 796 if (ah->is_clk_25mhz) {
790 if (AR_SREV_9531(ah)) { 797 if (AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
791 pll2_divint = 0x1c; 798 pll2_divint = 0x1c;
792 pll2_divfrac = 0xa3d2; 799 pll2_divfrac = 0xa3d2;
793 refdiv = 1; 800 refdiv = 1;
@@ -803,14 +810,15 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
803 refdiv = 5; 810 refdiv = 5;
804 } else { 811 } else {
805 pll2_divint = 0x11; 812 pll2_divint = 0x11;
806 pll2_divfrac = 813 pll2_divfrac = (AR_SREV_9531(ah) ||
807 AR_SREV_9531(ah) ? 0x26665 : 0x26666; 814 AR_SREV_9561(ah)) ?
815 0x26665 : 0x26666;
808 refdiv = 1; 816 refdiv = 1;
809 } 817 }
810 } 818 }
811 819
812 regval = REG_READ(ah, AR_PHY_PLL_MODE); 820 regval = REG_READ(ah, AR_PHY_PLL_MODE);
813 if (AR_SREV_9531(ah)) 821 if (AR_SREV_9531(ah) || AR_SREV_9561(ah))
814 regval |= (0x1 << 22); 822 regval |= (0x1 << 22);
815 else 823 else
816 regval |= (0x1 << 16); 824 regval |= (0x1 << 16);
@@ -828,14 +836,16 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
828 (0x1 << 13) | 836 (0x1 << 13) |
829 (0x4 << 26) | 837 (0x4 << 26) |
830 (0x18 << 19); 838 (0x18 << 19);
831 else if (AR_SREV_9531(ah)) 839 else if (AR_SREV_9531(ah) || AR_SREV_9561(ah)) {
832 regval = (regval & 0x01c00fff) | 840 regval = (regval & 0x01c00fff) |
833 (0x1 << 31) | 841 (0x1 << 31) |
834 (0x2 << 29) | 842 (0x2 << 29) |
835 (0xa << 25) | 843 (0xa << 25) |
836 (0x1 << 19) | 844 (0x1 << 19);
837 (0x6 << 12); 845
838 else 846 if (AR_SREV_9531(ah))
847 regval |= (0x6 << 12);
848 } else
839 regval = (regval & 0x80071fff) | 849 regval = (regval & 0x80071fff) |
840 (0x3 << 30) | 850 (0x3 << 30) |
841 (0x1 << 13) | 851 (0x1 << 13) |
@@ -843,7 +853,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
843 (0x60 << 19); 853 (0x60 << 19);
844 REG_WRITE(ah, AR_PHY_PLL_MODE, regval); 854 REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
845 855
846 if (AR_SREV_9531(ah)) 856 if (AR_SREV_9531(ah) || AR_SREV_9561(ah))
847 REG_WRITE(ah, AR_PHY_PLL_MODE, 857 REG_WRITE(ah, AR_PHY_PLL_MODE,
848 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff); 858 REG_READ(ah, AR_PHY_PLL_MODE) & 0xffbfffff);
849 else 859 else
@@ -882,7 +892,8 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
882 AR_IMR_RXORN | 892 AR_IMR_RXORN |
883 AR_IMR_BCNMISC; 893 AR_IMR_BCNMISC;
884 894
885 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))
886 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; 897 sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
887 898
888 if (AR_SREV_9300_20_OR_LATER(ah)) { 899 if (AR_SREV_9300_20_OR_LATER(ah)) {
@@ -1671,7 +1682,8 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
1671 } 1682 }
1672#ifdef __BIG_ENDIAN 1683#ifdef __BIG_ENDIAN
1673 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) || 1684 else if (AR_SREV_9330(ah) || AR_SREV_9340(ah) ||
1674 AR_SREV_9550(ah) || AR_SREV_9531(ah)) 1685 AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
1686 AR_SREV_9561(ah))
1675 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);
1676 else 1688 else
1677 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 1689 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
@@ -2459,7 +2471,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2459 2471
2460 if (AR_SREV_9300_20_OR_LATER(ah)) { 2472 if (AR_SREV_9300_20_OR_LATER(ah)) {
2461 pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; 2473 pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
2462 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))
2463 pCap->hw_caps |= ATH9K_HW_CAP_LDPC; 2476 pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
2464 2477
2465 pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; 2478 pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
@@ -2476,7 +2489,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2476 if (AR_SREV_9300_20_OR_LATER(ah)) 2489 if (AR_SREV_9300_20_OR_LATER(ah))
2477 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; 2490 pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED;
2478 2491
2479 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))
2480 ah->ent_mode = REG_READ(ah, AR_ENT_OTP); 2495 ah->ent_mode = REG_READ(ah, AR_ENT_OTP);
2481 2496
2482 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))
@@ -2529,13 +2544,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2529 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2544 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2530 } 2545 }
2531 2546
2532 if (AR_SREV_9462(ah))
2533 pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE;
2534
2535 if (AR_SREV_9300_20_OR_LATER(ah) && 2547 if (AR_SREV_9300_20_OR_LATER(ah) &&
2536 ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) 2548 ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
2537 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; 2549 pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
2538 2550
2551#ifdef CONFIG_ATH9K_WOW
2552 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565_11_OR_LATER(ah))
2553 ah->wow.max_patterns = MAX_NUM_PATTERN;
2554 else
2555 ah->wow.max_patterns = MAX_NUM_PATTERN_LEGACY;
2556#endif
2557
2539 return 0; 2558 return 0;
2540} 2559}
2541 2560
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 1cbd33551513..e82e570de330 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
@@ -198,12 +199,13 @@
198#define KAL_NUM_DESC_WORDS 12 199#define KAL_NUM_DESC_WORDS 12
199#define KAL_ANTENNA_MODE 1 200#define KAL_ANTENNA_MODE 1
200#define KAL_TO_DS 1 201#define KAL_TO_DS 1
201#define KAL_DELAY 4 /*delay of 4ms between 2 KAL frames */ 202#define KAL_DELAY 4 /* delay of 4ms between 2 KAL frames */
202#define KAL_TIMEOUT 900 203#define KAL_TIMEOUT 900
203 204
204#define MAX_PATTERN_SIZE 256 205#define MAX_PATTERN_SIZE 256
205#define MAX_PATTERN_MASK_SIZE 32 206#define MAX_PATTERN_MASK_SIZE 32
206#define MAX_NUM_PATTERN 8 207#define MAX_NUM_PATTERN 16
208#define MAX_NUM_PATTERN_LEGACY 8
207#define MAX_NUM_USER_PATTERN 6 /* deducting the disassociate and 209#define MAX_NUM_USER_PATTERN 6 /* deducting the disassociate and
208 deauthenticate packets */ 210 deauthenticate packets */
209 211
@@ -247,12 +249,10 @@ enum ath9k_hw_caps {
247#ifdef CONFIG_ATH9K_PCOEM 249#ifdef CONFIG_ATH9K_PCOEM
248 ATH9K_HW_CAP_RTT = BIT(14), 250 ATH9K_HW_CAP_RTT = BIT(14),
249 ATH9K_HW_CAP_MCI = BIT(15), 251 ATH9K_HW_CAP_MCI = BIT(15),
250 ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(16),
251 ATH9K_HW_CAP_BT_ANT_DIV = BIT(17), 252 ATH9K_HW_CAP_BT_ANT_DIV = BIT(17),
252#else 253#else
253 ATH9K_HW_CAP_RTT = 0, 254 ATH9K_HW_CAP_RTT = 0,
254 ATH9K_HW_CAP_MCI = 0, 255 ATH9K_HW_CAP_MCI = 0,
255 ATH9K_HW_WOW_DEVICE_CAPABLE = 0,
256 ATH9K_HW_CAP_BT_ANT_DIV = 0, 256 ATH9K_HW_CAP_BT_ANT_DIV = 0,
257#endif 257#endif
258 ATH9K_HW_CAP_DFS = BIT(18), 258 ATH9K_HW_CAP_DFS = BIT(18),
@@ -271,6 +271,12 @@ enum ath9k_hw_caps {
271 * of those types. 271 * of those types.
272 */ 272 */
273 273
274struct ath9k_hw_wow {
275 u32 wow_event_mask;
276 u32 wow_event_mask2;
277 u8 max_patterns;
278};
279
274struct ath9k_hw_capabilities { 280struct ath9k_hw_capabilities {
275 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ 281 u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
276 u16 rts_aggr_limit; 282 u16 rts_aggr_limit;
@@ -929,7 +935,7 @@ struct ath_hw {
929 u32 ent_mode; 935 u32 ent_mode;
930 936
931#ifdef CONFIG_ATH9K_WOW 937#ifdef CONFIG_ATH9K_WOW
932 u32 wow_event_mask; 938 struct ath9k_hw_wow wow;
933#endif 939#endif
934 bool is_clk_25mhz; 940 bool is_clk_25mhz;
935 int (*get_mac_revision)(void); 941 int (*get_mac_revision)(void);
@@ -1086,6 +1092,8 @@ bool ar9003_is_paprd_enabled(struct ath_hw *ah);
1086void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); 1092void 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, 1093void ar9003_hw_init_rate_txpower(struct ath_hw *ah, u8 *rate_array,
1088 struct ath9k_channel *chan); 1094 struct ath9k_channel *chan);
1095void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,
1096 struct ath9k_channel *chan, int ht40_delta);
1089 1097
1090/* Hardware family op attach helpers */ 1098/* Hardware family op attach helpers */
1091int ar5008_hw_attach_phy_ops(struct ath_hw *ah); 1099int ar5008_hw_attach_phy_ops(struct ath_hw *ah);
@@ -1145,23 +1153,19 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
1145 1153
1146 1154
1147#ifdef CONFIG_ATH9K_WOW 1155#ifdef CONFIG_ATH9K_WOW
1148const char *ath9k_hw_wow_event_to_string(u32 wow_event); 1156int ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
1149void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 1157 u8 *user_mask, int pattern_count,
1150 u8 *user_mask, int pattern_count, 1158 int pattern_len);
1151 int pattern_len);
1152u32 ath9k_hw_wow_wakeup(struct ath_hw *ah); 1159u32 ath9k_hw_wow_wakeup(struct ath_hw *ah);
1153void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable); 1160void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable);
1154#else 1161#else
1155static inline const char *ath9k_hw_wow_event_to_string(u32 wow_event) 1162static inline int ath9k_hw_wow_apply_pattern(struct ath_hw *ah,
1156{ 1163 u8 *user_pattern,
1157 return NULL; 1164 u8 *user_mask,
1158} 1165 int pattern_count,
1159static inline void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, 1166 int pattern_len)
1160 u8 *user_pattern,
1161 u8 *user_mask,
1162 int pattern_count,
1163 int pattern_len)
1164{ 1167{
1168 return 0;
1165} 1169}
1166static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) 1170static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
1167{ 1171{
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index d1c39346b264..6c6e88495394 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -45,8 +45,8 @@ int ath9k_modparam_nohwcrypt;
45module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444); 45module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
46MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); 46MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
47 47
48int led_blink; 48int ath9k_led_blink;
49module_param_named(blink, led_blink, int, 0444); 49module_param_named(blink, ath9k_led_blink, int, 0444);
50MODULE_PARM_DESC(blink, "Enable LED blink on activity"); 50MODULE_PARM_DESC(blink, "Enable LED blink on activity");
51 51
52static int ath9k_btcoex_enable; 52static int ath9k_btcoex_enable;
@@ -996,6 +996,7 @@ void ath9k_deinit_device(struct ath_softc *sc)
996 ath9k_ps_restore(sc); 996 ath9k_ps_restore(sc);
997 997
998 ath9k_deinit_debug(sc); 998 ath9k_deinit_debug(sc);
999 ath9k_deinit_wow(hw);
999 ieee80211_unregister_hw(hw); 1000 ieee80211_unregister_hw(hw);
1000 ath_rx_cleanup(sc); 1001 ath_rx_cleanup(sc);
1001 ath9k_deinit_softc(sc); 1002 ath9k_deinit_softc(sc);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index b829263e3d0a..90631d768a60 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -516,14 +516,14 @@ int ath_update_survey_stats(struct ath_softc *sc)
516 ath_hw_cycle_counters_update(common); 516 ath_hw_cycle_counters_update(common);
517 517
518 if (cc->cycles > 0) { 518 if (cc->cycles > 0) {
519 survey->filled |= SURVEY_INFO_CHANNEL_TIME | 519 survey->filled |= SURVEY_INFO_TIME |
520 SURVEY_INFO_CHANNEL_TIME_BUSY | 520 SURVEY_INFO_TIME_BUSY |
521 SURVEY_INFO_CHANNEL_TIME_RX | 521 SURVEY_INFO_TIME_RX |
522 SURVEY_INFO_CHANNEL_TIME_TX; 522 SURVEY_INFO_TIME_TX;
523 survey->channel_time += cc->cycles / div; 523 survey->time += cc->cycles / div;
524 survey->channel_time_busy += cc->rx_busy / div; 524 survey->time_busy += cc->rx_busy / div;
525 survey->channel_time_rx += cc->rx_frame / div; 525 survey->time_rx += cc->rx_frame / div;
526 survey->channel_time_tx += cc->tx_frame / div; 526 survey->time_tx += cc->tx_frame / div;
527 } 527 }
528 528
529 if (cc->cycles < div) 529 if (cc->cycles < div)
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/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 62b0bf4fdf6b..9ede991b8d76 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -555,15 +555,6 @@ irqreturn_t ath_isr(int irq, void *dev)
555 (status & ATH9K_INT_BB_WATCHDOG)) 555 (status & ATH9K_INT_BB_WATCHDOG))
556 goto chip_reset; 556 goto chip_reset;
557 557
558#ifdef CONFIG_ATH9K_WOW
559 if (status & ATH9K_INT_BMISS) {
560 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
561 atomic_inc(&sc->wow_got_bmiss_intr);
562 atomic_dec(&sc->wow_sleep_proc_intr);
563 }
564 }
565#endif
566
567 if (status & ATH9K_INT_SWBA) 558 if (status & ATH9K_INT_SWBA)
568 tasklet_schedule(&sc->bcon_tasklet); 559 tasklet_schedule(&sc->bcon_tasklet);
569 560
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index f009b5b57e5e..e6fef1be9977 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 },
@@ -913,9 +998,12 @@ static int ath_pci_suspend(struct device *device)
913 struct pci_dev *pdev = to_pci_dev(device); 998 struct pci_dev *pdev = to_pci_dev(device);
914 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 999 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
915 struct ath_softc *sc = hw->priv; 1000 struct ath_softc *sc = hw->priv;
1001 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
916 1002
917 if (sc->wow_enabled) 1003 if (test_bit(ATH_OP_WOW_ENABLED, &common->op_flags)) {
1004 dev_info(&pdev->dev, "WOW is enabled, bypassing PCI suspend\n");
918 return 0; 1005 return 0;
1006 }
919 1007
920 /* The device has to be moved to FULLSLEEP forcibly. 1008 /* The device has to be moved to FULLSLEEP forcibly.
921 * Otherwise the chip never moved to full sleep, 1009 * Otherwise the chip never moved to full sleep,
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..9587ec655680 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) || \
@@ -899,10 +900,13 @@
899 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485)) 900 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
900#define AR_SREV_9565(_ah) \ 901#define AR_SREV_9565(_ah) \
901 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 902 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
903#define AR_SREV_9003_PCOEM(_ah) \
904 (AR_SREV_9462(_ah) || AR_SREV_9485(_ah) || AR_SREV_9565(_ah))
902#else 905#else
903#define AR_SREV_9462(_ah) 0 906#define AR_SREV_9462(_ah) 0
904#define AR_SREV_9485(_ah) 0 907#define AR_SREV_9485(_ah) 0
905#define AR_SREV_9565(_ah) 0 908#define AR_SREV_9565(_ah) 0
909#define AR_SREV_9003_PCOEM(_ah) 0
906#endif 910#endif
907 911
908#define AR_SREV_9485_11_OR_LATER(_ah) \ 912#define AR_SREV_9485_11_OR_LATER(_ah) \
@@ -974,6 +978,9 @@
974 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \ 978 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
975 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20)) 979 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20))
976 980
981#define AR_SREV_9561(_ah) \
982 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9561))
983
977/* NOTE: When adding chips newer than Peacock, add chip check here */ 984/* NOTE: When adding chips newer than Peacock, add chip check here */
978#define AR_SREV_9580_10_OR_LATER(_ah) \ 985#define AR_SREV_9580_10_OR_LATER(_ah) \
979 (AR_SREV_9580(_ah)) 986 (AR_SREV_9580(_ah))
@@ -1876,6 +1883,7 @@ enum {
1876#define AR_FIRST_NDP_TIMER 7 1883#define AR_FIRST_NDP_TIMER 7
1877#define AR_NDP2_PERIOD 0x81a0 1884#define AR_NDP2_PERIOD 0x81a0
1878#define AR_NDP2_TIMER_MODE 0x81c0 1885#define AR_NDP2_TIMER_MODE 0x81c0
1886#define AR_GEN_TIMERS2_MODE_ENABLE_MASK 0x000000FF
1879 1887
1880#define AR_GEN_TIMERS(_i) (0x8200 + ((_i) << 2)) 1888#define AR_GEN_TIMERS(_i) (0x8200 + ((_i) << 2))
1881#define AR_NEXT_TBTT_TIMER AR_GEN_TIMERS(0) 1889#define AR_NEXT_TBTT_TIMER AR_GEN_TIMERS(0)
@@ -1971,6 +1979,7 @@ enum {
1971 1979
1972#define AR_DIRECT_CONNECT 0x83a0 1980#define AR_DIRECT_CONNECT 0x83a0
1973#define AR_DC_AP_STA_EN 0x00000001 1981#define AR_DC_AP_STA_EN 0x00000001
1982#define AR_DC_TSF2_ENABLE 0x00000001
1974 1983
1975#define AR_AES_MUTE_MASK0 0x805c 1984#define AR_AES_MUTE_MASK0 0x805c
1976#define AR_AES_MUTE_MASK0_FC 0x0000FFFF 1985#define AR_AES_MUTE_MASK0_FC 0x0000FFFF
@@ -2003,126 +2012,6 @@ enum {
2003 2012
2004#define AR_WOW_BEACON_TIMO_MAX 0xffffffff 2013#define AR_WOW_BEACON_TIMO_MAX 0xffffffff
2005 2014
2006/*
2007 * MAC WoW Registers
2008 */
2009
2010#define AR_WOW_PATTERN 0x825C
2011#define AR_WOW_COUNT 0x8260
2012#define AR_WOW_BCN_EN 0x8270
2013#define AR_WOW_BCN_TIMO 0x8274
2014#define AR_WOW_KEEP_ALIVE_TIMO 0x8278
2015#define AR_WOW_KEEP_ALIVE 0x827c
2016#define AR_WOW_US_SCALAR 0x8284
2017#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
2018#define AR_WOW_PATTERN_MATCH 0x828c
2019#define AR_WOW_PATTERN_OFF1 0x8290 /* pattern bytes 0 -> 3 */
2020#define AR_WOW_PATTERN_OFF2 0x8294 /* pattern bytes 4 -> 7 */
2021
2022/* for AR9285 or later version of chips */
2023#define AR_WOW_EXACT 0x829c
2024#define AR_WOW_LENGTH1 0x8360
2025#define AR_WOW_LENGTH2 0X8364
2026/* register to enable match for less than 256 bytes packets */
2027#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
2028
2029#define AR_SW_WOW_CONTROL 0x20018
2030#define AR_SW_WOW_ENABLE 0x1
2031#define AR_SWITCH_TO_REFCLK 0x2
2032#define AR_RESET_CONTROL 0x4
2033#define AR_RESET_VALUE_MASK 0x8
2034#define AR_HW_WOW_DISABLE 0x10
2035#define AR_CLR_MAC_INTERRUPT 0x20
2036#define AR_CLR_KA_INTERRUPT 0x40
2037
2038/* AR_WOW_PATTERN register values */
2039#define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 28) /* in usecs */
2040#define AR_WOW_MAC_INTR_EN 0x00040000
2041#define AR_WOW_MAGIC_EN 0x00010000
2042#define AR_WOW_PATTERN_EN(x) (x & 0xff)
2043#define AR_WOW_PAT_FOUND_SHIFT 8
2044#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
2045#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
2046#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
2047#define AR_WOW_MAC_INTR 0x00080000
2048#define AR_WOW_KEEP_ALIVE_FAIL 0x00100000
2049#define AR_WOW_BEACON_FAIL 0x00200000
2050
2051#define AR_WOW_STATUS(x) (x & (AR_WOW_PATTERN_FOUND_MASK | \
2052 AR_WOW_MAGIC_PAT_FOUND | \
2053 AR_WOW_KEEP_ALIVE_FAIL | \
2054 AR_WOW_BEACON_FAIL))
2055#define AR_WOW_CLEAR_EVENTS(x) (x & ~(AR_WOW_PATTERN_EN(0xff) | \
2056 AR_WOW_MAGIC_EN | \
2057 AR_WOW_MAC_INTR_EN | \
2058 AR_WOW_BEACON_FAIL | \
2059 AR_WOW_KEEP_ALIVE_FAIL))
2060
2061/* AR_WOW_COUNT register values */
2062#define AR_WOW_AIFS_CNT(x) (x & 0xff)
2063#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
2064#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
2065
2066/* AR_WOW_BCN_EN register */
2067#define AR_WOW_BEACON_FAIL_EN 0x00000001
2068
2069/* AR_WOW_BCN_TIMO rgister */
2070#define AR_WOW_BEACON_TIMO 0x40000000 /* valid if BCN_EN is set */
2071
2072/* AR_WOW_KEEP_ALIVE_TIMO register */
2073#define AR_WOW_KEEP_ALIVE_TIMO_VALUE
2074#define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff
2075
2076/* AR_WOW_KEEP_ALIVE register */
2077#define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001
2078#define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002
2079
2080/* AR_WOW_KEEP_ALIVE_DELAY register */
2081#define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */
2082
2083
2084/*
2085 * keep it long for beacon workaround - ensure no false alarm
2086 */
2087#define AR_WOW_BMISSTHRESHOLD 0x20
2088
2089/* AR_WOW_PATTERN_MATCH register */
2090#define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf)
2091#define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8)
2092
2093/*
2094 * default values for Wow Configuration for backoff, aifs, slot, keep-alive
2095 * to be programmed into various registers.
2096 */
2097#define AR_WOW_PAT_BACKOFF 0x00000004 /* AR_WOW_PATTERN_REG */
2098#define AR_WOW_CNT_AIFS_CNT 0x00000022 /* AR_WOW_COUNT_REG */
2099#define AR_WOW_CNT_SLOT_CNT 0x00000009 /* AR_WOW_COUNT_REG */
2100/*
2101 * Keepalive count applicable for AR9280 2.0 and above.
2102 */
2103#define AR_WOW_CNT_KA_CNT 0x00000008 /* AR_WOW_COUNT register */
2104
2105/* WoW - Transmit buffer for keep alive frames */
2106#define AR_WOW_TRANSMIT_BUFFER 0xe000 /* E000 - EFFC */
2107
2108#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
2109
2110#define AR_WOW_KA_DESC_WORD2 0xe000
2111
2112#define AR_WOW_KA_DATA_WORD0 0xe030
2113
2114/* WoW Transmit Buffer for patterns */
2115#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
2116#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
2117
2118/* Currently Pattern 0-7 are supported - so bit 0-7 are set */
2119#define AR_WOW_PATTERN_SUPPORTED 0xff
2120#define AR_WOW_LENGTH_MAX 0xff
2121#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
2122#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
2123#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
2124#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
2125
2126#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ 2015#define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */
2127#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ 2016#define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */
2128 2017
diff --git a/drivers/net/wireless/ath/ath9k/reg_wow.h b/drivers/net/wireless/ath/ath9k/reg_wow.h
new file mode 100644
index 000000000000..3abfca56ca58
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/reg_wow.h
@@ -0,0 +1,128 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REG_WOW_H
18#define REG_WOW_H
19
20#define AR_WOW_PATTERN 0x825C
21#define AR_WOW_COUNT 0x8260
22#define AR_WOW_BCN_EN 0x8270
23#define AR_WOW_BCN_TIMO 0x8274
24#define AR_WOW_KEEP_ALIVE_TIMO 0x8278
25#define AR_WOW_KEEP_ALIVE 0x827c
26#define AR_WOW_KEEP_ALIVE_DELAY 0x8288
27#define AR_WOW_PATTERN_MATCH 0x828c
28
29/*
30 * AR_WOW_LENGTH1
31 * bit 31:24 pattern 0 length
32 * bit 23:16 pattern 1 length
33 * bit 15:8 pattern 2 length
34 * bit 7:0 pattern 3 length
35 *
36 * AR_WOW_LENGTH2
37 * bit 31:24 pattern 4 length
38 * bit 23:16 pattern 5 length
39 * bit 15:8 pattern 6 length
40 * bit 7:0 pattern 7 length
41 *
42 * AR_WOW_LENGTH3
43 * bit 31:24 pattern 8 length
44 * bit 23:16 pattern 9 length
45 * bit 15:8 pattern 10 length
46 * bit 7:0 pattern 11 length
47 *
48 * AR_WOW_LENGTH4
49 * bit 31:24 pattern 12 length
50 * bit 23:16 pattern 13 length
51 * bit 15:8 pattern 14 length
52 * bit 7:0 pattern 15 length
53 */
54#define AR_WOW_LENGTH1 0x8360
55#define AR_WOW_LENGTH2 0X8364
56#define AR_WOW_LENGTH3 0X8380
57#define AR_WOW_LENGTH4 0X8384
58
59#define AR_WOW_PATTERN_MATCH_LT_256B 0x8368
60#define AR_MAC_PCU_WOW4 0x8370
61
62#define AR_SW_WOW_CONTROL 0x20018
63#define AR_SW_WOW_ENABLE 0x1
64#define AR_SWITCH_TO_REFCLK 0x2
65#define AR_RESET_CONTROL 0x4
66#define AR_RESET_VALUE_MASK 0x8
67#define AR_HW_WOW_DISABLE 0x10
68#define AR_CLR_MAC_INTERRUPT 0x20
69#define AR_CLR_KA_INTERRUPT 0x40
70
71#define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 27) /* in usecs */
72#define AR_WOW_MAC_INTR_EN 0x00040000
73#define AR_WOW_MAGIC_EN 0x00010000
74#define AR_WOW_PATTERN_EN(x) (x & 0xff)
75#define AR_WOW_PAT_FOUND_SHIFT 8
76#define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT))
77#define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT)
78#define AR_WOW_MAGIC_PAT_FOUND 0x00020000
79#define AR_WOW_MAC_INTR 0x00080000
80#define AR_WOW_KEEP_ALIVE_FAIL 0x00100000
81#define AR_WOW_BEACON_FAIL 0x00200000
82
83#define AR_WOW_STATUS(x) (x & (AR_WOW_PATTERN_FOUND_MASK | \
84 AR_WOW_MAGIC_PAT_FOUND | \
85 AR_WOW_KEEP_ALIVE_FAIL | \
86 AR_WOW_BEACON_FAIL))
87#define AR_WOW_CLEAR_EVENTS(x) (x & ~(AR_WOW_PATTERN_EN(0xff) | \
88 AR_WOW_MAGIC_EN | \
89 AR_WOW_MAC_INTR_EN | \
90 AR_WOW_BEACON_FAIL | \
91 AR_WOW_KEEP_ALIVE_FAIL))
92
93#define AR_WOW_AIFS_CNT(x) (x & 0xff)
94#define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8)
95#define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16)
96
97#define AR_WOW_BEACON_FAIL_EN 0x00000001
98#define AR_WOW_BEACON_TIMO 0x40000000
99#define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff
100#define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001
101#define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002
102#define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */
103#define AR_WOW_BMISSTHRESHOLD 0x20
104#define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf)
105#define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8)
106#define AR_WOW_PAT_BACKOFF 0x00000004
107#define AR_WOW_CNT_AIFS_CNT 0x00000022
108#define AR_WOW_CNT_SLOT_CNT 0x00000009
109#define AR_WOW_CNT_KA_CNT 0x00000008
110
111#define AR_WOW_TRANSMIT_BUFFER 0xe000
112#define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2))
113#define AR_WOW_KA_DESC_WORD2 0xe000
114#define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8))
115#define AR_WOW_TB_MASK(i) (0xec00 + (i << 5))
116#define AR_WOW_PATTERN_SUPPORTED_LEGACY 0xff
117#define AR_WOW_PATTERN_SUPPORTED 0xffff
118#define AR_WOW_LENGTH_MAX 0xff
119#define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3)
120#define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i))
121#define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3)
122#define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i))
123#define AR_WOW_LEN3_SHIFT(_i) ((0xb - ((_i) & 0xb)) << 0x3)
124#define AR_WOW_LENGTH3_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN3_SHIFT(_i))
125#define AR_WOW_LEN4_SHIFT(_i) ((0xf - ((_i) & 0xf)) << 0x3)
126#define AR_WOW_LENGTH4_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN4_SHIFT(_i))
127
128#endif /* REG_WOW_H */
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 5f30e580d942..8d0b1730a9d5 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -16,36 +16,43 @@
16 16
17#include "ath9k.h" 17#include "ath9k.h"
18 18
19static const struct wiphy_wowlan_support ath9k_wowlan_support = { 19static const struct wiphy_wowlan_support ath9k_wowlan_support_legacy = {
20 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, 20 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
21 .n_patterns = MAX_NUM_USER_PATTERN, 21 .n_patterns = MAX_NUM_USER_PATTERN,
22 .pattern_min_len = 1, 22 .pattern_min_len = 1,
23 .pattern_max_len = MAX_PATTERN_SIZE, 23 .pattern_max_len = MAX_PATTERN_SIZE,
24}; 24};
25 25
26static void ath9k_wow_map_triggers(struct ath_softc *sc, 26static const struct wiphy_wowlan_support ath9k_wowlan_support = {
27 struct cfg80211_wowlan *wowlan, 27 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
28 u32 *wow_triggers) 28 .n_patterns = MAX_NUM_PATTERN - 2,
29 .pattern_min_len = 1,
30 .pattern_max_len = MAX_PATTERN_SIZE,
31};
32
33static u8 ath9k_wow_map_triggers(struct ath_softc *sc,
34 struct cfg80211_wowlan *wowlan)
29{ 35{
36 u8 wow_triggers = 0;
37
30 if (wowlan->disconnect) 38 if (wowlan->disconnect)
31 *wow_triggers |= AH_WOW_LINK_CHANGE | 39 wow_triggers |= AH_WOW_LINK_CHANGE |
32 AH_WOW_BEACON_MISS; 40 AH_WOW_BEACON_MISS;
33 if (wowlan->magic_pkt) 41 if (wowlan->magic_pkt)
34 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN; 42 wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
35 43
36 if (wowlan->n_patterns) 44 if (wowlan->n_patterns)
37 *wow_triggers |= AH_WOW_USER_PATTERN_EN; 45 wow_triggers |= AH_WOW_USER_PATTERN_EN;
38
39 sc->wow_enabled = *wow_triggers;
40 46
47 return wow_triggers;
41} 48}
42 49
43static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc) 50static int ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
44{ 51{
45 struct ath_hw *ah = sc->sc_ah; 52 struct ath_hw *ah = sc->sc_ah;
46 struct ath_common *common = ath9k_hw_common(ah); 53 struct ath_common *common = ath9k_hw_common(ah);
47 int pattern_count = 0; 54 int pattern_count = 0;
48 int i, byte_cnt; 55 int ret, i, byte_cnt = 0;
49 u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; 56 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
50 u8 dis_deauth_mask[MAX_PATTERN_SIZE]; 57 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
51 58
@@ -80,12 +87,7 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
80 * | x:x:x:x:x:x -- 22 bytes 87 * | x:x:x:x:x:x -- 22 bytes
81 */ 88 */
82 89
83 /* Create Disassociate Pattern first */
84
85 byte_cnt = 0;
86
87 /* Fill out the mask with all FF's */ 90 /* Fill out the mask with all FF's */
88
89 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++) 91 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
90 dis_deauth_mask[i] = 0xff; 92 dis_deauth_mask[i] = 0xff;
91 93
@@ -108,19 +110,17 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
108 byte_cnt += 6; 110 byte_cnt += 6;
109 111
110 /* copy the bssid, its same as the source mac address */ 112 /* copy the bssid, its same as the source mac address */
111
112 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); 113 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
113 114
114 /* Create Disassociate pattern mask */ 115 /* Create Disassociate pattern mask */
115
116 dis_deauth_mask[0] = 0xfe; 116 dis_deauth_mask[0] = 0xfe;
117 dis_deauth_mask[1] = 0x03; 117 dis_deauth_mask[1] = 0x03;
118 dis_deauth_mask[2] = 0xc0; 118 dis_deauth_mask[2] = 0xc0;
119 119
120 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); 120 ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
121 121 pattern_count, byte_cnt);
122 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 122 if (ret)
123 pattern_count, byte_cnt); 123 goto exit;
124 124
125 pattern_count++; 125 pattern_count++;
126 /* 126 /*
@@ -129,59 +129,39 @@ static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
129 */ 129 */
130 dis_deauth_pattern[0] = 0xC0; 130 dis_deauth_pattern[0] = 0xC0;
131 131
132 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, 132 ret = ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
133 pattern_count, byte_cnt); 133 pattern_count, byte_cnt);
134 134exit:
135 return ret;
135} 136}
136 137
137static void ath9k_wow_add_pattern(struct ath_softc *sc, 138static int ath9k_wow_add_pattern(struct ath_softc *sc,
138 struct cfg80211_wowlan *wowlan) 139 struct cfg80211_wowlan *wowlan)
139{ 140{
140 struct ath_hw *ah = sc->sc_ah; 141 struct ath_hw *ah = sc->sc_ah;
141 struct ath9k_wow_pattern *wow_pattern = NULL;
142 struct cfg80211_pkt_pattern *patterns = wowlan->patterns; 142 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
143 int mask_len; 143 u8 wow_pattern[MAX_PATTERN_SIZE];
144 u8 wow_mask[MAX_PATTERN_SIZE];
145 int mask_len, ret = 0;
144 s8 i = 0; 146 s8 i = 0;
145 147
146 if (!wowlan->n_patterns)
147 return;
148
149 /*
150 * Add the new user configured patterns
151 */
152 for (i = 0; i < wowlan->n_patterns; i++) { 148 for (i = 0; i < wowlan->n_patterns; i++) {
153 149 mask_len = DIV_ROUND_UP(patterns[i].pattern_len, 8);
154 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL); 150 memset(wow_pattern, 0, MAX_PATTERN_SIZE);
155 151 memset(wow_mask, 0, MAX_PATTERN_SIZE);
156 if (!wow_pattern) 152 memcpy(wow_pattern, patterns[i].pattern, patterns[i].pattern_len);
157 return; 153 memcpy(wow_mask, patterns[i].mask, mask_len);
158 154
159 /* 155 ret = ath9k_hw_wow_apply_pattern(ah,
160 * TODO: convert the generic user space pattern to 156 wow_pattern,
161 * appropriate chip specific/802.11 pattern. 157 wow_mask,
162 */ 158 i + 2,
163 159 patterns[i].pattern_len);
164 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); 160 if (ret)
165 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE); 161 break;
166 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
167 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
168 patterns[i].pattern_len);
169 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
170 wow_pattern->pattern_len = patterns[i].pattern_len;
171
172 /*
173 * just need to take care of deauth and disssoc pattern,
174 * make sure we don't overwrite them.
175 */
176
177 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
178 wow_pattern->mask_bytes,
179 i + 2,
180 wow_pattern->pattern_len);
181 kfree(wow_pattern);
182
183 } 162 }
184 163
164 return ret;
185} 165}
186 166
187int ath9k_suspend(struct ieee80211_hw *hw, 167int ath9k_suspend(struct ieee80211_hw *hw,
@@ -190,41 +170,39 @@ int ath9k_suspend(struct ieee80211_hw *hw,
190 struct ath_softc *sc = hw->priv; 170 struct ath_softc *sc = hw->priv;
191 struct ath_hw *ah = sc->sc_ah; 171 struct ath_hw *ah = sc->sc_ah;
192 struct ath_common *common = ath9k_hw_common(ah); 172 struct ath_common *common = ath9k_hw_common(ah);
193 u32 wow_triggers_enabled = 0; 173 u8 triggers;
194 int ret = 0; 174 int ret = 0;
195 175
196 ath9k_deinit_channel_context(sc); 176 ath9k_deinit_channel_context(sc);
197 177
198 mutex_lock(&sc->mutex); 178 mutex_lock(&sc->mutex);
199 179
200 ath_cancel_work(sc);
201 ath_stop_ani(sc);
202
203 if (test_bit(ATH_OP_INVALID, &common->op_flags)) { 180 if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
204 ath_dbg(common, ANY, "Device not present\n"); 181 ath_err(common, "Device not present\n");
205 ret = -EINVAL; 182 ret = -ENODEV;
206 goto fail_wow; 183 goto fail_wow;
207 } 184 }
208 185
209 if (WARN_ON(!wowlan)) { 186 if (WARN_ON(!wowlan)) {
210 ath_dbg(common, WOW, "None of the WoW triggers enabled\n"); 187 ath_err(common, "None of the WoW triggers enabled\n");
211 ret = -EINVAL; 188 ret = -EINVAL;
212 goto fail_wow; 189 goto fail_wow;
213 } 190 }
214 191
215 if (!device_can_wakeup(sc->dev)) { 192 if (sc->cur_chan->nvifs > 1) {
216 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n"); 193 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
217 ret = 1; 194 ret = 1;
218 goto fail_wow; 195 goto fail_wow;
219 } 196 }
220 197
221 /* 198 if (ath9k_is_chanctx_enabled()) {
222 * none of the sta vifs are associated 199 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) {
223 * and we are not currently handling multivif 200 ath_dbg(common, WOW,
224 * cases, for instance we have to seperately 201 "Multi-channel WOW is not supported\n");
225 * configure 'keep alive frame' for each 202 ret = 1;
226 * STA. 203 goto fail_wow;
227 */ 204 }
205 }
228 206
229 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { 207 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) {
230 ath_dbg(common, WOW, "None of the STA vifs are associated\n"); 208 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
@@ -232,16 +210,15 @@ int ath9k_suspend(struct ieee80211_hw *hw,
232 goto fail_wow; 210 goto fail_wow;
233 } 211 }
234 212
235 if (sc->cur_chan->nvifs > 1) { 213 triggers = ath9k_wow_map_triggers(sc, wowlan);
236 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); 214 if (!triggers) {
215 ath_dbg(common, WOW, "No valid WoW triggers\n");
237 ret = 1; 216 ret = 1;
238 goto fail_wow; 217 goto fail_wow;
239 } 218 }
240 219
241 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled); 220 ath_cancel_work(sc);
242 221 ath_stop_ani(sc);
243 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
244 wow_triggers_enabled);
245 222
246 ath9k_ps_wakeup(sc); 223 ath9k_ps_wakeup(sc);
247 224
@@ -251,10 +228,21 @@ int ath9k_suspend(struct ieee80211_hw *hw,
251 * Enable wake up on recieving disassoc/deauth 228 * Enable wake up on recieving disassoc/deauth
252 * frame by default. 229 * frame by default.
253 */ 230 */
254 ath9k_wow_add_disassoc_deauth_pattern(sc); 231 ret = ath9k_wow_add_disassoc_deauth_pattern(sc);
232 if (ret) {
233 ath_err(common,
234 "Unable to add disassoc/deauth pattern: %d\n", ret);
235 goto fail_wow;
236 }
255 237
256 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN) 238 if (triggers & AH_WOW_USER_PATTERN_EN) {
257 ath9k_wow_add_pattern(sc, wowlan); 239 ret = ath9k_wow_add_pattern(sc, wowlan);
240 if (ret) {
241 ath_err(common,
242 "Unable to add user pattern: %d\n", ret);
243 goto fail_wow;
244 }
245 }
258 246
259 spin_lock_bh(&sc->sc_pcu_lock); 247 spin_lock_bh(&sc->sc_pcu_lock);
260 /* 248 /*
@@ -278,12 +266,12 @@ int ath9k_suspend(struct ieee80211_hw *hw,
278 synchronize_irq(sc->irq); 266 synchronize_irq(sc->irq);
279 tasklet_kill(&sc->intr_tq); 267 tasklet_kill(&sc->intr_tq);
280 268
281 ath9k_hw_wow_enable(ah, wow_triggers_enabled); 269 ath9k_hw_wow_enable(ah, triggers);
282 270
283 ath9k_ps_restore(sc); 271 ath9k_ps_restore(sc);
284 ath_dbg(common, ANY, "WoW enabled in ath9k\n"); 272 ath_dbg(common, WOW, "Suspend with WoW triggers: 0x%x\n", triggers);
285 atomic_inc(&sc->wow_sleep_proc_intr);
286 273
274 set_bit(ATH_OP_WOW_ENABLED, &common->op_flags);
287fail_wow: 275fail_wow:
288 mutex_unlock(&sc->mutex); 276 mutex_unlock(&sc->mutex);
289 return ret; 277 return ret;
@@ -294,7 +282,7 @@ int ath9k_resume(struct ieee80211_hw *hw)
294 struct ath_softc *sc = hw->priv; 282 struct ath_softc *sc = hw->priv;
295 struct ath_hw *ah = sc->sc_ah; 283 struct ath_hw *ah = sc->sc_ah;
296 struct ath_common *common = ath9k_hw_common(ah); 284 struct ath_common *common = ath9k_hw_common(ah);
297 u32 wow_status; 285 u8 status;
298 286
299 mutex_lock(&sc->mutex); 287 mutex_lock(&sc->mutex);
300 288
@@ -309,29 +297,14 @@ int ath9k_resume(struct ieee80211_hw *hw)
309 297
310 spin_unlock_bh(&sc->sc_pcu_lock); 298 spin_unlock_bh(&sc->sc_pcu_lock);
311 299
312 wow_status = ath9k_hw_wow_wakeup(ah); 300 status = ath9k_hw_wow_wakeup(ah);
313 301 ath_dbg(common, WOW, "Resume with WoW status: 0x%x\n", status);
314 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
315 /*
316 * some devices may not pick beacon miss
317 * as the reason they woke up so we add
318 * that here for that shortcoming.
319 */
320 wow_status |= AH_WOW_BEACON_MISS;
321 atomic_dec(&sc->wow_got_bmiss_intr);
322 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
323 }
324
325 atomic_dec(&sc->wow_sleep_proc_intr);
326
327 if (wow_status) {
328 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
329 ath9k_hw_wow_event_to_string(wow_status), wow_status);
330 }
331 302
332 ath_restart_work(sc); 303 ath_restart_work(sc);
333 ath9k_start_btcoex(sc); 304 ath9k_start_btcoex(sc);
334 305
306 clear_bit(ATH_OP_WOW_ENABLED, &common->op_flags);
307
335 ath9k_ps_restore(sc); 308 ath9k_ps_restore(sc);
336 mutex_unlock(&sc->mutex); 309 mutex_unlock(&sc->mutex);
337 310
@@ -341,22 +314,35 @@ int ath9k_resume(struct ieee80211_hw *hw)
341void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) 314void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
342{ 315{
343 struct ath_softc *sc = hw->priv; 316 struct ath_softc *sc = hw->priv;
317 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
344 318
345 mutex_lock(&sc->mutex); 319 mutex_lock(&sc->mutex);
346 device_init_wakeup(sc->dev, 1);
347 device_set_wakeup_enable(sc->dev, enabled); 320 device_set_wakeup_enable(sc->dev, enabled);
348 mutex_unlock(&sc->mutex); 321 mutex_unlock(&sc->mutex);
322
323 ath_dbg(common, WOW, "WoW wakeup source is %s\n",
324 (enabled) ? "enabled" : "disabled");
349} 325}
350 326
351void ath9k_init_wow(struct ieee80211_hw *hw) 327void ath9k_init_wow(struct ieee80211_hw *hw)
352{ 328{
353 struct ath_softc *sc = hw->priv; 329 struct ath_softc *sc = hw->priv;
330 struct ath_hw *ah = sc->sc_ah;
331
332 if ((sc->driver_data & ATH9K_PCI_WOW) || sc->force_wow) {
333 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565_11_OR_LATER(ah))
334 hw->wiphy->wowlan = &ath9k_wowlan_support;
335 else
336 hw->wiphy->wowlan = &ath9k_wowlan_support_legacy;
354 337
355 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 338 device_init_wakeup(sc->dev, 1);
356 (sc->driver_data & ATH9K_PCI_WOW) && 339 }
357 device_can_wakeup(sc->dev)) 340}
358 hw->wiphy->wowlan = &ath9k_wowlan_support; 341
342void ath9k_deinit_wow(struct ieee80211_hw *hw)
343{
344 struct ath_softc *sc = hw->priv;
359 345
360 atomic_set(&sc->wow_sleep_proc_intr, -1); 346 if ((sc->driver_data & ATH9K_PCI_WOW) || sc->force_wow)
361 atomic_set(&sc->wow_got_bmiss_intr, -1); 347 device_init_wakeup(sc->dev, 0);
362} 348}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index e9bd02c2e844..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 is not sipported 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 */
@@ -2259,7 +2303,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2259 struct ath_txq *txq = txctl->txq; 2303 struct ath_txq *txq = txctl->txq;
2260 struct ath_atx_tid *tid = NULL; 2304 struct ath_atx_tid *tid = NULL;
2261 struct ath_buf *bf; 2305 struct ath_buf *bf;
2262 bool queue, skip_uapsd = false; 2306 bool queue, skip_uapsd = false, ps_resp;
2263 int q, ret; 2307 int q, ret;
2264 2308
2265 if (vif) 2309 if (vif)
@@ -2268,6 +2312,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2268 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) 2312 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
2269 txctl->force_channel = true; 2313 txctl->force_channel = true;
2270 2314
2315 ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE);
2316
2271 ret = ath_tx_prepare(hw, skb, txctl); 2317 ret = ath_tx_prepare(hw, skb, txctl);
2272 if (ret) 2318 if (ret)
2273 return ret; 2319 return ret;
@@ -2310,7 +2356,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2310 if (txctl->an && queue) 2356 if (txctl->an && queue)
2311 tid = ath_get_skb_tid(sc, txctl->an, skb); 2357 tid = ath_get_skb_tid(sc, txctl->an, skb);
2312 2358
2313 if (!skip_uapsd && (info->flags & IEEE80211_TX_CTL_PS_RESPONSE)) { 2359 if (!skip_uapsd && ps_resp) {
2314 ath_txq_unlock(sc, txq); 2360 ath_txq_unlock(sc, txq);
2315 txq = sc->tx.uapsdq; 2361 txq = sc->tx.uapsdq;
2316 ath_txq_lock(sc, txq); 2362 ath_txq_lock(sc, txq);
@@ -2443,9 +2489,12 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
2443 if (sc->sc_ah->caldata) 2489 if (sc->sc_ah->caldata)
2444 set_bit(PAPRD_PACKET_SENT, &sc->sc_ah->caldata->cal_flags); 2490 set_bit(PAPRD_PACKET_SENT, &sc->sc_ah->caldata->cal_flags);
2445 2491
2446 if (!(tx_flags & ATH_TX_ERROR)) 2492 if (!(tx_flags & ATH_TX_ERROR)) {
2447 /* Frame was ACKed */ 2493 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
2448 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 }
2449 2498
2450 padpos = ieee80211_hdrlen(hdr->frame_control); 2499 padpos = ieee80211_hdrlen(hdr->frame_control);
2451 padsize = padpos & 3; 2500 padsize = padpos & 3;
diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c
index 39a63874b275..f2b4f537e4c1 100644
--- a/drivers/net/wireless/ath/carl9170/cmd.c
+++ b/drivers/net/wireless/ath/carl9170/cmd.c
@@ -188,12 +188,12 @@ int carl9170_collect_tally(struct ar9170 *ar)
188 188
189 if (ar->channel) { 189 if (ar->channel) {
190 info = &ar->survey[ar->channel->hw_value]; 190 info = &ar->survey[ar->channel->hw_value];
191 info->channel_time = ar->tally.active; 191 info->time = ar->tally.active;
192 info->channel_time_busy = ar->tally.cca; 192 info->time_busy = ar->tally.cca;
193 info->channel_time_tx = ar->tally.tx_time; 193 info->time_tx = ar->tally.tx_time;
194 do_div(info->channel_time, 1000); 194 do_div(info->time, 1000);
195 do_div(info->channel_time_busy, 1000); 195 do_div(info->time_busy, 1000);
196 do_div(info->channel_time_tx, 1000); 196 do_div(info->time_tx, 1000);
197 } 197 }
198 } 198 }
199 return 0; 199 return 0;
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index ef5b6dc7b7f1..f1455a04cb62 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1690,9 +1690,9 @@ found:
1690 survey->filled |= SURVEY_INFO_IN_USE; 1690 survey->filled |= SURVEY_INFO_IN_USE;
1691 1691
1692 if (ar->fw.hw_counters) { 1692 if (ar->fw.hw_counters) {
1693 survey->filled |= SURVEY_INFO_CHANNEL_TIME | 1693 survey->filled |= SURVEY_INFO_TIME |
1694 SURVEY_INFO_CHANNEL_TIME_BUSY | 1694 SURVEY_INFO_TIME_BUSY |
1695 SURVEY_INFO_CHANNEL_TIME_TX; 1695 SURVEY_INFO_TIME_TX;
1696 } 1696 }
1697 1697
1698 return 0; 1698 return 0;
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c
index cfd0554cf140..3d57f8772389 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -86,7 +86,7 @@ static const struct radar_detector_specs fcc_radar_ref_types[] = {
86 FCC_PATTERN(1, 0, 5, 150, 230, 1, 23), 86 FCC_PATTERN(1, 0, 5, 150, 230, 1, 23),
87 FCC_PATTERN(2, 6, 10, 200, 500, 1, 16), 87 FCC_PATTERN(2, 6, 10, 200, 500, 1, 16),
88 FCC_PATTERN(3, 11, 20, 200, 500, 1, 12), 88 FCC_PATTERN(3, 11, 20, 200, 500, 1, 12),
89 FCC_PATTERN(4, 50, 100, 1000, 2000, 1, 20), 89 FCC_PATTERN(4, 50, 100, 1000, 2000, 1, 1),
90 FCC_PATTERN(5, 0, 1, 333, 333, 1, 9), 90 FCC_PATTERN(5, 0, 1, 333, 333, 1, 9),
91}; 91};
92 92
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/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index 481680a3aa55..ce8c0381825e 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -39,12 +39,3 @@ config WIL6210_TRACING
39 option if you are interested in debugging the driver. 39 option if you are interested in debugging the driver.
40 40
41 If unsure, say Y to make it easier to debug problems. 41 If unsure, say Y to make it easier to debug problems.
42
43config WIL6210_PLATFORM_MSM
44 bool "wil6210 MSM platform specific support"
45 depends on WIL6210
46 depends on ARCH_MSM
47 default y
48 ---help---
49 Say Y here to enable wil6210 driver support for MSM
50 platform specific features
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index 8ad4b5f97e04..caa717bf52f3 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -14,7 +14,6 @@ wil6210-y += ioctl.o
14wil6210-y += fw.o 14wil6210-y += fw.o
15wil6210-$(CONFIG_WIL6210_TRACING) += trace.o 15wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
16wil6210-y += wil_platform.o 16wil6210-y += wil_platform.o
17wil6210-$(CONFIG_WIL6210_PLATFORM_MSM) += wil_platform_msm.o
18wil6210-y += ethtool.o 17wil6210-y += ethtool.o
19 18
20# for tracing framework to find trace.h 19# for tracing framework to find trace.h
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 38332a6dfb3a..2d5ea21be47e 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -142,14 +142,14 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
142 142
143 sinfo->generation = wil->sinfo_gen; 143 sinfo->generation = wil->sinfo_gen;
144 144
145 sinfo->filled = STATION_INFO_RX_BYTES | 145 sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) |
146 STATION_INFO_TX_BYTES | 146 BIT(NL80211_STA_INFO_TX_BYTES) |
147 STATION_INFO_RX_PACKETS | 147 BIT(NL80211_STA_INFO_RX_PACKETS) |
148 STATION_INFO_TX_PACKETS | 148 BIT(NL80211_STA_INFO_TX_PACKETS) |
149 STATION_INFO_RX_BITRATE | 149 BIT(NL80211_STA_INFO_RX_BITRATE) |
150 STATION_INFO_TX_BITRATE | 150 BIT(NL80211_STA_INFO_TX_BITRATE) |
151 STATION_INFO_RX_DROP_MISC | 151 BIT(NL80211_STA_INFO_RX_DROP_MISC) |
152 STATION_INFO_TX_FAILED; 152 BIT(NL80211_STA_INFO_TX_FAILED);
153 153
154 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G; 154 sinfo->txrate.flags = RATE_INFO_FLAGS_MCS | RATE_INFO_FLAGS_60G;
155 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs); 155 sinfo->txrate.mcs = le16_to_cpu(reply.evt.bf_mcs);
@@ -162,8 +162,8 @@ 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 |= STATION_INFO_SIGNAL; 166 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
167 sinfo->signal = reply.evt.sqi; 167 sinfo->signal = reply.evt.sqi;
168 } 168 }
169 169
@@ -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 }
@@ -334,6 +334,30 @@ out:
334 return rc; 334 return rc;
335} 335}
336 336
337static void wil_print_crypto(struct wil6210_priv *wil,
338 struct cfg80211_crypto_settings *c)
339{
340 int i, n;
341
342 wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
343 c->wpa_versions, c->cipher_group);
344 wil_dbg_misc(wil, "Pairwise ciphers [%d] {\n", c->n_ciphers_pairwise);
345 n = min_t(int, c->n_ciphers_pairwise, ARRAY_SIZE(c->ciphers_pairwise));
346 for (i = 0; i < n; i++)
347 wil_dbg_misc(wil, " [%d] = 0x%08x\n", i,
348 c->ciphers_pairwise[i]);
349 wil_dbg_misc(wil, "}\n");
350 wil_dbg_misc(wil, "AKM suites [%d] {\n", c->n_akm_suites);
351 n = min_t(int, c->n_akm_suites, ARRAY_SIZE(c->akm_suites));
352 for (i = 0; i < n; i++)
353 wil_dbg_misc(wil, " [%d] = 0x%08x\n", i,
354 c->akm_suites[i]);
355 wil_dbg_misc(wil, "}\n");
356 wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
357 c->control_port, be16_to_cpu(c->control_port_ethertype),
358 c->control_port_no_encrypt);
359}
360
337static void wil_print_connect_params(struct wil6210_priv *wil, 361static void wil_print_connect_params(struct wil6210_priv *wil,
338 struct cfg80211_connect_params *sme) 362 struct cfg80211_connect_params *sme)
339{ 363{
@@ -348,6 +372,7 @@ static void wil_print_connect_params(struct wil6210_priv *wil,
348 print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET, 372 print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET,
349 16, 1, sme->ssid, sme->ssid_len, true); 373 16, 1, sme->ssid, sme->ssid_len, true);
350 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open"); 374 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open");
375 wil_print_crypto(wil, &sme->crypto);
351} 376}
352 377
353static int wil_cfg80211_connect(struct wiphy *wiphy, 378static int wil_cfg80211_connect(struct wiphy *wiphy,
@@ -362,8 +387,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
362 int ch; 387 int ch;
363 int rc = 0; 388 int rc = 0;
364 389
365 if (test_bit(wil_status_fwconnecting, &wil->status) || 390 if (test_bit(wil_status_fwconnecting, wil->status) ||
366 test_bit(wil_status_fwconnected, &wil->status)) 391 test_bit(wil_status_fwconnected, wil->status))
367 return -EALREADY; 392 return -EALREADY;
368 393
369 wil_print_connect_params(wil, sme); 394 wil_print_connect_params(wil, sme);
@@ -450,15 +475,16 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
450 memcpy(conn.bssid, bss->bssid, ETH_ALEN); 475 memcpy(conn.bssid, bss->bssid, ETH_ALEN);
451 memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); 476 memcpy(conn.dst_mac, bss->bssid, ETH_ALEN);
452 477
453 set_bit(wil_status_fwconnecting, &wil->status); 478 set_bit(wil_status_fwconnecting, wil->status);
454 479
455 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); 480 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn));
456 if (rc == 0) { 481 if (rc == 0) {
482 netif_carrier_on(ndev);
457 /* Connect can take lots of time */ 483 /* Connect can take lots of time */
458 mod_timer(&wil->connect_timer, 484 mod_timer(&wil->connect_timer,
459 jiffies + msecs_to_jiffies(2000)); 485 jiffies + msecs_to_jiffies(2000));
460 } else { 486 } else {
461 clear_bit(wil_status_fwconnecting, &wil->status); 487 clear_bit(wil_status_fwconnecting, wil->status);
462 } 488 }
463 489
464 out: 490 out:
@@ -618,18 +644,6 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
618 b->assocresp_ies, b->assocresp_ies_len); 644 b->assocresp_ies, b->assocresp_ies_len);
619} 645}
620 646
621static void wil_print_crypto(struct wil6210_priv *wil,
622 struct cfg80211_crypto_settings *c)
623{
624 wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
625 c->wpa_versions, c->cipher_group);
626 wil_dbg_misc(wil, "Pairwise ciphers [%d]\n", c->n_ciphers_pairwise);
627 wil_dbg_misc(wil, "AKM suites [%d]\n", c->n_akm_suites);
628 wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
629 c->control_port, be16_to_cpu(c->control_port_ethertype),
630 c->control_port_no_encrypt);
631}
632
633static int wil_fix_bcon(struct wil6210_priv *wil, 647static int wil_fix_bcon(struct wil6210_priv *wil,
634 struct cfg80211_beacon_data *bcon) 648 struct cfg80211_beacon_data *bcon)
635{ 649{
@@ -757,12 +771,12 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
757 771
758 wil->secure_pcp = info->privacy; 772 wil->secure_pcp = info->privacy;
759 773
774 netif_carrier_on(ndev);
775
760 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, 776 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
761 channel->hw_value); 777 channel->hw_value);
762 if (rc) 778 if (rc)
763 goto out; 779 netif_carrier_off(ndev);
764
765 netif_carrier_on(ndev);
766 780
767out: 781out:
768 mutex_unlock(&wil->mutex); 782 mutex_unlock(&wil->mutex);
@@ -772,23 +786,26 @@ out:
772static int wil_cfg80211_stop_ap(struct wiphy *wiphy, 786static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
773 struct net_device *ndev) 787 struct net_device *ndev)
774{ 788{
775 int rc, rc1;
776 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 789 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
777 790
778 wil_dbg_misc(wil, "%s()\n", __func__); 791 wil_dbg_misc(wil, "%s()\n", __func__);
779 792
793 netif_carrier_off(ndev);
780 wil_set_recovery_state(wil, fw_recovery_idle); 794 wil_set_recovery_state(wil, fw_recovery_idle);
781 795
782 mutex_lock(&wil->mutex); 796 mutex_lock(&wil->mutex);
783 797
784 rc = wmi_pcp_stop(wil); 798 wmi_pcp_stop(wil);
785 799
786 __wil_down(wil); 800 __wil_down(wil);
787 rc1 = __wil_up(wil); 801 __wil_up(wil);
788 802
789 mutex_unlock(&wil->mutex); 803 mutex_unlock(&wil->mutex);
790 804
791 return min(rc, rc1); 805 /* some functions above might fail (e.g. __wil_up). Nevertheless, we
806 * return success because AP has stopped
807 */
808 return 0;
792} 809}
793 810
794static int wil_cfg80211_del_station(struct wiphy *wiphy, 811static int wil_cfg80211_del_station(struct wiphy *wiphy,
@@ -804,6 +821,96 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy,
804 return 0; 821 return 0;
805} 822}
806 823
824/* probe_client handling */
825static void wil_probe_client_handle(struct wil6210_priv *wil,
826 struct wil_probe_client_req *req)
827{
828 struct net_device *ndev = wil_to_ndev(wil);
829 struct wil_sta_info *sta = &wil->sta[req->cid];
830 /* assume STA is alive if it is still connected,
831 * else FW will disconnect it
832 */
833 bool alive = (sta->status == wil_sta_connected);
834
835 cfg80211_probe_status(ndev, sta->addr, req->cookie, alive, GFP_KERNEL);
836}
837
838static struct list_head *next_probe_client(struct wil6210_priv *wil)
839{
840 struct list_head *ret = NULL;
841
842 mutex_lock(&wil->probe_client_mutex);
843
844 if (!list_empty(&wil->probe_client_pending)) {
845 ret = wil->probe_client_pending.next;
846 list_del(ret);
847 }
848
849 mutex_unlock(&wil->probe_client_mutex);
850
851 return ret;
852}
853
854void wil_probe_client_worker(struct work_struct *work)
855{
856 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
857 probe_client_worker);
858 struct wil_probe_client_req *req;
859 struct list_head *lh;
860
861 while ((lh = next_probe_client(wil)) != NULL) {
862 req = list_entry(lh, struct wil_probe_client_req, list);
863
864 wil_probe_client_handle(wil, req);
865 kfree(req);
866 }
867}
868
869void wil_probe_client_flush(struct wil6210_priv *wil)
870{
871 struct wil_probe_client_req *req, *t;
872
873 wil_dbg_misc(wil, "%s()\n", __func__);
874
875 mutex_lock(&wil->probe_client_mutex);
876
877 list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) {
878 list_del(&req->list);
879 kfree(req);
880 }
881
882 mutex_unlock(&wil->probe_client_mutex);
883}
884
885static int wil_cfg80211_probe_client(struct wiphy *wiphy,
886 struct net_device *dev,
887 const u8 *peer, u64 *cookie)
888{
889 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
890 struct wil_probe_client_req *req;
891 int cid = wil_find_cid(wil, peer);
892
893 wil_dbg_misc(wil, "%s(%pM => CID %d)\n", __func__, peer, cid);
894
895 if (cid < 0)
896 return -ENOLINK;
897
898 req = kzalloc(sizeof(*req), GFP_KERNEL);
899 if (!req)
900 return -ENOMEM;
901
902 req->cid = cid;
903 req->cookie = cid;
904
905 mutex_lock(&wil->probe_client_mutex);
906 list_add_tail(&req->list, &wil->probe_client_pending);
907 mutex_unlock(&wil->probe_client_mutex);
908
909 *cookie = req->cookie;
910 queue_work(wil->wq_service, &wil->probe_client_worker);
911 return 0;
912}
913
807static struct cfg80211_ops wil_cfg80211_ops = { 914static struct cfg80211_ops wil_cfg80211_ops = {
808 .scan = wil_cfg80211_scan, 915 .scan = wil_cfg80211_scan,
809 .connect = wil_cfg80211_connect, 916 .connect = wil_cfg80211_connect,
@@ -823,6 +930,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
823 .start_ap = wil_cfg80211_start_ap, 930 .start_ap = wil_cfg80211_start_ap,
824 .stop_ap = wil_cfg80211_stop_ap, 931 .stop_ap = wil_cfg80211_stop_ap,
825 .del_station = wil_cfg80211_del_station, 932 .del_station = wil_cfg80211_del_station,
933 .probe_client = wil_cfg80211_probe_client,
826}; 934};
827 935
828static void wil_wiphy_init(struct wiphy *wiphy) 936static void wil_wiphy_init(struct wiphy *wiphy)
@@ -854,6 +962,7 @@ static void wil_wiphy_init(struct wiphy *wiphy)
854 wiphy->cipher_suites = wil_cipher_suites; 962 wiphy->cipher_suites = wil_cipher_suites;
855 wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites); 963 wiphy->n_cipher_suites = ARRAY_SIZE(wil_cipher_suites);
856 wiphy->mgmt_stypes = wil_mgmt_stypes; 964 wiphy->mgmt_stypes = wil_mgmt_stypes;
965 wiphy->features |= NL80211_FEATURE_SK_TX_STATUS;
857} 966}
858 967
859struct wireless_dev *wil_cfg80211_init(struct device *dev) 968struct wireless_dev *wil_cfg80211_init(struct device *dev)
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..b04e0afdcb21 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -33,15 +33,18 @@ 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; 36/* if not set via modparam, will be set to default value of 1/8 of
37 37 * rx ring size during init flow
38module_param(itr_trsh, uint, S_IRUGO); 38 */
39MODULE_PARM_DESC(itr_trsh, " Interrupt moderation threshold, usecs."); 39unsigned short rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_INIT;
40module_param(rx_ring_overflow_thrsh, ushort, S_IRUGO);
41MODULE_PARM_DESC(rx_ring_overflow_thrsh,
42 " RX ring overflow threshold in descriptors.");
40 43
41/* We allow allocation of more than 1 page buffers to support large packets. 44/* 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. 45 * It is suboptimal behavior performance wise in case MTU above page size.
43 */ 46 */
44unsigned int mtu_max = TXRX_BUF_LEN_DEFAULT - ETH_HLEN; 47unsigned int mtu_max = TXRX_BUF_LEN_DEFAULT - WIL_MAX_MPDU_OVERHEAD;
45static int mtu_max_set(const char *val, const struct kernel_param *kp) 48static int mtu_max_set(const char *val, const struct kernel_param *kp)
46{ 49{
47 int ret; 50 int ret;
@@ -53,7 +56,7 @@ static int mtu_max_set(const char *val, const struct kernel_param *kp)
53 if (ret) 56 if (ret)
54 return ret; 57 return ret;
55 58
56 if (mtu_max < 68 || mtu_max > IEEE80211_MAX_DATA_LEN_DMG) 59 if (mtu_max < 68 || mtu_max > WIL_MAX_ETH_MTU)
57 ret = -EINVAL; 60 ret = -EINVAL;
58 61
59 return ret; 62 return ret;
@@ -135,12 +138,14 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
135 138
136static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, 139static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
137 u16 reason_code, bool from_event) 140 u16 reason_code, bool from_event)
141__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
138{ 142{
139 uint i; 143 uint i;
140 struct net_device *ndev = wil_to_ndev(wil); 144 struct net_device *ndev = wil_to_ndev(wil);
141 struct wireless_dev *wdev = wil->wdev; 145 struct wireless_dev *wdev = wil->wdev;
142 struct wil_sta_info *sta = &wil->sta[cid]; 146 struct wil_sta_info *sta = &wil->sta[cid];
143 147
148 might_sleep();
144 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, 149 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
145 sta->status); 150 sta->status);
146 151
@@ -163,15 +168,14 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid,
163 168
164 for (i = 0; i < WIL_STA_TID_NUM; i++) { 169 for (i = 0; i < WIL_STA_TID_NUM; i++) {
165 struct wil_tid_ampdu_rx *r; 170 struct wil_tid_ampdu_rx *r;
166 unsigned long flags;
167 171
168 spin_lock_irqsave(&sta->tid_rx_lock, flags); 172 spin_lock_bh(&sta->tid_rx_lock);
169 173
170 r = sta->tid_rx[i]; 174 r = sta->tid_rx[i];
171 sta->tid_rx[i] = NULL; 175 sta->tid_rx[i] = NULL;
172 wil_tid_ampdu_rx_free(wil, r); 176 wil_tid_ampdu_rx_free(wil, r);
173 177
174 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 178 spin_unlock_bh(&sta->tid_rx_lock);
175 } 179 }
176 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 180 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
177 if (wil->vring2cid_tid[i][0] == cid) 181 if (wil->vring2cid_tid[i][0] == cid)
@@ -188,34 +192,47 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
188 struct wireless_dev *wdev = wil->wdev; 192 struct wireless_dev *wdev = wil->wdev;
189 193
190 might_sleep(); 194 might_sleep();
191 if (bssid) { 195 wil_dbg_misc(wil, "%s(bssid=%pM, reason=%d, ev%s)\n", __func__, bssid,
196 reason_code, from_event ? "+" : "-");
197
198 /* Cases are:
199 * - disconnect single STA, still connected
200 * - disconnect single STA, already disconnected
201 * - disconnect all
202 *
203 * For "disconnect all", there are 2 options:
204 * - bssid == NULL
205 * - bssid is our MAC address
206 */
207 if (bssid && memcmp(ndev->dev_addr, bssid, ETH_ALEN)) {
192 cid = wil_find_cid(wil, bssid); 208 cid = wil_find_cid(wil, bssid);
193 wil_dbg_misc(wil, "%s(%pM, CID %d)\n", __func__, bssid, cid); 209 wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
194 } else { 210 bssid, cid, reason_code);
195 wil_dbg_misc(wil, "%s(all)\n", __func__); 211 if (cid >= 0) /* disconnect 1 peer */
196 } 212 wil_disconnect_cid(wil, cid, reason_code, from_event);
197 213 } else { /* all */
198 if (cid >= 0) /* disconnect 1 peer */ 214 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++) 215 for (cid = 0; cid < WIL6210_MAX_CID; cid++)
202 wil_disconnect_cid(wil, cid, reason_code, from_event); 216 wil_disconnect_cid(wil, cid, reason_code, from_event);
217 }
203 218
204 /* link state */ 219 /* link state */
205 switch (wdev->iftype) { 220 switch (wdev->iftype) {
206 case NL80211_IFTYPE_STATION: 221 case NL80211_IFTYPE_STATION:
207 case NL80211_IFTYPE_P2P_CLIENT: 222 case NL80211_IFTYPE_P2P_CLIENT:
208 wil_link_off(wil); 223 netif_tx_stop_all_queues(ndev);
209 if (test_bit(wil_status_fwconnected, &wil->status)) { 224 netif_carrier_off(ndev);
210 clear_bit(wil_status_fwconnected, &wil->status); 225
226 if (test_bit(wil_status_fwconnected, wil->status)) {
227 clear_bit(wil_status_fwconnected, wil->status);
211 cfg80211_disconnected(ndev, reason_code, 228 cfg80211_disconnected(ndev, reason_code,
212 NULL, 0, GFP_KERNEL); 229 NULL, 0, GFP_KERNEL);
213 } else if (test_bit(wil_status_fwconnecting, &wil->status)) { 230 } else if (test_bit(wil_status_fwconnecting, wil->status)) {
214 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 231 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
215 WLAN_STATUS_UNSPECIFIED_FAILURE, 232 WLAN_STATUS_UNSPECIFIED_FAILURE,
216 GFP_KERNEL); 233 GFP_KERNEL);
217 } 234 }
218 clear_bit(wil_status_fwconnecting, &wil->status); 235 clear_bit(wil_status_fwconnecting, wil->status);
219 break; 236 break;
220 default: 237 default:
221 break; 238 break;
@@ -248,7 +265,7 @@ static void wil_scan_timer_fn(ulong x)
248{ 265{
249 struct wil6210_priv *wil = (void *)x; 266 struct wil6210_priv *wil = (void *)x;
250 267
251 clear_bit(wil_status_fwready, &wil->status); 268 clear_bit(wil_status_fwready, wil->status);
252 wil_err(wil, "Scan timeout detected, start fw error recovery\n"); 269 wil_err(wil, "Scan timeout detected, start fw error recovery\n");
253 wil->recovery_state = fw_recovery_pending; 270 wil->recovery_state = fw_recovery_pending;
254 schedule_work(&wil->fw_error_worker); 271 schedule_work(&wil->fw_error_worker);
@@ -352,6 +369,8 @@ static void wil_connect_worker(struct work_struct *work)
352 int rc; 369 int rc;
353 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 370 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
354 connect_worker); 371 connect_worker);
372 struct net_device *ndev = wil_to_ndev(wil);
373
355 int cid = wil->pending_connect_cid; 374 int cid = wil->pending_connect_cid;
356 int ringid = wil_find_free_vring(wil); 375 int ringid = wil_find_free_vring(wil);
357 376
@@ -366,7 +385,7 @@ static void wil_connect_worker(struct work_struct *work)
366 wil->pending_connect_cid = -1; 385 wil->pending_connect_cid = -1;
367 if (rc == 0) { 386 if (rc == 0) {
368 wil->sta[cid].status = wil_sta_connected; 387 wil->sta[cid].status = wil_sta_connected;
369 wil_link_on(wil); 388 netif_tx_wake_all_queues(ndev);
370 } else { 389 } else {
371 wil->sta[cid].status = wil_sta_unused; 390 wil->sta[cid].status = wil_sta_unused;
372 } 391 }
@@ -384,6 +403,9 @@ int wil_priv_init(struct wil6210_priv *wil)
384 403
385 mutex_init(&wil->mutex); 404 mutex_init(&wil->mutex);
386 mutex_init(&wil->wmi_mutex); 405 mutex_init(&wil->wmi_mutex);
406 mutex_init(&wil->back_rx_mutex);
407 mutex_init(&wil->back_tx_mutex);
408 mutex_init(&wil->probe_client_mutex);
387 409
388 init_completion(&wil->wmi_ready); 410 init_completion(&wil->wmi_ready);
389 init_completion(&wil->wmi_call); 411 init_completion(&wil->wmi_call);
@@ -396,25 +418,39 @@ int wil_priv_init(struct wil6210_priv *wil)
396 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker); 418 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
397 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 419 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
398 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 420 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
421 INIT_WORK(&wil->back_rx_worker, wil_back_rx_worker);
422 INIT_WORK(&wil->back_tx_worker, wil_back_tx_worker);
423 INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker);
399 424
400 INIT_LIST_HEAD(&wil->pending_wmi_ev); 425 INIT_LIST_HEAD(&wil->pending_wmi_ev);
426 INIT_LIST_HEAD(&wil->back_rx_pending);
427 INIT_LIST_HEAD(&wil->back_tx_pending);
428 INIT_LIST_HEAD(&wil->probe_client_pending);
401 spin_lock_init(&wil->wmi_ev_lock); 429 spin_lock_init(&wil->wmi_ev_lock);
402 init_waitqueue_head(&wil->wq); 430 init_waitqueue_head(&wil->wq);
403 431
404 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME"_wmi"); 432 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
405 if (!wil->wmi_wq) 433 if (!wil->wmi_wq)
406 return -EAGAIN; 434 return -EAGAIN;
407 435
408 wil->wmi_wq_conn = create_singlethread_workqueue(WIL_NAME"_connect"); 436 wil->wq_service = create_singlethread_workqueue(WIL_NAME "_service");
409 if (!wil->wmi_wq_conn) { 437 if (!wil->wq_service)
410 destroy_workqueue(wil->wmi_wq); 438 goto out_wmi_wq;
411 return -EAGAIN;
412 }
413 439
414 wil->last_fw_recovery = jiffies; 440 wil->last_fw_recovery = jiffies;
415 wil->itr_trsh = itr_trsh; 441 wil->tx_interframe_timeout = WIL6210_ITR_TX_INTERFRAME_TIMEOUT_DEFAULT;
442 wil->rx_interframe_timeout = WIL6210_ITR_RX_INTERFRAME_TIMEOUT_DEFAULT;
443 wil->tx_max_burst_duration = WIL6210_ITR_TX_MAX_BURST_DURATION_DEFAULT;
444 wil->rx_max_burst_duration = WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT;
416 445
446 if (rx_ring_overflow_thrsh == WIL6210_RX_HIGH_TRSH_INIT)
447 rx_ring_overflow_thrsh = WIL6210_RX_HIGH_TRSH_DEFAULT;
417 return 0; 448 return 0;
449
450out_wmi_wq:
451 destroy_workqueue(wil->wmi_wq);
452
453 return -EAGAIN;
418} 454}
419 455
420/** 456/**
@@ -448,7 +484,13 @@ void wil_priv_deinit(struct wil6210_priv *wil)
448 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 484 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
449 mutex_unlock(&wil->mutex); 485 mutex_unlock(&wil->mutex);
450 wmi_event_flush(wil); 486 wmi_event_flush(wil);
451 destroy_workqueue(wil->wmi_wq_conn); 487 wil_back_rx_flush(wil);
488 cancel_work_sync(&wil->back_rx_worker);
489 wil_back_tx_flush(wil);
490 cancel_work_sync(&wil->back_tx_worker);
491 wil_probe_client_flush(wil);
492 cancel_work_sync(&wil->probe_client_worker);
493 destroy_workqueue(wil->wq_service);
452 destroy_workqueue(wil->wmi_wq); 494 destroy_workqueue(wil->wmi_wq);
453} 495}
454 496
@@ -478,13 +520,10 @@ static int wil_target_reset(struct wil6210_priv *wil)
478{ 520{
479 int delay = 0; 521 int delay = 0;
480 u32 x; 522 u32 x;
481 u32 rev_id; 523 bool is_reset_v2 = test_bit(hw_capability_reset_v2,
482 bool is_sparrow = (wil->board->board == WIL_BOARD_SPARROW); 524 wil->hw_capabilities);
483 525
484 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name); 526 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->hw_name);
485
486 wil->hw_version = R(RGF_USER_FW_REV_ID);
487 rev_id = wil->hw_version & 0xff;
488 527
489 /* Clear MAC link up */ 528 /* Clear MAC link up */
490 S(RGF_HP_CTRL, BIT(15)); 529 S(RGF_HP_CTRL, BIT(15));
@@ -496,7 +535,7 @@ static int wil_target_reset(struct wil6210_priv *wil)
496 /* Clear Fw Download notification */ 535 /* Clear Fw Download notification */
497 C(RGF_USER_USAGE_6, BIT(0)); 536 C(RGF_USER_USAGE_6, BIT(0));
498 537
499 if (is_sparrow) { 538 if (is_reset_v2) {
500 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN); 539 S(RGF_CAF_OSC_CONTROL, BIT_CAF_OSC_XTAL_EN);
501 /* XTAL stabilization should take about 3ms */ 540 /* XTAL stabilization should take about 3ms */
502 usleep_range(5000, 7000); 541 usleep_range(5000, 7000);
@@ -517,10 +556,11 @@ static int wil_target_reset(struct wil6210_priv *wil)
517 556
518 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 557 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
519 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 558 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
520 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000f0 : 0x00000170); 559 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3,
560 is_reset_v2 ? 0x000000f0 : 0x00000170);
521 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); 561 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00);
522 562
523 if (is_sparrow) { 563 if (is_reset_v2) {
524 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 564 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
525 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0); 565 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
526 } 566 }
@@ -530,19 +570,14 @@ static int wil_target_reset(struct wil6210_priv *wil)
530 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 570 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
531 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 571 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
532 572
533 if (is_sparrow) { 573 if (is_reset_v2) {
534 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 574 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
535 /* reset A2 PCIE AHB */ 575 /* reset A2 PCIE AHB */
536 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 576 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
537 } else { 577 } else {
538 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 578 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
539 if (rev_id == 1) { 579 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
540 /* reset A1 BOTH PCIE AHB & PCIE RGF */ 580 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 } 581 }
547 582
548 /* TODO: check order here!!! Erez code is different */ 583 /* TODO: check order here!!! Erez code is different */
@@ -559,8 +594,7 @@ static int wil_target_reset(struct wil6210_priv *wil)
559 } 594 }
560 } while (x != HW_MACHINE_BOOT_DONE); 595 } while (x != HW_MACHINE_BOOT_DONE);
561 596
562 /* TODO: Erez check rev_id != 1 */ 597 if (!is_reset_v2)
563 if (!is_sparrow && (rev_id != 1))
564 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 598 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
565 599
566 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 600 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
@@ -569,26 +603,6 @@ static int wil_target_reset(struct wil6210_priv *wil)
569 return 0; 603 return 0;
570} 604}
571 605
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 606#undef R
593#undef W 607#undef W
594#undef S 608#undef S
@@ -629,13 +643,17 @@ int wil_reset(struct wil6210_priv *wil)
629 643
630 wil_dbg_misc(wil, "%s()\n", __func__); 644 wil_dbg_misc(wil, "%s()\n", __func__);
631 645
646 if (wil->hw_version == HW_VER_UNKNOWN)
647 return -ENODEV;
648
632 WARN_ON(!mutex_is_locked(&wil->mutex)); 649 WARN_ON(!mutex_is_locked(&wil->mutex));
633 WARN_ON(test_bit(wil_status_napi_en, &wil->status)); 650 WARN_ON(test_bit(wil_status_napi_en, wil->status));
634 651
635 cancel_work_sync(&wil->disconnect_worker); 652 cancel_work_sync(&wil->disconnect_worker);
636 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 653 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
637 654
638 wil->status = 0; /* prevent NAPI from being scheduled */ 655 /* prevent NAPI from being scheduled */
656 bitmap_zero(wil->status, wil_status_last);
639 657
640 if (wil->scan_request) { 658 if (wil->scan_request) {
641 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 659 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
@@ -649,7 +667,7 @@ int wil_reset(struct wil6210_priv *wil)
649 667
650 wmi_event_flush(wil); 668 wmi_event_flush(wil);
651 669
652 flush_workqueue(wil->wmi_wq_conn); 670 flush_workqueue(wil->wq_service);
653 flush_workqueue(wil->wmi_wq); 671 flush_workqueue(wil->wmi_wq);
654 672
655 rc = wil_target_reset(wil); 673 rc = wil_target_reset(wil);
@@ -688,6 +706,7 @@ int wil_reset(struct wil6210_priv *wil)
688 reinit_completion(&wil->wmi_ready); 706 reinit_completion(&wil->wmi_ready);
689 reinit_completion(&wil->wmi_call); 707 reinit_completion(&wil->wmi_call);
690 708
709 wil_configure_interrupt_moderation(wil);
691 wil_unmask_irq(wil); 710 wil_unmask_irq(wil);
692 711
693 /* we just started MAC, wait for FW ready */ 712 /* we just started MAC, wait for FW ready */
@@ -703,28 +722,6 @@ void wil_fw_error_recovery(struct wil6210_priv *wil)
703 schedule_work(&wil->fw_error_worker); 722 schedule_work(&wil->fw_error_worker);
704} 723}
705 724
706void wil_link_on(struct wil6210_priv *wil)
707{
708 struct net_device *ndev = wil_to_ndev(wil);
709
710 wil_dbg_misc(wil, "%s()\n", __func__);
711
712 netif_carrier_on(ndev);
713 wil_dbg_misc(wil, "netif_tx_wake : link on\n");
714 netif_tx_wake_all_queues(ndev);
715}
716
717void wil_link_off(struct wil6210_priv *wil)
718{
719 struct net_device *ndev = wil_to_ndev(wil);
720
721 wil_dbg_misc(wil, "%s()\n", __func__);
722
723 netif_tx_stop_all_queues(ndev);
724 wil_dbg_misc(wil, "netif_tx_stop : link off\n");
725 netif_carrier_off(ndev);
726}
727
728int __wil_up(struct wil6210_priv *wil) 725int __wil_up(struct wil6210_priv *wil)
729{ 726{
730 struct net_device *ndev = wil_to_ndev(wil); 727 struct net_device *ndev = wil_to_ndev(wil);
@@ -774,7 +771,7 @@ int __wil_up(struct wil6210_priv *wil)
774 wil_dbg_misc(wil, "NAPI enable\n"); 771 wil_dbg_misc(wil, "NAPI enable\n");
775 napi_enable(&wil->napi_rx); 772 napi_enable(&wil->napi_rx);
776 napi_enable(&wil->napi_tx); 773 napi_enable(&wil->napi_tx);
777 set_bit(wil_status_napi_en, &wil->status); 774 set_bit(wil_status_napi_en, wil->status);
778 775
779 if (wil->platform_ops.bus_request) 776 if (wil->platform_ops.bus_request)
780 wil->platform_ops.bus_request(wil->platform_handle, 777 wil->platform_ops.bus_request(wil->platform_handle,
@@ -807,7 +804,7 @@ int __wil_down(struct wil6210_priv *wil)
807 wil->platform_ops.bus_request(wil->platform_handle, 0); 804 wil->platform_ops.bus_request(wil->platform_handle, 0);
808 805
809 wil_disable_irq(wil); 806 wil_disable_irq(wil);
810 if (test_and_clear_bit(wil_status_napi_en, &wil->status)) { 807 if (test_and_clear_bit(wil_status_napi_en, wil->status)) {
811 napi_disable(&wil->napi_rx); 808 napi_disable(&wil->napi_rx);
812 napi_disable(&wil->napi_tx); 809 napi_disable(&wil->napi_tx);
813 wil_dbg_misc(wil, "NAPI disable\n"); 810 wil_dbg_misc(wil, "NAPI disable\n");
@@ -822,15 +819,15 @@ int __wil_down(struct wil6210_priv *wil)
822 wil->scan_request = NULL; 819 wil->scan_request = NULL;
823 } 820 }
824 821
825 if (test_bit(wil_status_fwconnected, &wil->status) || 822 if (test_bit(wil_status_fwconnected, wil->status) ||
826 test_bit(wil_status_fwconnecting, &wil->status)) 823 test_bit(wil_status_fwconnecting, wil->status))
827 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); 824 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
828 825
829 /* make sure wil is idle (not connected) */ 826 /* make sure wil is idle (not connected) */
830 mutex_unlock(&wil->mutex); 827 mutex_unlock(&wil->mutex);
831 while (iter--) { 828 while (iter--) {
832 int idle = !test_bit(wil_status_fwconnected, &wil->status) && 829 int idle = !test_bit(wil_status_fwconnected, wil->status) &&
833 !test_bit(wil_status_fwconnecting, &wil->status); 830 !test_bit(wil_status_fwconnecting, wil->status);
834 if (idle) 831 if (idle)
835 break; 832 break;
836 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS); 833 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index e81703ca7701..ace30c1b5c64 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
18
19#include "wil6210.h" 18#include "wil6210.h"
20#include "txrx.h" 19#include "txrx.h"
21 20
@@ -122,6 +121,12 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
122 return min(tx_done, budget); 121 return min(tx_done, budget);
123} 122}
124 123
124static void wil_dev_setup(struct net_device *dev)
125{
126 ether_setup(dev);
127 dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
128}
129
125void *wil_if_alloc(struct device *dev, void __iomem *csr) 130void *wil_if_alloc(struct device *dev, void __iomem *csr)
126{ 131{
127 struct net_device *ndev; 132 struct net_device *ndev;
@@ -153,7 +158,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
153 ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels; 158 ch = wdev->wiphy->bands[IEEE80211_BAND_60GHZ]->channels;
154 cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT); 159 cfg80211_chandef_create(&wdev->preset_chandef, ch, NL80211_CHAN_NO_HT);
155 160
156 ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, ether_setup); 161 ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, wil_dev_setup);
157 if (!ndev) { 162 if (!ndev) {
158 dev_err(dev, "alloc_netdev_mqs failed\n"); 163 dev_err(dev, "alloc_netdev_mqs failed\n");
159 rc = -ENOMEM; 164 rc = -ENOMEM;
@@ -174,7 +179,7 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
174 netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx, 179 netif_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx,
175 WIL6210_NAPI_BUDGET); 180 WIL6210_NAPI_BUDGET);
176 181
177 wil_link_off(wil); 182 netif_tx_stop_all_queues(ndev);
178 183
179 return wil; 184 return wil;
180 185
@@ -217,8 +222,6 @@ int wil_if_add(struct wil6210_priv *wil)
217 return rc; 222 return rc;
218 } 223 }
219 224
220 wil_link_off(wil);
221
222 return 0; 225 return 0;
223} 226}
224 227
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..ca10dcf0986e 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -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 struct wil_tid_ampdu_rx *r;
296 int rc;
297
298 might_sleep();
299 parse_cidxtid(req->cidxtid, &cid, &tid);
300
301 /* sanity checks */
302 if (cid >= WIL6210_MAX_CID) {
303 wil_err(wil, "BACK: invalid CID %d\n", cid);
304 return;
305 }
306
307 sta = &wil->sta[cid];
308 if (sta->status != wil_sta_connected) {
309 wil_err(wil, "BACK: CID %d not connected\n", cid);
310 return;
311 }
312
313 wil_dbg_wmi(wil,
314 "ADDBA request for CID %d %pM TID %d size %d timeout %d AMSDU%s policy %d token %d SSN 0x%03x\n",
315 cid, sta->addr, tid, req_agg_wsize, req->ba_timeout,
316 agg_amsdu ? "+" : "-", !!ba_policy, req->dialog_token, ssn);
317
318 /* apply policies */
319 if (ba_policy) {
320 wil_err(wil, "BACK requested unsupported ba_policy == 1\n");
321 status = WLAN_STATUS_INVALID_QOS_PARAM;
322 }
323 if (status == WLAN_STATUS_SUCCESS)
324 agg_wsize = wil_agg_size(wil, req_agg_wsize);
325
326 rc = wmi_addba_rx_resp(wil, cid, tid, req->dialog_token, status,
327 agg_amsdu, agg_wsize, agg_timeout);
328 if (rc || (status != WLAN_STATUS_SUCCESS))
329 return;
330
331 /* apply */
332 r = wil_tid_ampdu_rx_alloc(wil, agg_wsize, ssn);
333 spin_lock_bh(&sta->tid_rx_lock);
334 wil_tid_ampdu_rx_free(wil, sta->tid_rx[tid]);
335 sta->tid_rx[tid] = r;
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..8439f65db259 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),
@@ -677,6 +671,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
677 } 671 }
678 672
679 memset(txdata, 0, sizeof(*txdata)); 673 memset(txdata, 0, sizeof(*txdata));
674 spin_lock_init(&txdata->lock);
680 vring->size = size; 675 vring->size = size;
681 rc = wil_vring_alloc(wil, vring); 676 rc = wil_vring_alloc(wil, vring);
682 if (rc) 677 if (rc)
@@ -701,6 +696,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); 696 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
702 697
703 txdata->enabled = 1; 698 txdata->enabled = 1;
699 if (wil->sta[cid].data_port_open && (agg_wsize >= 0))
700 wil_addba_tx_request(wil, id, agg_wsize);
704 701
705 return 0; 702 return 0;
706 out_free: 703 out_free:
@@ -713,6 +710,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) 710void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
714{ 711{
715 struct vring *vring = &wil->vring_tx[id]; 712 struct vring *vring = &wil->vring_tx[id];
713 struct vring_tx_data *txdata = &wil->vring_tx_data[id];
716 714
717 WARN_ON(!mutex_is_locked(&wil->mutex)); 715 WARN_ON(!mutex_is_locked(&wil->mutex));
718 716
@@ -721,12 +719,15 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
721 719
722 wil_dbg_misc(wil, "%s() id=%d\n", __func__, id); 720 wil_dbg_misc(wil, "%s() id=%d\n", __func__, id);
723 721
722 spin_lock_bh(&txdata->lock);
723 txdata->enabled = 0; /* no Tx can be in progress or start anew */
724 spin_unlock_bh(&txdata->lock);
724 /* make sure NAPI won't touch this vring */ 725 /* make sure NAPI won't touch this vring */
725 wil->vring_tx_data[id].enabled = 0; 726 if (test_bit(wil_status_napi_en, wil->status))
726 if (test_bit(wil_status_napi_en, &wil->status))
727 napi_synchronize(&wil->napi_tx); 727 napi_synchronize(&wil->napi_tx);
728 728
729 wil_vring_free(wil, vring, 1); 729 wil_vring_free(wil, vring, 1);
730 memset(txdata, 0, sizeof(*txdata));
730} 731}
731 732
732static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, 733static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
@@ -773,6 +774,38 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil,
773 774
774static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 775static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
775 struct sk_buff *skb); 776 struct sk_buff *skb);
777
778static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
779 struct sk_buff *skb)
780{
781 struct vring *v;
782 int i;
783 u8 cid;
784
785 /* In the STA mode, it is expected to have only 1 VRING
786 * for the AP we connected to.
787 * find 1-st vring and see whether it is eligible for data
788 */
789 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
790 v = &wil->vring_tx[i];
791 if (!v->va)
792 continue;
793
794 cid = wil->vring2cid_tid[i][0];
795 if (!wil->sta[cid].data_port_open &&
796 (skb->protocol != cpu_to_be16(ETH_P_PAE)))
797 break;
798
799 wil_dbg_txrx(wil, "Tx -> ring %d\n", i);
800
801 return v;
802 }
803
804 wil_dbg_txrx(wil, "Tx while no vrings active?\n");
805
806 return NULL;
807}
808
776/* 809/*
777 * Find 1-st vring and return it; set dest address for this vring in skb 810 * 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 811 * duplicate skb and send it to other active vrings
@@ -843,9 +876,6 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
843 d->mac.d[1] = 0; 876 d->mac.d[1] = 0;
844 d->mac.d[2] = 0; 877 d->mac.d[2] = 0;
845 d->mac.ucode_cmd = 0; 878 d->mac.ucode_cmd = 0;
846 /* use dst index 0 */
847 d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_DST_INDEX_EN_POS) |
848 (0 << MAC_CFG_DESC_TX_1_DST_INDEX_POS);
849 /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */ 879 /* translation type: 0 - bypass; 1 - 802.3; 2 - native wifi */
850 d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) | 880 d->mac.d[2] = BIT(MAC_CFG_DESC_TX_2_SNAP_HDR_INSERTION_EN_POS) |
851 (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS); 881 (1 << MAC_CFG_DESC_TX_2_L2_TRANSLATION_TYPE_POS);
@@ -908,8 +938,8 @@ static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
908 return 0; 938 return 0;
909} 939}
910 940
911static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 941static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
912 struct sk_buff *skb) 942 struct sk_buff *skb)
913{ 943{
914 struct device *dev = wil_to_dev(wil); 944 struct device *dev = wil_to_dev(wil);
915 struct vring_tx_desc dd, *d = &dd; 945 struct vring_tx_desc dd, *d = &dd;
@@ -925,18 +955,21 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
925 955
926 wil_dbg_txrx(wil, "%s()\n", __func__); 956 wil_dbg_txrx(wil, "%s()\n", __func__);
927 957
958 if (unlikely(!txdata->enabled))
959 return -EINVAL;
960
928 if (avail < 1 + nr_frags) { 961 if (avail < 1 + nr_frags) {
929 wil_err_ratelimited(wil, 962 wil_err_ratelimited(wil,
930 "Tx ring full. No space for %d fragments\n", 963 "Tx ring[%2d] full. No space for %d fragments\n",
931 1 + nr_frags); 964 vring_index, 1 + nr_frags);
932 return -ENOMEM; 965 return -ENOMEM;
933 } 966 }
934 _d = &vring->va[i].tx; 967 _d = &vring->va[i].tx;
935 968
936 pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); 969 pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
937 970
938 wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb), 971 wil_dbg_txrx(wil, "Tx[%2d] skb %d bytes 0x%p -> %pad\n", vring_index,
939 skb->data, &pa); 972 skb_headlen(skb), skb->data, &pa);
940 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1, 973 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1,
941 skb->data, skb_headlen(skb), false); 974 skb->data, skb_headlen(skb), false);
942 975
@@ -947,15 +980,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
947 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 980 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
948 /* Process TCP/UDP checksum offloading */ 981 /* Process TCP/UDP checksum offloading */
949 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) { 982 if (wil_tx_desc_offload_cksum_set(wil, d, skb)) {
950 wil_err(wil, "VRING #%d Failed to set cksum, drop packet\n", 983 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
951 vring_index); 984 vring_index);
952 goto dma_error; 985 goto dma_error;
953 } 986 }
954 987
955 vring->ctx[i].nr_frags = nr_frags; 988 vring->ctx[i].nr_frags = nr_frags;
956 wil_tx_desc_set_nr_frags(d, nr_frags); 989 wil_tx_desc_set_nr_frags(d, nr_frags);
957 if (nr_frags)
958 *_d = *d;
959 990
960 /* middle segments */ 991 /* middle segments */
961 for (; f < nr_frags; f++) { 992 for (; f < nr_frags; f++) {
@@ -963,6 +994,10 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
963 &skb_shinfo(skb)->frags[f]; 994 &skb_shinfo(skb)->frags[f];
964 int len = skb_frag_size(frag); 995 int len = skb_frag_size(frag);
965 996
997 *_d = *d;
998 wil_dbg_txrx(wil, "Tx[%2d] desc[%4d]\n", vring_index, i);
999 wil_hex_dump_txrx("TxD ", DUMP_PREFIX_NONE, 32, 4,
1000 (const void *)d, sizeof(*d), false);
966 i = (swhead + f + 1) % vring->size; 1001 i = (swhead + f + 1) % vring->size;
967 _d = &vring->va[i].tx; 1002 _d = &vring->va[i].tx;
968 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), 1003 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
@@ -976,13 +1011,15 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
976 * it will succeed here too 1011 * it will succeed here too
977 */ 1012 */
978 wil_tx_desc_offload_cksum_set(wil, d, skb); 1013 wil_tx_desc_offload_cksum_set(wil, d, skb);
979 *_d = *d;
980 } 1014 }
981 /* for the last seg only */ 1015 /* for the last seg only */
982 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 1016 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
983 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS); 1017 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS);
984 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 1018 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
985 *_d = *d; 1019 *_d = *d;
1020 wil_dbg_txrx(wil, "Tx[%2d] desc[%4d]\n", vring_index, i);
1021 wil_hex_dump_txrx("TxD ", DUMP_PREFIX_NONE, 32, 4,
1022 (const void *)d, sizeof(*d), false);
986 1023
987 /* hold reference to skb 1024 /* hold reference to skb
988 * to prevent skb release before accounting 1025 * to prevent skb release before accounting
@@ -990,15 +1027,13 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
990 */ 1027 */
991 vring->ctx[i].skb = skb_get(skb); 1028 vring->ctx[i].skb = skb_get(skb);
992 1029
993 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
994 (const void *)d, sizeof(*d), false);
995
996 if (wil_vring_is_empty(vring)) /* performance monitoring */ 1030 if (wil_vring_is_empty(vring)) /* performance monitoring */
997 txdata->idle += get_cycles() - txdata->last_idle; 1031 txdata->idle += get_cycles() - txdata->last_idle;
998 1032
999 /* advance swhead */ 1033 /* advance swhead */
1000 wil_vring_advance_head(vring, nr_frags + 1); 1034 wil_vring_advance_head(vring, nr_frags + 1);
1001 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 1035 wil_dbg_txrx(wil, "Tx[%2d] swhead %d -> %d\n", vring_index, swhead,
1036 vring->swhead);
1002 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags); 1037 trace_wil6210_tx(vring_index, swhead, skb->len, nr_frags);
1003 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail)); 1038 iowrite32(vring->swhead, wil->csr + HOSTADDR(vring->hwtail));
1004 1039
@@ -1025,6 +1060,19 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1025 return -EINVAL; 1060 return -EINVAL;
1026} 1061}
1027 1062
1063static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1064 struct sk_buff *skb)
1065{
1066 int vring_index = vring - wil->vring_tx;
1067 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
1068 int rc;
1069
1070 spin_lock(&txdata->lock);
1071 rc = __wil_tx_vring(wil, vring, skb);
1072 spin_unlock(&txdata->lock);
1073 return rc;
1074}
1075
1028netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 1076netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1029{ 1077{
1030 struct wil6210_priv *wil = ndev_to_wil(ndev); 1078 struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -1034,14 +1082,14 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1034 int rc; 1082 int rc;
1035 1083
1036 wil_dbg_txrx(wil, "%s()\n", __func__); 1084 wil_dbg_txrx(wil, "%s()\n", __func__);
1037 if (!test_bit(wil_status_fwready, &wil->status)) { 1085 if (!test_bit(wil_status_fwready, wil->status)) {
1038 if (!pr_once_fw) { 1086 if (!pr_once_fw) {
1039 wil_err(wil, "FW not ready\n"); 1087 wil_err(wil, "FW not ready\n");
1040 pr_once_fw = true; 1088 pr_once_fw = true;
1041 } 1089 }
1042 goto drop; 1090 goto drop;
1043 } 1091 }
1044 if (!test_bit(wil_status_fwconnected, &wil->status)) { 1092 if (!test_bit(wil_status_fwconnected, wil->status)) {
1045 wil_err(wil, "FW not connected\n"); 1093 wil_err(wil, "FW not connected\n");
1046 goto drop; 1094 goto drop;
1047 } 1095 }
@@ -1052,15 +1100,19 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1052 pr_once_fw = false; 1100 pr_once_fw = false;
1053 1101
1054 /* find vring */ 1102 /* find vring */
1055 if (is_unicast_ether_addr(eth->h_dest)) 1103 if (wil->wdev->iftype == NL80211_IFTYPE_STATION) {
1056 vring = wil_find_tx_vring(wil, skb); 1104 /* in STA mode (ESS), all to same VRING */
1057 else 1105 vring = wil_find_tx_vring_sta(wil, skb);
1058 vring = wil_tx_bcast(wil, skb); 1106 } else { /* direct communication, find matching VRING */
1107 if (is_unicast_ether_addr(eth->h_dest))
1108 vring = wil_find_tx_vring(wil, skb);
1109 else
1110 vring = wil_tx_bcast(wil, skb);
1111 }
1059 if (!vring) { 1112 if (!vring) {
1060 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1113 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1061 goto drop; 1114 goto drop;
1062 } 1115 }
1063
1064 /* set up vring entry */ 1116 /* set up vring entry */
1065 rc = wil_tx_vring(wil, vring, skb); 1117 rc = wil_tx_vring(wil, vring, skb);
1066 1118
@@ -1087,6 +1139,22 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1087 return NET_XMIT_DROP; 1139 return NET_XMIT_DROP;
1088} 1140}
1089 1141
1142static inline bool wil_need_txstat(struct sk_buff *skb)
1143{
1144 struct ethhdr *eth = (void *)skb->data;
1145
1146 return is_unicast_ether_addr(eth->h_dest) && skb->sk &&
1147 (skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS);
1148}
1149
1150static inline void wil_consume_skb(struct sk_buff *skb, bool acked)
1151{
1152 if (unlikely(wil_need_txstat(skb)))
1153 skb_complete_wifi_ack(skb, acked);
1154 else
1155 acked ? dev_consume_skb_any(skb) : dev_kfree_skb_any(skb);
1156}
1157
1090/** 1158/**
1091 * Clean up transmitted skb's from the Tx VRING 1159 * Clean up transmitted skb's from the Tx VRING
1092 * 1160 *
@@ -1147,10 +1215,10 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1147 trace_wil6210_tx_done(ringid, vring->swtail, dmalen, 1215 trace_wil6210_tx_done(ringid, vring->swtail, dmalen,
1148 d->dma.error); 1216 d->dma.error);
1149 wil_dbg_txrx(wil, 1217 wil_dbg_txrx(wil,
1150 "Tx[%3d] : %d bytes, status 0x%02x err 0x%02x\n", 1218 "TxC[%2d][%3d] : %d bytes, status 0x%02x err 0x%02x\n",
1151 vring->swtail, dmalen, d->dma.status, 1219 ringid, vring->swtail, dmalen,
1152 d->dma.error); 1220 d->dma.status, d->dma.error);
1153 wil_hex_dump_txrx("TxC ", DUMP_PREFIX_NONE, 32, 4, 1221 wil_hex_dump_txrx("TxCD ", DUMP_PREFIX_NONE, 32, 4,
1154 (const void *)d, sizeof(*d), false); 1222 (const void *)d, sizeof(*d), false);
1155 1223
1156 wil_txdesc_unmap(dev, d, ctx); 1224 wil_txdesc_unmap(dev, d, ctx);
@@ -1165,8 +1233,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1165 ndev->stats.tx_errors++; 1233 ndev->stats.tx_errors++;
1166 stats->tx_errors++; 1234 stats->tx_errors++;
1167 } 1235 }
1168 1236 wil_consume_skb(skb, d->dma.error == 0);
1169 dev_kfree_skb_any(skb);
1170 } 1237 }
1171 memset(ctx, 0, sizeof(*ctx)); 1238 memset(ctx, 0, sizeof(*ctx));
1172 /* There is no need to touch HW descriptor: 1239 /* There is no need to touch HW descriptor:
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..94611568fc9a 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -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
@@ -49,21 +44,50 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
49 44
50#define WIL6210_MEM_SIZE (2*1024*1024UL) 45#define WIL6210_MEM_SIZE (2*1024*1024UL)
51 46
52#define WIL_RX_RING_SIZE_ORDER_DEFAULT (9) 47#define WIL_TX_Q_LEN_DEFAULT (4000)
53#define WIL_TX_RING_SIZE_ORDER_DEFAULT (9) 48#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10)
49#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10)
54/* limit ring size in range [32..32k] */ 50/* limit ring size in range [32..32k] */
55#define WIL_RING_SIZE_ORDER_MIN (5) 51#define WIL_RING_SIZE_ORDER_MIN (5)
56#define WIL_RING_SIZE_ORDER_MAX (15) 52#define WIL_RING_SIZE_ORDER_MAX (15)
57#define WIL6210_MAX_TX_RINGS (24) /* HW limit */ 53#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
58#define WIL6210_MAX_CID (8) /* HW limit */ 54#define WIL6210_MAX_CID (8) /* HW limit */
59#define WIL6210_NAPI_BUDGET (16) /* arbitrary */ 55#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
56#define WIL_MAX_AMPDU_SIZE (64 * 1024) /* FW/HW limit */
57#define WIL_MAX_AGG_WSIZE (32) /* FW/HW limit */
58/* Hardware offload block adds the following:
59 * 26 bytes - 3-address QoS data header
60 * 8 bytes - IV + EIV (for GCMP)
61 * 8 bytes - SNAP
62 * 16 bytes - MIC (for GCMP)
63 * 4 bytes - CRC
64 */
65#define WIL_MAX_MPDU_OVERHEAD (62)
66
67/* Calculate MAC buffer size for the firmware. It includes all overhead,
68 * as it will go over the air, and need to be 8 byte aligned
69 */
70static inline u32 wil_mtu2macbuf(u32 mtu)
71{
72 return ALIGN(mtu + WIL_MAX_MPDU_OVERHEAD, 8);
73}
74
75/* MTU for Ethernet need to take into account 8-byte SNAP header
76 * to be added when encapsulating Ethernet frame into 802.11
77 */
78#define WIL_MAX_ETH_MTU (IEEE80211_MAX_DATA_LEN_DMG - 8)
60/* Max supported by wil6210 value for interrupt threshold is 5sec. */ 79/* Max supported by wil6210 value for interrupt threshold is 5sec. */
61#define WIL6210_ITR_TRSH_MAX (5000000) 80#define WIL6210_ITR_TRSH_MAX (5000000)
62#define WIL6210_ITR_TRSH_DEFAULT (300) /* usec */ 81#define WIL6210_ITR_TX_INTERFRAME_TIMEOUT_DEFAULT (13) /* usec */
82#define WIL6210_ITR_RX_INTERFRAME_TIMEOUT_DEFAULT (13) /* usec */
83#define WIL6210_ITR_TX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
84#define WIL6210_ITR_RX_MAX_BURST_DURATION_DEFAULT (500) /* usec */
63#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */ 85#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */
64#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000) 86#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)
65#define WIL6210_SCAN_TO msecs_to_jiffies(10000) 87#define WIL6210_SCAN_TO msecs_to_jiffies(10000)
66 88#define WIL6210_RX_HIGH_TRSH_INIT (0)
89#define WIL6210_RX_HIGH_TRSH_DEFAULT \
90 (1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
67/* Hardware definitions begin */ 91/* Hardware definitions begin */
68 92
69/* 93/*
@@ -135,7 +159,7 @@ struct RGF_ICR {
135 #define BIT_DMA_EP_MISC_ICR_TX_NO_ACT BIT(1) 159 #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] */ 160 #define BIT_DMA_EP_MISC_ICR_FW_INT(n) BIT(28+n) /* n = [0..3] */
137 161
138/* Interrupt moderation control */ 162/* Legacy interrupt moderation control (before Sparrow v2)*/
139#define RGF_DMA_ITR_CNT_TRSH (0x881c5c) 163#define RGF_DMA_ITR_CNT_TRSH (0x881c5c)
140#define RGF_DMA_ITR_CNT_DATA (0x881c60) 164#define RGF_DMA_ITR_CNT_DATA (0x881c60)
141#define RGF_DMA_ITR_CNT_CRL (0x881c64) 165#define RGF_DMA_ITR_CNT_CRL (0x881c64)
@@ -145,6 +169,46 @@ struct RGF_ICR {
145 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3) 169 #define BIT_DMA_ITR_CNT_CRL_CLR BIT(3)
146 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4) 170 #define BIT_DMA_ITR_CNT_CRL_REACH_TRSH BIT(4)
147 171
172/* New (sparrow v2+) interrupt moderation control */
173#define RGF_DMA_ITR_TX_DESQ_NO_MOD (0x881d40)
174#define RGF_DMA_ITR_TX_CNT_TRSH (0x881d34)
175#define RGF_DMA_ITR_TX_CNT_DATA (0x881d38)
176#define RGF_DMA_ITR_TX_CNT_CTL (0x881d3c)
177 #define BIT_DMA_ITR_TX_CNT_CTL_EN BIT(0)
178 #define BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL BIT(1)
179 #define BIT_DMA_ITR_TX_CNT_CTL_FOREVER BIT(2)
180 #define BIT_DMA_ITR_TX_CNT_CTL_CLR BIT(3)
181 #define BIT_DMA_ITR_TX_CNT_CTL_REACHED_TRESH BIT(4)
182 #define BIT_DMA_ITR_TX_CNT_CTL_CROSS_EN BIT(5)
183 #define BIT_DMA_ITR_TX_CNT_CTL_FREE_RUNNIG BIT(6)
184#define RGF_DMA_ITR_TX_IDL_CNT_TRSH (0x881d60)
185#define RGF_DMA_ITR_TX_IDL_CNT_DATA (0x881d64)
186#define RGF_DMA_ITR_TX_IDL_CNT_CTL (0x881d68)
187 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EN BIT(0)
188 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL BIT(1)
189 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_FOREVER BIT(2)
190 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR BIT(3)
191 #define BIT_DMA_ITR_TX_IDL_CNT_CTL_REACHED_TRESH BIT(4)
192#define RGF_DMA_ITR_RX_DESQ_NO_MOD (0x881d50)
193#define RGF_DMA_ITR_RX_CNT_TRSH (0x881d44)
194#define RGF_DMA_ITR_RX_CNT_DATA (0x881d48)
195#define RGF_DMA_ITR_RX_CNT_CTL (0x881d4c)
196 #define BIT_DMA_ITR_RX_CNT_CTL_EN BIT(0)
197 #define BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL BIT(1)
198 #define BIT_DMA_ITR_RX_CNT_CTL_FOREVER BIT(2)
199 #define BIT_DMA_ITR_RX_CNT_CTL_CLR BIT(3)
200 #define BIT_DMA_ITR_RX_CNT_CTL_REACHED_TRESH BIT(4)
201 #define BIT_DMA_ITR_RX_CNT_CTL_CROSS_EN BIT(5)
202 #define BIT_DMA_ITR_RX_CNT_CTL_FREE_RUNNIG BIT(6)
203#define RGF_DMA_ITR_RX_IDL_CNT_TRSH (0x881d54)
204#define RGF_DMA_ITR_RX_IDL_CNT_DATA (0x881d58)
205#define RGF_DMA_ITR_RX_IDL_CNT_CTL (0x881d5c)
206 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EN BIT(0)
207 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL BIT(1)
208 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_FOREVER BIT(2)
209 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR BIT(3)
210 #define BIT_DMA_ITR_RX_IDL_CNT_CTL_REACHED_TRESH BIT(4)
211
148#define RGF_DMA_PSEUDO_CAUSE (0x881c68) 212#define RGF_DMA_PSEUDO_CAUSE (0x881c68)
149#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c) 213#define RGF_DMA_PSEUDO_CAUSE_MASK_SW (0x881c6c)
150#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70) 214#define RGF_DMA_PSEUDO_CAUSE_MASK_FW (0x881c70)
@@ -164,6 +228,20 @@ struct RGF_ICR {
164#define RGF_CAF_PLL_LOCK_STATUS (0x88afec) 228#define RGF_CAF_PLL_LOCK_STATUS (0x88afec)
165 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0) 229 #define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
166 230
231#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
232 #define JTAG_DEV_ID_MARLON_B0 (0x0612072f)
233 #define JTAG_DEV_ID_SPARROW_A0 (0x0632072f)
234 #define JTAG_DEV_ID_SPARROW_A1 (0x1632072f)
235 #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
236
237enum {
238 HW_VER_UNKNOWN,
239 HW_VER_MARLON_B0, /* JTAG_DEV_ID_MARLON_B0 */
240 HW_VER_SPARROW_A0, /* JTAG_DEV_ID_SPARROW_A0 */
241 HW_VER_SPARROW_A1, /* JTAG_DEV_ID_SPARROW_A1 */
242 HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
243};
244
167/* popular locations */ 245/* popular locations */
168#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) 246#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
169#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ 247#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
@@ -303,6 +381,11 @@ struct vring {
303struct vring_tx_data { 381struct vring_tx_data {
304 int enabled; 382 int enabled;
305 cycles_t idle, last_idle, begin; 383 cycles_t idle, last_idle, begin;
384 u8 agg_wsize; /* agreed aggregation window, 0 - no agg */
385 u16 agg_timeout;
386 u8 agg_amsdu;
387 bool addba_in_progress; /* if set, agg_xxx is for request in progress */
388 spinlock_t lock;
306}; 389};
307 390
308enum { /* for wil6210_priv.status */ 391enum { /* for wil6210_priv.status */
@@ -313,6 +396,7 @@ enum { /* for wil6210_priv.status */
313 wil_status_reset_done, 396 wil_status_reset_done,
314 wil_status_irqen, /* FIXME: interrupts enabled - for debug */ 397 wil_status_irqen, /* FIXME: interrupts enabled - for debug */
315 wil_status_napi_en, /* NAPI enabled protected by wil->mutex */ 398 wil_status_napi_en, /* NAPI enabled protected by wil->mutex */
399 wil_status_last /* keep last */
316}; 400};
317 401
318struct pci_dev; 402struct pci_dev;
@@ -397,15 +481,46 @@ enum {
397 fw_recovery_running = 2, 481 fw_recovery_running = 2,
398}; 482};
399 483
484enum {
485 hw_capability_reset_v2 = 0,
486 hw_capability_advanced_itr_moderation = 1,
487 hw_capability_last
488};
489
490struct wil_back_rx {
491 struct list_head list;
492 /* request params, converted to CPU byte order - what we asked for */
493 u8 cidxtid;
494 u8 dialog_token;
495 u16 ba_param_set;
496 u16 ba_timeout;
497 u16 ba_seq_ctrl;
498};
499
500struct wil_back_tx {
501 struct list_head list;
502 /* request params, converted to CPU byte order - what we asked for */
503 u8 ringid;
504 u8 agg_wsize;
505 u16 agg_timeout;
506};
507
508struct wil_probe_client_req {
509 struct list_head list;
510 u64 cookie;
511 u8 cid;
512};
513
400struct wil6210_priv { 514struct wil6210_priv {
401 struct pci_dev *pdev; 515 struct pci_dev *pdev;
402 int n_msi; 516 int n_msi;
403 struct wireless_dev *wdev; 517 struct wireless_dev *wdev;
404 void __iomem *csr; 518 void __iomem *csr;
405 ulong status; 519 DECLARE_BITMAP(status, wil_status_last);
406 u32 fw_version; 520 u32 fw_version;
407 u32 hw_version; 521 u32 hw_version;
408 struct wil_board *board; 522 const char *hw_name;
523 DECLARE_BITMAP(hw_capabilities, hw_capability_last);
409 u8 n_mids; /* number of additional MIDs as reported by FW */ 524 u8 n_mids; /* number of additional MIDs as reported by FW */
410 u32 recovery_count; /* num of FW recovery attempts in a short time */ 525 u32 recovery_count; /* num of FW recovery attempts in a short time */
411 u32 recovery_state; /* FW recovery state machine */ 526 u32 recovery_state; /* FW recovery state machine */
@@ -415,7 +530,11 @@ struct wil6210_priv {
415 u32 monitor_flags; 530 u32 monitor_flags;
416 u32 secure_pcp; /* create secure PCP? */ 531 u32 secure_pcp; /* create secure PCP? */
417 int sinfo_gen; 532 int sinfo_gen;
418 u32 itr_trsh; 533 /* interrupt moderation */
534 u32 tx_max_burst_duration;
535 u32 tx_interframe_timeout;
536 u32 rx_max_burst_duration;
537 u32 rx_interframe_timeout;
419 /* cached ISR registers */ 538 /* cached ISR registers */
420 u32 isr_misc; 539 u32 isr_misc;
421 /* mailbox related */ 540 /* mailbox related */
@@ -429,7 +548,7 @@ struct wil6210_priv {
429 u16 reply_size; 548 u16 reply_size;
430 struct workqueue_struct *wmi_wq; /* for deferred calls */ 549 struct workqueue_struct *wmi_wq; /* for deferred calls */
431 struct work_struct wmi_event_worker; 550 struct work_struct wmi_event_worker;
432 struct workqueue_struct *wmi_wq_conn; /* for connect worker */ 551 struct workqueue_struct *wq_service;
433 struct work_struct connect_worker; 552 struct work_struct connect_worker;
434 struct work_struct disconnect_worker; 553 struct work_struct disconnect_worker;
435 struct work_struct fw_error_worker; /* for FW error recovery */ 554 struct work_struct fw_error_worker; /* for FW error recovery */
@@ -445,6 +564,17 @@ struct wil6210_priv {
445 spinlock_t wmi_ev_lock; 564 spinlock_t wmi_ev_lock;
446 struct napi_struct napi_rx; 565 struct napi_struct napi_rx;
447 struct napi_struct napi_tx; 566 struct napi_struct napi_tx;
567 /* BACK */
568 struct list_head back_rx_pending;
569 struct mutex back_rx_mutex; /* protect @back_rx_pending */
570 struct work_struct back_rx_worker;
571 struct list_head back_tx_pending;
572 struct mutex back_tx_mutex; /* protect @back_tx_pending */
573 struct work_struct back_tx_worker;
574 /* keep alive */
575 struct list_head probe_client_pending;
576 struct mutex probe_client_mutex; /* protect @probe_client_pending */
577 struct work_struct probe_client_worker;
448 /* DMA related */ 578 /* DMA related */
449 struct vring vring_rx; 579 struct vring vring_rx;
450 struct vring vring_tx[WIL6210_MAX_TX_RINGS]; 580 struct vring vring_tx[WIL6210_MAX_TX_RINGS];
@@ -529,11 +659,8 @@ void wil_if_remove(struct wil6210_priv *wil);
529int wil_priv_init(struct wil6210_priv *wil); 659int wil_priv_init(struct wil6210_priv *wil);
530void wil_priv_deinit(struct wil6210_priv *wil); 660void wil_priv_deinit(struct wil6210_priv *wil);
531int wil_reset(struct wil6210_priv *wil); 661int wil_reset(struct wil6210_priv *wil);
532void wil_set_itr_trsh(struct wil6210_priv *wil);
533void wil_fw_error_recovery(struct wil6210_priv *wil); 662void wil_fw_error_recovery(struct wil6210_priv *wil);
534void wil_set_recovery_state(struct wil6210_priv *wil, int state); 663void wil_set_recovery_state(struct wil6210_priv *wil, int state);
535void wil_link_on(struct wil6210_priv *wil);
536void wil_link_off(struct wil6210_priv *wil);
537int wil_up(struct wil6210_priv *wil); 664int wil_up(struct wil6210_priv *wil);
538int __wil_up(struct wil6210_priv *wil); 665int __wil_up(struct wil6210_priv *wil);
539int wil_down(struct wil6210_priv *wil); 666int wil_down(struct wil6210_priv *wil);
@@ -567,12 +694,26 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
567int wmi_rxon(struct wil6210_priv *wil, bool on); 694int wmi_rxon(struct wil6210_priv *wil, bool on);
568int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 695int 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); 696int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
697int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
698int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
699int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
700int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
701 u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
702int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
703 u8 dialog_token, __le16 ba_param_set,
704 __le16 ba_timeout, __le16 ba_seq_ctrl);
705void wil_back_rx_worker(struct work_struct *work);
706void wil_back_rx_flush(struct wil6210_priv *wil);
707int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize);
708void wil_back_tx_worker(struct work_struct *work);
709void wil_back_tx_flush(struct wil6210_priv *wil);
570 710
571void wil6210_clear_irq(struct wil6210_priv *wil); 711void wil6210_clear_irq(struct wil6210_priv *wil);
572int wil6210_init_irq(struct wil6210_priv *wil, int irq); 712int wil6210_init_irq(struct wil6210_priv *wil, int irq);
573void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 713void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
574void wil_mask_irq(struct wil6210_priv *wil); 714void wil_mask_irq(struct wil6210_priv *wil);
575void wil_unmask_irq(struct wil6210_priv *wil); 715void wil_unmask_irq(struct wil6210_priv *wil);
716void wil_configure_interrupt_moderation(struct wil6210_priv *wil);
576void wil_disable_irq(struct wil6210_priv *wil); 717void wil_disable_irq(struct wil6210_priv *wil);
577void wil_enable_irq(struct wil6210_priv *wil); 718void wil_enable_irq(struct wil6210_priv *wil);
578int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 719int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
@@ -592,6 +733,8 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan);
592int wmi_pcp_stop(struct wil6210_priv *wil); 733int wmi_pcp_stop(struct wil6210_priv *wil);
593void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 734void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
594 u16 reason_code, bool from_event); 735 u16 reason_code, bool from_event);
736void wil_probe_client_flush(struct wil6210_priv *wil);
737void wil_probe_client_worker(struct work_struct *work);
595 738
596int wil_rx_init(struct wil6210_priv *wil, u16 size); 739int wil_rx_init(struct wil6210_priv *wil, u16 size);
597void wil_rx_fini(struct wil6210_priv *wil); 740void wil_rx_fini(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.c b/drivers/net/wireless/ath/wil6210/wil_platform.c
index 8f1d78f8a74d..976a071ba74e 100644
--- a/drivers/net/wireless/ath/wil6210/wil_platform.c
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.c
@@ -17,10 +17,6 @@
17#include "linux/device.h" 17#include "linux/device.h"
18#include "wil_platform.h" 18#include "wil_platform.h"
19 19
20#ifdef CONFIG_WIL6210_PLATFORM_MSM
21#include "wil_platform_msm.h"
22#endif
23
24/** 20/**
25 * wil_platform_init() - wil6210 platform module init 21 * wil_platform_init() - wil6210 platform module init
26 * 22 *
@@ -37,13 +33,7 @@ void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops)
37 return NULL; 33 return NULL;
38 } 34 }
39 35
40#ifdef CONFIG_WIL6210_PLATFORM_MSM 36 /* platform specific init functions should be called here */
41 handle = wil_platform_msm_init(dev, ops);
42 if (handle)
43 return handle;
44#endif
45
46 /* other platform specific init functions should be called here */
47 37
48 return handle; 38 return handle;
49} 39}
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.c b/drivers/net/wireless/ath/wil6210/wil_platform_msm.c
deleted file mode 100644
index b354a743240d..000000000000
--- a/drivers/net/wireless/ath/wil6210/wil_platform_msm.c
+++ /dev/null
@@ -1,257 +0,0 @@
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/of.h>
18#include <linux/slab.h>
19#include <linux/msm-bus.h>
20
21#include "wil_platform.h"
22#include "wil_platform_msm.h"
23
24/**
25 * struct wil_platform_msm - wil6210 msm platform module info
26 *
27 * @dev: device object
28 * @msm_bus_handle: handle for using msm_bus API
29 * @pdata: bus scale info retrieved from DT
30 */
31struct wil_platform_msm {
32 struct device *dev;
33 uint32_t msm_bus_handle;
34 struct msm_bus_scale_pdata *pdata;
35};
36
37#define KBTOB(a) (a * 1000ULL)
38
39/**
40 * wil_platform_get_pdata() - Generate bus client data from device tree
41 * provided by clients.
42 *
43 * dev: device object
44 * of_node: Device tree node to extract information from
45 *
46 * The function returns a valid pointer to the allocated bus-scale-pdata
47 * if the vectors were correctly read from the client's device node.
48 * Any error in reading or parsing the device node will return NULL
49 * to the caller.
50 */
51static struct msm_bus_scale_pdata *wil_platform_get_pdata(
52 struct device *dev,
53 struct device_node *of_node)
54{
55 struct msm_bus_scale_pdata *pdata;
56 struct msm_bus_paths *usecase;
57 int i, j, ret, len;
58 unsigned int num_usecases, num_paths, mem_size;
59 const uint32_t *vec_arr;
60 struct msm_bus_vectors *vectors;
61
62 /* first read num_usecases and num_paths so we can calculate
63 * amount of memory to allocate
64 */
65 ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases",
66 &num_usecases);
67 if (ret) {
68 dev_err(dev, "Error: num-usecases not found\n");
69 return NULL;
70 }
71
72 ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths",
73 &num_paths);
74 if (ret) {
75 dev_err(dev, "Error: num_paths not found\n");
76 return NULL;
77 }
78
79 /* pdata memory layout:
80 * msm_bus_scale_pdata
81 * msm_bus_paths[num_usecases]
82 * msm_bus_vectors[num_usecases][num_paths]
83 */
84 mem_size = sizeof(struct msm_bus_scale_pdata) +
85 sizeof(struct msm_bus_paths) * num_usecases +
86 sizeof(struct msm_bus_vectors) * num_usecases * num_paths;
87
88 pdata = kzalloc(mem_size, GFP_KERNEL);
89 if (!pdata)
90 return NULL;
91
92 ret = of_property_read_string(of_node, "qcom,msm-bus,name",
93 &pdata->name);
94 if (ret) {
95 dev_err(dev, "Error: Client name not found\n");
96 goto err;
97 }
98
99 if (of_property_read_bool(of_node, "qcom,msm-bus,active-only")) {
100 pdata->active_only = 1;
101 } else {
102 dev_info(dev, "active_only flag absent.\n");
103 dev_info(dev, "Using dual context by default\n");
104 }
105
106 pdata->num_usecases = num_usecases;
107 pdata->usecase = (struct msm_bus_paths *)(pdata + 1);
108
109 vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len);
110 if (vec_arr == NULL) {
111 dev_err(dev, "Error: Vector array not found\n");
112 goto err;
113 }
114
115 if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) {
116 dev_err(dev, "Error: Length-error on getting vectors\n");
117 goto err;
118 }
119
120 vectors = (struct msm_bus_vectors *)(pdata->usecase + num_usecases);
121 for (i = 0; i < num_usecases; i++) {
122 usecase = &pdata->usecase[i];
123 usecase->num_paths = num_paths;
124 usecase->vectors = &vectors[i];
125
126 for (j = 0; j < num_paths; j++) {
127 int index = ((i * num_paths) + j) * 4;
128
129 usecase->vectors[j].src = be32_to_cpu(vec_arr[index]);
130 usecase->vectors[j].dst =
131 be32_to_cpu(vec_arr[index + 1]);
132 usecase->vectors[j].ab = (uint64_t)
133 KBTOB(be32_to_cpu(vec_arr[index + 2]));
134 usecase->vectors[j].ib = (uint64_t)
135 KBTOB(be32_to_cpu(vec_arr[index + 3]));
136 }
137 }
138
139 return pdata;
140
141err:
142 kfree(pdata);
143
144 return NULL;
145}
146
147/* wil_platform API (callbacks) */
148
149static int wil_platform_bus_request(void *handle,
150 uint32_t kbps /* KBytes/Sec */)
151{
152 int rc, i;
153 struct wil_platform_msm *msm = (struct wil_platform_msm *)handle;
154 int vote = 0; /* vote 0 in case requested kbps cannot be satisfied */
155 struct msm_bus_paths *usecase;
156 uint32_t usecase_kbps;
157 uint32_t min_kbps = ~0;
158
159 /* find the lowest usecase that is bigger than requested kbps */
160 for (i = 0; i < msm->pdata->num_usecases; i++) {
161 usecase = &msm->pdata->usecase[i];
162 /* assume we have single path (vectors[0]). If we ever
163 * have multiple paths, need to define the behavior */
164 usecase_kbps = div64_u64(usecase->vectors[0].ib, 1000);
165 if (usecase_kbps >= kbps && usecase_kbps < min_kbps) {
166 min_kbps = usecase_kbps;
167 vote = i;
168 }
169 }
170
171 rc = msm_bus_scale_client_update_request(msm->msm_bus_handle, vote);
172 if (rc)
173 dev_err(msm->dev, "Failed msm_bus voting. kbps=%d vote=%d, rc=%d\n",
174 kbps, vote, rc);
175 else
176 /* TOOD: remove */
177 dev_info(msm->dev, "msm_bus_scale_client_update_request succeeded. kbps=%d vote=%d\n",
178 kbps, vote);
179
180 return rc;
181}
182
183static void wil_platform_uninit(void *handle)
184{
185 struct wil_platform_msm *msm = (struct wil_platform_msm *)handle;
186
187 dev_info(msm->dev, "wil_platform_uninit\n");
188
189 if (msm->msm_bus_handle)
190 msm_bus_scale_unregister_client(msm->msm_bus_handle);
191
192 kfree(msm->pdata);
193 kfree(msm);
194}
195
196static int wil_platform_msm_bus_register(struct wil_platform_msm *msm,
197 struct device_node *node)
198{
199 msm->pdata = wil_platform_get_pdata(msm->dev, node);
200 if (!msm->pdata) {
201 dev_err(msm->dev, "Failed getting DT info\n");
202 return -EINVAL;
203 }
204
205 msm->msm_bus_handle = msm_bus_scale_register_client(msm->pdata);
206 if (!msm->msm_bus_handle) {
207 dev_err(msm->dev, "Failed msm_bus registration\n");
208 return -EINVAL;
209 }
210
211 dev_info(msm->dev, "msm_bus registration succeeded! handle 0x%x\n",
212 msm->msm_bus_handle);
213
214 return 0;
215}
216
217/**
218 * wil_platform_msm_init() - wil6210 msm platform module init
219 *
220 * The function must be called before all other functions in this module.
221 * It returns a handle which is used with the rest of the API
222 *
223 */
224void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops)
225{
226 struct device_node *of_node;
227 struct wil_platform_msm *msm;
228 int rc;
229
230 of_node = of_find_compatible_node(NULL, NULL, "qcom,wil6210");
231 if (!of_node) {
232 /* this could mean non-msm platform */
233 dev_err(dev, "DT node not found\n");
234 return NULL;
235 }
236
237 msm = kzalloc(sizeof(*msm), GFP_KERNEL);
238 if (!msm)
239 return NULL;
240
241 msm->dev = dev;
242
243 /* register with msm_bus module for scaling requests */
244 rc = wil_platform_msm_bus_register(msm, of_node);
245 if (rc)
246 goto cleanup;
247
248 memset(ops, 0, sizeof(*ops));
249 ops->bus_request = wil_platform_bus_request;
250 ops->uninit = wil_platform_uninit;
251
252 return (void *)msm;
253
254cleanup:
255 kfree(msm);
256 return NULL;
257}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 63476c86cd0e..0f3e4334c8e3 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 }
@@ -457,13 +462,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
457 if (assoc_req_ie) { 462 if (assoc_req_ie) {
458 sinfo.assoc_req_ies = assoc_req_ie; 463 sinfo.assoc_req_ies = assoc_req_ie;
459 sinfo.assoc_req_ies_len = assoc_req_ielen; 464 sinfo.assoc_req_ies_len = assoc_req_ielen;
460 sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
461 } 465 }
462 466
463 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL); 467 cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
464 } 468 }
465 clear_bit(wil_status_fwconnecting, &wil->status); 469 clear_bit(wil_status_fwconnecting, wil->status);
466 set_bit(wil_status_fwconnected, &wil->status); 470 set_bit(wil_status_fwconnected, wil->status);
467 471
468 /* FIXME FW can transmit only ucast frames to peer */ 472 /* FIXME FW can transmit only ucast frames to peer */
469 /* FIXME real ring_id instead of hard coded 0 */ 473 /* FIXME real ring_id instead of hard coded 0 */
@@ -471,7 +475,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
471 wil->sta[evt->cid].status = wil_sta_conn_pending; 475 wil->sta[evt->cid].status = wil_sta_conn_pending;
472 476
473 wil->pending_connect_cid = evt->cid; 477 wil->pending_connect_cid = evt->cid;
474 queue_work(wil->wmi_wq_conn, &wil->connect_worker); 478 queue_work(wil->wq_service, &wil->connect_worker);
475} 479}
476 480
477static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 481static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
@@ -544,9 +548,24 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
544 } 548 }
545} 549}
546 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
547static 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)
548{ 568{
549 struct net_device *ndev = wil_to_ndev(wil);
550 struct wmi_data_port_open_event *evt = d; 569 struct wmi_data_port_open_event *evt = d;
551 u8 cid = evt->cid; 570 u8 cid = evt->cid;
552 571
@@ -558,7 +577,8 @@ static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
558 } 577 }
559 578
560 wil->sta[cid].data_port_open = true; 579 wil->sta[cid].data_port_open = true;
561 netif_carrier_on(ndev); 580 if (agg_wsize >= 0)
581 wil_addba_tx_cid(wil, cid, agg_wsize);
562} 582}
563 583
564static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len) 584static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len)
@@ -583,55 +603,89 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
583 int len) 603 int len)
584{ 604{
585 struct wmi_vring_ba_status_event *evt = d; 605 struct wmi_vring_ba_status_event *evt = d;
586 struct wil_sta_info *sta; 606 struct vring_tx_data *txdata;
587 uint i, cid;
588 607
589 /* TODO: use Rx BA status, not Tx one */ 608 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d AMSDU%s\n",
590
591 wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
592 evt->ringid, 609 evt->ringid,
593 evt->status == WMI_BA_AGREED ? "OK" : "N/A", 610 evt->status == WMI_BA_AGREED ? "OK" : "N/A",
594 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout)); 611 evt->agg_wsize, __le16_to_cpu(evt->ba_timeout),
612 evt->amsdu ? "+" : "-");
595 613
596 if (evt->ringid >= WIL6210_MAX_TX_RINGS) { 614 if (evt->ringid >= WIL6210_MAX_TX_RINGS) {
597 wil_err(wil, "invalid ring id %d\n", evt->ringid); 615 wil_err(wil, "invalid ring id %d\n", evt->ringid);
598 return; 616 return;
599 } 617 }
600 618
601 mutex_lock(&wil->mutex); 619 if (evt->status != WMI_BA_AGREED) {
602 620 evt->ba_timeout = 0;
603 cid = wil->vring2cid_tid[evt->ringid][0]; 621 evt->agg_wsize = 0;
604 if (cid >= WIL6210_MAX_CID) { 622 evt->amsdu = 0;
605 wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
606 goto out;
607 } 623 }
608 624
609 sta = &wil->sta[cid]; 625 txdata = &wil->vring_tx_data[evt->ringid];
610 if (sta->status == wil_sta_unused) {
611 wil_err(wil, "CID %d unused\n", cid);
612 goto out;
613 }
614 626
615 wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); 627 txdata->agg_timeout = le16_to_cpu(evt->ba_timeout);
616 for (i = 0; i < WIL_STA_TID_NUM; i++) { 628 txdata->agg_wsize = evt->agg_wsize;
617 struct wil_tid_ampdu_rx *r; 629 txdata->agg_amsdu = evt->amsdu;
618 unsigned long flags; 630 txdata->addba_in_progress = false;
631}
619 632
620 spin_lock_irqsave(&sta->tid_rx_lock, flags); 633static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d,
634 int len)
635{
636 struct wmi_rcp_addba_req_event *evt = d;
621 637
622 r = sta->tid_rx[i]; 638 wil_addba_rx_request(wil, evt->cidxtid, evt->dialog_token,
623 sta->tid_rx[i] = NULL; 639 evt->ba_param_set, evt->ba_timeout,
624 wil_tid_ampdu_rx_free(wil, r); 640 evt->ba_seq_ctrl);
641}
625 642
626 spin_unlock_irqrestore(&sta->tid_rx_lock, flags); 643static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len)
644__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
645{
646 struct wmi_delba_event *evt = d;
647 u8 cid, tid;
648 u16 reason = __le16_to_cpu(evt->reason);
649 struct wil_sta_info *sta;
650 struct wil_tid_ampdu_rx *r;
627 651
628 if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) 652 might_sleep();
629 sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, 653 parse_cidxtid(evt->cidxtid, &cid, &tid);
630 evt->agg_wsize, 0); 654 wil_dbg_wmi(wil, "DELBA CID %d TID %d from %s reason %d\n",
655 cid, tid,
656 evt->from_initiator ? "originator" : "recipient",
657 reason);
658 if (!evt->from_initiator) {
659 int i;
660 /* find Tx vring it belongs to */
661 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) {
662 if ((wil->vring2cid_tid[i][0] == cid) &&
663 (wil->vring2cid_tid[i][1] == tid)) {
664 struct vring_tx_data *txdata =
665 &wil->vring_tx_data[i];
666
667 wil_dbg_wmi(wil, "DELBA Tx vring %d\n", i);
668 txdata->agg_timeout = 0;
669 txdata->agg_wsize = 0;
670 txdata->addba_in_progress = false;
671
672 break; /* max. 1 matching ring */
673 }
674 }
675 if (i >= ARRAY_SIZE(wil->vring2cid_tid))
676 wil_err(wil, "DELBA: unable to find Tx vring\n");
677 return;
631 } 678 }
632 679
633out: 680 sta = &wil->sta[cid];
634 mutex_unlock(&wil->mutex); 681
682 spin_lock_bh(&sta->tid_rx_lock);
683
684 r = sta->tid_rx[tid];
685 sta->tid_rx[tid] = NULL;
686 wil_tid_ampdu_rx_free(wil, r);
687
688 spin_unlock_bh(&sta->tid_rx_lock);
635} 689}
636 690
637static const struct { 691static const struct {
@@ -649,6 +703,8 @@ static const struct {
649 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup}, 703 {WMI_DATA_PORT_OPEN_EVENTID, wmi_evt_linkup},
650 {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown}, 704 {WMI_WBE_LINKDOWN_EVENTID, wmi_evt_linkdown},
651 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status}, 705 {WMI_BA_STATUS_EVENTID, wmi_evt_ba_status},
706 {WMI_RCP_ADDBA_REQ_EVENTID, wmi_evt_addba_rx_req},
707 {WMI_DELBA_EVENTID, wmi_evt_delba},
652}; 708};
653 709
654/* 710/*
@@ -668,7 +724,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
668 ulong flags; 724 ulong flags;
669 unsigned n; 725 unsigned n;
670 726
671 if (!test_bit(wil_status_reset_done, &wil->status)) { 727 if (!test_bit(wil_status_reset_done, wil->status)) {
672 wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); 728 wil_err(wil, "Reset in progress. Cannot handle WMI event\n");
673 return; 729 return;
674 } 730 }
@@ -1025,13 +1081,14 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1025 struct wmi_cfg_rx_chain_cmd cmd = { 1081 struct wmi_cfg_rx_chain_cmd cmd = {
1026 .action = WMI_RX_CHAIN_ADD, 1082 .action = WMI_RX_CHAIN_ADD,
1027 .rx_sw_ring = { 1083 .rx_sw_ring = {
1028 .max_mpdu_size = cpu_to_le16(mtu_max + ETH_HLEN), 1084 .max_mpdu_size = cpu_to_le16(wil_mtu2macbuf(mtu_max)),
1029 .ring_mem_base = cpu_to_le64(vring->pa), 1085 .ring_mem_base = cpu_to_le64(vring->pa),
1030 .ring_size = cpu_to_le16(vring->size), 1086 .ring_size = cpu_to_le16(vring->size),
1031 }, 1087 },
1032 .mid = 0, /* TODO - what is it? */ 1088 .mid = 0, /* TODO - what is it? */
1033 .decap_trans_type = WMI_DECAP_TYPE_802_3, 1089 .decap_trans_type = WMI_DECAP_TYPE_802_3,
1034 .reorder_type = WMI_RX_SW_REORDER, 1090 .reorder_type = WMI_RX_SW_REORDER,
1091 .host_thrsh = cpu_to_le16(rx_ring_overflow_thrsh),
1035 }; 1092 };
1036 struct { 1093 struct {
1037 struct wil6210_mbox_hdr_wmi wmi; 1094 struct wil6210_mbox_hdr_wmi wmi;
@@ -1074,12 +1131,13 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1074 return rc; 1131 return rc;
1075} 1132}
1076 1133
1077int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r) 1134int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
1078{ 1135{
1079 int rc; 1136 int rc;
1080 struct wmi_temp_sense_cmd cmd = { 1137 struct wmi_temp_sense_cmd cmd = {
1081 .measure_marlon_m_en = cpu_to_le32(!!t_m), 1138 .measure_baseband_en = cpu_to_le32(!!t_bb),
1082 .measure_marlon_r_en = cpu_to_le32(!!t_r), 1139 .measure_rf_en = cpu_to_le32(!!t_rf),
1140 .measure_mode = cpu_to_le32(TEMPERATURE_MEASURE_NOW),
1083 }; 1141 };
1084 struct { 1142 struct {
1085 struct wil6210_mbox_hdr_wmi wmi; 1143 struct wil6210_mbox_hdr_wmi wmi;
@@ -1091,10 +1149,10 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
1091 if (rc) 1149 if (rc)
1092 return rc; 1150 return rc;
1093 1151
1094 if (t_m) 1152 if (t_bb)
1095 *t_m = le32_to_cpu(reply.evt.marlon_m_t1000); 1153 *t_bb = le32_to_cpu(reply.evt.baseband_t1000);
1096 if (t_r) 1154 if (t_rf)
1097 *t_r = le32_to_cpu(reply.evt.marlon_r_t1000); 1155 *t_rf = le32_to_cpu(reply.evt.rf_t1000);
1098 1156
1099 return 0; 1157 return 0;
1100} 1158}
@@ -1111,6 +1169,87 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1111 return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd)); 1169 return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd));
1112} 1170}
1113 1171
1172int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout)
1173{
1174 struct wmi_vring_ba_en_cmd cmd = {
1175 .ringid = ringid,
1176 .agg_max_wsize = size,
1177 .ba_timeout = cpu_to_le16(timeout),
1178 .amsdu = 0,
1179 };
1180
1181 wil_dbg_wmi(wil, "%s(ring %d size %d timeout %d)\n", __func__,
1182 ringid, size, timeout);
1183
1184 return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd));
1185}
1186
1187int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason)
1188{
1189 struct wmi_vring_ba_dis_cmd cmd = {
1190 .ringid = ringid,
1191 .reason = cpu_to_le16(reason),
1192 };
1193
1194 wil_dbg_wmi(wil, "%s(ring %d reason %d)\n", __func__,
1195 ringid, reason);
1196
1197 return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd));
1198}
1199
1200int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason)
1201{
1202 struct wmi_rcp_delba_cmd cmd = {
1203 .cidxtid = cidxtid,
1204 .reason = cpu_to_le16(reason),
1205 };
1206
1207 wil_dbg_wmi(wil, "%s(CID %d TID %d reason %d)\n", __func__,
1208 cidxtid & 0xf, (cidxtid >> 4) & 0xf, reason);
1209
1210 return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd));
1211}
1212
1213int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
1214 u16 status, bool amsdu, u16 agg_wsize, u16 timeout)
1215{
1216 int rc;
1217 struct wmi_rcp_addba_resp_cmd cmd = {
1218 .cidxtid = mk_cidxtid(cid, tid),
1219 .dialog_token = token,
1220 .status_code = cpu_to_le16(status),
1221 /* bit 0: A-MSDU supported
1222 * bit 1: policy (should be 0 for us)
1223 * bits 2..5: TID
1224 * bits 6..15: buffer size
1225 */
1226 .ba_param_set = cpu_to_le16((amsdu ? 1 : 0) | (tid << 2) |
1227 (agg_wsize << 6)),
1228 .ba_timeout = cpu_to_le16(timeout),
1229 };
1230 struct {
1231 struct wil6210_mbox_hdr_wmi wmi;
1232 struct wmi_rcp_addba_resp_sent_event evt;
1233 } __packed reply;
1234
1235 wil_dbg_wmi(wil,
1236 "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s\n",
1237 cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-");
1238
1239 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, &cmd, sizeof(cmd),
1240 WMI_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), 100);
1241 if (rc)
1242 return rc;
1243
1244 if (reply.evt.status) {
1245 wil_err(wil, "ADDBA response failed with status %d\n",
1246 le16_to_cpu(reply.evt.status));
1247 rc = -EINVAL;
1248 }
1249
1250 return rc;
1251}
1252
1114void wmi_event_flush(struct wil6210_priv *wil) 1253void wmi_event_flush(struct wil6210_priv *wil)
1115{ 1254{
1116 struct pending_wmi_event *evt, *t; 1255 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..8a4af613e191 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -29,8 +29,10 @@
29 29
30/* General */ 30/* General */
31#define WILOCITY_MAX_ASSOC_STA (8) 31#define WILOCITY_MAX_ASSOC_STA (8)
32#define WILOCITY_DEFAULT_ASSOC_STA (1)
32#define WMI_MAC_LEN (6) 33#define WMI_MAC_LEN (6)
33#define WMI_PROX_RANGE_NUM (3) 34#define WMI_PROX_RANGE_NUM (3)
35#define WMI_MAX_LOSS_DMG_BEACONS (32)
34 36
35/* List of Commands */ 37/* List of Commands */
36enum wmi_command_id { 38enum wmi_command_id {
@@ -48,7 +50,7 @@ enum wmi_command_id {
48 WMI_SET_WSC_STATUS_CMDID = 0x0041, 50 WMI_SET_WSC_STATUS_CMDID = 0x0041,
49 WMI_PXMT_RANGE_CFG_CMDID = 0x0042, 51 WMI_PXMT_RANGE_CFG_CMDID = 0x0042,
50 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043, 52 WMI_PXMT_SNR2_RANGE_CFG_CMDID = 0x0043,
51 WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300, 53/* WMI_FAST_MEM_ACC_MODE_CMDID = 0x0300, */
52 WMI_MEM_READ_CMDID = 0x0800, 54 WMI_MEM_READ_CMDID = 0x0800,
53 WMI_MEM_WR_CMDID = 0x0801, 55 WMI_MEM_WR_CMDID = 0x0801,
54 WMI_ECHO_CMDID = 0x0803, 56 WMI_ECHO_CMDID = 0x0803,
@@ -102,6 +104,8 @@ enum wmi_command_id {
102 WMI_MAINTAIN_RESUME_CMDID = 0x0851, 104 WMI_MAINTAIN_RESUME_CMDID = 0x0851,
103 WMI_RS_MGMT_CMDID = 0x0852, 105 WMI_RS_MGMT_CMDID = 0x0852,
104 WMI_RF_MGMT_CMDID = 0x0853, 106 WMI_RF_MGMT_CMDID = 0x0853,
107 WMI_THERMAL_THROTTLING_CTRL_CMDID = 0x0854,
108 WMI_THERMAL_THROTTLING_GET_STATUS_CMDID = 0x0855,
105 /* Performance monitoring commands */ 109 /* Performance monitoring commands */
106 WMI_BF_CTRL_CMDID = 0x0862, 110 WMI_BF_CTRL_CMDID = 0x0862,
107 WMI_NOTIFY_REQ_CMDID = 0x0863, 111 WMI_NOTIFY_REQ_CMDID = 0x0863,
@@ -136,6 +140,7 @@ enum wmi_command_id {
136 WMI_EAPOL_TX_CMDID = 0xf04c, 140 WMI_EAPOL_TX_CMDID = 0xf04c,
137 WMI_MAC_ADDR_REQ_CMDID = 0xf04d, 141 WMI_MAC_ADDR_REQ_CMDID = 0xf04d,
138 WMI_FW_VER_CMDID = 0xf04e, 142 WMI_FW_VER_CMDID = 0xf04e,
143 WMI_PMC_CMDID = 0xf04f,
139}; 144};
140 145
141/* 146/*
@@ -283,8 +288,8 @@ enum wmi_scan_type {
283 WMI_LONG_SCAN = 0, 288 WMI_LONG_SCAN = 0,
284 WMI_SHORT_SCAN = 1, 289 WMI_SHORT_SCAN = 1,
285 WMI_PBC_SCAN = 2, 290 WMI_PBC_SCAN = 2,
286 WMI_ACTIVE_SCAN = 3, 291 WMI_DIRECT_SCAN = 3,
287 WMI_DIRECT_SCAN = 4, 292 WMI_ACTIVE_SCAN = 4,
288}; 293};
289 294
290struct wmi_start_scan_cmd { 295struct wmi_start_scan_cmd {
@@ -375,6 +380,17 @@ struct wmi_rf_mgmt_cmd {
375} __packed; 380} __packed;
376 381
377/* 382/*
383 * WMI_THERMAL_THROTTLING_CTRL_CMDID
384 */
385#define THERMAL_THROTTLING_USE_DEFAULT_MAX_TXOP_LENGTH (0xFFFFFFFF)
386
387struct wmi_thermal_throttling_ctrl_cmd {
388 __le32 time_on_usec;
389 __le32 time_off_usec;
390 __le32 max_txop_length_usec;
391} __packed;
392
393/*
378 * WMI_RF_RX_TEST_CMDID 394 * WMI_RF_RX_TEST_CMDID
379 */ 395 */
380struct wmi_rf_rx_test_cmd { 396struct wmi_rf_rx_test_cmd {
@@ -586,6 +602,7 @@ struct wmi_vring_ba_en_cmd {
586 u8 ringid; 602 u8 ringid;
587 u8 agg_max_wsize; 603 u8 agg_max_wsize;
588 __le16 ba_timeout; 604 __le16 ba_timeout;
605 u8 amsdu;
589} __packed; 606} __packed;
590 607
591/* 608/*
@@ -647,6 +664,7 @@ enum wmi_cfg_rx_chain_cmd_action {
647enum wmi_cfg_rx_chain_cmd_decap_trans_type { 664enum wmi_cfg_rx_chain_cmd_decap_trans_type {
648 WMI_DECAP_TYPE_802_3 = 0, 665 WMI_DECAP_TYPE_802_3 = 0,
649 WMI_DECAP_TYPE_NATIVE_WIFI = 1, 666 WMI_DECAP_TYPE_NATIVE_WIFI = 1,
667 WMI_DECAP_TYPE_NONE = 2,
650}; 668};
651 669
652enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type { 670enum wmi_cfg_rx_chain_cmd_nwifi_ds_trans_type {
@@ -784,9 +802,17 @@ struct wmi_echo_cmd {
784 * 802 *
785 * Measure MAC and radio temperatures 803 * Measure MAC and radio temperatures
786 */ 804 */
805
806/* Possible modes for temperature measurement */
807enum wmi_temperature_measure_mode {
808 TEMPERATURE_USE_OLD_VALUE = 0x1,
809 TEMPERATURE_MEASURE_NOW = 0x2,
810};
811
787struct wmi_temp_sense_cmd { 812struct wmi_temp_sense_cmd {
788 __le32 measure_marlon_m_en; 813 __le32 measure_baseband_en;
789 __le32 measure_marlon_r_en; 814 __le32 measure_rf_en;
815 __le32 measure_mode;
790} __packed; 816} __packed;
791 817
792/* 818/*
@@ -842,6 +868,7 @@ enum wmi_event_id {
842 WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839, 868 WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
843 WMI_RS_MGMT_DONE_EVENTID = 0x1852, 869 WMI_RS_MGMT_DONE_EVENTID = 0x1852,
844 WMI_RF_MGMT_STATUS_EVENTID = 0x1853, 870 WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
871 WMI_THERMAL_THROTTLING_STATUS_EVENTID = 0x1855,
845 WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838, 872 WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
846 WMI_RX_MGMT_PACKET_EVENTID = 0x1840, 873 WMI_RX_MGMT_PACKET_EVENTID = 0x1840,
847 WMI_TX_MGMT_PACKET_EVENTID = 0x1841, 874 WMI_TX_MGMT_PACKET_EVENTID = 0x1841,
@@ -858,6 +885,7 @@ enum wmi_event_id {
858 WMI_FLASH_READ_DONE_EVENTID = 0x1902, 885 WMI_FLASH_READ_DONE_EVENTID = 0x1902,
859 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903, 886 WMI_FLASH_WRITE_DONE_EVENTID = 0x1903,
860 /*P2P*/ 887 /*P2P*/
888 WMI_P2P_CFG_DONE_EVENTID = 0x1910,
861 WMI_PORT_ALLOCATED_EVENTID = 0x1911, 889 WMI_PORT_ALLOCATED_EVENTID = 0x1911,
862 WMI_PORT_DELETED_EVENTID = 0x1912, 890 WMI_PORT_DELETED_EVENTID = 0x1912,
863 WMI_LISTEN_STARTED_EVENTID = 0x1914, 891 WMI_LISTEN_STARTED_EVENTID = 0x1914,
@@ -898,6 +926,15 @@ struct wmi_rf_mgmt_status_event {
898} __packed; 926} __packed;
899 927
900/* 928/*
929 * WMI_THERMAL_THROTTLING_STATUS_EVENTID
930 */
931struct wmi_thermal_throttling_status_event {
932 __le32 time_on_usec;
933 __le32 time_off_usec;
934 __le32 max_txop_length_usec;
935} __packed;
936
937/*
901 * WMI_GET_STATUS_DONE_EVENTID 938 * WMI_GET_STATUS_DONE_EVENTID
902 */ 939 */
903struct wmi_get_status_done_event { 940struct wmi_get_status_done_event {
@@ -1052,14 +1089,23 @@ struct wmi_scan_complete_event {
1052enum wmi_vring_ba_status { 1089enum wmi_vring_ba_status {
1053 WMI_BA_AGREED = 0, 1090 WMI_BA_AGREED = 0,
1054 WMI_BA_NON_AGREED = 1, 1091 WMI_BA_NON_AGREED = 1,
1092 /* BA_EN in middle of teardown flow */
1093 WMI_BA_TD_WIP = 2,
1094 /* BA_DIS or BA_EN in middle of BA SETUP flow */
1095 WMI_BA_SETUP_WIP = 3,
1096 /* BA_EN when the BA session is already active */
1097 WMI_BA_SESSION_ACTIVE = 4,
1098 /* BA_DIS when the BA session is not active */
1099 WMI_BA_SESSION_NOT_ACTIVE = 5,
1055}; 1100};
1056 1101
1057struct wmi_vring_ba_status_event { 1102struct wmi_vring_ba_status_event {
1058 __le16 status; 1103 __le16 status; /* enum wmi_vring_ba_status */
1059 u8 reserved[2]; 1104 u8 reserved[2];
1060 u8 ringid; 1105 u8 ringid;
1061 u8 agg_wsize; 1106 u8 agg_wsize;
1062 __le16 ba_timeout; 1107 __le16 ba_timeout;
1108 u8 amsdu;
1063} __packed; 1109} __packed;
1064 1110
1065/* 1111/*
@@ -1145,6 +1191,14 @@ struct wmi_get_pcp_channel_event {
1145} __packed; 1191} __packed;
1146 1192
1147/* 1193/*
1194 * WMI_P2P_CFG_DONE_EVENTID
1195 */
1196struct wmi_p2p_cfg_done_event {
1197 u8 status; /* wmi_fw_status */
1198 u8 reserved[3];
1199} __packed;
1200
1201/*
1148* WMI_PORT_ALLOCATED_EVENTID 1202* WMI_PORT_ALLOCATED_EVENTID
1149*/ 1203*/
1150struct wmi_port_allocated_event { 1204struct wmi_port_allocated_event {
@@ -1272,8 +1326,8 @@ struct wmi_echo_event {
1272 * Measure MAC and radio temperatures 1326 * Measure MAC and radio temperatures
1273 */ 1327 */
1274struct wmi_temp_sense_done_event { 1328struct wmi_temp_sense_done_event {
1275 __le32 marlon_m_t1000; 1329 __le32 baseband_t1000;
1276 __le32 marlon_r_t1000; 1330 __le32 rf_t1000;
1277} __packed; 1331} __packed;
1278 1332
1279#endif /* __WILOCITY_WMI_H__ */ 1333#endif /* __WILOCITY_WMI_H__ */
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/Kconfig b/drivers/net/wireless/b43/Kconfig
index 64a5b672e30a..759fb8d41fc9 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -166,6 +166,15 @@ config B43_PHY_LCN
166 166
167 Say N, this is BROKEN and crashes driver. 167 Say N, this is BROKEN and crashes driver.
168 168
169config B43_PHY_AC
170 bool "Support for AC-PHY (802.11ac) devices (BROKEN)"
171 depends on B43 && B43_BCMA && BROKEN
172 ---help---
173 This PHY type can be found in the following chipsets:
174 PCI: BCM4352, BCM4360
175
176 Say N, this is BROKEN and crashes driver.
177
169# This config option automatically enables b43 LEDS support, 178# This config option automatically enables b43 LEDS support,
170# if it's possible. 179# if it's possible.
171config B43_LEDS 180config B43_LEDS
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 9f7965aae93d..c624d4d90e4f 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -13,6 +13,7 @@ b43-$(CONFIG_B43_PHY_HT) += phy_ht.o
13b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o 13b43-$(CONFIG_B43_PHY_HT) += tables_phy_ht.o
14b43-$(CONFIG_B43_PHY_HT) += radio_2059.o 14b43-$(CONFIG_B43_PHY_HT) += radio_2059.o
15b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o 15b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o
16b43-$(CONFIG_B43_PHY_AC) += phy_ac.o
16b43-y += sysfs.o 17b43-y += sysfs.o
17b43-y += xmit.o 18b43-y += xmit.o
18b43-y += dma.o 19b43-y += dma.o
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index bb12586cd7cd..036552439816 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -500,6 +500,8 @@ enum {
500#define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */ 500#define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */
501#define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */ 501#define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */
502#define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */ 502#define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */
503#define B43_BCMA_IOCTL_PHY_BW_80MHZ 0x000000C0 /* 80 MHz bandwidth */
504#define B43_BCMA_IOCTL_DAC 0x00000300 /* Highspeed DAC mode control field */
503#define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */ 505#define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */
504 506
505/* BCMA 802.11 core specific IO status (BCMA_IOST) flags */ 507/* BCMA 802.11 core specific IO status (BCMA_IOST) flags */
@@ -941,6 +943,7 @@ struct b43_wl {
941 bool beacon1_uploaded; 943 bool beacon1_uploaded;
942 bool beacon_templates_virgin; /* Never wrote the templates? */ 944 bool beacon_templates_virgin; /* Never wrote the templates? */
943 struct work_struct beacon_update_trigger; 945 struct work_struct beacon_update_trigger;
946 spinlock_t beacon_lock;
944 947
945 /* The current QOS parameters for the 4 queues. */ 948 /* The current QOS parameters for the 4 queues. */
946 struct b43_qos_params qos_params[B43_QOS_QUEUE_NUM]; 949 struct b43_qos_params qos_params[B43_QOS_QUEUE_NUM];
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 47731cb0d815..2c9088633ec6 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1262,6 +1262,23 @@ static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1262 flags |= B43_BCMA_IOCTL_GMODE; 1262 flags |= B43_BCMA_IOCTL_GMODE;
1263 b43_device_enable(dev, flags); 1263 b43_device_enable(dev, flags);
1264 1264
1265 if (dev->phy.type == B43_PHYTYPE_AC) {
1266 u16 tmp;
1267
1268 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1269 tmp &= ~B43_BCMA_IOCTL_DAC;
1270 tmp |= 0x100;
1271 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1272
1273 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1274 tmp &= ~B43_BCMA_IOCTL_PHY_CLKEN;
1275 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1276
1277 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1278 tmp |= B43_BCMA_IOCTL_PHY_CLKEN;
1279 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1280 }
1281
1265 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); 1282 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
1266 b43_bcma_phy_reset(dev); 1283 b43_bcma_phy_reset(dev);
1267 bcma_core_pll_ctl(dev->dev->bdev, req, status, true); 1284 bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
@@ -1601,12 +1618,26 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1601 unsigned int rate; 1618 unsigned int rate;
1602 u16 ctl; 1619 u16 ctl;
1603 int antenna; 1620 int antenna;
1604 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); 1621 struct ieee80211_tx_info *info;
1622 unsigned long flags;
1623 struct sk_buff *beacon_skb;
1605 1624
1606 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); 1625 spin_lock_irqsave(&dev->wl->beacon_lock, flags);
1607 len = min_t(size_t, dev->wl->current_beacon->len, 1626 info = IEEE80211_SKB_CB(dev->wl->current_beacon);
1608 0x200 - sizeof(struct b43_plcp_hdr6));
1609 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; 1627 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
1628 /* Clone the beacon, so it cannot go away, while we write it to hw. */
1629 beacon_skb = skb_clone(dev->wl->current_beacon, GFP_ATOMIC);
1630 spin_unlock_irqrestore(&dev->wl->beacon_lock, flags);
1631
1632 if (!beacon_skb) {
1633 b43dbg(dev->wl, "Could not upload beacon. "
1634 "Failed to clone beacon skb.");
1635 return;
1636 }
1637
1638 bcn = (const struct ieee80211_mgmt *)(beacon_skb->data);
1639 len = min_t(size_t, beacon_skb->len,
1640 0x200 - sizeof(struct b43_plcp_hdr6));
1610 1641
1611 b43_write_template_common(dev, (const u8 *)bcn, 1642 b43_write_template_common(dev, (const u8 *)bcn,
1612 len, ram_offset, shm_size_offset, rate); 1643 len, ram_offset, shm_size_offset, rate);
@@ -1674,6 +1705,8 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1674 B43_SHM_SH_DTIMPER, 0); 1705 B43_SHM_SH_DTIMPER, 0);
1675 } 1706 }
1676 b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset); 1707 b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
1708
1709 dev_kfree_skb_any(beacon_skb);
1677} 1710}
1678 1711
1679static void b43_upload_beacon0(struct b43_wldev *dev) 1712static void b43_upload_beacon0(struct b43_wldev *dev)
@@ -1790,13 +1823,13 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1790 mutex_unlock(&wl->mutex); 1823 mutex_unlock(&wl->mutex);
1791} 1824}
1792 1825
1793/* Asynchronously update the packet templates in template RAM. 1826/* Asynchronously update the packet templates in template RAM. */
1794 * Locking: Requires wl->mutex to be locked. */
1795static void b43_update_templates(struct b43_wl *wl) 1827static void b43_update_templates(struct b43_wl *wl)
1796{ 1828{
1797 struct sk_buff *beacon; 1829 struct sk_buff *beacon, *old_beacon;
1830 unsigned long flags;
1798 1831
1799 /* This is the top half of the ansynchronous beacon update. 1832 /* This is the top half of the asynchronous beacon update.
1800 * The bottom half is the beacon IRQ. 1833 * The bottom half is the beacon IRQ.
1801 * Beacon update must be asynchronous to avoid sending an 1834 * Beacon update must be asynchronous to avoid sending an
1802 * invalid beacon. This can happen for example, if the firmware 1835 * invalid beacon. This can happen for example, if the firmware
@@ -1810,12 +1843,17 @@ static void b43_update_templates(struct b43_wl *wl)
1810 if (unlikely(!beacon)) 1843 if (unlikely(!beacon))
1811 return; 1844 return;
1812 1845
1813 if (wl->current_beacon) 1846 spin_lock_irqsave(&wl->beacon_lock, flags);
1814 dev_kfree_skb_any(wl->current_beacon); 1847 old_beacon = wl->current_beacon;
1815 wl->current_beacon = beacon; 1848 wl->current_beacon = beacon;
1816 wl->beacon0_uploaded = false; 1849 wl->beacon0_uploaded = false;
1817 wl->beacon1_uploaded = false; 1850 wl->beacon1_uploaded = false;
1851 spin_unlock_irqrestore(&wl->beacon_lock, flags);
1852
1818 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); 1853 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
1854
1855 if (old_beacon)
1856 dev_kfree_skb_any(old_beacon);
1819} 1857}
1820 1858
1821static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) 1859static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
@@ -4318,6 +4356,7 @@ redo:
4318 mutex_unlock(&wl->mutex); 4356 mutex_unlock(&wl->mutex);
4319 cancel_delayed_work_sync(&dev->periodic_work); 4357 cancel_delayed_work_sync(&dev->periodic_work);
4320 cancel_work_sync(&wl->tx_work); 4358 cancel_work_sync(&wl->tx_work);
4359 b43_leds_stop(dev);
4321 mutex_lock(&wl->mutex); 4360 mutex_lock(&wl->mutex);
4322 dev = wl->current_dev; 4361 dev = wl->current_dev;
4323 if (!dev || b43_status(dev) < B43_STAT_STARTED) { 4362 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -4505,6 +4544,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4505 unsupported = 1; 4544 unsupported = 1;
4506 break; 4545 break;
4507#endif 4546#endif
4547#ifdef CONFIG_B43_PHY_AC
4548 case B43_PHYTYPE_AC:
4549 if (phy_rev > 1)
4550 unsupported = 1;
4551 break;
4552#endif
4508 default: 4553 default:
4509 unsupported = 1; 4554 unsupported = 1;
4510 } 4555 }
@@ -4601,6 +4646,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4601 if (radio_id != 0x2064) 4646 if (radio_id != 0x2064)
4602 unsupported = 1; 4647 unsupported = 1;
4603 break; 4648 break;
4649 case B43_PHYTYPE_AC:
4650 if (radio_id != 0x2069)
4651 unsupported = 1;
4652 break;
4604 default: 4653 default:
4605 B43_WARN_ON(1); 4654 B43_WARN_ON(1);
4606 } 4655 }
@@ -5094,7 +5143,6 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
5094{ 5143{
5095 struct b43_wl *wl = hw_to_b43_wl(hw); 5144 struct b43_wl *wl = hw_to_b43_wl(hw);
5096 5145
5097 /* FIXME: add locking */
5098 b43_update_templates(wl); 5146 b43_update_templates(wl);
5099 5147
5100 return 0; 5148 return 0;
@@ -5584,6 +5632,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
5584 wl->hw = hw; 5632 wl->hw = hw;
5585 mutex_init(&wl->mutex); 5633 mutex_init(&wl->mutex);
5586 spin_lock_init(&wl->hardirq_lock); 5634 spin_lock_init(&wl->hardirq_lock);
5635 spin_lock_init(&wl->beacon_lock);
5587 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 5636 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
5588 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 5637 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
5589 INIT_WORK(&wl->tx_work, b43_tx_work); 5638 INIT_WORK(&wl->tx_work, b43_tx_work);
diff --git a/drivers/net/wireless/b43/phy_ac.c b/drivers/net/wireless/b43/phy_ac.c
new file mode 100644
index 000000000000..e75633d67938
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_ac.c
@@ -0,0 +1,92 @@
1/*
2 * Broadcom B43 wireless driver
3 * IEEE 802.11ac AC-PHY support
4 *
5 * Copyright (c) 2015 Rafał Miłecki <zajec5@gmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include "b43.h"
14#include "phy_ac.h"
15
16/**************************************************
17 * Basic PHY ops
18 **************************************************/
19
20static int b43_phy_ac_op_allocate(struct b43_wldev *dev)
21{
22 struct b43_phy_ac *phy_ac;
23
24 phy_ac = kzalloc(sizeof(*phy_ac), GFP_KERNEL);
25 if (!phy_ac)
26 return -ENOMEM;
27 dev->phy.ac = phy_ac;
28
29 return 0;
30}
31
32static void b43_phy_ac_op_free(struct b43_wldev *dev)
33{
34 struct b43_phy *phy = &dev->phy;
35 struct b43_phy_ac *phy_ac = phy->ac;
36
37 kfree(phy_ac);
38 phy->ac = NULL;
39}
40
41static void b43_phy_ac_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
42 u16 set)
43{
44 b43_write16f(dev, B43_MMIO_PHY_CONTROL, reg);
45 b43_write16(dev, B43_MMIO_PHY_DATA,
46 (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
47}
48
49static u16 b43_phy_ac_op_radio_read(struct b43_wldev *dev, u16 reg)
50{
51 b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
52 return b43_read16(dev, B43_MMIO_RADIO24_DATA);
53}
54
55static void b43_phy_ac_op_radio_write(struct b43_wldev *dev, u16 reg,
56 u16 value)
57{
58 b43_write16f(dev, B43_MMIO_RADIO24_CONTROL, reg);
59 b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
60}
61
62static unsigned int b43_phy_ac_op_get_default_chan(struct b43_wldev *dev)
63{
64 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
65 return 11;
66 return 36;
67}
68
69static enum b43_txpwr_result
70b43_phy_ac_op_recalc_txpower(struct b43_wldev *dev, bool ignore_tssi)
71{
72 return B43_TXPWR_RES_DONE;
73}
74
75static void b43_phy_ac_op_adjust_txpower(struct b43_wldev *dev)
76{
77}
78
79/**************************************************
80 * PHY ops struct
81 **************************************************/
82
83const struct b43_phy_operations b43_phyops_ac = {
84 .allocate = b43_phy_ac_op_allocate,
85 .free = b43_phy_ac_op_free,
86 .phy_maskset = b43_phy_ac_op_maskset,
87 .radio_read = b43_phy_ac_op_radio_read,
88 .radio_write = b43_phy_ac_op_radio_write,
89 .get_default_chan = b43_phy_ac_op_get_default_chan,
90 .recalc_txpower = b43_phy_ac_op_recalc_txpower,
91 .adjust_txpower = b43_phy_ac_op_adjust_txpower,
92};
diff --git a/drivers/net/wireless/b43/phy_ac.h b/drivers/net/wireless/b43/phy_ac.h
new file mode 100644
index 000000000000..d1ca79e0eb24
--- /dev/null
+++ b/drivers/net/wireless/b43/phy_ac.h
@@ -0,0 +1,38 @@
1#ifndef B43_PHY_AC_H_
2#define B43_PHY_AC_H_
3
4#include "phy_common.h"
5
6#define B43_PHY_AC_BBCFG 0x001
7#define B43_PHY_AC_BBCFG_RSTCCA 0x4000 /* Reset CCA */
8#define B43_PHY_AC_BANDCTL 0x003 /* Band control */
9#define B43_PHY_AC_BANDCTL_5GHZ 0x0001
10#define B43_PHY_AC_TABLE_ID 0x00d
11#define B43_PHY_AC_TABLE_OFFSET 0x00e
12#define B43_PHY_AC_TABLE_DATA1 0x00f
13#define B43_PHY_AC_TABLE_DATA2 0x010
14#define B43_PHY_AC_TABLE_DATA3 0x011
15#define B43_PHY_AC_CLASSCTL 0x140 /* Classifier control */
16#define B43_PHY_AC_CLASSCTL_CCKEN 0x0001 /* CCK enable */
17#define B43_PHY_AC_CLASSCTL_OFDMEN 0x0002 /* OFDM enable */
18#define B43_PHY_AC_CLASSCTL_WAITEDEN 0x0004 /* Waited enable */
19#define B43_PHY_AC_BW1A 0x371
20#define B43_PHY_AC_BW2 0x372
21#define B43_PHY_AC_BW3 0x373
22#define B43_PHY_AC_BW4 0x374
23#define B43_PHY_AC_BW5 0x375
24#define B43_PHY_AC_BW6 0x376
25#define B43_PHY_AC_RFCTL_CMD 0x408
26#define B43_PHY_AC_C1_CLIP 0x6d4
27#define B43_PHY_AC_C1_CLIP_DIS 0x4000
28#define B43_PHY_AC_C2_CLIP 0x8d4
29#define B43_PHY_AC_C2_CLIP_DIS 0x4000
30#define B43_PHY_AC_C3_CLIP 0xad4
31#define B43_PHY_AC_C3_CLIP_DIS 0x4000
32
33struct b43_phy_ac {
34};
35
36extern const struct b43_phy_operations b43_phyops_ac;
37
38#endif /* B43_PHY_AC_H_ */
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index ee27b06074e1..ec2b9c577b90 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -33,6 +33,7 @@
33#include "phy_lp.h" 33#include "phy_lp.h"
34#include "phy_ht.h" 34#include "phy_ht.h"
35#include "phy_lcn.h" 35#include "phy_lcn.h"
36#include "phy_ac.h"
36#include "b43.h" 37#include "b43.h"
37#include "main.h" 38#include "main.h"
38 39
@@ -70,6 +71,11 @@ int b43_phy_allocate(struct b43_wldev *dev)
70 phy->ops = &b43_phyops_lcn; 71 phy->ops = &b43_phyops_lcn;
71#endif 72#endif
72 break; 73 break;
74 case B43_PHYTYPE_AC:
75#ifdef CONFIG_B43_PHY_AC
76 phy->ops = &b43_phyops_ac;
77#endif
78 break;
73 } 79 }
74 if (B43_WARN_ON(!phy->ops)) 80 if (B43_WARN_ON(!phy->ops))
75 return -ENODEV; 81 return -ENODEV;
@@ -572,7 +578,8 @@ void b43_phy_force_clock(struct b43_wldev *dev, bool force)
572 u32 tmp; 578 u32 tmp;
573 579
574 WARN_ON(dev->phy.type != B43_PHYTYPE_N && 580 WARN_ON(dev->phy.type != B43_PHYTYPE_N &&
575 dev->phy.type != B43_PHYTYPE_HT); 581 dev->phy.type != B43_PHYTYPE_HT &&
582 dev->phy.type != B43_PHYTYPE_AC);
576 583
577 switch (dev->dev->bus_type) { 584 switch (dev->dev->bus_type) {
578#ifdef CONFIG_B43_BCMA 585#ifdef CONFIG_B43_BCMA
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 3912274f71e3..78d86526799e 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -222,6 +222,8 @@ struct b43_phy {
222 struct b43_phy_ht *ht; 222 struct b43_phy_ht *ht;
223 /* LCN-PHY specific information */ 223 /* LCN-PHY specific information */
224 struct b43_phy_lcn *lcn; 224 struct b43_phy_lcn *lcn;
225 /* AC-PHY specific information */
226 struct b43_phy_ac *ac;
225 }; 227 };
226 228
227 /* Band support flags. */ 229 /* Band support flags. */
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..7944224e3fc9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -97,25 +97,6 @@ static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func)
97{ 97{
98} 98}
99 99
100static bool brcmf_sdiod_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
101{
102 bool is_err = false;
103#ifdef CONFIG_PM_SLEEP
104 is_err = atomic_read(&sdiodev->suspend);
105#endif
106 return is_err;
107}
108
109static void brcmf_sdiod_pm_resume_wait(struct brcmf_sdio_dev *sdiodev,
110 wait_queue_head_t *wq)
111{
112#ifdef CONFIG_PM_SLEEP
113 int retry = 0;
114 while (atomic_read(&sdiodev->suspend) && retry++ != 30)
115 wait_event_timeout(*wq, false, HZ/100);
116#endif
117}
118
119int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) 100int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
120{ 101{
121 int ret = 0; 102 int ret = 0;
@@ -244,10 +225,6 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
244 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", 225 brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
245 write, fn, addr, regsz); 226 write, fn, addr, regsz);
246 227
247 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
248 if (brcmf_sdiod_pm_resume_error(sdiodev))
249 return -EIO;
250
251 /* only allow byte access on F0 */ 228 /* only allow byte access on F0 */
252 if (WARN_ON(regsz > 1 && !fn)) 229 if (WARN_ON(regsz > 1 && !fn))
253 return -EINVAL; 230 return -EINVAL;
@@ -292,6 +269,12 @@ static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn,
292 return ret; 269 return ret;
293} 270}
294 271
272static void brcmf_sdiod_nomedium_state(struct brcmf_sdio_dev *sdiodev)
273{
274 sdiodev->state = BRCMF_STATE_NOMEDIUM;
275 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_DOWN);
276}
277
295static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 278static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
296 u8 regsz, void *data, bool write) 279 u8 regsz, void *data, bool write)
297{ 280{
@@ -299,7 +282,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
299 s32 retry = 0; 282 s32 retry = 0;
300 int ret; 283 int ret;
301 284
302 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) 285 if (sdiodev->state == BRCMF_STATE_NOMEDIUM)
303 return -ENOMEDIUM; 286 return -ENOMEDIUM;
304 287
305 /* 288 /*
@@ -325,7 +308,7 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
325 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); 308 retry++ < SDIOH_API_ACCESS_RETRY_LIMIT);
326 309
327 if (ret == -ENOMEDIUM) 310 if (ret == -ENOMEDIUM)
328 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); 311 brcmf_sdiod_nomedium_state(sdiodev);
329 else if (ret != 0) { 312 else if (ret != 0) {
330 /* 313 /*
331 * SleepCSR register access can fail when 314 * SleepCSR register access can fail when
@@ -348,7 +331,7 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
348 int err = 0, i; 331 int err = 0, i;
349 u8 addr[3]; 332 u8 addr[3];
350 333
351 if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) 334 if (sdiodev->state == BRCMF_STATE_NOMEDIUM)
352 return -ENOMEDIUM; 335 return -ENOMEDIUM;
353 336
354 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; 337 addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK;
@@ -462,10 +445,6 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
462 unsigned int req_sz; 445 unsigned int req_sz;
463 int err; 446 int err;
464 447
465 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
466 if (brcmf_sdiod_pm_resume_error(sdiodev))
467 return -EIO;
468
469 /* Single skb use the standard mmc interface */ 448 /* Single skb use the standard mmc interface */
470 req_sz = pkt->len + 3; 449 req_sz = pkt->len + 3;
471 req_sz &= (uint)~3; 450 req_sz &= (uint)~3;
@@ -481,7 +460,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
481 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, 460 err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr,
482 req_sz); 461 req_sz);
483 if (err == -ENOMEDIUM) 462 if (err == -ENOMEDIUM)
484 brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); 463 brcmf_sdiod_nomedium_state(sdiodev);
485 return err; 464 return err;
486} 465}
487 466
@@ -516,10 +495,6 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
516 if (!pktlist->qlen) 495 if (!pktlist->qlen)
517 return -EINVAL; 496 return -EINVAL;
518 497
519 brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
520 if (brcmf_sdiod_pm_resume_error(sdiodev))
521 return -EIO;
522
523 target_list = pktlist; 498 target_list = pktlist;
524 /* for host with broken sg support, prepare a page aligned list */ 499 /* for host with broken sg support, prepare a page aligned list */
525 __skb_queue_head_init(&local_list); 500 __skb_queue_head_init(&local_list);
@@ -620,8 +595,7 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn,
620 595
621 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; 596 ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error;
622 if (ret == -ENOMEDIUM) { 597 if (ret == -ENOMEDIUM) {
623 brcmf_bus_change_state(sdiodev->bus_if, 598 brcmf_sdiod_nomedium_state(sdiodev);
624 BRCMF_BUS_NOMEDIUM);
625 break; 599 break;
626 } else if (ret != 0) { 600 } else if (ret != 0) {
627 brcmf_err("CMD53 sg block %s failed %d\n", 601 brcmf_err("CMD53 sg block %s failed %d\n",
@@ -996,18 +970,20 @@ out:
996} 970}
997 971
998#define BRCMF_SDIO_DEVICE(dev_id) \ 972#define BRCMF_SDIO_DEVICE(dev_id) \
999 {SDIO_DEVICE(BRCM_SDIO_VENDOR_ID_BROADCOM, dev_id)} 973 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, dev_id)}
1000 974
1001/* devices we support, null terminated */ 975/* devices we support, null terminated */
1002static const struct sdio_device_id brcmf_sdmmc_ids[] = { 976static const struct sdio_device_id brcmf_sdmmc_ids[] = {
1003 BRCMF_SDIO_DEVICE(BRCM_SDIO_43143_DEVICE_ID), 977 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43143),
1004 BRCMF_SDIO_DEVICE(BRCM_SDIO_43241_DEVICE_ID), 978 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43241),
1005 BRCMF_SDIO_DEVICE(BRCM_SDIO_4329_DEVICE_ID), 979 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4329),
1006 BRCMF_SDIO_DEVICE(BRCM_SDIO_4330_DEVICE_ID), 980 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4330),
1007 BRCMF_SDIO_DEVICE(BRCM_SDIO_4334_DEVICE_ID), 981 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4334),
1008 BRCMF_SDIO_DEVICE(BRCM_SDIO_43362_DEVICE_ID), 982 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43340),
1009 BRCMF_SDIO_DEVICE(BRCM_SDIO_4335_4339_DEVICE_ID), 983 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
1010 BRCMF_SDIO_DEVICE(BRCM_SDIO_4354_DEVICE_ID), 984 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
985 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
986 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
1011 { /* end: all zeroes */ } 987 { /* end: all zeroes */ }
1012}; 988};
1013MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 989MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
@@ -1074,9 +1050,9 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
1074 bus_if->wowl_supported = true; 1050 bus_if->wowl_supported = true;
1075#endif 1051#endif
1076 1052
1053 sdiodev->sleeping = false;
1077 atomic_set(&sdiodev->suspend, false); 1054 atomic_set(&sdiodev->suspend, false);
1078 init_waitqueue_head(&sdiodev->request_word_wait); 1055 init_waitqueue_head(&sdiodev->idle_wait);
1079 init_waitqueue_head(&sdiodev->request_buffer_wait);
1080 1056
1081 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n"); 1057 brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n");
1082 err = brcmf_sdiod_probe(sdiodev); 1058 err = brcmf_sdiod_probe(sdiodev);
@@ -1138,12 +1114,23 @@ void brcmf_sdio_wowl_config(struct device *dev, bool enabled)
1138#ifdef CONFIG_PM_SLEEP 1114#ifdef CONFIG_PM_SLEEP
1139static int brcmf_ops_sdio_suspend(struct device *dev) 1115static int brcmf_ops_sdio_suspend(struct device *dev)
1140{ 1116{
1141 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1117 struct brcmf_bus *bus_if;
1142 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 1118 struct brcmf_sdio_dev *sdiodev;
1143 mmc_pm_flag_t sdio_flags; 1119 mmc_pm_flag_t sdio_flags;
1144 1120
1145 brcmf_dbg(SDIO, "Enter\n"); 1121 brcmf_dbg(SDIO, "Enter\n");
1146 1122
1123 bus_if = dev_get_drvdata(dev);
1124 sdiodev = bus_if->bus_priv.sdio;
1125
1126 /* wait for watchdog to go idle */
1127 if (wait_event_timeout(sdiodev->idle_wait, sdiodev->sleeping,
1128 msecs_to_jiffies(3 * BRCMF_WD_POLL_MS)) == 0) {
1129 brcmf_err("bus still active\n");
1130 return -EBUSY;
1131 }
1132 /* disable watchdog */
1133 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1147 atomic_set(&sdiodev->suspend, true); 1134 atomic_set(&sdiodev->suspend, true);
1148 1135
1149 if (sdiodev->wowl_enabled) { 1136 if (sdiodev->wowl_enabled) {
@@ -1155,9 +1142,6 @@ static int brcmf_ops_sdio_suspend(struct device *dev)
1155 if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags)) 1142 if (sdio_set_host_pm_flags(sdiodev->func[1], sdio_flags))
1156 brcmf_err("Failed to set pm_flags %x\n", sdio_flags); 1143 brcmf_err("Failed to set pm_flags %x\n", sdio_flags);
1157 } 1144 }
1158
1159 brcmf_sdio_wd_timer(sdiodev->bus, 0);
1160
1161 return 0; 1145 return 0;
1162} 1146}
1163 1147
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
index ef344e47218a..89e6a4dc105e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
@@ -33,11 +33,8 @@
33 33
34/* The level of bus communication with the dongle */ 34/* The level of bus communication with the dongle */
35enum brcmf_bus_state { 35enum brcmf_bus_state {
36 BRCMF_BUS_UNKNOWN, /* Not determined yet */
37 BRCMF_BUS_NOMEDIUM, /* No medium access to dongle */
38 BRCMF_BUS_DOWN, /* Not ready for frame transfers */ 36 BRCMF_BUS_DOWN, /* Not ready for frame transfers */
39 BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ 37 BRCMF_BUS_UP /* Ready for frame transfers */
40 BRCMF_BUS_DATA /* Ready for frame transfers */
41}; 38};
42 39
43/* The level of bus communication with the dongle */ 40/* The level of bus communication with the dongle */
@@ -188,22 +185,6 @@ void brcmf_bus_wowl_config(struct brcmf_bus *bus, bool enabled)
188 bus->ops->wowl_config(bus->dev, enabled); 185 bus->ops->wowl_config(bus->dev, enabled);
189} 186}
190 187
191static inline bool brcmf_bus_ready(struct brcmf_bus *bus)
192{
193 return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA;
194}
195
196static inline void brcmf_bus_change_state(struct brcmf_bus *bus,
197 enum brcmf_bus_state new_state)
198{
199 /* NOMEDIUM is permanent */
200 if (bus->state == BRCMF_BUS_NOMEDIUM)
201 return;
202
203 brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state);
204 bus->state = new_state;
205}
206
207/* 188/*
208 * interface functions from common layer 189 * interface functions from common layer
209 */ 190 */
@@ -226,6 +207,9 @@ void brcmf_txflowblock(struct device *dev, bool state);
226/* Notify the bus has transferred the tx packet to firmware */ 207/* Notify the bus has transferred the tx packet to firmware */
227void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 208void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
228 209
210/* Configure the "global" bus state used by upper layers */
211void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state);
212
229int brcmf_bus_start(struct device *dev); 213int brcmf_bus_start(struct device *dev);
230s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); 214s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len);
231void brcmf_bus_add_txhdrlen(struct device *dev, uint len); 215void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
index 3aecc5f48719..b59b8c6c42ab 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)
@@ -1228,7 +1229,25 @@ static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1228 memset(prof, 0, sizeof(*prof)); 1229 memset(prof, 0, sizeof(*prof));
1229} 1230}
1230 1231
1231static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) 1232static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1233{
1234 u16 reason;
1235
1236 switch (e->event_code) {
1237 case BRCMF_E_DEAUTH:
1238 case BRCMF_E_DEAUTH_IND:
1239 case BRCMF_E_DISASSOC_IND:
1240 reason = e->reason;
1241 break;
1242 case BRCMF_E_LINK:
1243 default:
1244 reason = 0;
1245 break;
1246 }
1247 return reason;
1248}
1249
1250static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1232{ 1251{
1233 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); 1252 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1234 s32 err = 0; 1253 s32 err = 0;
@@ -1243,7 +1262,8 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1243 brcmf_err("WLC_DISASSOC failed (%d)\n", err); 1262 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1244 } 1263 }
1245 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); 1264 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1246 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL); 1265 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1266 GFP_KERNEL);
1247 1267
1248 } 1268 }
1249 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); 1269 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
@@ -1413,7 +1433,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1413 if (!check_vif_up(ifp->vif)) 1433 if (!check_vif_up(ifp->vif))
1414 return -EIO; 1434 return -EIO;
1415 1435
1416 brcmf_link_down(ifp->vif); 1436 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1417 1437
1418 brcmf_dbg(TRACE, "Exit\n"); 1438 brcmf_dbg(TRACE, "Exit\n");
1419 1439
@@ -1670,7 +1690,7 @@ brcmf_set_sharedkey(struct net_device *ndev,
1670 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n", 1690 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1671 key.len, key.index, key.algo); 1691 key.len, key.index, key.algo);
1672 brcmf_dbg(CONN, "key \"%s\"\n", key.data); 1692 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1673 err = send_key_to_dongle(ndev, &key); 1693 err = send_key_to_dongle(netdev_priv(ndev), &key);
1674 if (err) 1694 if (err)
1675 return err; 1695 return err;
1676 1696
@@ -2052,7 +2072,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2052 /* check for key index change */ 2072 /* check for key index change */
2053 if (key.len == 0) { 2073 if (key.len == 0) {
2054 /* key delete */ 2074 /* key delete */
2055 err = send_key_to_dongle(ndev, &key); 2075 err = send_key_to_dongle(ifp, &key);
2056 if (err) 2076 if (err)
2057 brcmf_err("key delete error (%d)\n", err); 2077 brcmf_err("key delete error (%d)\n", err);
2058 } else { 2078 } else {
@@ -2108,7 +2128,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2108 brcmf_err("Invalid cipher (0x%x)\n", params->cipher); 2128 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2109 return -EINVAL; 2129 return -EINVAL;
2110 } 2130 }
2111 err = send_key_to_dongle(ndev, &key); 2131 err = send_key_to_dongle(ifp, &key);
2112 if (err) 2132 if (err)
2113 brcmf_err("wsec_key error (%d)\n", err); 2133 brcmf_err("wsec_key error (%d)\n", err);
2114 } 2134 }
@@ -2121,7 +2141,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2121 struct key_params *params) 2141 struct key_params *params)
2122{ 2142{
2123 struct brcmf_if *ifp = netdev_priv(ndev); 2143 struct brcmf_if *ifp = netdev_priv(ndev);
2124 struct brcmf_wsec_key key; 2144 struct brcmf_wsec_key *key;
2125 s32 val; 2145 s32 val;
2126 s32 wsec; 2146 s32 wsec;
2127 s32 err = 0; 2147 s32 err = 0;
@@ -2132,54 +2152,62 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2132 if (!check_vif_up(ifp->vif)) 2152 if (!check_vif_up(ifp->vif))
2133 return -EIO; 2153 return -EIO;
2134 2154
2155 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2156 /* we ignore this key index in this case */
2157 brcmf_err("invalid key index (%d)\n", key_idx);
2158 return -EINVAL;
2159 }
2160
2135 if (mac_addr && 2161 if (mac_addr &&
2136 (params->cipher != WLAN_CIPHER_SUITE_WEP40) && 2162 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2137 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { 2163 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2138 brcmf_dbg(TRACE, "Exit"); 2164 brcmf_dbg(TRACE, "Exit");
2139 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params); 2165 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2140 } 2166 }
2141 memset(&key, 0, sizeof(key));
2142 2167
2143 key.len = (u32) params->key_len; 2168 key = &ifp->vif->profile.key[key_idx];
2144 key.index = (u32) key_idx; 2169 memset(key, 0, sizeof(*key));
2145 2170
2146 if (key.len > sizeof(key.data)) { 2171 if (params->key_len > sizeof(key->data)) {
2147 brcmf_err("Too long key length (%u)\n", key.len); 2172 brcmf_err("Too long key length (%u)\n", params->key_len);
2148 err = -EINVAL; 2173 err = -EINVAL;
2149 goto done; 2174 goto done;
2150 } 2175 }
2151 memcpy(key.data, params->key, key.len); 2176 key->len = params->key_len;
2177 key->index = key_idx;
2152 2178
2153 key.flags = BRCMF_PRIMARY_KEY; 2179 memcpy(key->data, params->key, key->len);
2180
2181 key->flags = BRCMF_PRIMARY_KEY;
2154 switch (params->cipher) { 2182 switch (params->cipher) {
2155 case WLAN_CIPHER_SUITE_WEP40: 2183 case WLAN_CIPHER_SUITE_WEP40:
2156 key.algo = CRYPTO_ALGO_WEP1; 2184 key->algo = CRYPTO_ALGO_WEP1;
2157 val = WEP_ENABLED; 2185 val = WEP_ENABLED;
2158 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n"); 2186 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2159 break; 2187 break;
2160 case WLAN_CIPHER_SUITE_WEP104: 2188 case WLAN_CIPHER_SUITE_WEP104:
2161 key.algo = CRYPTO_ALGO_WEP128; 2189 key->algo = CRYPTO_ALGO_WEP128;
2162 val = WEP_ENABLED; 2190 val = WEP_ENABLED;
2163 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); 2191 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2164 break; 2192 break;
2165 case WLAN_CIPHER_SUITE_TKIP: 2193 case WLAN_CIPHER_SUITE_TKIP:
2166 if (!brcmf_is_apmode(ifp->vif)) { 2194 if (!brcmf_is_apmode(ifp->vif)) {
2167 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); 2195 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2168 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2196 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2169 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2197 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2170 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 2198 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2171 } 2199 }
2172 key.algo = CRYPTO_ALGO_TKIP; 2200 key->algo = CRYPTO_ALGO_TKIP;
2173 val = TKIP_ENABLED; 2201 val = TKIP_ENABLED;
2174 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); 2202 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2175 break; 2203 break;
2176 case WLAN_CIPHER_SUITE_AES_CMAC: 2204 case WLAN_CIPHER_SUITE_AES_CMAC:
2177 key.algo = CRYPTO_ALGO_AES_CCM; 2205 key->algo = CRYPTO_ALGO_AES_CCM;
2178 val = AES_ENABLED; 2206 val = AES_ENABLED;
2179 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); 2207 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2180 break; 2208 break;
2181 case WLAN_CIPHER_SUITE_CCMP: 2209 case WLAN_CIPHER_SUITE_CCMP:
2182 key.algo = CRYPTO_ALGO_AES_CCM; 2210 key->algo = CRYPTO_ALGO_AES_CCM;
2183 val = AES_ENABLED; 2211 val = AES_ENABLED;
2184 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); 2212 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2185 break; 2213 break;
@@ -2189,7 +2217,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2189 goto done; 2217 goto done;
2190 } 2218 }
2191 2219
2192 err = send_key_to_dongle(ndev, &key); 2220 err = send_key_to_dongle(ifp, key);
2193 if (err) 2221 if (err)
2194 goto done; 2222 goto done;
2195 2223
@@ -2222,7 +2250,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2222 if (!check_vif_up(ifp->vif)) 2250 if (!check_vif_up(ifp->vif))
2223 return -EIO; 2251 return -EIO;
2224 2252
2225 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { 2253 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2226 /* we ignore this key index in this case */ 2254 /* we ignore this key index in this case */
2227 brcmf_err("invalid key index (%d)\n", key_idx); 2255 brcmf_err("invalid key index (%d)\n", key_idx);
2228 return -EINVAL; 2256 return -EINVAL;
@@ -2237,7 +2265,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2237 brcmf_dbg(CONN, "key index (%d)\n", key_idx); 2265 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2238 2266
2239 /* Set the new key/index */ 2267 /* Set the new key/index */
2240 err = send_key_to_dongle(ndev, &key); 2268 err = send_key_to_dongle(ifp, &key);
2241 2269
2242 brcmf_dbg(TRACE, "Exit\n"); 2270 brcmf_dbg(TRACE, "Exit\n");
2243 return err; 2271 return err;
@@ -2305,6 +2333,39 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2305 return -EOPNOTSUPP; 2333 return -EOPNOTSUPP;
2306} 2334}
2307 2335
2336static void
2337brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2338{
2339 s32 err;
2340 u8 key_idx;
2341 struct brcmf_wsec_key *key;
2342 s32 wsec;
2343
2344 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2345 key = &ifp->vif->profile.key[key_idx];
2346 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2347 (key->algo == CRYPTO_ALGO_WEP128))
2348 break;
2349 }
2350 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2351 return;
2352
2353 err = send_key_to_dongle(ifp, key);
2354 if (err) {
2355 brcmf_err("Setting WEP key failed (%d)\n", err);
2356 return;
2357 }
2358 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2359 if (err) {
2360 brcmf_err("get wsec error (%d)\n", err);
2361 return;
2362 }
2363 wsec |= WEP_ENABLED;
2364 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2365 if (err)
2366 brcmf_err("set wsec error (%d)\n", err);
2367}
2368
2308static s32 2369static s32
2309brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2370brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2310 const u8 *mac, struct station_info *sinfo) 2371 const u8 *mac, struct station_info *sinfo)
@@ -2333,10 +2394,10 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2333 brcmf_err("GET STA INFO failed, %d\n", err); 2394 brcmf_err("GET STA INFO failed, %d\n", err);
2334 goto done; 2395 goto done;
2335 } 2396 }
2336 sinfo->filled = STATION_INFO_INACTIVE_TIME; 2397 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2337 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; 2398 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2338 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { 2399 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2339 sinfo->filled |= STATION_INFO_CONNECTED_TIME; 2400 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2340 sinfo->connected_time = le32_to_cpu(sta_info_le.in); 2401 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2341 } 2402 }
2342 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", 2403 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
@@ -2354,7 +2415,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2354 brcmf_err("Could not get rate (%d)\n", err); 2415 brcmf_err("Could not get rate (%d)\n", err);
2355 goto done; 2416 goto done;
2356 } else { 2417 } else {
2357 sinfo->filled |= STATION_INFO_TX_BITRATE; 2418 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2358 sinfo->txrate.legacy = rate * 5; 2419 sinfo->txrate.legacy = rate * 5;
2359 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); 2420 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2360 } 2421 }
@@ -2369,7 +2430,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2369 goto done; 2430 goto done;
2370 } else { 2431 } else {
2371 rssi = le32_to_cpu(scb_val.val); 2432 rssi = le32_to_cpu(scb_val.val);
2372 sinfo->filled |= STATION_INFO_SIGNAL; 2433 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2373 sinfo->signal = rssi; 2434 sinfo->signal = rssi;
2374 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); 2435 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2375 } 2436 }
@@ -2396,7 +2457,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2396 brcmf_dbg(CONN, "DTIM peroid %d\n", 2457 brcmf_dbg(CONN, "DTIM peroid %d\n",
2397 dtim_period); 2458 dtim_period);
2398 } 2459 }
2399 sinfo->filled |= STATION_INFO_BSS_PARAM; 2460 sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2400 } 2461 }
2401 } else 2462 } else
2402 err = -EPERM; 2463 err = -EPERM;
@@ -2999,7 +3060,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2999 * disassociate from AP to save power while system is 3060 * disassociate from AP to save power while system is
3000 * in suspended state 3061 * in suspended state
3001 */ 3062 */
3002 brcmf_link_down(vif); 3063 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3003 /* Make sure WPA_Supplicant receives all the event 3064 /* Make sure WPA_Supplicant receives all the event
3004 * generated due to DISASSOC call to the fw to keep 3065 * generated due to DISASSOC call to the fw to keep
3005 * the state fw and WPA_Supplicant state consistent 3066 * the state fw and WPA_Supplicant state consistent
@@ -3695,17 +3756,12 @@ static u32
3695brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) 3756brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3696{ 3757{
3697 3758
3698 __le32 iecount_le;
3699 __le32 pktflag_le;
3700
3701 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); 3759 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3702 iebuf[VNDR_IE_CMD_LEN - 1] = '\0'; 3760 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3703 3761
3704 iecount_le = cpu_to_le32(1); 3762 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3705 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3706 3763
3707 pktflag_le = cpu_to_le32(pktflag); 3764 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3708 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3709 3765
3710 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len); 3766 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3711 3767
@@ -3924,6 +3980,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3924 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3925 struct brcmf_if *ifp = netdev_priv(ndev); 3981 struct brcmf_if *ifp = netdev_priv(ndev);
3926 const struct brcmf_tlv *ssid_ie; 3982 const struct brcmf_tlv *ssid_ie;
3983 const struct brcmf_tlv *country_ie;
3927 struct brcmf_ssid_le ssid_le; 3984 struct brcmf_ssid_le ssid_le;
3928 s32 err = -EPERM; 3985 s32 err = -EPERM;
3929 const struct brcmf_tlv *rsn_ie; 3986 const struct brcmf_tlv *rsn_ie;
@@ -3933,6 +3990,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3933 struct brcmf_fil_bss_enable_le bss_enable; 3990 struct brcmf_fil_bss_enable_le bss_enable;
3934 u16 chanspec; 3991 u16 chanspec;
3935 bool mbss; 3992 bool mbss;
3993 int is_11d;
3936 3994
3937 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", 3995 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3938 settings->chandef.chan->hw_value, 3996 settings->chandef.chan->hw_value,
@@ -3941,10 +3999,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", 3999 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3942 settings->ssid, settings->ssid_len, settings->auth_type, 4000 settings->ssid, settings->ssid_len, settings->auth_type,
3943 settings->inactivity_timeout); 4001 settings->inactivity_timeout);
3944
3945 dev_role = ifp->vif->wdev.iftype; 4002 dev_role = ifp->vif->wdev.iftype;
3946 mbss = ifp->vif->mbss; 4003 mbss = ifp->vif->mbss;
3947 4004
4005 /* store current 11d setting */
4006 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4007 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4008 settings->beacon.tail_len,
4009 WLAN_EID_COUNTRY);
4010 is_11d = country_ie ? 1 : 0;
4011
3948 memset(&ssid_le, 0, sizeof(ssid_le)); 4012 memset(&ssid_le, 0, sizeof(ssid_le));
3949 if (settings->ssid == NULL || settings->ssid_len == 0) { 4013 if (settings->ssid == NULL || settings->ssid_len == 0) {
3950 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN; 4014 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
@@ -4010,6 +4074,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4010 goto exit; 4074 goto exit;
4011 } 4075 }
4012 4076
4077 if (is_11d != ifp->vif->is_11d) {
4078 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4079 is_11d);
4080 if (err < 0) {
4081 brcmf_err("Regulatory Set Error, %d\n", err);
4082 goto exit;
4083 }
4084 }
4013 if (settings->beacon_interval) { 4085 if (settings->beacon_interval) {
4014 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, 4086 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4015 settings->beacon_interval); 4087 settings->beacon_interval);
@@ -4042,6 +4114,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4042 brcmf_err("SET INFRA error %d\n", err); 4114 brcmf_err("SET INFRA error %d\n", err);
4043 goto exit; 4115 goto exit;
4044 } 4116 }
4117 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4118 /* Multiple-BSS should use same 11d configuration */
4119 err = -EINVAL;
4120 goto exit;
4045 } 4121 }
4046 if (dev_role == NL80211_IFTYPE_AP) { 4122 if (dev_role == NL80211_IFTYPE_AP) {
4047 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) 4123 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
@@ -4057,6 +4133,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4057 brcmf_err("BRCMF_C_UP error (%d)\n", err); 4133 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4058 goto exit; 4134 goto exit;
4059 } 4135 }
4136 /* On DOWN the firmware removes the WEP keys, reconfigure
4137 * them if they were set.
4138 */
4139 brcmf_cfg80211_reconfigure_wep(ifp);
4060 4140
4061 memset(&join_params, 0, sizeof(join_params)); 4141 memset(&join_params, 0, sizeof(join_params));
4062 /* join parameters starts with ssid */ 4142 /* join parameters starts with ssid */
@@ -4133,6 +4213,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4133 brcmf_err("setting INFRA mode failed %d\n", err); 4213 brcmf_err("setting INFRA mode failed %d\n", err);
4134 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) 4214 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4135 brcmf_fil_iovar_int_set(ifp, "mbss", 0); 4215 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4216 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4217 ifp->vif->is_11d);
4218 if (err < 0)
4219 brcmf_err("restoring REGULATORY setting failed %d\n",
4220 err);
4136 /* Bring device back up so it can be used again */ 4221 /* Bring device back up so it can be used again */
4137 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); 4222 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4138 if (err < 0) 4223 if (err < 0)
@@ -4197,6 +4282,34 @@ brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4197 return err; 4282 return err;
4198} 4283}
4199 4284
4285static int
4286brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4287 const u8 *mac, struct station_parameters *params)
4288{
4289 struct brcmf_if *ifp = netdev_priv(ndev);
4290 s32 err;
4291
4292 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4293 params->sta_flags_mask, params->sta_flags_set);
4294
4295 /* Ignore all 00 MAC */
4296 if (is_zero_ether_addr(mac))
4297 return 0;
4298
4299 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4300 return 0;
4301
4302 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4303 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4304 (void *)mac, ETH_ALEN);
4305 else
4306 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4307 (void *)mac, ETH_ALEN);
4308 if (err < 0)
4309 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4310
4311 return err;
4312}
4200 4313
4201static void 4314static void
4202brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy, 4315brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
@@ -4471,6 +4584,7 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4471 .stop_ap = brcmf_cfg80211_stop_ap, 4584 .stop_ap = brcmf_cfg80211_stop_ap,
4472 .change_beacon = brcmf_cfg80211_change_beacon, 4585 .change_beacon = brcmf_cfg80211_change_beacon,
4473 .del_station = brcmf_cfg80211_del_station, 4586 .del_station = brcmf_cfg80211_del_station,
4587 .change_station = brcmf_cfg80211_change_station,
4474 .sched_scan_start = brcmf_cfg80211_sched_scan_start, 4588 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4475 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, 4589 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4476 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register, 4590 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
@@ -4778,7 +4892,6 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4778 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && 4892 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4779 (reason == BRCMF_E_STATUS_SUCCESS)) { 4893 (reason == BRCMF_E_STATUS_SUCCESS)) {
4780 memset(&sinfo, 0, sizeof(sinfo)); 4894 memset(&sinfo, 0, sizeof(sinfo));
4781 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4782 if (!data) { 4895 if (!data) {
4783 brcmf_err("No IEs present in ASSOC/REASSOC_IND"); 4896 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4784 return -EINVAL; 4897 return -EINVAL;
@@ -4833,7 +4946,7 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4833 if (!brcmf_is_ibssmode(ifp->vif)) { 4946 if (!brcmf_is_ibssmode(ifp->vif)) {
4834 brcmf_bss_connect_done(cfg, ndev, e, false); 4947 brcmf_bss_connect_done(cfg, ndev, e, false);
4835 } 4948 }
4836 brcmf_link_down(ifp->vif); 4949 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
4837 brcmf_init_prof(ndev_to_prof(ndev)); 4950 brcmf_init_prof(ndev_to_prof(ndev));
4838 if (ndev != cfg_to_ndev(cfg)) 4951 if (ndev != cfg_to_ndev(cfg))
4839 complete(&cfg->vif_disabled); 4952 complete(&cfg->vif_disabled);
@@ -5774,7 +5887,7 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5774 * from AP to save power 5887 * from AP to save power
5775 */ 5888 */
5776 if (check_vif_up(ifp->vif)) { 5889 if (check_vif_up(ifp->vif)) {
5777 brcmf_link_down(ifp->vif); 5890 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
5778 5891
5779 /* Make sure WPA_Supplicant receives all the event 5892 /* Make sure WPA_Supplicant receives all the event
5780 generated due to DISASSOC call to the fw to keep 5893 generated due to DISASSOC call to the fw to keep
@@ -5876,6 +5989,29 @@ int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5876 vif_event_equals(event, action), timeout); 5989 vif_event_equals(event, action), timeout);
5877} 5990}
5878 5991
5992static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
5993 struct regulatory_request *req)
5994{
5995 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5996 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5997 struct brcmf_fil_country_le ccreq;
5998 int i;
5999
6000 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6001 req->alpha2[0], req->alpha2[1]);
6002
6003 /* ignore non-ISO3166 country codes */
6004 for (i = 0; i < sizeof(req->alpha2); i++)
6005 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6006 brcmf_err("not a ISO3166 code\n");
6007 return;
6008 }
6009 memset(&ccreq, 0, sizeof(ccreq));
6010 ccreq.rev = cpu_to_le32(-1);
6011 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6012 brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6013}
6014
5879static void brcmf_free_wiphy(struct wiphy *wiphy) 6015static void brcmf_free_wiphy(struct wiphy *wiphy)
5880{ 6016{
5881 kfree(wiphy->iface_combinations); 6017 kfree(wiphy->iface_combinations);
@@ -5952,6 +6088,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5952 goto priv_out; 6088 goto priv_out;
5953 6089
5954 brcmf_dbg(INFO, "Registering custom regulatory\n"); 6090 brcmf_dbg(INFO, "Registering custom regulatory\n");
6091 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
5955 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 6092 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
5956 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 6093 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5957 6094
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..fe54844c75e0 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
@@ -38,6 +41,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
38 s8 eventmask[BRCMF_EVENTING_MASK_LEN]; 41 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
39 u8 buf[BRCMF_DCMD_SMLEN]; 42 u8 buf[BRCMF_DCMD_SMLEN];
40 struct brcmf_join_pref_params join_pref_params[2]; 43 struct brcmf_join_pref_params join_pref_params[2];
44 struct brcmf_rev_info_le revinfo;
45 struct brcmf_rev_info *ri;
41 char *ptr; 46 char *ptr;
42 s32 err; 47 s32 err;
43 48
@@ -45,12 +50,37 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
45 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, 50 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
46 sizeof(ifp->mac_addr)); 51 sizeof(ifp->mac_addr));
47 if (err < 0) { 52 if (err < 0) {
48 brcmf_err("Retreiving cur_etheraddr failed, %d\n", 53 brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
49 err);
50 goto done; 54 goto done;
51 } 55 }
52 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac)); 56 memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
53 57
58 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO,
59 &revinfo, sizeof(revinfo));
60 ri = &ifp->drvr->revinfo;
61 if (err < 0) {
62 brcmf_err("retrieving revision info failed, %d\n", err);
63 } else {
64 ri->vendorid = le32_to_cpu(revinfo.vendorid);
65 ri->deviceid = le32_to_cpu(revinfo.deviceid);
66 ri->radiorev = le32_to_cpu(revinfo.radiorev);
67 ri->chiprev = le32_to_cpu(revinfo.chiprev);
68 ri->corerev = le32_to_cpu(revinfo.corerev);
69 ri->boardid = le32_to_cpu(revinfo.boardid);
70 ri->boardvendor = le32_to_cpu(revinfo.boardvendor);
71 ri->boardrev = le32_to_cpu(revinfo.boardrev);
72 ri->driverrev = le32_to_cpu(revinfo.driverrev);
73 ri->ucoderev = le32_to_cpu(revinfo.ucoderev);
74 ri->bus = le32_to_cpu(revinfo.bus);
75 ri->chipnum = le32_to_cpu(revinfo.chipnum);
76 ri->phytype = le32_to_cpu(revinfo.phytype);
77 ri->phyrev = le32_to_cpu(revinfo.phyrev);
78 ri->anarev = le32_to_cpu(revinfo.anarev);
79 ri->chippkg = le32_to_cpu(revinfo.chippkg);
80 ri->nvramrev = le32_to_cpu(revinfo.nvramrev);
81 }
82 ri->result = err;
83
54 /* query for 'ver' to get version info from firmware */ 84 /* query for 'ver' to get version info from firmware */
55 memset(buf, 0, sizeof(buf)); 85 memset(buf, 0, sizeof(buf));
56 strcpy(buf, "ver"); 86 strcpy(buf, "ver");
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.h b/drivers/net/wireless/brcm80211/brcmfmac/common.h
index 2f2229edb498..0d39d80cee28 100644
--- a/drivers/net/wireless/ath/wil6210/wil_platform_msm.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.h
@@ -1,5 +1,4 @@
1/* 1/* Copyright (c) 2014 Broadcom Corporation
2 * Copyright (c) 2014 Qualcomm Atheros, Inc.
3 * 2 *
4 * Permission to use, copy, modify, and/or distribute this software for any 3 * 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 4 * purpose with or without fee is hereby granted, provided that the above
@@ -7,18 +6,15 @@
7 * 6 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 14 */
15#ifndef BRCMFMAC_COMMON_H
16#define BRCMFMAC_COMMON_H
16 17
17#ifndef __WIL_PLATFORM__MSM_H__ 18extern const u8 ALLFFMAC[ETH_ALEN];
18#define __WIL_PLATFORM_MSM_H__
19 19
20#include "wil_platform.h" 20#endif /* BRCMFMAC_COMMON_H */
21
22void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops);
23
24#endif /* __WIL_PLATFORM__MSM_H__ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
index 002336e35764..3d404016a92e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/commonring.h
@@ -37,6 +37,8 @@ struct brcmf_commonring {
37 unsigned long flags; 37 unsigned long flags;
38 bool inited; 38 bool inited;
39 bool was_full; 39 bool was_full;
40
41 atomic_t outstanding_tx;
40}; 42};
41 43
42 44
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.c b/drivers/net/wireless/brcm80211/brcmfmac/core.c
index effe6d7831d9..2d6e2cc1b12c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -197,7 +197,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
197 brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); 197 brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
198 198
199 /* Can the device send data? */ 199 /* Can the device send data? */
200 if (drvr->bus_if->state != BRCMF_BUS_DATA) { 200 if (drvr->bus_if->state != BRCMF_BUS_UP) {
201 brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); 201 brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state);
202 netif_stop_queue(ndev); 202 netif_stop_queue(ndev);
203 dev_kfree_skb(skb); 203 dev_kfree_skb(skb);
@@ -601,9 +601,12 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
601{ 601{
602 struct brcmf_if *ifp = netdev_priv(ndev); 602 struct brcmf_if *ifp = netdev_priv(ndev);
603 struct brcmf_pub *drvr = ifp->drvr; 603 struct brcmf_pub *drvr = ifp->drvr;
604 char drev[BRCMU_DOTREV_LEN] = "n/a";
604 605
606 if (drvr->revinfo.result == 0)
607 brcmu_dotrev_str(drvr->revinfo.driverrev, drev);
605 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 608 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
606 snprintf(info->version, sizeof(info->version), "n/a"); 609 strlcpy(info->version, drev, sizeof(info->version));
607 strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version)); 610 strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
608 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev), 611 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
609 sizeof(info->bus_info)); 612 sizeof(info->bus_info));
@@ -637,7 +640,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
637 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); 640 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
638 641
639 /* If bus is not ready, can't continue */ 642 /* If bus is not ready, can't continue */
640 if (bus_if->state != BRCMF_BUS_DATA) { 643 if (bus_if->state != BRCMF_BUS_UP) {
641 brcmf_err("failed bus is not ready\n"); 644 brcmf_err("failed bus is not ready\n");
642 return -EAGAIN; 645 return -EAGAIN;
643 } 646 }
@@ -964,13 +967,20 @@ int brcmf_bus_start(struct device *dev)
964 p2p_ifp = NULL; 967 p2p_ifp = NULL;
965 968
966 /* signal bus ready */ 969 /* signal bus ready */
967 brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA); 970 brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);
968 971
969 /* Bus is ready, do any initialization */ 972 /* Bus is ready, do any initialization */
970 ret = brcmf_c_preinit_dcmds(ifp); 973 ret = brcmf_c_preinit_dcmds(ifp);
971 if (ret < 0) 974 if (ret < 0)
972 goto fail; 975 goto fail;
973 976
977 /* assure we have chipid before feature attach */
978 if (!bus_if->chip) {
979 bus_if->chip = drvr->revinfo.chipnum;
980 bus_if->chiprev = drvr->revinfo.chiprev;
981 brcmf_dbg(INFO, "firmware revinfo: chip %x (%d) rev %d\n",
982 bus_if->chip, bus_if->chip, bus_if->chiprev);
983 }
974 brcmf_feat_attach(drvr); 984 brcmf_feat_attach(drvr);
975 985
976 ret = brcmf_fws_init(drvr); 986 ret = brcmf_fws_init(drvr);
@@ -1093,9 +1103,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1093 return atomic_read(&ifp->pend_8021x_cnt); 1103 return atomic_read(&ifp->pend_8021x_cnt);
1094} 1104}
1095 1105
1096int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 1106int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp)
1097{ 1107{
1098 struct brcmf_if *ifp = netdev_priv(ndev);
1099 int err; 1108 int err;
1100 1109
1101 err = wait_event_timeout(ifp->pend_8021x_wait, 1110 err = wait_event_timeout(ifp->pend_8021x_wait,
@@ -1107,6 +1116,27 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
1107 return !err; 1116 return !err;
1108} 1117}
1109 1118
1119void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state)
1120{
1121 struct brcmf_pub *drvr = bus->drvr;
1122 struct net_device *ndev;
1123 int ifidx;
1124
1125 brcmf_dbg(TRACE, "%d -> %d\n", bus->state, state);
1126 bus->state = state;
1127
1128 if (state == BRCMF_BUS_UP) {
1129 for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) {
1130 if ((drvr->iflist[ifidx]) &&
1131 (drvr->iflist[ifidx]->ndev)) {
1132 ndev = drvr->iflist[ifidx]->ndev;
1133 if (netif_queue_stopped(ndev))
1134 netif_wake_queue(ndev);
1135 }
1136 }
1137 }
1138}
1139
1110static void brcmf_driver_register(struct work_struct *work) 1140static void brcmf_driver_register(struct work_struct *work)
1111{ 1141{
1112#ifdef CONFIG_BRCMFMAC_SDIO 1142#ifdef CONFIG_BRCMFMAC_SDIO
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/core.h b/drivers/net/wireless/brcm80211/brcmfmac/core.h
index 23f74b139cc8..fd74a9c6e9ac 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
@@ -73,6 +71,35 @@ struct brcmf_proto; /* device communication protocol info */
73struct brcmf_cfg80211_dev; /* cfg80211 device info */ 71struct brcmf_cfg80211_dev; /* cfg80211 device info */
74struct brcmf_fws_info; /* firmware signalling info */ 72struct brcmf_fws_info; /* firmware signalling info */
75 73
74/*
75 * struct brcmf_rev_info
76 *
77 * The result field stores the error code of the
78 * revision info request from firmware. For the
79 * other fields see struct brcmf_rev_info_le in
80 * fwil_types.h
81 */
82struct brcmf_rev_info {
83 int result;
84 u32 vendorid;
85 u32 deviceid;
86 u32 radiorev;
87 u32 chiprev;
88 u32 corerev;
89 u32 boardid;
90 u32 boardvendor;
91 u32 boardrev;
92 u32 driverrev;
93 u32 ucoderev;
94 u32 bus;
95 u32 chipnum;
96 u32 phytype;
97 u32 phyrev;
98 u32 anarev;
99 u32 chippkg;
100 u32 nvramrev;
101};
102
76/* Common structure for module and instance linkage */ 103/* Common structure for module and instance linkage */
77struct brcmf_pub { 104struct brcmf_pub {
78 /* Linkage ponters */ 105 /* Linkage ponters */
@@ -106,6 +133,7 @@ struct brcmf_pub {
106 u32 feat_flags; 133 u32 feat_flags;
107 u32 chip_quirks; 134 u32 chip_quirks;
108 135
136 struct brcmf_rev_info revinfo;
109#ifdef DEBUG 137#ifdef DEBUG
110 struct dentry *dbgfs_dir; 138 struct dentry *dbgfs_dir;
111#endif 139#endif
@@ -167,7 +195,7 @@ struct brcmf_skb_reorder_data {
167 u8 *reorder; 195 u8 *reorder;
168}; 196};
169 197
170int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 198int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp);
171 199
172/* Return pointer to interface name */ 200/* Return pointer to interface name */
173char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 201char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
index 1ff787d1a36b..9cb99152ad17 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -103,7 +103,11 @@ static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
103 103
104 c = nvp->fwnv->data[nvp->pos]; 104 c = nvp->fwnv->data[nvp->pos];
105 if (c == '=') { 105 if (c == '=') {
106 st = VALUE; 106 /* ignore RAW1 by treating as comment */
107 if (strncmp(&nvp->fwnv->data[nvp->entry], "RAW1", 4) == 0)
108 st = COMMENT;
109 else
110 st = VALUE;
107 } else if (!is_nvram_char(c)) { 111 } else if (!is_nvram_char(c)) {
108 brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", 112 brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
109 nvp->line, nvp->column); 113 nvp->line, nvp->column);
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.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 03f2c406a17b..dcfa0bb149ce 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -109,7 +109,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
109 struct brcmf_pub *drvr = ifp->drvr; 109 struct brcmf_pub *drvr = ifp->drvr;
110 s32 err; 110 s32 err;
111 111
112 if (drvr->bus_if->state != BRCMF_BUS_DATA) { 112 if (drvr->bus_if->state != BRCMF_BUS_UP) {
113 brcmf_err("bus is down. we have nothing to do.\n"); 113 brcmf_err("bus is down. we have nothing to do.\n");
114 return -EIO; 114 return -EIO;
115 } 115 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index a30be683f4a1..5434dcf64f7d 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
@@ -57,9 +59,12 @@
57#define BRCMF_C_SET_COUNTRY 84 59#define BRCMF_C_SET_COUNTRY 84
58#define BRCMF_C_GET_PM 85 60#define BRCMF_C_GET_PM 85
59#define BRCMF_C_SET_PM 86 61#define BRCMF_C_SET_PM 86
62#define BRCMF_C_GET_REVINFO 98
60#define BRCMF_C_GET_CURR_RATESET 114 63#define BRCMF_C_GET_CURR_RATESET 114
61#define BRCMF_C_GET_AP 117 64#define BRCMF_C_GET_AP 117
62#define BRCMF_C_SET_AP 118 65#define BRCMF_C_SET_AP 118
66#define BRCMF_C_SET_SCB_AUTHORIZE 121
67#define BRCMF_C_SET_SCB_DEAUTHORIZE 122
63#define BRCMF_C_GET_RSSI 127 68#define BRCMF_C_GET_RSSI 127
64#define BRCMF_C_GET_WSEC 133 69#define BRCMF_C_GET_WSEC 133
65#define BRCMF_C_SET_WSEC 134 70#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..374920965108 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,58 @@ 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
542/**
543 * struct brcmf_rev_info_le - device revision info.
544 *
545 * @vendorid: PCI vendor id.
546 * @deviceid: device id of chip.
547 * @radiorev: radio revision.
548 * @chiprev: chip revision.
549 * @corerev: core revision.
550 * @boardid: board identifier (usu. PCI sub-device id).
551 * @boardvendor: board vendor (usu. PCI sub-vendor id).
552 * @boardrev: board revision.
553 * @driverrev: driver version.
554 * @ucoderev: microcode version.
555 * @bus: bus type.
556 * @chipnum: chip number.
557 * @phytype: phy type.
558 * @phyrev: phy revision.
559 * @anarev: anacore rev.
560 * @chippkg: chip package info.
561 * @nvramrev: nvram revision number.
562 */
563struct brcmf_rev_info_le {
564 __le32 vendorid;
565 __le32 deviceid;
566 __le32 radiorev;
567 __le32 chiprev;
568 __le32 corerev;
569 __le32 boardid;
570 __le32 boardvendor;
571 __le32 boardrev;
572 __le32 driverrev;
573 __le32 ucoderev;
574 __le32 bus;
575 __le32 chipnum;
576 __le32 phytype;
577 __le32 phyrev;
578 __le32 anarev;
579 __le32 chippkg;
580 __le32 nvramrev;
581};
582
528#endif /* FWIL_TYPES_H_ */ 583#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 456944a6a2db..6262612dec45 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -73,6 +73,8 @@
73#define BRCMF_MSGBUF_TX_FLUSH_CNT1 32 73#define BRCMF_MSGBUF_TX_FLUSH_CNT1 32
74#define BRCMF_MSGBUF_TX_FLUSH_CNT2 96 74#define BRCMF_MSGBUF_TX_FLUSH_CNT2 96
75 75
76#define BRCMF_MSGBUF_DELAY_TXWORKER_THRS 64
77#define BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS 32
76 78
77struct msgbuf_common_hdr { 79struct msgbuf_common_hdr {
78 u8 msgtype; 80 u8 msgtype;
@@ -583,7 +585,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
583 u32 flowid; 585 u32 flowid;
584 void *dma_buf; 586 void *dma_buf;
585 u32 dma_sz; 587 u32 dma_sz;
586 long long address; 588 u64 address;
587 int err; 589 int err;
588 590
589 flowid = work->flowid; 591 flowid = work->flowid;
@@ -620,7 +622,7 @@ brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf,
620 BRCMF_NROF_H2D_COMMON_MSGRINGS); 622 BRCMF_NROF_H2D_COMMON_MSGRINGS);
621 memcpy(create->sa, work->sa, ETH_ALEN); 623 memcpy(create->sa, work->sa, ETH_ALEN);
622 memcpy(create->da, work->da, ETH_ALEN); 624 memcpy(create->da, work->da, ETH_ALEN);
623 address = (long long)(long)msgbuf->flowring_dma_handle[flowid]; 625 address = (u64)msgbuf->flowring_dma_handle[flowid];
624 create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32); 626 create->flow_ring_addr.high_addr = cpu_to_le32(address >> 32);
625 create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff); 627 create->flow_ring_addr.low_addr = cpu_to_le32(address & 0xffffffff);
626 create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM); 628 create->max_items = cpu_to_le16(BRCMF_H2D_TXFLOWRING_MAX_ITEM);
@@ -698,7 +700,7 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid)
698 dma_addr_t physaddr; 700 dma_addr_t physaddr;
699 u32 pktid; 701 u32 pktid;
700 struct msgbuf_tx_msghdr *tx_msghdr; 702 struct msgbuf_tx_msghdr *tx_msghdr;
701 long long address; 703 u64 address;
702 704
703 commonring = msgbuf->flowrings[flowid]; 705 commonring = msgbuf->flowrings[flowid];
704 if (!brcmf_commonring_write_available(commonring)) 706 if (!brcmf_commonring_write_available(commonring))
@@ -742,13 +744,14 @@ static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid)
742 tx_msghdr->seg_cnt = 1; 744 tx_msghdr->seg_cnt = 1;
743 memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN); 745 memcpy(tx_msghdr->txhdr, skb->data, ETH_HLEN);
744 tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN); 746 tx_msghdr->data_len = cpu_to_le16(skb->len - ETH_HLEN);
745 address = (long long)(long)physaddr; 747 address = (u64)physaddr;
746 tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32); 748 tx_msghdr->data_buf_addr.high_addr = cpu_to_le32(address >> 32);
747 tx_msghdr->data_buf_addr.low_addr = 749 tx_msghdr->data_buf_addr.low_addr =
748 cpu_to_le32(address & 0xffffffff); 750 cpu_to_le32(address & 0xffffffff);
749 tx_msghdr->metadata_buf_len = 0; 751 tx_msghdr->metadata_buf_len = 0;
750 tx_msghdr->metadata_buf_addr.high_addr = 0; 752 tx_msghdr->metadata_buf_addr.high_addr = 0;
751 tx_msghdr->metadata_buf_addr.low_addr = 0; 753 tx_msghdr->metadata_buf_addr.low_addr = 0;
754 atomic_inc(&commonring->outstanding_tx);
752 if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) { 755 if (count >= BRCMF_MSGBUF_TX_FLUSH_CNT2) {
753 brcmf_commonring_write_complete(commonring); 756 brcmf_commonring_write_complete(commonring);
754 count = 0; 757 count = 0;
@@ -773,10 +776,16 @@ static void brcmf_msgbuf_txflow_worker(struct work_struct *worker)
773} 776}
774 777
775 778
776static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid) 779static int brcmf_msgbuf_schedule_txdata(struct brcmf_msgbuf *msgbuf, u32 flowid,
780 bool force)
777{ 781{
782 struct brcmf_commonring *commonring;
783
778 set_bit(flowid, msgbuf->flow_map); 784 set_bit(flowid, msgbuf->flow_map);
779 queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work); 785 commonring = msgbuf->flowrings[flowid];
786 if ((force) || (atomic_read(&commonring->outstanding_tx) <
787 BRCMF_MSGBUF_DELAY_TXWORKER_THRS))
788 queue_work(msgbuf->txflow_wq, &msgbuf->txflow_work);
780 789
781 return 0; 790 return 0;
782} 791}
@@ -797,7 +806,7 @@ static int brcmf_msgbuf_txdata(struct brcmf_pub *drvr, int ifidx,
797 return -ENOMEM; 806 return -ENOMEM;
798 } 807 }
799 brcmf_flowring_enqueue(flow, flowid, skb); 808 brcmf_flowring_enqueue(flow, flowid, skb);
800 brcmf_msgbuf_schedule_txdata(msgbuf, flowid); 809 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, false);
801 810
802 return 0; 811 return 0;
803} 812}
@@ -854,6 +863,7 @@ brcmf_msgbuf_process_ioctl_complete(struct brcmf_msgbuf *msgbuf, void *buf)
854static void 863static void
855brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf) 864brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
856{ 865{
866 struct brcmf_commonring *commonring;
857 struct msgbuf_tx_status *tx_status; 867 struct msgbuf_tx_status *tx_status;
858 u32 idx; 868 u32 idx;
859 struct sk_buff *skb; 869 struct sk_buff *skb;
@@ -871,6 +881,8 @@ brcmf_msgbuf_process_txstatus(struct brcmf_msgbuf *msgbuf, void *buf)
871 } 881 }
872 882
873 set_bit(flowid, msgbuf->txstatus_done_map); 883 set_bit(flowid, msgbuf->txstatus_done_map);
884 commonring = msgbuf->flowrings[flowid];
885 atomic_dec(&commonring->outstanding_tx);
874 886
875 brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true); 887 brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true);
876} 888}
@@ -885,7 +897,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
885 u32 pktlen; 897 u32 pktlen;
886 dma_addr_t physaddr; 898 dma_addr_t physaddr;
887 struct msgbuf_rx_bufpost *rx_bufpost; 899 struct msgbuf_rx_bufpost *rx_bufpost;
888 long long address; 900 u64 address;
889 u32 pktid; 901 u32 pktid;
890 u32 i; 902 u32 i;
891 903
@@ -894,7 +906,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
894 count, 906 count,
895 &alloced); 907 &alloced);
896 if (!ret_ptr) { 908 if (!ret_ptr) {
897 brcmf_err("Failed to reserve space in commonring\n"); 909 brcmf_dbg(MSGBUF, "Failed to reserve space in commonring\n");
898 return 0; 910 return 0;
899 } 911 }
900 912
@@ -921,7 +933,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
921 } 933 }
922 934
923 if (msgbuf->rx_metadata_offset) { 935 if (msgbuf->rx_metadata_offset) {
924 address = (long long)(long)physaddr; 936 address = (u64)physaddr;
925 rx_bufpost->metadata_buf_len = 937 rx_bufpost->metadata_buf_len =
926 cpu_to_le16(msgbuf->rx_metadata_offset); 938 cpu_to_le16(msgbuf->rx_metadata_offset);
927 rx_bufpost->metadata_buf_addr.high_addr = 939 rx_bufpost->metadata_buf_addr.high_addr =
@@ -936,7 +948,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count)
936 rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST; 948 rx_bufpost->msg.msgtype = MSGBUF_TYPE_RXBUF_POST;
937 rx_bufpost->msg.request_id = cpu_to_le32(pktid); 949 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
938 950
939 address = (long long)(long)physaddr; 951 address = (u64)physaddr;
940 rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen); 952 rx_bufpost->data_buf_len = cpu_to_le16((u16)pktlen);
941 rx_bufpost->data_buf_addr.high_addr = 953 rx_bufpost->data_buf_addr.high_addr =
942 cpu_to_le32(address >> 32); 954 cpu_to_le32(address >> 32);
@@ -992,7 +1004,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
992 u32 pktlen; 1004 u32 pktlen;
993 dma_addr_t physaddr; 1005 dma_addr_t physaddr;
994 struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost; 1006 struct msgbuf_rx_ioctl_resp_or_event *rx_bufpost;
995 long long address; 1007 u64 address;
996 u32 pktid; 1008 u32 pktid;
997 u32 i; 1009 u32 i;
998 1010
@@ -1035,7 +1047,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf,
1035 MSGBUF_TYPE_IOCTLRESP_BUF_POST; 1047 MSGBUF_TYPE_IOCTLRESP_BUF_POST;
1036 rx_bufpost->msg.request_id = cpu_to_le32(pktid); 1048 rx_bufpost->msg.request_id = cpu_to_le32(pktid);
1037 1049
1038 address = (long long)(long)physaddr; 1050 address = (u64)physaddr;
1039 rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen); 1051 rx_bufpost->host_buf_len = cpu_to_le16((u16)pktlen);
1040 rx_bufpost->host_buf_addr.high_addr = 1052 rx_bufpost->host_buf_addr.high_addr =
1041 cpu_to_le32(address >> 32); 1053 cpu_to_le32(address >> 32);
@@ -1181,7 +1193,7 @@ brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf,
1181 1193
1182 brcmf_flowring_open(msgbuf->flow, flowid); 1194 brcmf_flowring_open(msgbuf->flow, flowid);
1183 1195
1184 brcmf_msgbuf_schedule_txdata(msgbuf, flowid); 1196 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);
1185} 1197}
1186 1198
1187 1199
@@ -1280,8 +1292,10 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
1280 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 1292 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1281 struct brcmf_pub *drvr = bus_if->drvr; 1293 struct brcmf_pub *drvr = bus_if->drvr;
1282 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; 1294 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
1295 struct brcmf_commonring *commonring;
1283 void *buf; 1296 void *buf;
1284 u32 flowid; 1297 u32 flowid;
1298 int qlen;
1285 1299
1286 buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE]; 1300 buf = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
1287 brcmf_msgbuf_process_rx(msgbuf, buf); 1301 brcmf_msgbuf_process_rx(msgbuf, buf);
@@ -1293,8 +1307,12 @@ int brcmf_proto_msgbuf_rx_trigger(struct device *dev)
1293 for_each_set_bit(flowid, msgbuf->txstatus_done_map, 1307 for_each_set_bit(flowid, msgbuf->txstatus_done_map,
1294 msgbuf->nrof_flowrings) { 1308 msgbuf->nrof_flowrings) {
1295 clear_bit(flowid, msgbuf->txstatus_done_map); 1309 clear_bit(flowid, msgbuf->txstatus_done_map);
1296 if (brcmf_flowring_qlen(msgbuf->flow, flowid)) 1310 commonring = msgbuf->flowrings[flowid];
1297 brcmf_msgbuf_schedule_txdata(msgbuf, flowid); 1311 qlen = brcmf_flowring_qlen(msgbuf->flow, flowid);
1312 if ((qlen > BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS) ||
1313 ((qlen) && (atomic_read(&commonring->outstanding_tx) <
1314 BRCMF_MSGBUF_TRICKLE_TXWORKER_THRS)))
1315 brcmf_msgbuf_schedule_txdata(msgbuf, flowid, true);
1298 } 1316 }
1299 1317
1300 return 0; 1318 return 0;
@@ -1348,7 +1366,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1348{ 1366{
1349 struct brcmf_bus_msgbuf *if_msgbuf; 1367 struct brcmf_bus_msgbuf *if_msgbuf;
1350 struct brcmf_msgbuf *msgbuf; 1368 struct brcmf_msgbuf *msgbuf;
1351 long long address; 1369 u64 address;
1352 u32 count; 1370 u32 count;
1353 1371
1354 if_msgbuf = drvr->bus_if->msgbuf; 1372 if_msgbuf = drvr->bus_if->msgbuf;
@@ -1379,7 +1397,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
1379 GFP_KERNEL); 1397 GFP_KERNEL);
1380 if (!msgbuf->ioctbuf) 1398 if (!msgbuf->ioctbuf)
1381 goto fail; 1399 goto fail;
1382 address = (long long)(long)msgbuf->ioctbuf_handle; 1400 address = (u64)msgbuf->ioctbuf_handle;
1383 msgbuf->ioctbuf_phys_hi = address >> 32; 1401 msgbuf->ioctbuf_phys_hi = address >> 32;
1384 msgbuf->ioctbuf_phys_lo = address & 0xffffffff; 1402 msgbuf->ioctbuf_phys_lo = address & 0xffffffff;
1385 1403
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 905991fdb7b1..61c053a729be 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 +
@@ -1828,7 +1828,7 @@ static int brcmf_pcie_resume(struct pci_dev *pdev)
1828 goto cleanup; 1828 goto cleanup;
1829 brcmf_dbg(PCIE, "Hot resume, continue....\n"); 1829 brcmf_dbg(PCIE, "Hot resume, continue....\n");
1830 brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); 1830 brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
1831 brcmf_bus_change_state(bus, BRCMF_BUS_DATA); 1831 brcmf_bus_change_state(bus, BRCMF_BUS_UP);
1832 brcmf_pcie_intr_enable(devinfo); 1832 brcmf_pcie_intr_enable(devinfo);
1833 return 0; 1833 return 0;
1834 } 1834 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index 0b0d51a61060..faec35c899ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -44,7 +44,8 @@
44#include "chip.h" 44#include "chip.h"
45#include "firmware.h" 45#include "firmware.h"
46 46
47#define DCMD_RESP_TIMEOUT 2000 /* In milli second */ 47#define DCMD_RESP_TIMEOUT 2000 /* In milli second */
48#define CTL_DONE_TIMEOUT 2000 /* In milli second */
48 49
49#ifdef DEBUG 50#ifdef DEBUG
50 51
@@ -495,9 +496,9 @@ struct brcmf_sdio {
495 u8 *ctrl_frame_buf; 496 u8 *ctrl_frame_buf;
496 u16 ctrl_frame_len; 497 u16 ctrl_frame_len;
497 bool ctrl_frame_stat; 498 bool ctrl_frame_stat;
499 int ctrl_frame_err;
498 500
499 spinlock_t txq_lock; /* protect bus->txq */ 501 spinlock_t txq_lock; /* protect bus->txq */
500 struct semaphore tx_seq_lock; /* protect bus->tx_seq */
501 wait_queue_head_t ctrl_wait; 502 wait_queue_head_t ctrl_wait;
502 wait_queue_head_t dcmd_resp_wait; 503 wait_queue_head_t dcmd_resp_wait;
503 504
@@ -514,7 +515,6 @@ struct brcmf_sdio {
514 bool txoff; /* Transmit flow-controlled */ 515 bool txoff; /* Transmit flow-controlled */
515 struct brcmf_sdio_count sdcnt; 516 struct brcmf_sdio_count sdcnt;
516 bool sr_enabled; /* SaveRestore enabled */ 517 bool sr_enabled; /* SaveRestore enabled */
517 bool sleeping; /* SDIO bus sleeping */
518 518
519 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 519 u8 tx_hdrlen; /* sdio bus header length for tx packet */
520 bool txglom; /* host tx glomming enable flag */ 520 bool txglom; /* host tx glomming enable flag */
@@ -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) },
@@ -1008,12 +1013,12 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1008 1013
1009 brcmf_dbg(SDIO, "Enter: request %s currently %s\n", 1014 brcmf_dbg(SDIO, "Enter: request %s currently %s\n",
1010 (sleep ? "SLEEP" : "WAKE"), 1015 (sleep ? "SLEEP" : "WAKE"),
1011 (bus->sleeping ? "SLEEP" : "WAKE")); 1016 (bus->sdiodev->sleeping ? "SLEEP" : "WAKE"));
1012 1017
1013 /* If SR is enabled control bus state with KSO */ 1018 /* If SR is enabled control bus state with KSO */
1014 if (bus->sr_enabled) { 1019 if (bus->sr_enabled) {
1015 /* Done if we're already in the requested state */ 1020 /* Done if we're already in the requested state */
1016 if (sleep == bus->sleeping) 1021 if (sleep == bus->sdiodev->sleeping)
1017 goto end; 1022 goto end;
1018 1023
1019 /* Going to sleep */ 1024 /* Going to sleep */
@@ -1045,12 +1050,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1045 bus->idlecount = 0; 1050 bus->idlecount = 0;
1046 err = brcmf_sdio_kso_control(bus, true); 1051 err = brcmf_sdio_kso_control(bus, true);
1047 } 1052 }
1048 if (!err) { 1053 if (err) {
1049 /* Change state */
1050 bus->sleeping = sleep;
1051 brcmf_dbg(SDIO, "new state %s\n",
1052 (sleep ? "SLEEP" : "WAKE"));
1053 } else {
1054 brcmf_err("error while changing bus sleep state %d\n", 1054 brcmf_err("error while changing bus sleep state %d\n",
1055 err); 1055 err);
1056 goto done; 1056 goto done;
@@ -1065,6 +1065,11 @@ end:
1065 } else { 1065 } else {
1066 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1066 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
1067 } 1067 }
1068 bus->sdiodev->sleeping = sleep;
1069 if (sleep)
1070 wake_up(&bus->sdiodev->idle_wait);
1071 brcmf_dbg(SDIO, "new state %s\n",
1072 (sleep ? "SLEEP" : "WAKE"));
1068done: 1073done:
1069 brcmf_dbg(SDIO, "Exit: err=%d\n", err); 1074 brcmf_dbg(SDIO, "Exit: err=%d\n", err);
1070 return err; 1075 return err;
@@ -1904,7 +1909,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1904 bus->rxpending = true; 1909 bus->rxpending = true;
1905 1910
1906 for (rd->seq_num = bus->rx_seq, rxleft = maxframes; 1911 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1907 !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if); 1912 !bus->rxskip && rxleft && bus->sdiodev->state == BRCMF_STATE_DATA;
1908 rd->seq_num++, rxleft--) { 1913 rd->seq_num++, rxleft--) {
1909 1914
1910 /* Handle glomming separately */ 1915 /* Handle glomming separately */
@@ -2371,8 +2376,6 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2371 /* Send frames until the limit or some other event */ 2376 /* Send frames until the limit or some other event */
2372 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) { 2377 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
2373 pkt_num = 1; 2378 pkt_num = 1;
2374 if (down_interruptible(&bus->tx_seq_lock))
2375 return cnt;
2376 if (bus->txglom) 2379 if (bus->txglom)
2377 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, 2380 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2378 bus->sdiodev->txglomsz); 2381 bus->sdiodev->txglomsz);
@@ -2388,13 +2391,10 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2388 __skb_queue_tail(&pktq, pkt); 2391 __skb_queue_tail(&pktq, pkt);
2389 } 2392 }
2390 spin_unlock_bh(&bus->txq_lock); 2393 spin_unlock_bh(&bus->txq_lock);
2391 if (i == 0) { 2394 if (i == 0)
2392 up(&bus->tx_seq_lock);
2393 break; 2395 break;
2394 }
2395 2396
2396 ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); 2397 ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
2397 up(&bus->tx_seq_lock);
2398 2398
2399 cnt += i; 2399 cnt += i;
2400 2400
@@ -2415,7 +2415,7 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2415 } 2415 }
2416 2416
2417 /* Deflow-control stack if needed */ 2417 /* Deflow-control stack if needed */
2418 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) && 2418 if ((bus->sdiodev->state == BRCMF_STATE_DATA) &&
2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 2419 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
2420 bus->txoff = false; 2420 bus->txoff = false;
2421 brcmf_txflowblock(bus->sdiodev->dev, false); 2421 brcmf_txflowblock(bus->sdiodev->dev, false);
@@ -2503,7 +2503,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2503 bus->watchdog_tsk = NULL; 2503 bus->watchdog_tsk = NULL;
2504 } 2504 }
2505 2505
2506 if (bus_if->state == BRCMF_BUS_DOWN) { 2506 if (sdiodev->state != BRCMF_STATE_NOMEDIUM) {
2507 sdio_claim_host(sdiodev->func[1]); 2507 sdio_claim_host(sdiodev->func[1]);
2508 2508
2509 /* Enable clock for device interrupts */ 2509 /* Enable clock for device interrupts */
@@ -2538,8 +2538,7 @@ static void brcmf_sdio_bus_stop(struct device *dev)
2538 brcmu_pktq_flush(&bus->txq, true, NULL, NULL); 2538 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
2539 2539
2540 /* Clear any held glomming stuff */ 2540 /* Clear any held glomming stuff */
2541 if (bus->glomd) 2541 brcmu_pkt_buf_free_skb(bus->glomd);
2542 brcmu_pkt_buf_free_skb(bus->glomd);
2543 brcmf_sdio_free_glom(bus); 2542 brcmf_sdio_free_glom(bus);
2544 2543
2545 /* Clear rx control and wake any waiters */ 2544 /* Clear rx control and wake any waiters */
@@ -2604,6 +2603,21 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2604 return ret; 2603 return ret;
2605} 2604}
2606 2605
2606static int brcmf_sdio_pm_resume_wait(struct brcmf_sdio_dev *sdiodev)
2607{
2608#ifdef CONFIG_PM_SLEEP
2609 int retry;
2610
2611 /* Wait for possible resume to complete */
2612 retry = 0;
2613 while ((atomic_read(&sdiodev->suspend)) && (retry++ != 50))
2614 msleep(20);
2615 if (atomic_read(&sdiodev->suspend))
2616 return -EIO;
2617#endif
2618 return 0;
2619}
2620
2607static void brcmf_sdio_dpc(struct brcmf_sdio *bus) 2621static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2608{ 2622{
2609 u32 newstatus = 0; 2623 u32 newstatus = 0;
@@ -2614,6 +2628,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2614 2628
2615 brcmf_dbg(TRACE, "Enter\n"); 2629 brcmf_dbg(TRACE, "Enter\n");
2616 2630
2631 if (brcmf_sdio_pm_resume_wait(bus->sdiodev))
2632 return;
2633
2617 sdio_claim_host(bus->sdiodev->func[1]); 2634 sdio_claim_host(bus->sdiodev->func[1]);
2618 2635
2619 /* If waiting for HTAVAIL, check status */ 2636 /* If waiting for HTAVAIL, check status */
@@ -2720,17 +2737,14 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2720 brcmf_sdio_clrintr(bus); 2737 brcmf_sdio_clrintr(bus);
2721 2738
2722 if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && 2739 if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
2723 (down_interruptible(&bus->tx_seq_lock) == 0)) { 2740 data_ok(bus)) {
2724 if (data_ok(bus)) { 2741 sdio_claim_host(bus->sdiodev->func[1]);
2725 sdio_claim_host(bus->sdiodev->func[1]); 2742 err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
2726 err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, 2743 bus->ctrl_frame_len);
2727 bus->ctrl_frame_len); 2744 sdio_release_host(bus->sdiodev->func[1]);
2728 sdio_release_host(bus->sdiodev->func[1]); 2745 bus->ctrl_frame_err = err;
2729 2746 bus->ctrl_frame_stat = false;
2730 bus->ctrl_frame_stat = false; 2747 brcmf_sdio_wait_event_wakeup(bus);
2731 brcmf_sdio_wait_event_wakeup(bus);
2732 }
2733 up(&bus->tx_seq_lock);
2734 } 2748 }
2735 /* Send queued frames (limit 1 if rx may still be pending) */ 2749 /* Send queued frames (limit 1 if rx may still be pending) */
2736 if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) && 2750 if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
@@ -2741,7 +2755,7 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2741 brcmf_sdio_sendfromq(bus, framecnt); 2755 brcmf_sdio_sendfromq(bus, framecnt);
2742 } 2756 }
2743 2757
2744 if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) { 2758 if ((bus->sdiodev->state != BRCMF_STATE_DATA) || (err != 0)) {
2745 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2759 brcmf_err("failed backplane access over SDIO, halting operation\n");
2746 atomic_set(&bus->intstatus, 0); 2760 atomic_set(&bus->intstatus, 0);
2747 } else if (atomic_read(&bus->intstatus) || 2761 } else if (atomic_read(&bus->intstatus) ||
@@ -2942,43 +2956,30 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2942 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2956 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2943 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2957 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2944 struct brcmf_sdio *bus = sdiodev->bus; 2958 struct brcmf_sdio *bus = sdiodev->bus;
2945 int ret = -1; 2959 int ret;
2946 2960
2947 brcmf_dbg(TRACE, "Enter\n"); 2961 brcmf_dbg(TRACE, "Enter\n");
2948 2962
2949 if (down_interruptible(&bus->tx_seq_lock)) 2963 /* Send from dpc */
2950 return -EINTR; 2964 bus->ctrl_frame_buf = msg;
2951 2965 bus->ctrl_frame_len = msglen;
2952 if (!data_ok(bus)) { 2966 bus->ctrl_frame_stat = true;
2953 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", 2967 if (atomic_read(&bus->dpc_tskcnt) == 0) {
2954 bus->tx_max, bus->tx_seq); 2968 atomic_inc(&bus->dpc_tskcnt);
2955 up(&bus->tx_seq_lock); 2969 queue_work(bus->brcmf_wq, &bus->datawork);
2956 /* Send from dpc */
2957 bus->ctrl_frame_buf = msg;
2958 bus->ctrl_frame_len = msglen;
2959 bus->ctrl_frame_stat = true;
2960
2961 wait_event_interruptible_timeout(bus->ctrl_wait,
2962 !bus->ctrl_frame_stat,
2963 msecs_to_jiffies(2000));
2964
2965 if (!bus->ctrl_frame_stat) {
2966 brcmf_dbg(SDIO, "ctrl_frame_stat == false\n");
2967 ret = 0;
2968 } else {
2969 brcmf_dbg(SDIO, "ctrl_frame_stat == true\n");
2970 bus->ctrl_frame_stat = false;
2971 if (down_interruptible(&bus->tx_seq_lock))
2972 return -EINTR;
2973 ret = -1;
2974 }
2975 } 2970 }
2976 if (ret == -1) { 2971
2977 sdio_claim_host(bus->sdiodev->func[1]); 2972 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
2978 brcmf_sdio_bus_sleep(bus, false, false); 2973 msecs_to_jiffies(CTL_DONE_TIMEOUT));
2979 ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen); 2974
2980 sdio_release_host(bus->sdiodev->func[1]); 2975 if (!bus->ctrl_frame_stat) {
2981 up(&bus->tx_seq_lock); 2976 brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
2977 bus->ctrl_frame_err);
2978 ret = bus->ctrl_frame_err;
2979 } else {
2980 brcmf_dbg(SDIO, "ctrl_frame timeout\n");
2981 bus->ctrl_frame_stat = false;
2982 ret = -ETIMEDOUT;
2982 } 2983 }
2983 2984
2984 if (ret) 2985 if (ret)
@@ -2986,7 +2987,7 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2986 else 2987 else
2987 bus->sdcnt.tx_ctlpkts++; 2988 bus->sdcnt.tx_ctlpkts++;
2988 2989
2989 return ret ? -EIO : 0; 2990 return ret;
2990} 2991}
2991 2992
2992#ifdef DEBUG 2993#ifdef DEBUG
@@ -3409,8 +3410,8 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3409 goto err; 3410 goto err;
3410 } 3411 }
3411 3412
3412 /* Allow HT Clock now that the ARM is running. */ 3413 /* Allow full data communication using DPC from now on. */
3413 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD); 3414 bus->sdiodev->state = BRCMF_STATE_DATA;
3414 bcmerror = 0; 3415 bcmerror = 0;
3415 3416
3416err: 3417err:
@@ -3556,7 +3557,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3556 return; 3557 return;
3557 } 3558 }
3558 3559
3559 if (!brcmf_bus_ready(bus->sdiodev->bus_if)) { 3560 if (bus->sdiodev->state != BRCMF_STATE_DATA) {
3560 brcmf_err("bus is down. we have nothing to do\n"); 3561 brcmf_err("bus is down. we have nothing to do\n");
3561 return; 3562 return;
3562 } 3563 }
@@ -3579,10 +3580,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3579 3580
3580static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) 3581static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3581{ 3582{
3582#ifdef DEBUG
3583 struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
3584#endif /* DEBUG */
3585
3586 brcmf_dbg(TIMER, "Enter\n"); 3583 brcmf_dbg(TIMER, "Enter\n");
3587 3584
3588 /* Poll period: check device if appropriate. */ 3585 /* Poll period: check device if appropriate. */
@@ -3626,7 +3623,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3626 } 3623 }
3627#ifdef DEBUG 3624#ifdef DEBUG
3628 /* Poll for console output periodically */ 3625 /* Poll for console output periodically */
3629 if (bus_if && bus_if->state == BRCMF_BUS_DATA && 3626 if (bus->sdiodev->state == BRCMF_STATE_DATA &&
3630 bus->console_interval != 0) { 3627 bus->console_interval != 0) {
3631 bus->console.count += BRCMF_WD_POLL_MS; 3628 bus->console.count += BRCMF_WD_POLL_MS;
3632 if (bus->console.count >= bus->console_interval) { 3629 if (bus->console.count >= bus->console_interval) {
@@ -3811,7 +3808,7 @@ static u32 brcmf_sdio_buscore_read32(void *ctx, u32 addr)
3811 u32 val, rev; 3808 u32 val, rev;
3812 3809
3813 val = brcmf_sdiod_regrl(sdiodev, addr, NULL); 3810 val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
3814 if (sdiodev->func[0]->device == BRCM_SDIO_4335_4339_DEVICE_ID && 3811 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
3815 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { 3812 addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
3816 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; 3813 rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
3817 if (rev >= 2) { 3814 if (rev >= 2) {
@@ -3867,11 +3864,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3867 goto fail; 3864 goto fail;
3868 } 3865 }
3869 3866
3870 /* SDIO register access works so moving
3871 * state from UNKNOWN to DOWN.
3872 */
3873 brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);
3874
3875 bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); 3867 bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops);
3876 if (IS_ERR(bus->ci)) { 3868 if (IS_ERR(bus->ci)) {
3877 brcmf_err("brcmf_chip_attach failed!\n"); 3869 brcmf_err("brcmf_chip_attach failed!\n");
@@ -4005,18 +3997,16 @@ static void brcmf_sdio_firmware_callback(struct device *dev,
4005 3997
4006 brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev)); 3998 brcmf_dbg(TRACE, "Enter: dev=%s\n", dev_name(dev));
4007 3999
4008 /* try to download image and nvram to the dongle */
4009 if (bus_if->state == BRCMF_BUS_DOWN) {
4010 bus->alp_only = true;
4011 err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
4012 if (err)
4013 goto fail;
4014 bus->alp_only = false;
4015 }
4016
4017 if (!bus_if->drvr) 4000 if (!bus_if->drvr)
4018 return; 4001 return;
4019 4002
4003 /* try to download image and nvram to the dongle */
4004 bus->alp_only = true;
4005 err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
4006 if (err)
4007 goto fail;
4008 bus->alp_only = false;
4009
4020 /* Start the watchdog timer */ 4010 /* Start the watchdog timer */
4021 bus->sdcnt.tickcnt = 0; 4011 bus->sdcnt.tickcnt = 0;
4022 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); 4012 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
@@ -4142,7 +4132,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4142 4132
4143 spin_lock_init(&bus->rxctl_lock); 4133 spin_lock_init(&bus->rxctl_lock);
4144 spin_lock_init(&bus->txq_lock); 4134 spin_lock_init(&bus->txq_lock);
4145 sema_init(&bus->tx_seq_lock, 1);
4146 init_waitqueue_head(&bus->ctrl_wait); 4135 init_waitqueue_head(&bus->ctrl_wait);
4147 init_waitqueue_head(&bus->dcmd_resp_wait); 4136 init_waitqueue_head(&bus->dcmd_resp_wait);
4148 4137
@@ -4213,7 +4202,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4213 bus->idleclock = BRCMF_IDLE_ACTIVE; 4202 bus->idleclock = BRCMF_IDLE_ACTIVE;
4214 4203
4215 /* SR state */ 4204 /* SR state */
4216 bus->sleeping = false;
4217 bus->sr_enabled = false; 4205 bus->sr_enabled = false;
4218 4206
4219 brcmf_sdio_debugfs_create(bus); 4207 brcmf_sdio_debugfs_create(bus);
@@ -4254,7 +4242,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4254 destroy_workqueue(bus->brcmf_wq); 4242 destroy_workqueue(bus->brcmf_wq);
4255 4243
4256 if (bus->ci) { 4244 if (bus->ci) {
4257 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { 4245 if (bus->sdiodev->state != BRCMF_STATE_NOMEDIUM) {
4258 sdio_claim_host(bus->sdiodev->func[1]); 4246 sdio_claim_host(bus->sdiodev->func[1]);
4259 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4247 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4260 /* Leave the device in state where it is 4248 /* Leave the device in state where it is
@@ -4289,7 +4277,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick)
4289 } 4277 }
4290 4278
4291 /* don't start the wd until fw is loaded */ 4279 /* don't start the wd until fw is loaded */
4292 if (bus->sdiodev->bus_if->state != BRCMF_BUS_DATA) 4280 if (bus->sdiodev->state != BRCMF_STATE_DATA)
4293 return; 4281 return;
4294 4282
4295 if (wdtick) { 4283 if (wdtick) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
index 8eb42620129c..ec2586a8425c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.h
@@ -155,6 +155,13 @@
155/* watchdog polling interval in ms */ 155/* watchdog polling interval in ms */
156#define BRCMF_WD_POLL_MS 10 156#define BRCMF_WD_POLL_MS 10
157 157
158/* The state of the bus */
159enum brcmf_sdio_state {
160 BRCMF_STATE_DOWN, /* Device available, still initialising */
161 BRCMF_STATE_DATA, /* Ready for data transfers, DPC enabled */
162 BRCMF_STATE_NOMEDIUM /* No medium access to dongle possible */
163};
164
158struct brcmf_sdreg { 165struct brcmf_sdreg {
159 int func; 166 int func;
160 int offset; 167 int offset;
@@ -169,8 +176,8 @@ struct brcmf_sdio_dev {
169 u32 sbwad; /* Save backplane window address */ 176 u32 sbwad; /* Save backplane window address */
170 struct brcmf_sdio *bus; 177 struct brcmf_sdio *bus;
171 atomic_t suspend; /* suspend flag */ 178 atomic_t suspend; /* suspend flag */
172 wait_queue_head_t request_word_wait; 179 bool sleeping;
173 wait_queue_head_t request_buffer_wait; 180 wait_queue_head_t idle_wait;
174 struct device *dev; 181 struct device *dev;
175 struct brcmf_bus *bus_if; 182 struct brcmf_bus *bus_if;
176 struct brcmfmac_sdio_platform_data *pdata; 183 struct brcmfmac_sdio_platform_data *pdata;
@@ -187,6 +194,7 @@ struct brcmf_sdio_dev {
187 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 194 char fw_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
188 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN]; 195 char nvram_name[BRCMF_FW_PATH_LEN + BRCMF_FW_NAME_LEN];
189 bool wowl_enabled; 196 bool wowl_enabled;
197 enum brcmf_sdio_state state;
190}; 198};
191 199
192/* sdio core registers */ 200/* sdio core registers */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 4572defc280f..5df6aa72cc2d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -421,7 +421,7 @@ fail:
421 brcmf_err("fail!\n"); 421 brcmf_err("fail!\n");
422 while (!list_empty(q)) { 422 while (!list_empty(q)) {
423 req = list_entry(q->next, struct brcmf_usbreq, list); 423 req = list_entry(q->next, struct brcmf_usbreq, list);
424 if (req && req->urb) 424 if (req)
425 usb_free_urb(req->urb); 425 usb_free_urb(req->urb);
426 list_del(q->next); 426 list_del(q->next);
427 } 427 }
@@ -576,7 +576,7 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
576 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN); 576 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN);
577 } else if (state == BRCMFMAC_USB_STATE_UP) { 577 } else if (state == BRCMFMAC_USB_STATE_UP) {
578 brcmf_dbg(USB, "DBUS is up\n"); 578 brcmf_dbg(USB, "DBUS is up\n");
579 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DATA); 579 brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_UP);
580 } else { 580 } else {
581 brcmf_dbg(USB, "DBUS current state=%d\n", state); 581 brcmf_dbg(USB, "DBUS current state=%d\n", state);
582 } 582 }
@@ -1263,6 +1263,8 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1263 ret = brcmf_usb_bus_setup(devinfo); 1263 ret = brcmf_usb_bus_setup(devinfo);
1264 if (ret) 1264 if (ret)
1265 goto fail; 1265 goto fail;
1266 /* we are done */
1267 return 0;
1266 } 1268 }
1267 bus->chip = bus_pub->devid; 1269 bus->chip = bus_pub->devid;
1268 bus->chiprev = bus_pub->chiprev; 1270 bus->chiprev = bus_pub->chiprev;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
index c9a8b9360ab1..7a1fbb2e3a71 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
@@ -78,7 +78,7 @@ int brcms_debugfs_hardware_read(struct seq_file *s, void *data)
78 struct brcms_hardware *hw = drvr->wlc->hw; 78 struct brcms_hardware *hw = drvr->wlc->hw;
79 struct bcma_device *core = hw->d11core; 79 struct bcma_device *core = hw->d11core;
80 struct bcma_bus *bus = core->bus; 80 struct bcma_bus *bus = core->bus;
81 char boardrev[10]; 81 char boardrev[BRCMU_BOARDREV_LEN];
82 82
83 seq_printf(s, "chipnum 0x%x\n" 83 seq_printf(s, "chipnum 0x%x\n"
84 "chiprev 0x%x\n" 84 "chiprev 0x%x\n"
diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c
index 906e89ddf319..0543607002fd 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/utils.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c
@@ -267,15 +267,43 @@ char *brcmu_boardrev_str(u32 brev, char *buf)
267 char c; 267 char c;
268 268
269 if (brev < 0x100) { 269 if (brev < 0x100) {
270 snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf); 270 snprintf(buf, BRCMU_BOARDREV_LEN, "%d.%d",
271 (brev & 0xf0) >> 4, brev & 0xf);
271 } else { 272 } else {
272 c = (brev & 0xf000) == 0x1000 ? 'P' : 'A'; 273 c = (brev & 0xf000) == 0x1000 ? 'P' : 'A';
273 snprintf(buf, 8, "%c%03x", c, brev & 0xfff); 274 snprintf(buf, BRCMU_BOARDREV_LEN, "%c%03x", c, brev & 0xfff);
274 } 275 }
275 return buf; 276 return buf;
276} 277}
277EXPORT_SYMBOL(brcmu_boardrev_str); 278EXPORT_SYMBOL(brcmu_boardrev_str);
278 279
280char *brcmu_dotrev_str(u32 dotrev, char *buf)
281{
282 u8 dotval[4];
283
284 if (!dotrev) {
285 snprintf(buf, BRCMU_DOTREV_LEN, "unknown");
286 return buf;
287 }
288 dotval[0] = (dotrev >> 24) & 0xFF;
289 dotval[1] = (dotrev >> 16) & 0xFF;
290 dotval[2] = (dotrev >> 8) & 0xFF;
291 dotval[3] = dotrev & 0xFF;
292
293 if (dotval[3])
294 snprintf(buf, BRCMU_DOTREV_LEN, "%d.%d.%d.%d", dotval[0],
295 dotval[1], dotval[2], dotval[3]);
296 else if (dotval[2])
297 snprintf(buf, BRCMU_DOTREV_LEN, "%d.%d.%d", dotval[0],
298 dotval[1], dotval[2]);
299 else
300 snprintf(buf, BRCMU_DOTREV_LEN, "%d.%d", dotval[0],
301 dotval[1]);
302
303 return buf;
304}
305EXPORT_SYMBOL(brcmu_dotrev_str);
306
279#if defined(DEBUG) 307#if defined(DEBUG)
280/* pretty hex print a pkt buffer chain */ 308/* pretty hex print a pkt buffer chain */
281void brcmu_prpkt(const char *msg, struct sk_buff *p0) 309void brcmu_prpkt(const char *msg, struct sk_buff *p0)
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/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
index a043e29f07e2..41969527b459 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h
@@ -218,6 +218,10 @@ void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...)
218} 218}
219#endif 219#endif
220 220
221#define BRCMU_BOARDREV_LEN 8
222#define BRCMU_DOTREV_LEN 16
223
221char *brcmu_boardrev_str(u32 brev, char *buf); 224char *brcmu_boardrev_str(u32 brev, char *buf);
225char *brcmu_dotrev_str(u32 dotrev, char *buf);
222 226
223#endif /* _BRCMU_UTILS_H_ */ 227#endif /* _BRCMU_UTILS_H_ */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index 6f1b9aace8b3..30e7646d04af 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -66,25 +66,31 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
66 do { \ 66 do { \
67 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \ 67 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
68 if (ret < 0) \ 68 if (ret < 0) \
69 goto error; \ 69 goto exit; \
70 } while (0)
71#define APB_WRITE2(reg, val) \
72 do { \
73 ret = cw1200_apb_write_32(priv, CW1200_APB(reg), (val)); \
74 if (ret < 0) \
75 goto free_buffer; \
70 } while (0) 76 } while (0)
71#define APB_READ(reg, val) \ 77#define APB_READ(reg, val) \
72 do { \ 78 do { \
73 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \ 79 ret = cw1200_apb_read_32(priv, CW1200_APB(reg), &(val)); \
74 if (ret < 0) \ 80 if (ret < 0) \
75 goto error; \ 81 goto free_buffer; \
76 } while (0) 82 } while (0)
77#define REG_WRITE(reg, val) \ 83#define REG_WRITE(reg, val) \
78 do { \ 84 do { \
79 ret = cw1200_reg_write_32(priv, (reg), (val)); \ 85 ret = cw1200_reg_write_32(priv, (reg), (val)); \
80 if (ret < 0) \ 86 if (ret < 0) \
81 goto error; \ 87 goto exit; \
82 } while (0) 88 } while (0)
83#define REG_READ(reg, val) \ 89#define REG_READ(reg, val) \
84 do { \ 90 do { \
85 ret = cw1200_reg_read_32(priv, (reg), &(val)); \ 91 ret = cw1200_reg_read_32(priv, (reg), &(val)); \
86 if (ret < 0) \ 92 if (ret < 0) \
87 goto error; \ 93 goto exit; \
88 } while (0) 94 } while (0)
89 95
90 switch (priv->hw_revision) { 96 switch (priv->hw_revision) {
@@ -142,14 +148,14 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
142 ret = request_firmware(&firmware, fw_path, priv->pdev); 148 ret = request_firmware(&firmware, fw_path, priv->pdev);
143 if (ret) { 149 if (ret) {
144 pr_err("Can't load firmware file %s.\n", fw_path); 150 pr_err("Can't load firmware file %s.\n", fw_path);
145 goto error; 151 goto exit;
146 } 152 }
147 153
148 buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA); 154 buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
149 if (!buf) { 155 if (!buf) {
150 pr_err("Can't allocate firmware load buffer.\n"); 156 pr_err("Can't allocate firmware load buffer.\n");
151 ret = -ENOMEM; 157 ret = -ENOMEM;
152 goto error; 158 goto firmware_release;
153 } 159 }
154 160
155 /* Check if the bootloader is ready */ 161 /* Check if the bootloader is ready */
@@ -163,7 +169,7 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
163 if (val32 != DOWNLOAD_I_AM_HERE) { 169 if (val32 != DOWNLOAD_I_AM_HERE) {
164 pr_err("Bootloader is not ready.\n"); 170 pr_err("Bootloader is not ready.\n");
165 ret = -ETIMEDOUT; 171 ret = -ETIMEDOUT;
166 goto error; 172 goto free_buffer;
167 } 173 }
168 174
169 /* Calculcate number of download blocks */ 175 /* Calculcate number of download blocks */
@@ -171,7 +177,7 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
171 177
172 /* Updating the length in Download Ctrl Area */ 178 /* Updating the length in Download Ctrl Area */
173 val32 = firmware->size; /* Explicit cast from size_t to u32 */ 179 val32 = firmware->size; /* Explicit cast from size_t to u32 */
174 APB_WRITE(DOWNLOAD_IMAGE_SIZE_REG, val32); 180 APB_WRITE2(DOWNLOAD_IMAGE_SIZE_REG, val32);
175 181
176 /* Firmware downloading loop */ 182 /* Firmware downloading loop */
177 for (block = 0; block < num_blocks; block++) { 183 for (block = 0; block < num_blocks; block++) {
@@ -183,7 +189,7 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
183 if (val32 != DOWNLOAD_PENDING) { 189 if (val32 != DOWNLOAD_PENDING) {
184 pr_err("Bootloader reported error %d.\n", val32); 190 pr_err("Bootloader reported error %d.\n", val32);
185 ret = -EIO; 191 ret = -EIO;
186 goto error; 192 goto free_buffer;
187 } 193 }
188 194
189 /* loop until put - get <= 24K */ 195 /* loop until put - get <= 24K */
@@ -198,7 +204,7 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
198 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) { 204 if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
199 pr_err("Timeout waiting for FIFO.\n"); 205 pr_err("Timeout waiting for FIFO.\n");
200 ret = -ETIMEDOUT; 206 ret = -ETIMEDOUT;
201 goto error; 207 goto free_buffer;
202 } 208 }
203 209
204 /* calculate the block size */ 210 /* calculate the block size */
@@ -220,12 +226,12 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
220 if (ret < 0) { 226 if (ret < 0) {
221 pr_err("Can't write firmware block @ %d!\n", 227 pr_err("Can't write firmware block @ %d!\n",
222 put & (DOWNLOAD_FIFO_SIZE - 1)); 228 put & (DOWNLOAD_FIFO_SIZE - 1));
223 goto error; 229 goto free_buffer;
224 } 230 }
225 231
226 /* update the put register */ 232 /* update the put register */
227 put += block_size; 233 put += block_size;
228 APB_WRITE(DOWNLOAD_PUT_REG, put); 234 APB_WRITE2(DOWNLOAD_PUT_REG, put);
229 } /* End of firmware download loop */ 235 } /* End of firmware download loop */
230 236
231 /* Wait for the download completion */ 237 /* Wait for the download completion */
@@ -238,19 +244,21 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
238 if (val32 != DOWNLOAD_SUCCESS) { 244 if (val32 != DOWNLOAD_SUCCESS) {
239 pr_err("Wait for download completion failed: 0x%.8X\n", val32); 245 pr_err("Wait for download completion failed: 0x%.8X\n", val32);
240 ret = -ETIMEDOUT; 246 ret = -ETIMEDOUT;
241 goto error; 247 goto free_buffer;
242 } else { 248 } else {
243 pr_info("Firmware download completed.\n"); 249 pr_info("Firmware download completed.\n");
244 ret = 0; 250 ret = 0;
245 } 251 }
246 252
247error: 253free_buffer:
248 kfree(buf); 254 kfree(buf);
249 if (firmware) 255firmware_release:
250 release_firmware(firmware); 256 release_firmware(firmware);
257exit:
251 return ret; 258 return ret;
252 259
253#undef APB_WRITE 260#undef APB_WRITE
261#undef APB_WRITE2
254#undef APB_READ 262#undef APB_READ
255#undef REG_WRITE 263#undef REG_WRITE
256#undef REG_READ 264#undef REG_READ
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index 3e78cc3ccb78..3689dbbd10bd 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -282,7 +282,6 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
282 IEEE80211_HW_SUPPORTS_PS | 282 IEEE80211_HW_SUPPORTS_PS |
283 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 283 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
284 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 284 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
285 IEEE80211_HW_SUPPORTS_UAPSD |
286 IEEE80211_HW_CONNECTION_MONITOR | 285 IEEE80211_HW_CONNECTION_MONITOR |
287 IEEE80211_HW_AMPDU_AGGREGATION | 286 IEEE80211_HW_AMPDU_AGGREGATION |
288 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW | 287 IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
@@ -374,9 +373,8 @@ static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr,
374 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work); 373 INIT_WORK(&priv->update_filtering_work, cw1200_update_filtering_work);
375 INIT_WORK(&priv->set_beacon_wakeup_period_work, 374 INIT_WORK(&priv->set_beacon_wakeup_period_work,
376 cw1200_set_beacon_wakeup_period_work); 375 cw1200_set_beacon_wakeup_period_work);
377 init_timer(&priv->mcast_timeout); 376 setup_timer(&priv->mcast_timeout, cw1200_mcast_timeout,
378 priv->mcast_timeout.data = (unsigned long)priv; 377 (unsigned long)priv);
379 priv->mcast_timeout.function = cw1200_mcast_timeout;
380 378
381 if (cw1200_queue_stats_init(&priv->tx_queue_stats, 379 if (cw1200_queue_stats_init(&priv->tx_queue_stats,
382 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/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
index f2e276faca70..bff81b8d4164 100644
--- a/drivers/net/wireless/cw1200/scan.c
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -39,9 +39,9 @@ static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
39 cancel_delayed_work_sync(&priv->clear_recent_scan_work); 39 cancel_delayed_work_sync(&priv->clear_recent_scan_work);
40 atomic_set(&priv->scan.in_progress, 1); 40 atomic_set(&priv->scan.in_progress, 1);
41 atomic_set(&priv->recent_scan, 1); 41 atomic_set(&priv->recent_scan, 1);
42 cw1200_pm_stay_awake(&priv->pm_state, tmo * HZ / 1000); 42 cw1200_pm_stay_awake(&priv->pm_state, msecs_to_jiffies(tmo));
43 queue_delayed_work(priv->workqueue, &priv->scan.timeout, 43 queue_delayed_work(priv->workqueue, &priv->scan.timeout,
44 tmo * HZ / 1000); 44 msecs_to_jiffies(tmo));
45 ret = wsm_scan(priv, scan); 45 ret = wsm_scan(priv, scan);
46 if (ret) { 46 if (ret) {
47 atomic_set(&priv->scan.in_progress, 0); 47 atomic_set(&priv->scan.in_progress, 0);
@@ -386,8 +386,8 @@ void cw1200_probe_work(struct work_struct *work)
386 if (down_trylock(&priv->scan.lock)) { 386 if (down_trylock(&priv->scan.lock)) {
387 /* Scan is already in progress. Requeue self. */ 387 /* Scan is already in progress. Requeue self. */
388 schedule(); 388 schedule();
389 queue_delayed_work(priv->workqueue, 389 queue_delayed_work(priv->workqueue, &priv->scan.probe_work,
390 &priv->scan.probe_work, HZ / 10); 390 msecs_to_jiffies(100));
391 mutex_unlock(&priv->conf_mutex); 391 mutex_unlock(&priv->conf_mutex);
392 return; 392 return;
393 } 393 }
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 5b84664db13b..4a47c7f8a246 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -213,6 +213,7 @@ int cw1200_add_interface(struct ieee80211_hw *dev,
213 /* __le32 auto_calibration_mode = __cpu_to_le32(1); */ 213 /* __le32 auto_calibration_mode = __cpu_to_le32(1); */
214 214
215 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 215 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
216 IEEE80211_VIF_SUPPORTS_UAPSD |
216 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 217 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
217 218
218 mutex_lock(&priv->conf_mutex); 219 mutex_lock(&priv->conf_mutex);
@@ -708,7 +709,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
708 if (sta) 709 if (sta)
709 peer_addr = sta->addr; 710 peer_addr = sta->addr;
710 711
711 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE; 712 key->flags |= IEEE80211_KEY_FLAG_PUT_IV_SPACE |
713 IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
712 714
713 switch (key->cipher) { 715 switch (key->cipher) {
714 case WLAN_CIPHER_SUITE_WEP40: 716 case WLAN_CIPHER_SUITE_WEP40:
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 596525528f50..fd8d83dd4f62 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -145,7 +145,7 @@ static void ap_free_sta(struct ap_data *ap, struct sta_info *sta)
145 if (sta->aid > 0) 145 if (sta->aid > 0)
146 ap->sta_aid[sta->aid - 1] = NULL; 146 ap->sta_aid[sta->aid - 1] = NULL;
147 147
148 if (!sta->ap && sta->u.sta.challenge) 148 if (!sta->ap)
149 kfree(sta->u.sta.challenge); 149 kfree(sta->u.sta.challenge);
150 del_timer_sync(&sta->timer); 150 del_timer_sync(&sta->timer);
151#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 151#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
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..c4d6dd7402d9 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)
@@ -1244,11 +1228,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1244 trans_cfg.no_reclaim_cmds = no_reclaim_cmds; 1228 trans_cfg.no_reclaim_cmds = no_reclaim_cmds;
1245 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); 1229 trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds);
1246 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; 1230 trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K;
1247 if (!iwlwifi_mod_params.wd_disable) 1231 trans_cfg.cmd_q_wdg_timeout = IWL_WATCHDOG_DISABLED;
1248 trans_cfg.queue_watchdog_timeout = 1232
1249 priv->cfg->base_params->wd_timeout;
1250 else
1251 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
1252 trans_cfg.command_names = iwl_dvm_cmd_strings; 1233 trans_cfg.command_names = iwl_dvm_cmd_strings;
1253 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; 1234 trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM;
1254 1235
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/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index d1ce3ce13591..1e40a12de077 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -715,7 +715,7 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
715 fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; 715 fifo = ctx->ac_to_fifo[tid_to_ac[tid]];
716 716
717 iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid, 717 iwl_trans_txq_enable(priv->trans, q, fifo, sta_priv->sta_id, tid,
718 buf_size, ssn); 718 buf_size, ssn, 0);
719 719
720 /* 720 /*
721 * If the limit is 0, then it wasn't initialised yet, 721 * If the limit is 0, then it wasn't initialised yet,
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index d5cee1530597..4dbef7e58c2e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -267,7 +267,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
267 for (i = 0; i < n_queues; i++) 267 for (i = 0; i < n_queues; i++)
268 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) 268 if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED)
269 iwl_trans_ac_txq_enable(priv->trans, i, 269 iwl_trans_ac_txq_enable(priv->trans, i,
270 queue_to_txf[i]); 270 queue_to_txf[i], 0);
271 271
272 priv->passive_no_rx = false; 272 priv->passive_no_rx = false;
273 priv->transport_queue_stop = 0; 273 priv->transport_queue_stop = 0;
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..4b190d98a1ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -126,7 +126,7 @@ enum iwl_led_mode {
126 126
127/* TX queue watchdog timeouts in mSecs */ 127/* TX queue watchdog timeouts in mSecs */
128#define IWL_WATCHDOG_DISABLED 0 128#define IWL_WATCHDOG_DISABLED 0
129#define IWL_DEF_WD_TIMEOUT 2000 129#define IWL_DEF_WD_TIMEOUT 2500
130#define IWL_LONG_WD_TIMEOUT 10000 130#define IWL_LONG_WD_TIMEOUT 10000
131#define IWL_MAX_WD_TIMEOUT 120000 131#define IWL_MAX_WD_TIMEOUT 120000
132 132
@@ -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..996e7f16adf9 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:
@@ -1429,7 +1367,7 @@ struct iwl_mod_params iwlwifi_mod_params = {
1429 .restart_fw = true, 1367 .restart_fw = true,
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 .d0i3_disable = true,
1433#ifndef CONFIG_IWLWIFI_UAPSD 1371#ifndef CONFIG_IWLWIFI_UAPSD
1434 .uapsd_disable = true, 1372 .uapsd_disable = true,
1435#endif /* CONFIG_IWLWIFI_UAPSD */ 1373#endif /* CONFIG_IWLWIFI_UAPSD */
@@ -1492,7 +1430,7 @@ static int __init iwl_drv_init(void)
1492 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++) 1430 for (i = 0; i < ARRAY_SIZE(iwlwifi_opmode_table); i++)
1493 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv); 1431 INIT_LIST_HEAD(&iwlwifi_opmode_table[i].drv);
1494 1432
1495 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n"); 1433 pr_info(DRV_DESCRIPTION "\n");
1496 pr_info(DRV_COPYRIGHT "\n"); 1434 pr_info(DRV_COPYRIGHT "\n");
1497 1435
1498#ifdef CONFIG_IWLWIFI_DEBUGFS 1436#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -1539,15 +1477,15 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1539MODULE_PARM_DESC(antenna_coupling, 1477MODULE_PARM_DESC(antenna_coupling,
1540 "specify antenna coupling in dB (default: 0 dB)"); 1478 "specify antenna coupling in dB (default: 0 dB)");
1541 1479
1542module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1543MODULE_PARM_DESC(wd_disable,
1544 "Disable stuck queue watchdog timer 0=system default, 1=disable (default: 1)");
1545
1546module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO); 1480module_param_named(nvm_file, iwlwifi_mod_params.nvm_file, charp, S_IRUGO);
1547MODULE_PARM_DESC(nvm_file, "NVM file name"); 1481MODULE_PARM_DESC(nvm_file, "NVM file name");
1548 1482
1549module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1483module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable,
1550 bool, S_IRUGO); 1484 bool, S_IRUGO);
1485MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
1486
1487module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
1488 bool, S_IRUGO | S_IWUSR);
1551#ifdef CONFIG_IWLWIFI_UAPSD 1489#ifdef CONFIG_IWLWIFI_UAPSD
1552MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)"); 1490MODULE_PARM_DESC(uapsd_disable, "disable U-APSD functionality (default: N)");
1553#else 1491#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 660ddb1b7d8a..016d91384681 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,31 +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.
249 * @IWL_UCODE_TLV_API_SINGLE_SCAN_EBS: EBS is supported for single scans too. 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
250 */ 253 */
251enum iwl_ucode_tlv_api { 254enum iwl_ucode_tlv_api {
252 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
253 IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
254 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 255 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
255 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 256 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), 257 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), 258 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
259 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),
260 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),
261 IWL_UCODE_TLV_API_SINGLE_SCAN_EBS = BIT(16), 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),
262}; 266};
263 267
264/** 268/**
@@ -266,6 +270,7 @@ enum iwl_ucode_tlv_api {
266 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3 270 * @IWL_UCODE_TLV_CAPA_D0I3_SUPPORT: supports D0i3
267 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory 271 * @IWL_UCODE_TLV_CAPA_LAR_SUPPORT: supports Location Aware Regulatory
268 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan. 272 * @IWL_UCODE_TLV_CAPA_UMAC_SCAN: supports UMAC scan.
273 * @IWL_UCODE_TLV_CAPA_BEAMFORMER: supports Beamformer
269 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality 274 * @IWL_UCODE_TLV_CAPA_TDLS_SUPPORT: support basic TDLS functionality
270 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current 275 * @IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT: supports insertion of current
271 * tx power value into TPC Report action frame and Link Measurement Report 276 * tx power value into TPC Report action frame and Link Measurement Report
@@ -284,6 +289,7 @@ enum iwl_ucode_tlv_capa {
284 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), 289 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
285 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1), 290 IWL_UCODE_TLV_CAPA_LAR_SUPPORT = BIT(1),
286 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2), 291 IWL_UCODE_TLV_CAPA_UMAC_SCAN = BIT(2),
292 IWL_UCODE_TLV_CAPA_BEAMFORMER = BIT(3),
287 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6), 293 IWL_UCODE_TLV_CAPA_TDLS_SUPPORT = BIT(6),
288 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8), 294 IWL_UCODE_TLV_CAPA_TXPOWER_INSERTION_SUPPORT = BIT(8),
289 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9), 295 IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT = BIT(9),
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..e8eabd21ccfe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -96,13 +96,13 @@ enum iwl_disable_11n {
96 * use IWL_[DIS,EN]ABLE_HT_* constants 96 * use IWL_[DIS,EN]ABLE_HT_* constants
97 * @amsdu_size_8K: enable 8K amsdu size, default = 0 97 * @amsdu_size_8K: enable 8K amsdu size, default = 0
98 * @restart_fw: restart firmware, default = 1 98 * @restart_fw: restart firmware, default = 1
99 * @wd_disable: disable stuck queue check, default = 1
100 * @bt_coex_active: enable bt coex, default = true 99 * @bt_coex_active: enable bt coex, default = true
101 * @led_mode: system default, default = 0 100 * @led_mode: system default, default = 0
102 * @power_save: enable power save, default = false 101 * @power_save: enable power save, default = false
103 * @power_level: power level, default = 1 102 * @power_level: power level, default = 1
104 * @debug_level: levels are IWL_DL_* 103 * @debug_level: levels are IWL_DL_*
105 * @ant_coupling: antenna coupling in dB, default = 0 104 * @ant_coupling: antenna coupling in dB, default = 0
105 * @d0i3_disable: disable d0i3, default = 1,
106 * @fw_monitor: allow to use firmware monitor 106 * @fw_monitor: allow to use firmware monitor
107 */ 107 */
108struct iwl_mod_params { 108struct iwl_mod_params {
@@ -110,7 +110,6 @@ struct iwl_mod_params {
110 unsigned int disable_11n; 110 unsigned int disable_11n;
111 int amsdu_size_8K; 111 int amsdu_size_8K;
112 bool restart_fw; 112 bool restart_fw;
113 int wd_disable;
114 bool bt_coex_active; 113 bool bt_coex_active;
115 int led_mode; 114 int led_mode;
116 bool power_save; 115 bool power_save;
@@ -121,6 +120,7 @@ struct iwl_mod_params {
121 int ant_coupling; 120 int ant_coupling;
122 char *nvm_file; 121 char *nvm_file;
123 bool uapsd_disable; 122 bool uapsd_disable;
123 bool d0i3_disable;
124 bool fw_monitor; 124 bool fw_monitor;
125}; 125};
126 126
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..6221e4dfc64f 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
@@ -250,6 +252,7 @@
250#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F) 252#define SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK (0x0000007F)
251#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16) 253#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS (16)
252#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000) 254#define SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK (0x007F0000)
255#define SCD_GP_CTRL_ENABLE_31_QUEUES BIT(0)
253 256
254/* Context Data */ 257/* Context Data */
255#define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600) 258#define SCD_CONTEXT_MEM_LOWER_BOUND (SCD_MEM_LOWER_BOUND + 0x600)
@@ -283,32 +286,9 @@
283#define SCD_CHAINEXT_EN (SCD_BASE + 0x244) 286#define SCD_CHAINEXT_EN (SCD_BASE + 0x244)
284#define SCD_AGGR_SEL (SCD_BASE + 0x248) 287#define SCD_AGGR_SEL (SCD_BASE + 0x248)
285#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) 288#define SCD_INTERRUPT_MASK (SCD_BASE + 0x108)
289#define SCD_GP_CTRL (SCD_BASE + 0x1a8)
286#define SCD_EN_CTRL (SCD_BASE + 0x254) 290#define SCD_EN_CTRL (SCD_BASE + 0x254)
287 291
288static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
289{
290 if (chnl < 20)
291 return SCD_BASE + 0x18 + chnl * 4;
292 WARN_ON_ONCE(chnl >= 32);
293 return SCD_BASE + 0x284 + (chnl - 20) * 4;
294}
295
296static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
297{
298 if (chnl < 20)
299 return SCD_BASE + 0x68 + chnl * 4;
300 WARN_ON_ONCE(chnl >= 32);
301 return SCD_BASE + 0x2B4 + (chnl - 20) * 4;
302}
303
304static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
305{
306 if (chnl < 20)
307 return SCD_BASE + 0x10c + chnl * 4;
308 WARN_ON_ONCE(chnl >= 32);
309 return SCD_BASE + 0x384 + (chnl - 20) * 4;
310}
311
312/*********************** END TX SCHEDULER *************************************/ 292/*********************** END TX SCHEDULER *************************************/
313 293
314/* Oscillator clock */ 294/* Oscillator clock */
@@ -358,18 +338,40 @@ enum secure_load_status_reg {
358 338
359/* Rx FIFO */ 339/* Rx FIFO */
360#define RXF_SIZE_ADDR (0xa00c88) 340#define RXF_SIZE_ADDR (0xa00c88)
341#define RXF_RD_D_SPACE (0xa00c40)
342#define RXF_RD_WR_PTR (0xa00c50)
343#define RXF_RD_RD_PTR (0xa00c54)
344#define RXF_RD_FENCE_PTR (0xa00c4c)
345#define RXF_SET_FENCE_MODE (0xa00c14)
346#define RXF_LD_WR2FENCE (0xa00c1c)
347#define RXF_FIFO_RD_FENCE_INC (0xa00c68)
361#define RXF_SIZE_BYTE_CND_POS (7) 348#define RXF_SIZE_BYTE_CND_POS (7)
362#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS) 349#define RXF_SIZE_BYTE_CNT_MSK (0x3ff << RXF_SIZE_BYTE_CND_POS)
350#define RXF_DIFF_FROM_PREV (0x200)
363 351
364#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10) 352#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
365#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c) 353#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
366 354
355/* Tx FIFO */
356#define TXF_FIFO_ITEM_CNT (0xa00438)
357#define TXF_WR_PTR (0xa00414)
358#define TXF_RD_PTR (0xa00410)
359#define TXF_FENCE_PTR (0xa00418)
360#define TXF_LOCK_FENCE (0xa00424)
361#define TXF_LARC_NUM (0xa0043c)
362#define TXF_READ_MODIFY_DATA (0xa00448)
363#define TXF_READ_MODIFY_ADDR (0xa0044c)
364
367/* FW monitor */ 365/* FW monitor */
366#define MON_BUFF_SAMPLE_CTL (0xa03c00)
368#define MON_BUFF_BASE_ADDR (0xa03c3c) 367#define MON_BUFF_BASE_ADDR (0xa03c3c)
369#define MON_BUFF_END_ADDR (0xa03c40) 368#define MON_BUFF_END_ADDR (0xa03c40)
370#define MON_BUFF_WRPTR (0xa03c44) 369#define MON_BUFF_WRPTR (0xa03c44)
371#define MON_BUFF_CYCLE_CNT (0xa03c48) 370#define MON_BUFF_CYCLE_CNT (0xa03c48)
372 371
372#define DBGC_IN_SAMPLE (0xa03c00)
373#define DBGC_OUT_CTRL (0xa03c0c)
374
373/* FW chicken bits */ 375/* FW chicken bits */
374#define LMPM_CHICK 0xA01FF8 376#define LMPM_CHICK 0xA01FF8
375enum { 377enum {
diff --git a/drivers/net/wireless/iwlwifi/iwl-scd.h b/drivers/net/wireless/iwlwifi/iwl-scd.h
index 6c622b21bba7..f2353ebf2666 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scd.h
+++ b/drivers/net/wireless/iwlwifi/iwl-scd.h
@@ -69,14 +69,6 @@
69#include "iwl-prph.h" 69#include "iwl-prph.h"
70 70
71 71
72static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans,
73 u16 txq_id)
74{
75 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
76 (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
77 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
78}
79
80static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans, 72static inline void iwl_scd_txq_set_chain(struct iwl_trans *trans,
81 u16 txq_id) 73 u16 txq_id)
82{ 74{
@@ -115,4 +107,37 @@ static inline void iwl_scd_enable_set_active(struct iwl_trans *trans,
115{ 107{
116 iwl_write_prph(trans, SCD_EN_CTRL, value); 108 iwl_write_prph(trans, SCD_EN_CTRL, value);
117} 109}
110
111static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl)
112{
113 if (chnl < 20)
114 return SCD_BASE + 0x18 + chnl * 4;
115 WARN_ON_ONCE(chnl >= 32);
116 return SCD_BASE + 0x284 + (chnl - 20) * 4;
117}
118
119static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl)
120{
121 if (chnl < 20)
122 return SCD_BASE + 0x68 + chnl * 4;
123 WARN_ON_ONCE(chnl >= 32);
124 return SCD_BASE + 0x2B4 + chnl * 4;
125}
126
127static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl)
128{
129 if (chnl < 20)
130 return SCD_BASE + 0x10c + chnl * 4;
131 WARN_ON_ONCE(chnl >= 32);
132 return SCD_BASE + 0x334 + chnl * 4;
133}
134
135static inline void iwl_scd_txq_set_inactive(struct iwl_trans *trans,
136 u16 txq_id)
137{
138 iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id),
139 (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)|
140 (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
141}
142
118#endif 143#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 028408a6ecba..a96bd8db6ceb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -368,6 +368,7 @@ enum iwl_trans_status {
368 * @cmd_queue: the index of the command queue. 368 * @cmd_queue: the index of the command queue.
369 * Must be set before start_fw. 369 * Must be set before start_fw.
370 * @cmd_fifo: the fifo for host commands 370 * @cmd_fifo: the fifo for host commands
371 * @cmd_q_wdg_timeout: the timeout of the watchdog timer for the command queue.
371 * @no_reclaim_cmds: Some devices erroneously don't set the 372 * @no_reclaim_cmds: Some devices erroneously don't set the
372 * SEQ_RX_FRAME bit on some notifications, this is the 373 * SEQ_RX_FRAME bit on some notifications, this is the
373 * list of such notifications to filter. Max length is 374 * list of such notifications to filter. Max length is
@@ -378,24 +379,26 @@ enum iwl_trans_status {
378 * @bc_table_dword: set to true if the BC table expects the byte count to be 379 * @bc_table_dword: set to true if the BC table expects the byte count to be
379 * in DWORD (as opposed to bytes) 380 * in DWORD (as opposed to bytes)
380 * @scd_set_active: should the transport configure the SCD for HCMD queue 381 * @scd_set_active: should the transport configure the SCD for HCMD queue
381 * @queue_watchdog_timeout: time (in ms) after which queues
382 * are considered stuck and will trigger device restart
383 * @command_names: array of command names, must be 256 entries 382 * @command_names: array of command names, must be 256 entries
384 * (one for each command); for debugging only 383 * (one for each command); for debugging only
384 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
385 * we get the ALIVE from the uCode
385 */ 386 */
386struct iwl_trans_config { 387struct iwl_trans_config {
387 struct iwl_op_mode *op_mode; 388 struct iwl_op_mode *op_mode;
388 389
389 u8 cmd_queue; 390 u8 cmd_queue;
390 u8 cmd_fifo; 391 u8 cmd_fifo;
392 unsigned int cmd_q_wdg_timeout;
391 const u8 *no_reclaim_cmds; 393 const u8 *no_reclaim_cmds;
392 unsigned int n_no_reclaim_cmds; 394 unsigned int n_no_reclaim_cmds;
393 395
394 bool rx_buf_size_8k; 396 bool rx_buf_size_8k;
395 bool bc_table_dword; 397 bool bc_table_dword;
396 bool scd_set_active; 398 bool scd_set_active;
397 unsigned int queue_watchdog_timeout;
398 const char *const *command_names; 399 const char *const *command_names;
400
401 u32 sdio_adma_addr;
399}; 402};
400 403
401struct iwl_trans_dump_data { 404struct iwl_trans_dump_data {
@@ -507,7 +510,8 @@ struct iwl_trans_ops {
507 struct sk_buff_head *skbs); 510 struct sk_buff_head *skbs);
508 511
509 void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn, 512 void (*txq_enable)(struct iwl_trans *trans, int queue, u16 ssn,
510 const struct iwl_trans_txq_scd_cfg *cfg); 513 const struct iwl_trans_txq_scd_cfg *cfg,
514 unsigned int queue_wdg_timeout);
511 void (*txq_disable)(struct iwl_trans *trans, int queue, 515 void (*txq_disable)(struct iwl_trans *trans, int queue,
512 bool configure_scd); 516 bool configure_scd);
513 517
@@ -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 *));
@@ -808,19 +829,21 @@ static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue,
808 829
809static inline void 830static inline void
810iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn, 831iwl_trans_txq_enable_cfg(struct iwl_trans *trans, int queue, u16 ssn,
811 const struct iwl_trans_txq_scd_cfg *cfg) 832 const struct iwl_trans_txq_scd_cfg *cfg,
833 unsigned int queue_wdg_timeout)
812{ 834{
813 might_sleep(); 835 might_sleep();
814 836
815 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) 837 if (unlikely((trans->state != IWL_TRANS_FW_ALIVE)))
816 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); 838 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
817 839
818 trans->ops->txq_enable(trans, queue, ssn, cfg); 840 trans->ops->txq_enable(trans, queue, ssn, cfg, queue_wdg_timeout);
819} 841}
820 842
821static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, 843static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
822 int fifo, int sta_id, int tid, 844 int fifo, int sta_id, int tid,
823 int frame_limit, u16 ssn) 845 int frame_limit, u16 ssn,
846 unsigned int queue_wdg_timeout)
824{ 847{
825 struct iwl_trans_txq_scd_cfg cfg = { 848 struct iwl_trans_txq_scd_cfg cfg = {
826 .fifo = fifo, 849 .fifo = fifo,
@@ -830,11 +853,12 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue,
830 .aggregate = sta_id >= 0, 853 .aggregate = sta_id >= 0,
831 }; 854 };
832 855
833 iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg); 856 iwl_trans_txq_enable_cfg(trans, queue, ssn, &cfg, queue_wdg_timeout);
834} 857}
835 858
836static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, 859static inline
837 int fifo) 860void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo,
861 unsigned int queue_wdg_timeout)
838{ 862{
839 struct iwl_trans_txq_scd_cfg cfg = { 863 struct iwl_trans_txq_scd_cfg cfg = {
840 .fifo = fifo, 864 .fifo = fifo,
@@ -844,16 +868,16 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
844 .aggregate = false, 868 .aggregate = false,
845 }; 869 };
846 870
847 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); 871 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout);
848} 872}
849 873
850static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, 874static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
851 u32 txq_bm) 875 u32 txqs)
852{ 876{
853 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) 877 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
854 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state); 878 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
855 879
856 return trans->ops->wait_tx_queue_empty(trans, txq_bm); 880 return trans->ops->wait_tx_queue_empty(trans, txqs);
857} 881}
858 882
859static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans, 883static inline int iwl_trans_dbgfs_register(struct iwl_trans *trans,
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..beba375489f1 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 4
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..0f1ea80a55ef 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h
@@ -308,6 +308,42 @@ 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 Tx Parameters (lq_cmd->ss_params)
312 * Flags to control a smart FW decision about whether BFER/STBC/SISO will be
313 * used for single stream Tx.
314 */
315
316/* Bit 0-1: Max STBC streams allowed. Can be 0-3.
317 * (0) - No STBC allowed
318 * (1) - 2x1 STBC allowed (HT/VHT)
319 * (2) - 4x2 STBC allowed (HT/VHT)
320 * (3) - 3x2 STBC allowed (HT only)
321 * All our chips are at most 2 antennas so only (1) is valid for now.
322 */
323#define LQ_SS_STBC_ALLOWED_POS 0
324#define LQ_SS_STBC_ALLOWED_MSK (3 << LQ_SS_STBC_ALLOWED_MSK)
325
326/* 2x1 STBC is allowed */
327#define LQ_SS_STBC_1SS_ALLOWED (1 << LQ_SS_STBC_ALLOWED_POS)
328
329/* Bit 2: Beamformer (VHT only) is allowed */
330#define LQ_SS_BFER_ALLOWED_POS 2
331#define LQ_SS_BFER_ALLOWED (1 << LQ_SS_BFER_ALLOWED_POS)
332
333/* Bit 3: Force BFER or STBC for testing
334 * If this is set:
335 * If BFER is allowed then force the ucode to choose BFER else
336 * If STBC is allowed then force the ucode to choose STBC over SISO
337 */
338#define LQ_SS_FORCE_POS 3
339#define LQ_SS_FORCE (1 << LQ_SS_FORCE_POS)
340
341/* Bit 31: ss_params field is valid. Used for FW backward compatibility
342 * with other drivers which don't support the ss_params API yet
343 */
344#define LQ_SS_PARAMS_VALID_POS 31
345#define LQ_SS_PARAMS_VALID (1 << LQ_SS_PARAMS_VALID_POS)
346
311/** 347/**
312 * struct iwl_lq_cmd - link quality command 348 * struct iwl_lq_cmd - link quality command
313 * @sta_id: station to update 349 * @sta_id: station to update
@@ -330,7 +366,7 @@ enum {
330 * 2 - 0x3f: maximal number of frames (up to 3f == 63) 366 * 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, 367 * @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 368 * meaning it is a combination of RATE_MCS_* and IWL_RATE_*_PLCP
333 * @bf_params: beam forming params, currently not used 369 * @ss_params: single stream features. declare whether STBC or BFER are allowed.
334 */ 370 */
335struct iwl_lq_cmd { 371struct iwl_lq_cmd {
336 u8 sta_id; 372 u8 sta_id;
@@ -348,6 +384,6 @@ struct iwl_lq_cmd {
348 u8 agg_frame_cnt_limit; 384 u8 agg_frame_cnt_limit;
349 __le32 reserved2; 385 __le32 reserved2;
350 __le32 rs_table[LQ_MAX_RETRY_NUM]; 386 __le32 rs_table[LQ_MAX_RETRY_NUM];
351 __le32 bf_params; 387 __le32 ss_params;
352}; /* LINK_QUALITY_CMD_API_S_VER_1 */ 388}; /* LINK_QUALITY_CMD_API_S_VER_1 */
353#endif /* __fw_api_rs_h__ */ 389#endif /* __fw_api_rs_h__ */
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..ca38e9817374 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,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
482 goto error; 575 goto error;
483 } 576 }
484 577
578 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 10)
579 iwl_mvm_get_shared_mem_conf(mvm);
580
485 ret = iwl_mvm_sf_update(mvm, NULL, false); 581 ret = iwl_mvm_sf_update(mvm, NULL, false);
486 if (ret) 582 if (ret)
487 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n"); 583 IWL_ERR(mvm, "Failed to initialize Smart Fifo\n");
@@ -489,7 +585,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
489 mvm->fw_dbg_conf = FW_DBG_INVALID; 585 mvm->fw_dbg_conf = FW_DBG_INVALID;
490 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM); 586 iwl_mvm_start_fw_dbg_conf(mvm, FW_DBG_CUSTOM);
491 587
492 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 588 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
493 if (ret) 589 if (ret)
494 goto error; 590 goto error;
495 591
@@ -538,14 +634,7 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
538 /* Initialize tx backoffs to the minimal possible */ 634 /* Initialize tx backoffs to the minimal possible */
539 iwl_mvm_tt_tx_backoff(mvm, 0); 635 iwl_mvm_tt_tx_backoff(mvm, 0);
540 636
541 if (mvm->trans->ltr_enabled) { 637 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 638
550 ret = iwl_mvm_power_update_device(mvm); 639 ret = iwl_mvm_power_update_device(mvm);
551 if (ret) 640 if (ret)
@@ -584,7 +673,7 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
584 goto error; 673 goto error;
585 } 674 }
586 675
587 ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant); 676 ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
588 if (ret) 677 if (ret)
589 goto error; 678 goto error;
590 679
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index f6d86ccce6a8..7bdc6220743f 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);
@@ -460,6 +462,9 @@ exit_fail:
460 462
461int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) 463int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
462{ 464{
465 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
466 mvm->cfg->base_params->wd_timeout :
467 IWL_WATCHDOG_DISABLED;
463 u32 ac; 468 u32 ac;
464 int ret; 469 int ret;
465 470
@@ -472,16 +477,17 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
472 switch (vif->type) { 477 switch (vif->type) {
473 case NL80211_IFTYPE_P2P_DEVICE: 478 case NL80211_IFTYPE_P2P_DEVICE:
474 iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 479 iwl_mvm_enable_ac_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
475 IWL_MVM_TX_FIFO_VO); 480 IWL_MVM_TX_FIFO_VO, wdg_timeout);
476 break; 481 break;
477 case NL80211_IFTYPE_AP: 482 case NL80211_IFTYPE_AP:
478 iwl_mvm_enable_ac_txq(mvm, vif->cab_queue, 483 iwl_mvm_enable_ac_txq(mvm, vif->cab_queue,
479 IWL_MVM_TX_FIFO_MCAST); 484 IWL_MVM_TX_FIFO_MCAST, wdg_timeout);
480 /* fall through */ 485 /* fall through */
481 default: 486 default:
482 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 487 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
483 iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac], 488 iwl_mvm_enable_ac_txq(mvm, vif->hw_queue[ac],
484 iwl_mvm_ac_to_tx_fifo[ac]); 489 iwl_mvm_ac_to_tx_fifo[ac],
490 wdg_timeout);
485 break; 491 break;
486 } 492 }
487 493
@@ -496,14 +502,14 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
496 502
497 switch (vif->type) { 503 switch (vif->type) {
498 case NL80211_IFTYPE_P2P_DEVICE: 504 case NL80211_IFTYPE_P2P_DEVICE:
499 iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE); 505 iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE, 0);
500 break; 506 break;
501 case NL80211_IFTYPE_AP: 507 case NL80211_IFTYPE_AP:
502 iwl_mvm_disable_txq(mvm, vif->cab_queue); 508 iwl_mvm_disable_txq(mvm, vif->cab_queue, 0);
503 /* fall through */ 509 /* fall through */
504 default: 510 default:
505 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) 511 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
506 iwl_mvm_disable_txq(mvm, vif->hw_queue[ac]); 512 iwl_mvm_disable_txq(mvm, vif->hw_queue[ac], 0);
507 } 513 }
508} 514}
509 515
@@ -975,7 +981,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
975 beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags); 981 beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags);
976 982
977 mvm->mgmt_last_antenna_idx = 983 mvm->mgmt_last_antenna_idx =
978 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 984 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
979 mvm->mgmt_last_antenna_idx); 985 mvm->mgmt_last_antenna_idx);
980 986
981 beacon_cmd.tx.rate_n_flags = 987 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 20915587c820..1ff7ec08532d 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),
@@ -326,6 +327,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
326 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | 327 hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
327 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; 328 IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED;
328 hw->rate_control_algorithm = "iwl-mvm-rs"; 329 hw->rate_control_algorithm = "iwl-mvm-rs";
330 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
331 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
329 332
330 /* 333 /*
331 * Enable 11w if advertised by firmware and software crypto 334 * Enable 11w if advertised by firmware and software crypto
@@ -336,13 +339,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
336 !iwlwifi_mod_params.sw_crypto) 339 !iwlwifi_mod_params.sw_crypto)
337 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 340 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
338 341
339 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
340 !iwlwifi_mod_params.uapsd_disable) {
341 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
342 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
343 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
344 }
345
346 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN || 342 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN ||
347 mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 343 mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) {
348 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS; 344 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
@@ -377,6 +373,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
377 373
378 hw->wiphy->max_remain_on_channel_duration = 10000; 374 hw->wiphy->max_remain_on_channel_duration = 10000;
379 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;
380 378
381 /* Extract MAC address */ 379 /* Extract MAC address */
382 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);
@@ -403,10 +401,15 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
403 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) 401 if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
404 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 402 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
405 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 403 &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
406 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels) 404 if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels) {
407 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 405 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
408 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 406 &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
409 407
408 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER)
409 hw->wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap.cap |=
410 IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
411 }
412
410 hw->wiphy->hw_version = mvm->trans->hw_id; 413 hw->wiphy->hw_version = mvm->trans->hw_id;
411 414
412 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM) 415 if (iwlmvm_mod_params.power_scheme != IWL_POWER_SCHEME_CAM)
@@ -459,15 +462,17 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
459 device_can_wakeup(mvm->trans->dev)) { 462 device_can_wakeup(mvm->trans->dev)) {
460 mvm->wowlan.flags = WIPHY_WOWLAN_ANY; 463 mvm->wowlan.flags = WIPHY_WOWLAN_ANY;
461 hw->wiphy->wowlan = &mvm->wowlan; 464 hw->wiphy->wowlan = &mvm->wowlan;
462 } else if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 465 }
466
467 if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
463 mvm->trans->ops->d3_suspend && 468 mvm->trans->ops->d3_suspend &&
464 mvm->trans->ops->d3_resume && 469 mvm->trans->ops->d3_resume &&
465 device_can_wakeup(mvm->trans->dev)) { 470 device_can_wakeup(mvm->trans->dev)) {
466 mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 471 mvm->wowlan.flags |= WIPHY_WOWLAN_MAGIC_PKT |
467 WIPHY_WOWLAN_DISCONNECT | 472 WIPHY_WOWLAN_DISCONNECT |
468 WIPHY_WOWLAN_EAP_IDENTITY_REQ | 473 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
469 WIPHY_WOWLAN_RFKILL_RELEASE | 474 WIPHY_WOWLAN_RFKILL_RELEASE |
470 WIPHY_WOWLAN_NET_DETECT; 475 WIPHY_WOWLAN_NET_DETECT;
471 if (!iwlwifi_mod_params.sw_crypto) 476 if (!iwlwifi_mod_params.sw_crypto)
472 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 477 mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
473 WIPHY_WOWLAN_GTK_REKEY_FAILURE | 478 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
@@ -707,9 +712,6 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
707 mvmvif->uploaded = false; 712 mvmvif->uploaded = false;
708 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 713 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
709 714
710 /* does this make sense at all? */
711 mvmvif->color++;
712
713 spin_lock_bh(&mvm->time_event_lock); 715 spin_lock_bh(&mvm->time_event_lock);
714 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data); 716 iwl_mvm_te_clear_data(mvm, &mvmvif->time_event_data);
715 spin_unlock_bh(&mvm->time_event_lock); 717 spin_unlock_bh(&mvm->time_event_lock);
@@ -761,41 +763,215 @@ static void iwl_mvm_free_coredump(const void *data)
761 kfree(fw_error_dump); 763 kfree(fw_error_dump);
762} 764}
763 765
766static void iwl_mvm_dump_fifos(struct iwl_mvm *mvm,
767 struct iwl_fw_error_dump_data **dump_data)
768{
769 struct iwl_fw_error_dump_fifo *fifo_hdr;
770 u32 *fifo_data;
771 u32 fifo_len;
772 unsigned long flags;
773 int i, j;
774
775 if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags))
776 return;
777
778 /* Pull RXF data from all RXFs */
779 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++) {
780 /*
781 * Keep aside the additional offset that might be needed for
782 * next RXF
783 */
784 u32 offset_diff = RXF_DIFF_FROM_PREV * i;
785
786 fifo_hdr = (void *)(*dump_data)->data;
787 fifo_data = (void *)fifo_hdr->data;
788 fifo_len = mvm->shared_mem_cfg.rxfifo_size[i];
789
790 /* No need to try to read the data if the length is 0 */
791 if (fifo_len == 0)
792 continue;
793
794 /* Add a TLV for the RXF */
795 (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
796 (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
797
798 fifo_hdr->fifo_num = cpu_to_le32(i);
799 fifo_hdr->available_bytes =
800 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
801 RXF_RD_D_SPACE +
802 offset_diff));
803 fifo_hdr->wr_ptr =
804 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
805 RXF_RD_WR_PTR +
806 offset_diff));
807 fifo_hdr->rd_ptr =
808 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
809 RXF_RD_RD_PTR +
810 offset_diff));
811 fifo_hdr->fence_ptr =
812 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
813 RXF_RD_FENCE_PTR +
814 offset_diff));
815 fifo_hdr->fence_mode =
816 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
817 RXF_SET_FENCE_MODE +
818 offset_diff));
819
820 /* Lock fence */
821 iwl_trans_write_prph(mvm->trans,
822 RXF_SET_FENCE_MODE + offset_diff, 0x1);
823 /* Set fence pointer to the same place like WR pointer */
824 iwl_trans_write_prph(mvm->trans,
825 RXF_LD_WR2FENCE + offset_diff, 0x1);
826 /* Set fence offset */
827 iwl_trans_write_prph(mvm->trans,
828 RXF_LD_FENCE_OFFSET_ADDR + offset_diff,
829 0x0);
830
831 /* Read FIFO */
832 fifo_len /= sizeof(u32); /* Size in DWORDS */
833 for (j = 0; j < fifo_len; j++)
834 fifo_data[j] = iwl_trans_read_prph(mvm->trans,
835 RXF_FIFO_RD_FENCE_INC +
836 offset_diff);
837 *dump_data = iwl_fw_error_next_data(*dump_data);
838 }
839
840 /* Pull TXF data from all TXFs */
841 for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++) {
842 /* Mark the number of TXF we're pulling now */
843 iwl_trans_write_prph(mvm->trans, TXF_LARC_NUM, i);
844
845 fifo_hdr = (void *)(*dump_data)->data;
846 fifo_data = (void *)fifo_hdr->data;
847 fifo_len = mvm->shared_mem_cfg.txfifo_size[i];
848
849 /* No need to try to read the data if the length is 0 */
850 if (fifo_len == 0)
851 continue;
852
853 /* Add a TLV for the FIFO */
854 (*dump_data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXF);
855 (*dump_data)->len = cpu_to_le32(fifo_len + sizeof(*fifo_hdr));
856
857 fifo_hdr->fifo_num = cpu_to_le32(i);
858 fifo_hdr->available_bytes =
859 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
860 TXF_FIFO_ITEM_CNT));
861 fifo_hdr->wr_ptr =
862 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
863 TXF_WR_PTR));
864 fifo_hdr->rd_ptr =
865 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
866 TXF_RD_PTR));
867 fifo_hdr->fence_ptr =
868 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
869 TXF_FENCE_PTR));
870 fifo_hdr->fence_mode =
871 cpu_to_le32(iwl_trans_read_prph(mvm->trans,
872 TXF_LOCK_FENCE));
873
874 /* Set the TXF_READ_MODIFY_ADDR to TXF_WR_PTR */
875 iwl_trans_write_prph(mvm->trans, TXF_READ_MODIFY_ADDR,
876 TXF_WR_PTR);
877
878 /* Dummy-read to advance the read pointer to the head */
879 iwl_trans_read_prph(mvm->trans, TXF_READ_MODIFY_DATA);
880
881 /* Read FIFO */
882 fifo_len /= sizeof(u32); /* Size in DWORDS */
883 for (j = 0; j < fifo_len; j++)
884 fifo_data[j] = iwl_trans_read_prph(mvm->trans,
885 TXF_READ_MODIFY_DATA);
886 *dump_data = iwl_fw_error_next_data(*dump_data);
887 }
888
889 iwl_trans_release_nic_access(mvm->trans, &flags);
890}
891
764void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 892void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
765{ 893{
766 struct iwl_fw_error_dump_file *dump_file; 894 struct iwl_fw_error_dump_file *dump_file;
767 struct iwl_fw_error_dump_data *dump_data; 895 struct iwl_fw_error_dump_data *dump_data;
768 struct iwl_fw_error_dump_info *dump_info; 896 struct iwl_fw_error_dump_info *dump_info;
897 struct iwl_fw_error_dump_mem *dump_mem;
769 struct iwl_mvm_dump_ptrs *fw_error_dump; 898 struct iwl_mvm_dump_ptrs *fw_error_dump;
770 const struct fw_img *img;
771 u32 sram_len, sram_ofs; 899 u32 sram_len, sram_ofs;
772 u32 file_len, rxf_len; 900 u32 file_len, fifo_data_len = 0;
773 unsigned long flags; 901 u32 smem_len = mvm->cfg->smem_len;
774 int reg_val; 902 u32 sram2_len = mvm->cfg->dccm2_len;
775 903
776 lockdep_assert_held(&mvm->mutex); 904 lockdep_assert_held(&mvm->mutex);
777 905
906 /* W/A for 8000 HW family A-step */
907 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000 &&
908 CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) {
909 if (smem_len)
910 smem_len = 0x38000;
911
912 if (sram2_len)
913 sram2_len = 0x10000;
914 }
915
778 fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL); 916 fw_error_dump = kzalloc(sizeof(*fw_error_dump), GFP_KERNEL);
779 if (!fw_error_dump) 917 if (!fw_error_dump)
780 return; 918 return;
781 919
782 img = &mvm->fw->img[mvm->cur_ucode]; 920 /* SRAM - include stack CCM if driver knows the values for it */
783 sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 921 if (!mvm->cfg->dccm_offset || !mvm->cfg->dccm_len) {
784 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; 922 const struct fw_img *img;
923
924 img = &mvm->fw->img[mvm->cur_ucode];
925 sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
926 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
927 } else {
928 sram_ofs = mvm->cfg->dccm_offset;
929 sram_len = mvm->cfg->dccm_len;
930 }
931
932 /* reading RXF/TXF sizes */
933 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status)) {
934 struct iwl_mvm_shared_mem_cfg *mem_cfg = &mvm->shared_mem_cfg;
935 int i;
936
937 fifo_data_len = 0;
938
939 /* Count RXF size */
940 for (i = 0; i < ARRAY_SIZE(mem_cfg->rxfifo_size); i++) {
941 if (!mem_cfg->rxfifo_size[i])
942 continue;
943
944 /* Add header info */
945 fifo_data_len += mem_cfg->rxfifo_size[i] +
946 sizeof(*dump_data) +
947 sizeof(struct iwl_fw_error_dump_fifo);
948 }
785 949
786 /* reading buffer size */ 950 for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++) {
787 reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR); 951 if (!mem_cfg->txfifo_size[i])
788 rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS; 952 continue;
789 953
790 /* the register holds the value divided by 128 */ 954 /* Add header info */
791 rxf_len = rxf_len << 7; 955 fifo_data_len += mem_cfg->txfifo_size[i] +
956 sizeof(*dump_data) +
957 sizeof(struct iwl_fw_error_dump_fifo);
958 }
959 }
792 960
793 file_len = sizeof(*dump_file) + 961 file_len = sizeof(*dump_file) +
794 sizeof(*dump_data) * 3 + 962 sizeof(*dump_data) * 2 +
795 sram_len + 963 sram_len + sizeof(*dump_mem) +
796 rxf_len + 964 fifo_data_len +
797 sizeof(*dump_info); 965 sizeof(*dump_info);
798 966
967 /* Make room for the SMEM, if it exists */
968 if (smem_len)
969 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + smem_len;
970
971 /* Make room for the secondary SRAM, if it exists */
972 if (sram2_len)
973 file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len;
974
799 dump_file = vzalloc(file_len); 975 dump_file = vzalloc(file_len);
800 if (!dump_file) { 976 if (!dump_file) {
801 kfree(fw_error_dump); 977 kfree(fw_error_dump);
@@ -814,6 +990,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
814 mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ? 990 mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
815 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) : 991 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
816 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8); 992 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
993 dump_info->hw_step = cpu_to_le32(CSR_HW_REV_STEP(mvm->trans->hw_rev));
817 memcpy(dump_info->fw_human_readable, mvm->fw->human_readable, 994 memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
818 sizeof(dump_info->fw_human_readable)); 995 sizeof(dump_info->fw_human_readable));
819 strncpy(dump_info->dev_human_readable, mvm->cfg->name, 996 strncpy(dump_info->dev_human_readable, mvm->cfg->name,
@@ -822,28 +999,39 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
822 sizeof(dump_info->bus_human_readable)); 999 sizeof(dump_info->bus_human_readable));
823 1000
824 dump_data = iwl_fw_error_next_data(dump_data); 1001 dump_data = iwl_fw_error_next_data(dump_data);
825 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF); 1002 /* We only dump the FIFOs if the FW is in error state */
826 dump_data->len = cpu_to_le32(rxf_len); 1003 if (test_bit(STATUS_FW_ERROR, &mvm->trans->status))
827 1004 iwl_mvm_dump_fifos(mvm, &dump_data);
828 if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) { 1005
829 u32 *rxf = (void *)dump_data->data; 1006 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
830 int i; 1007 dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem));
1008 dump_mem = (void *)dump_data->data;
1009 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
1010 dump_mem->offset = cpu_to_le32(sram_ofs);
1011 iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_mem->data,
1012 sram_len);
831 1013
832 for (i = 0; i < (rxf_len / sizeof(u32)); i++) { 1014 if (smem_len) {
833 iwl_trans_write_prph(mvm->trans, 1015 dump_data = iwl_fw_error_next_data(dump_data);
834 RXF_LD_FENCE_OFFSET_ADDR, 1016 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
835 i * sizeof(u32)); 1017 dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem));
836 rxf[i] = iwl_trans_read_prph(mvm->trans, 1018 dump_mem = (void *)dump_data->data;
837 RXF_FIFO_RD_FENCE_ADDR); 1019 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SMEM);
838 } 1020 dump_mem->offset = cpu_to_le32(mvm->cfg->smem_offset);
839 iwl_trans_release_nic_access(mvm->trans, &flags); 1021 iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->smem_offset,
1022 dump_mem->data, smem_len);
840 } 1023 }
841 1024
842 dump_data = iwl_fw_error_next_data(dump_data); 1025 if (sram2_len) {
843 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM); 1026 dump_data = iwl_fw_error_next_data(dump_data);
844 dump_data->len = cpu_to_le32(sram_len); 1027 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
845 iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data, 1028 dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem));
846 sram_len); 1029 dump_mem = (void *)dump_data->data;
1030 dump_mem->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM_SRAM);
1031 dump_mem->offset = cpu_to_le32(mvm->cfg->dccm2_offset);
1032 iwl_trans_read_mem_bytes(mvm->trans, mvm->cfg->dccm2_offset,
1033 dump_mem->data, sram2_len);
1034 }
847 1035
848 fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans); 1036 fw_error_dump->trans_ptr = iwl_trans_dump_data(mvm->trans);
849 fw_error_dump->op_mode_len = file_len; 1037 fw_error_dump->op_mode_len = file_len;
@@ -864,6 +1052,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
864 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status)) 1052 if (!test_and_clear_bit(IWL_MVM_STATUS_D3_RECONFIG, &mvm->status))
865 iwl_mvm_fw_error_dump(mvm); 1053 iwl_mvm_fw_error_dump(mvm);
866 1054
1055 /* cleanup all stale references (scan, roc), but keep the
1056 * ucode_down ref until reconfig is complete
1057 */
1058 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
1059
867 iwl_trans_stop_device(mvm->trans); 1060 iwl_trans_stop_device(mvm->trans);
868 1061
869 mvm->scan_status = IWL_MVM_SCAN_NONE; 1062 mvm->scan_status = IWL_MVM_SCAN_NONE;
@@ -893,10 +1086,6 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
893 1086
894 ieee80211_wake_queues(mvm->hw); 1087 ieee80211_wake_queues(mvm->hw);
895 1088
896 /* cleanup all stale references (scan, roc), but keep the
897 * ucode_down ref until reconfig is complete */
898 iwl_mvm_unref_all_except(mvm, IWL_MVM_REF_UCODE_DOWN);
899
900 /* clear any stale d0i3 state */ 1089 /* clear any stale d0i3 state */
901 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status); 1090 clear_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status);
902 1091
@@ -933,6 +1122,19 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
933 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1122 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
934 int ret; 1123 int ret;
935 1124
1125 /* Some hw restart cleanups must not hold the mutex */
1126 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
1127 /*
1128 * Make sure we are out of d0i3. This is needed
1129 * to make sure the reference accounting is correct
1130 * (and there is no stale d0i3_exit_work).
1131 */
1132 wait_event_timeout(mvm->d0i3_exit_waitq,
1133 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1134 &mvm->status),
1135 HZ);
1136 }
1137
936 mutex_lock(&mvm->mutex); 1138 mutex_lock(&mvm->mutex);
937 ret = __iwl_mvm_mac_start(mvm); 1139 ret = __iwl_mvm_mac_start(mvm);
938 mutex_unlock(&mvm->mutex); 1140 mutex_unlock(&mvm->mutex);
@@ -982,6 +1184,13 @@ static void iwl_mvm_resume_complete(struct iwl_mvm *mvm)
982 IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n"); 1184 IWL_DEBUG_RPM(mvm, "Run deferred d0i3 exit\n");
983 _iwl_mvm_exit_d0i3(mvm); 1185 _iwl_mvm_exit_d0i3(mvm);
984 } 1186 }
1187
1188 if (mvm->trans->d0i3_mode == IWL_D0I3_MODE_ON_SUSPEND)
1189 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
1190 !test_bit(IWL_MVM_STATUS_IN_D0I3,
1191 &mvm->status),
1192 HZ))
1193 WARN_ONCE(1, "D0i3 exit on resume timed out\n");
985} 1194}
986 1195
987static void 1196static void
@@ -1146,7 +1355,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
1146 1355
1147 ret = iwl_mvm_power_update_mac(mvm); 1356 ret = iwl_mvm_power_update_mac(mvm);
1148 if (ret) 1357 if (ret)
1149 goto out_release; 1358 goto out_remove_mac;
1150 1359
1151 /* beacon filtering */ 1360 /* beacon filtering */
1152 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0); 1361 ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
@@ -2088,7 +2297,7 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
2088 struct ieee80211_sta *sta) 2297 struct ieee80211_sta *sta)
2089{ 2298{
2090 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2299 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2091 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 2300 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
2092 2301
2093 /* 2302 /*
2094 * This is called before mac80211 does RCU synchronisation, 2303 * This is called before mac80211 does RCU synchronisation,
@@ -2105,6 +2314,20 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
2105 mutex_unlock(&mvm->mutex); 2314 mutex_unlock(&mvm->mutex);
2106} 2315}
2107 2316
2317static void iwl_mvm_check_uapsd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
2318 const u8 *bssid)
2319{
2320 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT))
2321 return;
2322
2323 if (iwlwifi_mod_params.uapsd_disable) {
2324 vif->driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
2325 return;
2326 }
2327
2328 vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
2329}
2330
2108static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 2331static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2109 struct ieee80211_vif *vif, 2332 struct ieee80211_vif *vif,
2110 struct ieee80211_sta *sta, 2333 struct ieee80211_sta *sta,
@@ -2164,6 +2387,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2164 * Reset EBS status here assuming environment has been changed. 2387 * Reset EBS status here assuming environment has been changed.
2165 */ 2388 */
2166 mvm->last_ebs_successful = true; 2389 mvm->last_ebs_successful = true;
2390 iwl_mvm_check_uapsd(mvm, vif, sta->addr);
2167 ret = 0; 2391 ret = 0;
2168 } else if (old_state == IEEE80211_STA_AUTH && 2392 } else if (old_state == IEEE80211_STA_AUTH &&
2169 new_state == IEEE80211_STA_ASSOC) { 2393 new_state == IEEE80211_STA_ASSOC) {
@@ -3103,7 +3327,7 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
3103 bool set) 3327 bool set)
3104{ 3328{
3105 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 3329 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
3106 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 3330 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
3107 3331
3108 if (!mvm_sta || !mvm_sta->vif) { 3332 if (!mvm_sta || !mvm_sta->vif) {
3109 IWL_ERR(mvm, "Station is not associated to a vif\n"); 3333 IWL_ERR(mvm, "Station is not associated to a vif\n");
@@ -3343,16 +3567,18 @@ static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
3343 msk |= mvmsta->tfd_queue_msk; 3567 msk |= mvmsta->tfd_queue_msk;
3344 } 3568 }
3345 3569
3346 msk &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); 3570 if (drop) {
3347 3571 if (iwl_mvm_flush_tx_path(mvm, msk, true))
3348 if (iwl_mvm_flush_tx_path(mvm, msk, true)) 3572 IWL_ERR(mvm, "flush request fail\n");
3349 IWL_ERR(mvm, "flush request fail\n"); 3573 mutex_unlock(&mvm->mutex);
3350 mutex_unlock(&mvm->mutex); 3574 } else {
3575 mutex_unlock(&mvm->mutex);
3351 3576
3352 /* this can take a while, and we may need/want other operations 3577 /* this can take a while, and we may need/want other operations
3353 * to succeed while doing this, so do it without the mutex held 3578 * to succeed while doing this, so do it without the mutex held
3354 */ 3579 */
3355 iwl_trans_wait_tx_queue_empty(mvm->trans, msk); 3580 iwl_trans_wait_tx_queue_empty(mvm->trans, msk);
3581 }
3356} 3582}
3357 3583
3358const struct ieee80211_ops iwl_mvm_hw_ops = { 3584const struct ieee80211_ops iwl_mvm_hw_ops = {
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index d24660fb4ef2..6c69d0584f6c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -119,11 +119,13 @@ extern const struct ieee80211_ops iwl_mvm_hw_ops;
119 * We will register to mac80211 to have testmode working. The NIC must not 119 * We will register to mac80211 to have testmode working. The NIC must not
120 * be up'ed after the INIT fw asserted. This is useful to be able to use 120 * be up'ed after the INIT fw asserted. This is useful to be able to use
121 * proprietary tools over testmode to debug the INIT fw. 121 * proprietary tools over testmode to debug the INIT fw.
122 * @tfd_q_hang_detect: enabled the detection of hung transmit queues
122 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power 123 * @power_scheme: CAM(Continuous Active Mode)-1, BPS(Balanced Power
123 * Save)-2(default), LP(Low Power)-3 124 * Save)-2(default), LP(Low Power)-3
124 */ 125 */
125struct iwl_mvm_mod_params { 126struct iwl_mvm_mod_params {
126 bool init_dbg; 127 bool init_dbg;
128 bool tfd_q_hang_detect;
127 int power_scheme; 129 int power_scheme;
128}; 130};
129extern struct iwl_mvm_mod_params iwlmvm_mod_params; 131extern struct iwl_mvm_mod_params iwlmvm_mod_params;
@@ -276,6 +278,7 @@ enum iwl_mvm_ref_type {
276 IWL_MVM_REF_TM_CMD, 278 IWL_MVM_REF_TM_CMD,
277 IWL_MVM_REF_EXIT_WORK, 279 IWL_MVM_REF_EXIT_WORK,
278 IWL_MVM_REF_PROTECT_CSA, 280 IWL_MVM_REF_PROTECT_CSA,
281 IWL_MVM_REF_FW_DBG_COLLECT,
279 282
280 /* update debugfs.c when changing this */ 283 /* update debugfs.c when changing this */
281 284
@@ -531,10 +534,23 @@ enum {
531enum iwl_mvm_tdls_cs_state { 534enum iwl_mvm_tdls_cs_state {
532 IWL_MVM_TDLS_SW_IDLE = 0, 535 IWL_MVM_TDLS_SW_IDLE = 0,
533 IWL_MVM_TDLS_SW_REQ_SENT, 536 IWL_MVM_TDLS_SW_REQ_SENT,
537 IWL_MVM_TDLS_SW_RESP_RCVD,
534 IWL_MVM_TDLS_SW_REQ_RCVD, 538 IWL_MVM_TDLS_SW_REQ_RCVD,
535 IWL_MVM_TDLS_SW_ACTIVE, 539 IWL_MVM_TDLS_SW_ACTIVE,
536}; 540};
537 541
542struct iwl_mvm_shared_mem_cfg {
543 u32 shared_mem_addr;
544 u32 shared_mem_size;
545 u32 sample_buff_addr;
546 u32 sample_buff_size;
547 u32 txfifo_addr;
548 u32 txfifo_size[TX_FIFO_MAX_NUM];
549 u32 rxfifo_size[RX_FIFO_MAX_NUM];
550 u32 page_buff_addr;
551 u32 page_buff_size;
552};
553
538struct iwl_mvm { 554struct iwl_mvm {
539 /* for logger access */ 555 /* for logger access */
540 struct device *dev; 556 struct device *dev;
@@ -641,6 +657,8 @@ struct iwl_mvm {
641 bool disable_power_off; 657 bool disable_power_off;
642 bool disable_power_off_d3; 658 bool disable_power_off_d3;
643 659
660 bool scan_iter_notif_enabled;
661
644 struct debugfs_blob_wrapper nvm_hw_blob; 662 struct debugfs_blob_wrapper nvm_hw_blob;
645 struct debugfs_blob_wrapper nvm_sw_blob; 663 struct debugfs_blob_wrapper nvm_sw_blob;
646 struct debugfs_blob_wrapper nvm_calib_blob; 664 struct debugfs_blob_wrapper nvm_calib_blob;
@@ -782,8 +800,13 @@ struct iwl_mvm {
782 struct cfg80211_chan_def chandef; 800 struct cfg80211_chan_def chandef;
783 struct sk_buff *skb; /* ch sw template */ 801 struct sk_buff *skb; /* ch sw template */
784 u32 ch_sw_tm_ie; 802 u32 ch_sw_tm_ie;
803
804 /* timestamp of last ch-sw request sent (GP2 time) */
805 u32 sent_timestamp;
785 } peer; 806 } peer;
786 } tdls_cs; 807 } tdls_cs;
808
809 struct iwl_mvm_shared_mem_cfg shared_mem_cfg;
787}; 810};
788 811
789/* Extract MVM priv from op_mode and _hw */ 812/* Extract MVM priv from op_mode and _hw */
@@ -850,12 +873,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) 873static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
851{ 874{
852 return mvm->trans->cfg->d0i3 && 875 return mvm->trans->cfg->d0i3 &&
876 mvm->trans->d0i3_mode != IWL_D0I3_MODE_OFF &&
877 !iwlwifi_mod_params.d0i3_disable &&
853 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT); 878 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
854} 879}
855 880
856static inline bool iwl_mvm_is_dqa_supported(struct iwl_mvm *mvm) 881static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
857{ 882{
858 return mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_DQA_SUPPORT; 883 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG;
859} 884}
860 885
861extern const u8 iwl_mvm_ac_to_tx_fifo[]; 886extern const u8 iwl_mvm_ac_to_tx_fifo[];
@@ -937,6 +962,33 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
937int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic); 962int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
938int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm); 963int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
939 964
965static inline u8 iwl_mvm_get_valid_tx_ant(struct iwl_mvm *mvm)
966{
967 return mvm->nvm_data && mvm->nvm_data->valid_tx_ant ?
968 mvm->fw->valid_tx_ant & mvm->nvm_data->valid_tx_ant :
969 mvm->fw->valid_tx_ant;
970}
971
972static inline u8 iwl_mvm_get_valid_rx_ant(struct iwl_mvm *mvm)
973{
974 return mvm->nvm_data && mvm->nvm_data->valid_rx_ant ?
975 mvm->fw->valid_rx_ant & mvm->nvm_data->valid_rx_ant :
976 mvm->fw->valid_rx_ant;
977}
978
979static inline u32 iwl_mvm_get_phy_config(struct iwl_mvm *mvm)
980{
981 u32 phy_config = ~(FW_PHY_CFG_TX_CHAIN |
982 FW_PHY_CFG_RX_CHAIN);
983 u32 valid_rx_ant = iwl_mvm_get_valid_rx_ant(mvm);
984 u32 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
985
986 phy_config |= valid_tx_ant << FW_PHY_CFG_TX_CHAIN_POS |
987 valid_rx_ant << FW_PHY_CFG_RX_CHAIN_POS;
988
989 return mvm->fw->phy_config & phy_config;
990}
991
940int iwl_mvm_up(struct iwl_mvm *mvm); 992int iwl_mvm_up(struct iwl_mvm *mvm);
941int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm); 993int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm);
942 994
@@ -970,6 +1022,9 @@ int iwl_mvm_rx_radio_ver(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
970 struct iwl_device_cmd *cmd); 1022 struct iwl_device_cmd *cmd);
971int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, 1023int iwl_mvm_rx_mfuart_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
972 struct iwl_device_cmd *cmd); 1024 struct iwl_device_cmd *cmd);
1025int iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
1026 struct iwl_rx_cmd_buffer *rxb,
1027 struct iwl_device_cmd *cmd);
973 1028
974/* MVM PHY */ 1029/* MVM PHY */
975int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, 1030int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
@@ -1031,6 +1086,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, 1086int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
1032 struct iwl_rx_cmd_buffer *rxb, 1087 struct iwl_rx_cmd_buffer *rxb,
1033 struct iwl_device_cmd *cmd); 1088 struct iwl_device_cmd *cmd);
1089int iwl_mvm_rx_scan_offload_iter_complete_notif(struct iwl_mvm *mvm,
1090 struct iwl_rx_cmd_buffer *rxb,
1091 struct iwl_device_cmd *cmd);
1034int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 1092int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
1035 struct ieee80211_vif *vif, 1093 struct ieee80211_vif *vif,
1036 struct cfg80211_sched_scan_request *req, 1094 struct cfg80211_sched_scan_request *req,
@@ -1091,9 +1149,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1091 1149
1092/* rate scaling */ 1150/* rate scaling */
1093int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init); 1151int 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, 1152void 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); 1153int rs_pretty_print_rate(char *buf, const u32 rate);
1098void rs_update_last_rssi(struct iwl_mvm *mvm, 1154void rs_update_last_rssi(struct iwl_mvm *mvm,
1099 struct iwl_lq_sta *lq_sta, 1155 struct iwl_lq_sta *lq_sta,
@@ -1159,6 +1215,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); 1215int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type);
1160bool iwl_mvm_ref_taken(struct iwl_mvm *mvm); 1216bool iwl_mvm_ref_taken(struct iwl_mvm *mvm);
1161void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq); 1217void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq);
1218int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode);
1219int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode);
1162int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm); 1220int _iwl_mvm_exit_d0i3(struct iwl_mvm *mvm);
1163 1221
1164/* BT Coex */ 1222/* BT Coex */
@@ -1260,11 +1318,13 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
1260 1318
1261/* hw scheduler queue config */ 1319/* hw scheduler queue config */
1262void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn, 1320void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, u16 ssn,
1263 const struct iwl_trans_txq_scd_cfg *cfg); 1321 const struct iwl_trans_txq_scd_cfg *cfg,
1264void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue); 1322 unsigned int wdg_timeout);
1323void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags);
1265 1324
1266static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue, 1325static inline
1267 u8 fifo) 1326void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1327 u8 fifo, unsigned int wdg_timeout)
1268{ 1328{
1269 struct iwl_trans_txq_scd_cfg cfg = { 1329 struct iwl_trans_txq_scd_cfg cfg = {
1270 .fifo = fifo, 1330 .fifo = fifo,
@@ -1273,12 +1333,13 @@ static inline void iwl_mvm_enable_ac_txq(struct iwl_mvm *mvm, int queue,
1273 .frame_limit = IWL_FRAME_LIMIT, 1333 .frame_limit = IWL_FRAME_LIMIT,
1274 }; 1334 };
1275 1335
1276 iwl_mvm_enable_txq(mvm, queue, 0, &cfg); 1336 iwl_mvm_enable_txq(mvm, queue, 0, &cfg, wdg_timeout);
1277} 1337}
1278 1338
1279static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue, 1339static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1280 int fifo, int sta_id, int tid, 1340 int fifo, int sta_id, int tid,
1281 int frame_limit, u16 ssn) 1341 int frame_limit, u16 ssn,
1342 unsigned int wdg_timeout)
1282{ 1343{
1283 struct iwl_trans_txq_scd_cfg cfg = { 1344 struct iwl_trans_txq_scd_cfg cfg = {
1284 .fifo = fifo, 1345 .fifo = fifo,
@@ -1288,7 +1349,7 @@ static inline void iwl_mvm_enable_agg_txq(struct iwl_mvm *mvm, int queue,
1288 .aggregate = true, 1349 .aggregate = true,
1289 }; 1350 };
1290 1351
1291 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg); 1352 iwl_mvm_enable_txq(mvm, queue, ssn, &cfg, wdg_timeout);
1292} 1353}
1293 1354
1294/* Assoc status */ 1355/* Assoc status */
@@ -1344,4 +1405,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); 1405void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1345void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); 1406void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
1346 1407
1408int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, enum iwl_fw_dbg_conf id);
1409void iwl_mvm_fw_dbg_collect(struct iwl_mvm *mvm);
1410
1347#endif /* __IWL_MVM_H__ */ 1411#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..2dffc3600ed3 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
@@ -100,6 +93,7 @@ static const struct iwl_op_mode_ops iwl_mvm_ops;
100 93
101struct iwl_mvm_mod_params iwlmvm_mod_params = { 94struct iwl_mvm_mod_params iwlmvm_mod_params = {
102 .power_scheme = IWL_POWER_SCHEME_BPS, 95 .power_scheme = IWL_POWER_SCHEME_BPS,
96 .tfd_q_hang_detect = true
103 /* rest of fields are 0 by default */ 97 /* rest of fields are 0 by default */
104}; 98};
105 99
@@ -109,6 +103,10 @@ MODULE_PARM_DESC(init_dbg,
109module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO); 103module_param_named(power_scheme, iwlmvm_mod_params.power_scheme, int, S_IRUGO);
110MODULE_PARM_DESC(power_scheme, 104MODULE_PARM_DESC(power_scheme,
111 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2"); 105 "power management scheme: 1-active, 2-balanced, 3-low power, default: 2");
106module_param_named(tfd_q_hang_detect, iwlmvm_mod_params.tfd_q_hang_detect,
107 bool, S_IRUGO);
108MODULE_PARM_DESC(tfd_q_hang_detect,
109 "TFD queues hang detection (default: true");
112 110
113/* 111/*
114 * module init and exit functions 112 * module init and exit functions
@@ -146,13 +144,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); 144 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
147 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash; 145 u8 radio_cfg_type, radio_cfg_step, radio_cfg_dash;
148 u32 reg_val = 0; 146 u32 reg_val = 0;
147 u32 phy_config = iwl_mvm_get_phy_config(mvm);
149 148
150 radio_cfg_type = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_TYPE) >> 149 radio_cfg_type = (phy_config & FW_PHY_CFG_RADIO_TYPE) >>
151 FW_PHY_CFG_RADIO_TYPE_POS; 150 FW_PHY_CFG_RADIO_TYPE_POS;
152 radio_cfg_step = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_STEP) >> 151 radio_cfg_step = (phy_config & FW_PHY_CFG_RADIO_STEP) >>
153 FW_PHY_CFG_RADIO_STEP_POS; 152 FW_PHY_CFG_RADIO_STEP_POS;
154 radio_cfg_dash = (mvm->fw->phy_config & FW_PHY_CFG_RADIO_DASH) >> 153 radio_cfg_dash = (phy_config & FW_PHY_CFG_RADIO_DASH) >>
155 FW_PHY_CFG_RADIO_DASH_POS; 154 FW_PHY_CFG_RADIO_DASH_POS;
156 155
157 /* SKU control */ 156 /* SKU control */
158 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) << 157 reg_val |= CSR_HW_REV_STEP(mvm->trans->hw_rev) <<
@@ -240,6 +239,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
240 239
241 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 240 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
242 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), 241 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
242 RX_HANDLER(SCAN_ITERATION_COMPLETE,
243 iwl_mvm_rx_scan_offload_iter_complete_notif, false),
243 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 244 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
244 iwl_mvm_rx_scan_offload_complete_notif, true), 245 iwl_mvm_rx_scan_offload_complete_notif, true),
245 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results, 246 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
@@ -274,6 +275,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
274 CMD(MGMT_MCAST_KEY), 275 CMD(MGMT_MCAST_KEY),
275 CMD(TX_CMD), 276 CMD(TX_CMD),
276 CMD(TXPATH_FLUSH), 277 CMD(TXPATH_FLUSH),
278 CMD(SHARED_MEM_CFG),
277 CMD(MAC_CONTEXT_CMD), 279 CMD(MAC_CONTEXT_CMD),
278 CMD(TIME_EVENT_CMD), 280 CMD(TIME_EVENT_CMD),
279 CMD(TIME_EVENT_NOTIFICATION), 281 CMD(TIME_EVENT_NOTIFICATION),
@@ -476,17 +478,19 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
476 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) 478 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE)
477 trans_cfg.bc_table_dword = true; 479 trans_cfg.bc_table_dword = true;
478 480
479 if (!iwlwifi_mod_params.wd_disable)
480 trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout;
481 else
482 trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED;
483
484 trans_cfg.command_names = iwl_mvm_cmd_strings; 481 trans_cfg.command_names = iwl_mvm_cmd_strings;
485 482
486 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 483 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
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
489 /* Set a short watchdog for the command queue */
490 trans_cfg.cmd_q_wdg_timeout =
491 iwlmvm_mod_params.tfd_q_hang_detect ? IWL_DEF_WD_TIMEOUT :
492 IWL_WATCHDOG_DISABLED;
493
490 snprintf(mvm->hw->wiphy->fw_version, 494 snprintf(mvm->hw->wiphy->fw_version,
491 sizeof(mvm->hw->wiphy->fw_version), 495 sizeof(mvm->hw->wiphy->fw_version),
492 "%s", fw->fw_version); 496 "%s", fw->fw_version);
@@ -517,10 +521,15 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
517 min_backoff = calc_min_backoff(trans, cfg); 521 min_backoff = calc_min_backoff(trans, cfg);
518 iwl_mvm_tt_initialize(mvm, min_backoff); 522 iwl_mvm_tt_initialize(mvm, min_backoff);
519 /* set the nvm_file_name according to priority */ 523 /* set the nvm_file_name according to priority */
520 if (iwlwifi_mod_params.nvm_file) 524 if (iwlwifi_mod_params.nvm_file) {
521 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; 525 mvm->nvm_file_name = iwlwifi_mod_params.nvm_file;
522 else 526 } else {
523 mvm->nvm_file_name = mvm->cfg->default_nvm_file; 527 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
528 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
529 mvm->nvm_file_name = mvm->cfg->default_nvm_file_8000A;
530 else
531 mvm->nvm_file_name = mvm->cfg->default_nvm_file;
532 }
524 533
525 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, 534 if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name,
526 "not allowing power-up and not having nvm_file\n")) 535 "not allowing power-up and not having nvm_file\n"))
@@ -559,6 +568,9 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
559 if (!mvm->scan_cmd) 568 if (!mvm->scan_cmd)
560 goto out_free; 569 goto out_free;
561 570
571 /* Set EBS as successful as long as not stated otherwise by the FW. */
572 mvm->last_ebs_successful = true;
573
562 err = iwl_mvm_mac_setup_register(mvm); 574 err = iwl_mvm_mac_setup_register(mvm);
563 if (err) 575 if (err)
564 goto out_free; 576 goto out_free;
@@ -817,9 +829,20 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
817 struct iwl_mvm *mvm = 829 struct iwl_mvm *mvm =
818 container_of(work, struct iwl_mvm, fw_error_dump_wk); 830 container_of(work, struct iwl_mvm, fw_error_dump_wk);
819 831
832 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_FW_DBG_COLLECT))
833 return;
834
820 mutex_lock(&mvm->mutex); 835 mutex_lock(&mvm->mutex);
821 iwl_mvm_fw_error_dump(mvm); 836 iwl_mvm_fw_error_dump(mvm);
837
838 /* start recording again if the firmware is not crashed */
839 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
840 mvm->fw->dbg_dest_tlv &&
841 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
842
822 mutex_unlock(&mvm->mutex); 843 mutex_unlock(&mvm->mutex);
844
845 iwl_mvm_unref(mvm, IWL_MVM_REF_FW_DBG_COLLECT);
823} 846}
824 847
825void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) 848void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
@@ -855,7 +878,10 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
855 * If WoWLAN fw asserted, don't restart either, mac80211 878 * If WoWLAN fw asserted, don't restart either, mac80211
856 * can't recover this since we're already half suspended. 879 * can't recover this since we're already half suspended.
857 */ 880 */
858 if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { 881 if (!mvm->restart_fw && fw_error) {
882 schedule_work(&mvm->fw_error_dump_wk);
883 } else if (test_and_set_bit(IWL_MVM_STATUS_IN_HW_RESTART,
884 &mvm->status)) {
859 struct iwl_mvm_reprobe *reprobe; 885 struct iwl_mvm_reprobe *reprobe;
860 886
861 IWL_ERR(mvm, 887 IWL_ERR(mvm,
@@ -879,16 +905,13 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
879 reprobe->dev = mvm->trans->dev; 905 reprobe->dev = mvm->trans->dev;
880 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 906 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
881 schedule_work(&reprobe->work); 907 schedule_work(&reprobe->work);
882 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && 908 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR) {
883 (!fw_error || mvm->restart_fw)) {
884 /* don't let the transport/FW power down */ 909 /* don't let the transport/FW power down */
885 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 910 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
886 911
887 if (fw_error && mvm->restart_fw > 0) 912 if (fw_error && mvm->restart_fw > 0)
888 mvm->restart_fw--; 913 mvm->restart_fw--;
889 ieee80211_restart_hw(mvm->hw); 914 ieee80211_restart_hw(mvm->hw);
890 } else if (fw_error) {
891 schedule_work(&mvm->fw_error_dump_wk);
892 } 915 }
893} 916}
894 917
@@ -1031,7 +1054,8 @@ static void iwl_mvm_set_wowlan_data(struct iwl_mvm *mvm,
1031out: 1054out:
1032 rcu_read_unlock(); 1055 rcu_read_unlock();
1033} 1056}
1034static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode) 1057
1058int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1035{ 1059{
1036 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1060 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1037 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE; 1061 u32 flags = CMD_ASYNC | CMD_HIGH_PRIO | CMD_SEND_IN_IDLE;
@@ -1047,6 +1071,7 @@ static int iwl_mvm_enter_d0i3(struct iwl_op_mode *op_mode)
1047 }; 1071 };
1048 struct iwl_d3_manager_config d3_cfg_cmd = { 1072 struct iwl_d3_manager_config d3_cfg_cmd = {
1049 .min_sleep_time = cpu_to_le32(1000), 1073 .min_sleep_time = cpu_to_le32(1000),
1074 .wakeup_flags = cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR),
1050 }; 1075 };
1051 1076
1052 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n"); 1077 IWL_DEBUG_RPM(mvm, "MVM entering D0i3\n");
@@ -1146,7 +1171,7 @@ void iwl_mvm_d0i3_enable_tx(struct iwl_mvm *mvm, __le16 *qos_seq)
1146 1171
1147 if (mvm->d0i3_offloading && qos_seq) { 1172 if (mvm->d0i3_offloading && qos_seq) {
1148 /* update qos seq numbers if offloading was enabled */ 1173 /* update qos seq numbers if offloading was enabled */
1149 mvm_ap_sta = (struct iwl_mvm_sta *)sta->drv_priv; 1174 mvm_ap_sta = iwl_mvm_sta_from_mac80211(sta);
1150 for (i = 0; i < IWL_MAX_TID_COUNT; i++) { 1175 for (i = 0; i < IWL_MAX_TID_COUNT; i++) {
1151 u16 seq = le16_to_cpu(qos_seq[i]); 1176 u16 seq = le16_to_cpu(qos_seq[i]);
1152 /* firmware stores last-used one, we store next one */ 1177 /* firmware stores last-used one, we store next one */
@@ -1245,7 +1270,7 @@ out:
1245 return ret; 1270 return ret;
1246} 1271}
1247 1272
1248static int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode) 1273int iwl_mvm_exit_d0i3(struct iwl_op_mode *op_mode)
1249{ 1274{
1250 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 1275 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
1251 1276
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..194bd1f939ca 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -39,28 +39,16 @@
39#include "sta.h" 39#include "sta.h"
40#include "iwl-op-mode.h" 40#include "iwl-op-mode.h"
41#include "mvm.h" 41#include "mvm.h"
42#include "debugfs.h"
42 43
43#define RS_NAME "iwl-mvm-rs" 44#define RS_NAME "iwl-mvm-rs"
44 45
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 */ 46#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 47
60/* max allowed rate miss before sync LQ cmd */ 48/* Calculations of success ratio are done in fixed point where 12800 is 100%.
61#define IWL_MISSED_RATE_MAX 15 49 * Use this macro when dealing with thresholds consts set as a percentage
62#define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ) 50 */
63#define RS_IDLE_TIMEOUT (5*HZ) 51#define RS_PERCENT(x) (128 * x)
64 52
65static u8 rs_ht_to_legacy[] = { 53static u8 rs_ht_to_legacy[] = {
66 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, 54 [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX,
@@ -173,7 +161,7 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
173 if (sta->smps_mode == IEEE80211_SMPS_STATIC) 161 if (sta->smps_mode == IEEE80211_SMPS_STATIC)
174 return false; 162 return false;
175 163
176 if (num_of_ant(mvm->fw->valid_tx_ant) < 2) 164 if (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) < 2)
177 return false; 165 return false;
178 166
179 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 167 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
@@ -613,7 +601,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 601 * at this rate. window->data contains the bitmask of successful
614 * packets. 602 * packets.
615 */ 603 */
616static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, 604static int _rs_collect_tx_data(struct iwl_mvm *mvm,
605 struct iwl_scale_tbl_info *tbl,
617 int scale_index, int attempts, int successes, 606 int scale_index, int attempts, int successes,
618 struct iwl_rate_scale_data *window) 607 struct iwl_rate_scale_data *window)
619{ 608{
@@ -668,8 +657,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
668 fail_count = window->counter - window->success_counter; 657 fail_count = window->counter - window->success_counter;
669 658
670 /* Calculate average throughput, if we have enough history. */ 659 /* Calculate average throughput, if we have enough history. */
671 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || 660 if ((fail_count >= IWL_MVM_RS_RATE_MIN_FAILURE_TH) ||
672 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) 661 (window->success_counter >= IWL_MVM_RS_RATE_MIN_SUCCESS_TH))
673 window->average_tpt = (window->success_ratio * tpt + 64) / 128; 662 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
674 else 663 else
675 window->average_tpt = IWL_INVALID_VALUE; 664 window->average_tpt = IWL_INVALID_VALUE;
@@ -677,7 +666,8 @@ static int _rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
677 return 0; 666 return 0;
678} 667}
679 668
680static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta, 669static int rs_collect_tx_data(struct iwl_mvm *mvm,
670 struct iwl_lq_sta *lq_sta,
681 struct iwl_scale_tbl_info *tbl, 671 struct iwl_scale_tbl_info *tbl,
682 int scale_index, int attempts, int successes, 672 int scale_index, int attempts, int successes,
683 u8 reduced_txp) 673 u8 reduced_txp)
@@ -698,7 +688,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
698 /* Select window for current tx bit rate */ 688 /* Select window for current tx bit rate */
699 window = &(tbl->win[scale_index]); 689 window = &(tbl->win[scale_index]);
700 690
701 ret = _rs_collect_tx_data(tbl, scale_index, attempts, successes, 691 ret = _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
702 window); 692 window);
703 if (ret) 693 if (ret)
704 return ret; 694 return ret;
@@ -707,7 +697,7 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
707 return -EINVAL; 697 return -EINVAL;
708 698
709 window = &tbl->tpc_win[reduced_txp]; 699 window = &tbl->tpc_win[reduced_txp];
710 return _rs_collect_tx_data(tbl, scale_index, attempts, successes, 700 return _rs_collect_tx_data(mvm, tbl, scale_index, attempts, successes,
711 window); 701 window);
712} 702}
713 703
@@ -928,7 +918,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
928 break; 918 break;
929 if (rate_mask & (1 << low)) 919 if (rate_mask & (1 << low))
930 break; 920 break;
931 IWL_DEBUG_RATE(mvm, "Skipping masked lower rate: %d\n", low);
932 } 921 }
933 922
934 high = index; 923 high = index;
@@ -938,7 +927,6 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
938 break; 927 break;
939 if (rate_mask & (1 << high)) 928 if (rate_mask & (1 << high))
940 break; 929 break;
941 IWL_DEBUG_RATE(mvm, "Skipping masked higher rate: %d\n", high);
942 } 930 }
943 931
944 return (high << 8) | low; 932 return (high << 8) | low;
@@ -1004,7 +992,7 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
1004 } 992 }
1005 993
1006 if (num_of_ant(rate->ant) > 1) 994 if (num_of_ant(rate->ant) > 1)
1007 rate->ant = first_antenna(mvm->fw->valid_tx_ant); 995 rate->ant = first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
1008 996
1009 /* Relevant in both switching to SISO or Legacy */ 997 /* Relevant in both switching to SISO or Legacy */
1010 rate->sgi = false; 998 rate->sgi = false;
@@ -1125,7 +1113,8 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1125 } 1113 }
1126 1114
1127 if (time_after(jiffies, 1115 if (time_after(jiffies,
1128 (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) { 1116 (unsigned long)(lq_sta->last_tx +
1117 (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
1129 int t; 1118 int t;
1130 1119
1131 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); 1120 IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
@@ -1158,7 +1147,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1158 * ... driver. 1147 * ... driver.
1159 */ 1148 */
1160 lq_sta->missed_rate_counter++; 1149 lq_sta->missed_rate_counter++;
1161 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 1150 if (lq_sta->missed_rate_counter > IWL_MVM_RS_MISSED_RATE_MAX) {
1162 lq_sta->missed_rate_counter = 0; 1151 lq_sta->missed_rate_counter = 0;
1163 IWL_DEBUG_RATE(mvm, 1152 IWL_DEBUG_RATE(mvm,
1164 "Too many rates mismatch. Send sync LQ. rs_state %d\n", 1153 "Too many rates mismatch. Send sync LQ. rs_state %d\n",
@@ -1213,7 +1202,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1213 1202
1214 ucode_rate = le32_to_cpu(table->rs_table[0]); 1203 ucode_rate = le32_to_cpu(table->rs_table[0]);
1215 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate); 1204 rs_rate_from_ucode_rate(ucode_rate, info->band, &rate);
1216 rs_collect_tx_data(lq_sta, curr_tbl, rate.index, 1205 rs_collect_tx_data(mvm, lq_sta, curr_tbl, rate.index,
1217 info->status.ampdu_len, 1206 info->status.ampdu_len,
1218 info->status.ampdu_ack_len, 1207 info->status.ampdu_ack_len,
1219 reduced_txp); 1208 reduced_txp);
@@ -1249,7 +1238,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1249 else 1238 else
1250 continue; 1239 continue;
1251 1240
1252 rs_collect_tx_data(lq_sta, tmp_tbl, rate.index, 1, 1241 rs_collect_tx_data(mvm, lq_sta, tmp_tbl, rate.index, 1,
1253 i < retries ? 0 : legacy_success, 1242 i < retries ? 0 : legacy_success,
1254 reduced_txp); 1243 reduced_txp);
1255 } 1244 }
@@ -1303,13 +1292,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"); 1292 IWL_DEBUG_RATE(mvm, "Moving to RS_STATE_STAY_IN_COLUMN\n");
1304 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN; 1293 lq_sta->rs_state = RS_STATE_STAY_IN_COLUMN;
1305 if (is_legacy) { 1294 if (is_legacy) {
1306 lq_sta->table_count_limit = IWL_LEGACY_TABLE_COUNT; 1295 lq_sta->table_count_limit = IWL_MVM_RS_LEGACY_TABLE_COUNT;
1307 lq_sta->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 1296 lq_sta->max_failure_limit = IWL_MVM_RS_LEGACY_FAILURE_LIMIT;
1308 lq_sta->max_success_limit = IWL_LEGACY_SUCCESS_LIMIT; 1297 lq_sta->max_success_limit = IWL_MVM_RS_LEGACY_SUCCESS_LIMIT;
1309 } else { 1298 } else {
1310 lq_sta->table_count_limit = IWL_NONE_LEGACY_TABLE_COUNT; 1299 lq_sta->table_count_limit = IWL_MVM_RS_NON_LEGACY_TABLE_COUNT;
1311 lq_sta->max_failure_limit = IWL_NONE_LEGACY_FAILURE_LIMIT; 1300 lq_sta->max_failure_limit = IWL_MVM_RS_NON_LEGACY_FAILURE_LIMIT;
1312 lq_sta->max_success_limit = IWL_NONE_LEGACY_SUCCESS_LIMIT; 1301 lq_sta->max_success_limit = IWL_MVM_RS_NON_LEGACY_SUCCESS_LIMIT;
1313 } 1302 }
1314 lq_sta->table_count = 0; 1303 lq_sta->table_count = 0;
1315 lq_sta->total_failed = 0; 1304 lq_sta->total_failed = 0;
@@ -1318,6 +1307,13 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy,
1318 lq_sta->visited_columns = 0; 1307 lq_sta->visited_columns = 0;
1319} 1308}
1320 1309
1310static inline int rs_get_max_rate_from_mask(unsigned long rate_mask)
1311{
1312 if (rate_mask)
1313 return find_last_bit(&rate_mask, BITS_PER_LONG);
1314 return IWL_RATE_INVALID;
1315}
1316
1321static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta, 1317static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta,
1322 const struct rs_tx_column *column) 1318 const struct rs_tx_column *column)
1323{ 1319{
@@ -1420,7 +1416,7 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1420 u32 target_tpt; 1416 u32 target_tpt;
1421 int rate_idx; 1417 int rate_idx;
1422 1418
1423 if (success_ratio > RS_SR_NO_DECREASE) { 1419 if (success_ratio > IWL_MVM_RS_SR_NO_DECREASE) {
1424 target_tpt = 100 * expected_current_tpt; 1420 target_tpt = 100 * expected_current_tpt;
1425 IWL_DEBUG_RATE(mvm, 1421 IWL_DEBUG_RATE(mvm,
1426 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n", 1422 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n",
@@ -1488,7 +1484,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1488 flush_interval_passed = 1484 flush_interval_passed =
1489 time_after(jiffies, 1485 time_after(jiffies,
1490 (unsigned long)(lq_sta->flush_timer + 1486 (unsigned long)(lq_sta->flush_timer +
1491 RS_STAY_IN_COLUMN_TIMEOUT)); 1487 (IWL_MVM_RS_STAY_IN_COLUMN_TIMEOUT * HZ)));
1492 1488
1493 /* 1489 /*
1494 * Check if we should allow search for new modulation mode. 1490 * Check if we should allow search for new modulation mode.
@@ -1567,7 +1563,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]; 1563 const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column];
1568 const struct rs_tx_column *next_col; 1564 const struct rs_tx_column *next_col;
1569 allow_column_func_t allow_func; 1565 allow_column_func_t allow_func;
1570 u8 valid_ants = mvm->fw->valid_tx_ant; 1566 u8 valid_ants = iwl_mvm_get_valid_tx_ant(mvm);
1571 const u16 *expected_tpt_tbl; 1567 const u16 *expected_tpt_tbl;
1572 u16 tpt, max_expected_tpt; 1568 u16 tpt, max_expected_tpt;
1573 1569
@@ -1613,8 +1609,12 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1613 continue; 1609 continue;
1614 1610
1615 max_rate = rs_get_max_allowed_rate(lq_sta, next_col); 1611 max_rate = rs_get_max_allowed_rate(lq_sta, next_col);
1616 if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID)) 1612 if (max_rate == IWL_RATE_INVALID) {
1613 IWL_DEBUG_RATE(mvm,
1614 "Skip column %d: no rate is allowed in this column\n",
1615 next_col_id);
1617 continue; 1616 continue;
1617 }
1618 1618
1619 max_expected_tpt = expected_tpt_tbl[max_rate]; 1619 max_expected_tpt = expected_tpt_tbl[max_rate];
1620 if (tpt >= max_expected_tpt) { 1620 if (tpt >= max_expected_tpt) {
@@ -1724,7 +1724,8 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1724{ 1724{
1725 enum rs_action action = RS_ACTION_STAY; 1725 enum rs_action action = RS_ACTION_STAY;
1726 1726
1727 if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { 1727 if ((sr <= RS_PERCENT(IWL_MVM_RS_SR_FORCE_DECREASE)) ||
1728 (current_tpt == 0)) {
1728 IWL_DEBUG_RATE(mvm, 1729 IWL_DEBUG_RATE(mvm,
1729 "Decrease rate because of low SR\n"); 1730 "Decrease rate because of low SR\n");
1730 return RS_ACTION_DOWNSCALE; 1731 return RS_ACTION_DOWNSCALE;
@@ -1783,7 +1784,7 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm,
1783 1784
1784out: 1785out:
1785 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { 1786 if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) {
1786 if (sr >= RS_SR_NO_DECREASE) { 1787 if (sr >= RS_PERCENT(IWL_MVM_RS_SR_NO_DECREASE)) {
1787 IWL_DEBUG_RATE(mvm, 1788 IWL_DEBUG_RATE(mvm,
1788 "SR is above NO DECREASE. Avoid downscale\n"); 1789 "SR is above NO DECREASE. Avoid downscale\n");
1789 action = RS_ACTION_STAY; 1790 action = RS_ACTION_STAY;
@@ -1802,18 +1803,10 @@ out:
1802static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, 1803static bool rs_stbc_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1803 struct iwl_lq_sta *lq_sta) 1804 struct iwl_lq_sta *lq_sta)
1804{ 1805{
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 1806 /* Our chip supports Tx STBC and the peer is an HT/VHT STA which
1811 * supports STBC of at least 1*SS 1807 * supports STBC of at least 1*SS
1812 */ 1808 */
1813 if (!lq_sta->stbc) 1809 if (!lq_sta->stbc_capable)
1814 return false;
1815
1816 if (!mvm->ps_disabled && !sta_ps_disabled)
1817 return false; 1810 return false;
1818 1811
1819 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) 1812 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
@@ -1825,11 +1818,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, 1818static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,
1826 int *weaker, int *stronger) 1819 int *weaker, int *stronger)
1827{ 1820{
1828 *weaker = index + TPC_TX_POWER_STEP; 1821 *weaker = index + IWL_MVM_RS_TPC_TX_POWER_STEP;
1829 if (*weaker > TPC_MAX_REDUCTION) 1822 if (*weaker > TPC_MAX_REDUCTION)
1830 *weaker = TPC_INVALID; 1823 *weaker = TPC_INVALID;
1831 1824
1832 *stronger = index - TPC_TX_POWER_STEP; 1825 *stronger = index - IWL_MVM_RS_TPC_TX_POWER_STEP;
1833 if (*stronger < 0) 1826 if (*stronger < 0)
1834 *stronger = TPC_INVALID; 1827 *stronger = TPC_INVALID;
1835} 1828}
@@ -1885,7 +1878,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
1885 } 1878 }
1886 1879
1887 /* Too many failures, increase txp */ 1880 /* Too many failures, increase txp */
1888 if (sr <= TPC_SR_FORCE_INCREASE || current_tpt == 0) { 1881 if (sr <= RS_PERCENT(IWL_MVM_RS_TPC_SR_FORCE_INCREASE) ||
1882 current_tpt == 0) {
1889 IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n"); 1883 IWL_DEBUG_RATE(mvm, "increase txp because of weak SR\n");
1890 return TPC_ACTION_NO_RESTIRCTION; 1884 return TPC_ACTION_NO_RESTIRCTION;
1891 } 1885 }
@@ -1908,7 +1902,8 @@ static enum tpc_action rs_get_tpc_action(struct iwl_mvm *mvm,
1908 } 1902 }
1909 1903
1910 /* next, increase if needed */ 1904 /* next, increase if needed */
1911 if (sr < TPC_SR_NO_INCREASE && strong != TPC_INVALID) { 1905 if (sr < RS_PERCENT(IWL_MVM_RS_TPC_SR_NO_INCREASE) &&
1906 strong != TPC_INVALID) {
1912 if (weak_tpt == IWL_INVALID_VALUE && 1907 if (weak_tpt == IWL_INVALID_VALUE &&
1913 strong_tpt != IWL_INVALID_VALUE && 1908 strong_tpt != IWL_INVALID_VALUE &&
1914 current_tpt < strong_tpt) { 1909 current_tpt < strong_tpt) {
@@ -1935,7 +1930,7 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
1935 struct iwl_lq_sta *lq_sta, 1930 struct iwl_lq_sta *lq_sta,
1936 struct iwl_scale_tbl_info *tbl) 1931 struct iwl_scale_tbl_info *tbl)
1937{ 1932{
1938 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1933 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1939 struct ieee80211_vif *vif = mvm_sta->vif; 1934 struct ieee80211_vif *vif = mvm_sta->vif;
1940 struct ieee80211_chanctx_conf *chanctx_conf; 1935 struct ieee80211_chanctx_conf *chanctx_conf;
1941 enum ieee80211_band band; 1936 enum ieee80211_band band;
@@ -2044,7 +2039,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2044 u16 high_low; 2039 u16 high_low;
2045 s32 sr; 2040 s32 sr;
2046 u8 prev_agg = lq_sta->is_agg; 2041 u8 prev_agg = lq_sta->is_agg;
2047 struct iwl_mvm_sta *sta_priv = (void *)sta->drv_priv; 2042 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
2048 struct iwl_mvm_tid_data *tid_data; 2043 struct iwl_mvm_tid_data *tid_data;
2049 struct rs_rate *rate; 2044 struct rs_rate *rate;
2050 2045
@@ -2106,8 +2101,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2106 * in current association (use new rate found above). 2101 * in current association (use new rate found above).
2107 */ 2102 */
2108 fail_count = window->counter - window->success_counter; 2103 fail_count = window->counter - window->success_counter;
2109 if ((fail_count < IWL_RATE_MIN_FAILURE_TH) && 2104 if ((fail_count < IWL_MVM_RS_RATE_MIN_FAILURE_TH) &&
2110 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) { 2105 (window->success_counter < IWL_MVM_RS_RATE_MIN_SUCCESS_TH)) {
2111 IWL_DEBUG_RATE(mvm, 2106 IWL_DEBUG_RATE(mvm,
2112 "(%s: %d): Test Window: succ %d total %d\n", 2107 "(%s: %d): Test Window: succ %d total %d\n",
2113 rs_pretty_lq_type(rate->type), 2108 rs_pretty_lq_type(rate->type),
@@ -2385,7 +2380,7 @@ static void rs_get_initial_rate(struct iwl_mvm *mvm,
2385 int i, nentries; 2380 int i, nentries;
2386 s8 best_rssi = S8_MIN; 2381 s8 best_rssi = S8_MIN;
2387 u8 best_ant = ANT_NONE; 2382 u8 best_ant = ANT_NONE;
2388 u8 valid_tx_ant = mvm->fw->valid_tx_ant; 2383 u8 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
2389 const struct rs_init_rate_info *initial_rates; 2384 const struct rs_init_rate_info *initial_rates;
2390 2385
2391 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) { 2386 for (i = 0; i < ARRAY_SIZE(lq_sta->pers.chain_signal); i++) {
@@ -2530,7 +2525,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, 2525static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2531 gfp_t gfp) 2526 gfp_t gfp)
2532{ 2527{
2533 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2528 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; 2529 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
2535 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 2530 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2536 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta; 2531 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
@@ -2606,68 +2601,121 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2606 } 2601 }
2607} 2602}
2608 2603
2604static void rs_ht_init(struct iwl_mvm *mvm,
2605 struct ieee80211_sta *sta,
2606 struct iwl_lq_sta *lq_sta,
2607 struct ieee80211_sta_ht_cap *ht_cap)
2608{
2609 /* active_siso_rate mask includes 9 MBits (bit 5),
2610 * and CCK (bits 0-3), supp_rates[] does not;
2611 * shift to convert format, force 9 MBits off.
2612 */
2613 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2614 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2615 lq_sta->active_siso_rate &= ~((u16)0x2);
2616 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2617
2618 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2619 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2620 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2621 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2622
2623 if (mvm->cfg->ht_params->ldpc &&
2624 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
2625 lq_sta->ldpc = true;
2626
2627 if (mvm->cfg->ht_params->stbc &&
2628 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2629 (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC))
2630 lq_sta->stbc_capable = true;
2631
2632 lq_sta->is_vht = false;
2633}
2634
2635static void rs_vht_init(struct iwl_mvm *mvm,
2636 struct ieee80211_sta *sta,
2637 struct iwl_lq_sta *lq_sta,
2638 struct ieee80211_sta_vht_cap *vht_cap)
2639{
2640 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2641
2642 if (mvm->cfg->ht_params->ldpc &&
2643 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
2644 lq_sta->ldpc = true;
2645
2646 if (mvm->cfg->ht_params->stbc &&
2647 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2648 (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK))
2649 lq_sta->stbc_capable = true;
2650
2651 if ((mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BEAMFORMER) &&
2652 (num_of_ant(iwl_mvm_get_valid_tx_ant(mvm)) > 1) &&
2653 (vht_cap->cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE))
2654 lq_sta->bfer_capable = true;
2655
2656 lq_sta->is_vht = true;
2657}
2658
2609#ifdef CONFIG_IWLWIFI_DEBUGFS 2659#ifdef CONFIG_IWLWIFI_DEBUGFS
2610static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm, 2660static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm)
2611 struct iwl_mvm_frame_stats *stats)
2612{ 2661{
2613 spin_lock_bh(&mvm->drv_stats_lock); 2662 spin_lock_bh(&mvm->drv_stats_lock);
2614 memset(stats, 0, sizeof(*stats)); 2663 memset(&mvm->drv_rx_stats, 0, sizeof(mvm->drv_rx_stats));
2615 spin_unlock_bh(&mvm->drv_stats_lock); 2664 spin_unlock_bh(&mvm->drv_stats_lock);
2616} 2665}
2617 2666
2618void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, 2667void 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{ 2668{
2622 u8 nss = 0, mcs = 0; 2669 u8 nss = 0, mcs = 0;
2623 2670
2624 spin_lock(&mvm->drv_stats_lock); 2671 spin_lock(&mvm->drv_stats_lock);
2625 2672
2626 if (agg) 2673 if (agg)
2627 stats->agg_frames++; 2674 mvm->drv_rx_stats.agg_frames++;
2628 2675
2629 stats->success_frames++; 2676 mvm->drv_rx_stats.success_frames++;
2630 2677
2631 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) { 2678 switch (rate & RATE_MCS_CHAN_WIDTH_MSK) {
2632 case RATE_MCS_CHAN_WIDTH_20: 2679 case RATE_MCS_CHAN_WIDTH_20:
2633 stats->bw_20_frames++; 2680 mvm->drv_rx_stats.bw_20_frames++;
2634 break; 2681 break;
2635 case RATE_MCS_CHAN_WIDTH_40: 2682 case RATE_MCS_CHAN_WIDTH_40:
2636 stats->bw_40_frames++; 2683 mvm->drv_rx_stats.bw_40_frames++;
2637 break; 2684 break;
2638 case RATE_MCS_CHAN_WIDTH_80: 2685 case RATE_MCS_CHAN_WIDTH_80:
2639 stats->bw_80_frames++; 2686 mvm->drv_rx_stats.bw_80_frames++;
2640 break; 2687 break;
2641 default: 2688 default:
2642 WARN_ONCE(1, "bad BW. rate 0x%x", rate); 2689 WARN_ONCE(1, "bad BW. rate 0x%x", rate);
2643 } 2690 }
2644 2691
2645 if (rate & RATE_MCS_HT_MSK) { 2692 if (rate & RATE_MCS_HT_MSK) {
2646 stats->ht_frames++; 2693 mvm->drv_rx_stats.ht_frames++;
2647 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK; 2694 mcs = rate & RATE_HT_MCS_RATE_CODE_MSK;
2648 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1; 2695 nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1;
2649 } else if (rate & RATE_MCS_VHT_MSK) { 2696 } else if (rate & RATE_MCS_VHT_MSK) {
2650 stats->vht_frames++; 2697 mvm->drv_rx_stats.vht_frames++;
2651 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; 2698 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK;
2652 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> 2699 nss = ((rate & RATE_VHT_MCS_NSS_MSK) >>
2653 RATE_VHT_MCS_NSS_POS) + 1; 2700 RATE_VHT_MCS_NSS_POS) + 1;
2654 } else { 2701 } else {
2655 stats->legacy_frames++; 2702 mvm->drv_rx_stats.legacy_frames++;
2656 } 2703 }
2657 2704
2658 if (nss == 1) 2705 if (nss == 1)
2659 stats->siso_frames++; 2706 mvm->drv_rx_stats.siso_frames++;
2660 else if (nss == 2) 2707 else if (nss == 2)
2661 stats->mimo2_frames++; 2708 mvm->drv_rx_stats.mimo2_frames++;
2662 2709
2663 if (rate & RATE_MCS_SGI_MSK) 2710 if (rate & RATE_MCS_SGI_MSK)
2664 stats->sgi_frames++; 2711 mvm->drv_rx_stats.sgi_frames++;
2665 else 2712 else
2666 stats->ngi_frames++; 2713 mvm->drv_rx_stats.ngi_frames++;
2667 2714
2668 stats->last_rates[stats->last_frame_idx] = rate; 2715 mvm->drv_rx_stats.last_rates[mvm->drv_rx_stats.last_frame_idx] = rate;
2669 stats->last_frame_idx = (stats->last_frame_idx + 1) % 2716 mvm->drv_rx_stats.last_frame_idx =
2670 ARRAY_SIZE(stats->last_rates); 2717 (mvm->drv_rx_stats.last_frame_idx + 1) %
2718 ARRAY_SIZE(mvm->drv_rx_stats.last_rates);
2671 2719
2672 spin_unlock(&mvm->drv_stats_lock); 2720 spin_unlock(&mvm->drv_stats_lock);
2673} 2721}
@@ -2683,14 +2731,11 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2683 struct ieee80211_hw *hw = mvm->hw; 2731 struct ieee80211_hw *hw = mvm->hw;
2684 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2732 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2685 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; 2733 struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap;
2686 struct iwl_mvm_sta *sta_priv; 2734 struct iwl_mvm_sta *sta_priv = iwl_mvm_sta_from_mac80211(sta);
2687 struct iwl_lq_sta *lq_sta; 2735 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
2688 struct ieee80211_supported_band *sband; 2736 struct ieee80211_supported_band *sband;
2689 unsigned long supp; /* must be unsigned long for for_each_set_bit */ 2737 unsigned long supp; /* must be unsigned long for for_each_set_bit */
2690 2738
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 */ 2739 /* clear all non-persistent lq data */
2695 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers)); 2740 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
2696 2741
@@ -2712,7 +2757,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 2757 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2713 * after assoc.. */ 2758 * after assoc.. */
2714 2759
2715 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2760 lq_sta->missed_rate_counter = IWL_MVM_RS_MISSED_RATE_MAX;
2716 lq_sta->band = sband->band; 2761 lq_sta->band = sband->band;
2717 /* 2762 /*
2718 * active legacy rates as per supported rates bitmap 2763 * active legacy rates as per supported rates bitmap
@@ -2723,61 +2768,28 @@ 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); 2768 lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value);
2724 2769
2725 /* TODO: should probably account for rx_highest for both HT/VHT */ 2770 /* TODO: should probably account for rx_highest for both HT/VHT */
2726 if (!vht_cap || !vht_cap->vht_supported) { 2771 if (!vht_cap || !vht_cap->vht_supported)
2727 /* active_siso_rate mask includes 9 MBits (bit 5), 2772 rs_ht_init(mvm, sta, lq_sta, ht_cap);
2728 * and CCK (bits 0-3), supp_rates[] does not; 2773 else
2729 * shift to convert format, force 9 MBits off. 2774 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 2775
2765 if (IWL_MVM_RS_DISABLE_MIMO) 2776 if (IWL_MVM_RS_DISABLE_P2P_MIMO && sta_priv->vif->p2p)
2766 lq_sta->active_mimo2_rate = 0; 2777 lq_sta->active_mimo2_rate = 0;
2767 2778
2768 lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, 2779 lq_sta->max_legacy_rate_idx =
2769 BITS_PER_LONG); 2780 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, 2781 lq_sta->max_siso_rate_idx =
2771 BITS_PER_LONG); 2782 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, 2783 lq_sta->max_mimo2_rate_idx =
2773 BITS_PER_LONG); 2784 rs_get_max_rate_from_mask(lq_sta->active_mimo2_rate);
2774 2785
2775 IWL_DEBUG_RATE(mvm, 2786 IWL_DEBUG_RATE(mvm,
2776 "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC%d\n", 2787 "LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d STBC=%d BFER=%d\n",
2777 lq_sta->active_legacy_rate, 2788 lq_sta->active_legacy_rate,
2778 lq_sta->active_siso_rate, 2789 lq_sta->active_siso_rate,
2779 lq_sta->active_mimo2_rate, 2790 lq_sta->active_mimo2_rate,
2780 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc); 2791 lq_sta->is_vht, lq_sta->ldpc, lq_sta->stbc_capable,
2792 lq_sta->bfer_capable);
2781 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", 2793 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
2782 lq_sta->max_legacy_rate_idx, 2794 lq_sta->max_legacy_rate_idx,
2783 lq_sta->max_siso_rate_idx, 2795 lq_sta->max_siso_rate_idx,
@@ -2785,14 +2797,14 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2785 2797
2786 /* These values will be overridden later */ 2798 /* These values will be overridden later */
2787 lq_sta->lq.single_stream_ant_msk = 2799 lq_sta->lq.single_stream_ant_msk =
2788 first_antenna(mvm->fw->valid_tx_ant); 2800 first_antenna(iwl_mvm_get_valid_tx_ant(mvm));
2789 lq_sta->lq.dual_stream_ant_msk = ANT_AB; 2801 lq_sta->lq.dual_stream_ant_msk = ANT_AB;
2790 2802
2791 /* as default allow aggregation for all tids */ 2803 /* as default allow aggregation for all tids */
2792 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2804 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2793 lq_sta->is_agg = 0; 2805 lq_sta->is_agg = 0;
2794#ifdef CONFIG_IWLWIFI_DEBUGFS 2806#ifdef CONFIG_IWLWIFI_DEBUGFS
2795 iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats); 2807 iwl_mvm_reset_frame_stats(mvm);
2796#endif 2808#endif
2797 rs_initialize_lq(mvm, sta, lq_sta, band, init); 2809 rs_initialize_lq(mvm, sta, lq_sta, band, init);
2798} 2810}
@@ -2861,12 +2873,13 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2861 int index = *rs_table_index; 2873 int index = *rs_table_index;
2862 2874
2863 for (i = 0; i < num_rates && index < end; i++) { 2875 for (i = 0; i < num_rates && index < end; i++) {
2864 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm, rate)); 2876 for (j = 0; j < num_retries && index < end; j++, index++) {
2865 for (j = 0; j < num_retries && index < end; j++, index++) 2877 ucode_rate = cpu_to_le32(ucode_rate_from_rs_rate(mvm,
2878 rate));
2866 rs_table[index] = ucode_rate; 2879 rs_table[index] = ucode_rate;
2867 2880 if (toggle_ant)
2868 if (toggle_ant) 2881 rs_toggle_antenna(valid_tx_ant, rate);
2869 rs_toggle_antenna(valid_tx_ant, rate); 2882 }
2870 2883
2871 prev_rate_idx = rate->index; 2884 prev_rate_idx = rate->index;
2872 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate); 2885 bottom_reached = rs_get_lower_rate_in_column(lq_sta, rate);
@@ -2874,7 +2887,7 @@ static void rs_fill_rates_for_column(struct iwl_mvm *mvm,
2874 break; 2887 break;
2875 } 2888 }
2876 2889
2877 if (!bottom_reached) 2890 if (!bottom_reached && !is_legacy(rate))
2878 rate->index = prev_rate_idx; 2891 rate->index = prev_rate_idx;
2879 2892
2880 *rs_table_index = index; 2893 *rs_table_index = index;
@@ -2913,18 +2926,22 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2913 2926
2914 memcpy(&rate, initial_rate, sizeof(rate)); 2927 memcpy(&rate, initial_rate, sizeof(rate));
2915 2928
2916 valid_tx_ant = mvm->fw->valid_tx_ant; 2929 valid_tx_ant = iwl_mvm_get_valid_tx_ant(mvm);
2917 rate.stbc = rs_stbc_allow(mvm, sta, lq_sta); 2930
2931 /* TODO: remove old API when min FW API hits 14 */
2932 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS) &&
2933 rs_stbc_allow(mvm, sta, lq_sta))
2934 rate.stbc = true;
2918 2935
2919 if (is_siso(&rate)) { 2936 if (is_siso(&rate)) {
2920 num_rates = RS_INITIAL_SISO_NUM_RATES; 2937 num_rates = IWL_MVM_RS_INITIAL_SISO_NUM_RATES;
2921 num_retries = RS_HT_VHT_RETRIES_PER_RATE; 2938 num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
2922 } else if (is_mimo(&rate)) { 2939 } else if (is_mimo(&rate)) {
2923 num_rates = RS_INITIAL_MIMO_NUM_RATES; 2940 num_rates = IWL_MVM_RS_INITIAL_MIMO_NUM_RATES;
2924 num_retries = RS_HT_VHT_RETRIES_PER_RATE; 2941 num_retries = IWL_MVM_RS_HT_VHT_RETRIES_PER_RATE;
2925 } else { 2942 } else {
2926 num_rates = RS_INITIAL_LEGACY_NUM_RATES; 2943 num_rates = IWL_MVM_RS_INITIAL_LEGACY_NUM_RATES;
2927 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2944 num_retries = IWL_MVM_RS_INITIAL_LEGACY_RETRIES;
2928 toggle_ant = true; 2945 toggle_ant = true;
2929 } 2946 }
2930 2947
@@ -2935,12 +2952,12 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2935 rs_get_lower_rate_down_column(lq_sta, &rate); 2952 rs_get_lower_rate_down_column(lq_sta, &rate);
2936 2953
2937 if (is_siso(&rate)) { 2954 if (is_siso(&rate)) {
2938 num_rates = RS_SECONDARY_SISO_NUM_RATES; 2955 num_rates = IWL_MVM_RS_SECONDARY_SISO_NUM_RATES;
2939 num_retries = RS_SECONDARY_SISO_RETRIES; 2956 num_retries = IWL_MVM_RS_SECONDARY_SISO_RETRIES;
2940 lq_cmd->mimo_delim = index; 2957 lq_cmd->mimo_delim = index;
2941 } else if (is_legacy(&rate)) { 2958 } else if (is_legacy(&rate)) {
2942 num_rates = RS_SECONDARY_LEGACY_NUM_RATES; 2959 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
2943 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2960 num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
2944 } else { 2961 } else {
2945 WARN_ON_ONCE(1); 2962 WARN_ON_ONCE(1);
2946 } 2963 }
@@ -2953,8 +2970,8 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2953 2970
2954 rs_get_lower_rate_down_column(lq_sta, &rate); 2971 rs_get_lower_rate_down_column(lq_sta, &rate);
2955 2972
2956 num_rates = RS_SECONDARY_LEGACY_NUM_RATES; 2973 num_rates = IWL_MVM_RS_SECONDARY_LEGACY_NUM_RATES;
2957 num_retries = RS_LEGACY_RETRIES_PER_RATE; 2974 num_retries = IWL_MVM_RS_SECONDARY_LEGACY_RETRIES;
2958 2975
2959 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index, 2976 rs_fill_rates_for_column(mvm, lq_sta, &rate, lq_cmd->rs_table, &index,
2960 num_rates, num_retries, valid_tx_ant, 2977 num_rates, num_retries, valid_tx_ant,
@@ -2962,6 +2979,142 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
2962 2979
2963} 2980}
2964 2981
2982struct rs_bfer_active_iter_data {
2983 struct ieee80211_sta *exclude_sta;
2984 struct iwl_mvm_sta *bfer_mvmsta;
2985};
2986
2987static void rs_bfer_active_iter(void *_data,
2988 struct ieee80211_sta *sta)
2989{
2990 struct rs_bfer_active_iter_data *data = _data;
2991 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2992 struct iwl_lq_cmd *lq_cmd = &mvmsta->lq_sta.lq;
2993 u32 ss_params = le32_to_cpu(lq_cmd->ss_params);
2994
2995 if (sta == data->exclude_sta)
2996 return;
2997
2998 /* The current sta has BFER allowed */
2999 if (ss_params & LQ_SS_BFER_ALLOWED) {
3000 WARN_ON_ONCE(data->bfer_mvmsta != NULL);
3001
3002 data->bfer_mvmsta = mvmsta;
3003 }
3004}
3005
3006static int rs_bfer_priority(struct iwl_mvm_sta *sta)
3007{
3008 int prio = -1;
3009 enum nl80211_iftype viftype = ieee80211_vif_type_p2p(sta->vif);
3010
3011 switch (viftype) {
3012 case NL80211_IFTYPE_AP:
3013 case NL80211_IFTYPE_P2P_GO:
3014 prio = 3;
3015 break;
3016 case NL80211_IFTYPE_P2P_CLIENT:
3017 prio = 2;
3018 break;
3019 case NL80211_IFTYPE_STATION:
3020 prio = 1;
3021 break;
3022 default:
3023 WARN_ONCE(true, "viftype %d sta_id %d", viftype, sta->sta_id);
3024 prio = -1;
3025 }
3026
3027 return prio;
3028}
3029
3030/* Returns >0 if sta1 has a higher BFER priority compared to sta2 */
3031static int rs_bfer_priority_cmp(struct iwl_mvm_sta *sta1,
3032 struct iwl_mvm_sta *sta2)
3033{
3034 int prio1 = rs_bfer_priority(sta1);
3035 int prio2 = rs_bfer_priority(sta2);
3036
3037 if (prio1 > prio2)
3038 return 1;
3039 if (prio1 < prio2)
3040 return -1;
3041 return 0;
3042}
3043
3044static void rs_set_lq_ss_params(struct iwl_mvm *mvm,
3045 struct ieee80211_sta *sta,
3046 struct iwl_lq_sta *lq_sta,
3047 const struct rs_rate *initial_rate)
3048{
3049 struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
3050 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
3051 struct rs_bfer_active_iter_data data = {
3052 .exclude_sta = sta,
3053 .bfer_mvmsta = NULL,
3054 };
3055 struct iwl_mvm_sta *bfer_mvmsta = NULL;
3056 u32 ss_params = LQ_SS_PARAMS_VALID;
3057
3058 if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta))
3059 goto out;
3060
3061 /* Check if forcing the decision is configured.
3062 * Note that SISO is forced by not allowing STBC or BFER
3063 */
3064 if (lq_sta->ss_force == RS_SS_FORCE_STBC)
3065 ss_params |= (LQ_SS_STBC_1SS_ALLOWED | LQ_SS_FORCE);
3066 else if (lq_sta->ss_force == RS_SS_FORCE_BFER)
3067 ss_params |= (LQ_SS_BFER_ALLOWED | LQ_SS_FORCE);
3068
3069 if (lq_sta->ss_force != RS_SS_FORCE_NONE) {
3070 IWL_DEBUG_RATE(mvm, "Forcing single stream Tx decision %d\n",
3071 lq_sta->ss_force);
3072 goto out;
3073 }
3074
3075 if (lq_sta->stbc_capable)
3076 ss_params |= LQ_SS_STBC_1SS_ALLOWED;
3077
3078 if (!lq_sta->bfer_capable)
3079 goto out;
3080
3081 ieee80211_iterate_stations_atomic(mvm->hw,
3082 rs_bfer_active_iter,
3083 &data);
3084 bfer_mvmsta = data.bfer_mvmsta;
3085
3086 /* This code is safe as it doesn't run concurrently for different
3087 * stations. This is guaranteed by the fact that calls to
3088 * ieee80211_tx_status wouldn't run concurrently for a single HW.
3089 */
3090 if (!bfer_mvmsta) {
3091 IWL_DEBUG_RATE(mvm, "No sta with BFER allowed found. Allow\n");
3092
3093 ss_params |= LQ_SS_BFER_ALLOWED;
3094 goto out;
3095 }
3096
3097 IWL_DEBUG_RATE(mvm, "Found existing sta %d with BFER activated\n",
3098 bfer_mvmsta->sta_id);
3099
3100 /* Disallow BFER on another STA if active and we're a higher priority */
3101 if (rs_bfer_priority_cmp(mvmsta, bfer_mvmsta) > 0) {
3102 struct iwl_lq_cmd *bfersta_lq_cmd = &bfer_mvmsta->lq_sta.lq;
3103 u32 bfersta_ss_params = le32_to_cpu(bfersta_lq_cmd->ss_params);
3104
3105 bfersta_ss_params &= ~LQ_SS_BFER_ALLOWED;
3106 bfersta_lq_cmd->ss_params = cpu_to_le32(bfersta_ss_params);
3107 iwl_mvm_send_lq_cmd(mvm, bfersta_lq_cmd, false);
3108
3109 ss_params |= LQ_SS_BFER_ALLOWED;
3110 IWL_DEBUG_RATE(mvm,
3111 "Lower priority BFER sta found (%d). Switch BFER\n",
3112 bfer_mvmsta->sta_id);
3113 }
3114out:
3115 lq_cmd->ss_params = cpu_to_le32(ss_params);
3116}
3117
2965static void rs_fill_lq_cmd(struct iwl_mvm *mvm, 3118static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2966 struct ieee80211_sta *sta, 3119 struct ieee80211_sta *sta,
2967 struct iwl_lq_sta *lq_sta, 3120 struct iwl_lq_sta *lq_sta,
@@ -2971,9 +3124,9 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2971 struct iwl_mvm_sta *mvmsta; 3124 struct iwl_mvm_sta *mvmsta;
2972 struct iwl_mvm_vif *mvmvif; 3125 struct iwl_mvm_vif *mvmvif;
2973 3126
2974 lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; 3127 lq_cmd->agg_disable_start_th = IWL_MVM_RS_AGG_DISABLE_START;
2975 lq_cmd->agg_time_limit = 3128 lq_cmd->agg_time_limit =
2976 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); 3129 cpu_to_le16(IWL_MVM_RS_AGG_TIME_LIMIT);
2977 3130
2978#ifdef CONFIG_MAC80211_DEBUGFS 3131#ifdef CONFIG_MAC80211_DEBUGFS
2979 if (lq_sta->pers.dbg_fixed_rate) { 3132 if (lq_sta->pers.dbg_fixed_rate) {
@@ -2988,6 +3141,9 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2988 3141
2989 rs_build_rates_table(mvm, sta, lq_sta, initial_rate); 3142 rs_build_rates_table(mvm, sta, lq_sta, initial_rate);
2990 3143
3144 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LQ_SS_PARAMS)
3145 rs_set_lq_ss_params(mvm, sta, lq_sta, initial_rate);
3146
2991 if (num_of_ant(initial_rate->ant) == 1) 3147 if (num_of_ant(initial_rate->ant) == 1)
2992 lq_cmd->single_stream_ant_msk = initial_rate->ant; 3148 lq_cmd->single_stream_ant_msk = initial_rate->ant;
2993 3149
@@ -3167,9 +3323,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3167 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 3323 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
3168 lq_sta->pers.dbg_fixed_rate); 3324 lq_sta->pers.dbg_fixed_rate);
3169 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 3325 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
3170 (mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "", 3326 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "",
3171 (mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "", 3327 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "",
3172 (mvm->fw->valid_tx_ant & ANT_C) ? "ANT_C" : ""); 3328 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : "");
3173 desc += sprintf(buff+desc, "lq type %s\n", 3329 desc += sprintf(buff+desc, "lq type %s\n",
3174 (is_legacy(rate)) ? "legacy" : 3330 (is_legacy(rate)) ? "legacy" :
3175 is_vht(rate) ? "VHT" : "HT"); 3331 is_vht(rate) ? "VHT" : "HT");
@@ -3361,9 +3517,73 @@ static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {
3361 .llseek = default_llseek, 3517 .llseek = default_llseek,
3362}; 3518};
3363 3519
3520static ssize_t iwl_dbgfs_ss_force_read(struct file *file,
3521 char __user *user_buf,
3522 size_t count, loff_t *ppos)
3523{
3524 struct iwl_lq_sta *lq_sta = file->private_data;
3525 char buf[12];
3526 int bufsz = sizeof(buf);
3527 int pos = 0;
3528 static const char * const ss_force_name[] = {
3529 [RS_SS_FORCE_NONE] = "none",
3530 [RS_SS_FORCE_STBC] = "stbc",
3531 [RS_SS_FORCE_BFER] = "bfer",
3532 [RS_SS_FORCE_SISO] = "siso",
3533 };
3534
3535 pos += scnprintf(buf+pos, bufsz-pos, "%s\n",
3536 ss_force_name[lq_sta->ss_force]);
3537 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
3538}
3539
3540static ssize_t iwl_dbgfs_ss_force_write(struct iwl_lq_sta *lq_sta, char *buf,
3541 size_t count, loff_t *ppos)
3542{
3543 struct iwl_mvm *mvm = lq_sta->pers.drv;
3544 int ret = 0;
3545
3546 if (!strncmp("none", buf, 4)) {
3547 lq_sta->ss_force = RS_SS_FORCE_NONE;
3548 } else if (!strncmp("siso", buf, 4)) {
3549 lq_sta->ss_force = RS_SS_FORCE_SISO;
3550 } else if (!strncmp("stbc", buf, 4)) {
3551 if (lq_sta->stbc_capable) {
3552 lq_sta->ss_force = RS_SS_FORCE_STBC;
3553 } else {
3554 IWL_ERR(mvm,
3555 "can't force STBC. peer doesn't support\n");
3556 ret = -EINVAL;
3557 }
3558 } else if (!strncmp("bfer", buf, 4)) {
3559 if (lq_sta->bfer_capable) {
3560 lq_sta->ss_force = RS_SS_FORCE_BFER;
3561 } else {
3562 IWL_ERR(mvm,
3563 "can't force BFER. peer doesn't support\n");
3564 ret = -EINVAL;
3565 }
3566 } else {
3567 IWL_ERR(mvm, "valid values none|siso|stbc|bfer\n");
3568 ret = -EINVAL;
3569 }
3570 return ret ?: count;
3571}
3572
3573#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
3574 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_lq_sta)
3575#define MVM_DEBUGFS_ADD_FILE_RS(name, parent, mode) do { \
3576 if (!debugfs_create_file(#name, mode, parent, lq_sta, \
3577 &iwl_dbgfs_##name##_ops)) \
3578 goto err; \
3579 } while (0)
3580
3581MVM_DEBUGFS_READ_WRITE_FILE_OPS(ss_force, 32);
3582
3364static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) 3583static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3365{ 3584{
3366 struct iwl_lq_sta *lq_sta = mvm_sta; 3585 struct iwl_lq_sta *lq_sta = mvm_sta;
3586
3367 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, 3587 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
3368 lq_sta, &rs_sta_dbgfs_scale_table_ops); 3588 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3369 debugfs_create_file("rate_stats_table", S_IRUSR, dir, 3589 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
@@ -3374,6 +3594,11 @@ static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3374 &lq_sta->tx_agg_tid_en); 3594 &lq_sta->tx_agg_tid_en);
3375 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir, 3595 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
3376 &lq_sta->pers.dbg_fixed_txp_reduction); 3596 &lq_sta->pers.dbg_fixed_txp_reduction);
3597
3598 MVM_DEBUGFS_ADD_FILE_RS(ss_force, dir, S_IRUSR | S_IWUSR);
3599 return;
3600err:
3601 IWL_ERR((struct iwl_mvm *)mvm, "Can't create debugfs entity\n");
3377} 3602}
3378 3603
3379static void rs_remove_debugfs(void *mvm, void *mvm_sta) 3604static void rs_remove_debugfs(void *mvm, void *mvm_sta)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index defd70a6d9e6..dc4ef3dfafe1 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,
@@ -279,6 +240,13 @@ enum rs_column {
279 RS_COLUMN_INVALID, 240 RS_COLUMN_INVALID,
280}; 241};
281 242
243enum rs_ss_force_opt {
244 RS_SS_FORCE_NONE = 0,
245 RS_SS_FORCE_STBC,
246 RS_SS_FORCE_BFER,
247 RS_SS_FORCE_SISO,
248};
249
282/* Packet stats per rate */ 250/* Packet stats per rate */
283struct rs_rate_stats { 251struct rs_rate_stats {
284 u64 success; 252 u64 success;
@@ -332,7 +300,9 @@ struct iwl_lq_sta {
332 u64 last_tx; 300 u64 last_tx;
333 bool is_vht; 301 bool is_vht;
334 bool ldpc; /* LDPC Rx is supported by the STA */ 302 bool ldpc; /* LDPC Rx is supported by the STA */
335 bool stbc; /* Tx STBC is supported by chip and Rx by STA */ 303 bool stbc_capable; /* Tx STBC is supported by chip and Rx by STA */
304 bool bfer_capable; /* Remote supports beamformee and we BFer */
305
336 enum ieee80211_band band; 306 enum ieee80211_band band;
337 307
338 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 308 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
@@ -361,6 +331,9 @@ struct iwl_lq_sta {
361 /* tx power reduce for this sta */ 331 /* tx power reduce for this sta */
362 int tpc_reduce; 332 int tpc_reduce;
363 333
334 /* force STBC/BFER/SISO for testing */
335 enum rs_ss_force_opt ss_force;
336
364 /* persistent fields - initialized only once - keep last! */ 337 /* persistent fields - initialized only once - keep last! */
365 struct lq_sta_pers { 338 struct lq_sta_pers {
366#ifdef CONFIG_MAC80211_DEBUGFS 339#ifdef CONFIG_MAC80211_DEBUGFS
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 844bf7c4c8de..7e9aa3cb3254 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -99,7 +99,7 @@ static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
99{ 99{
100 if (mvm->scan_rx_ant != ANT_NONE) 100 if (mvm->scan_rx_ant != ANT_NONE)
101 return mvm->scan_rx_ant; 101 return mvm->scan_rx_ant;
102 return mvm->fw->valid_rx_ant; 102 return iwl_mvm_get_valid_rx_ant(mvm);
103} 103}
104 104
105static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) 105static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
@@ -130,7 +130,7 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
130 u32 tx_ant; 130 u32 tx_ant;
131 131
132 mvm->scan_last_antenna_idx = 132 mvm->scan_last_antenna_idx =
133 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 133 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
134 mvm->scan_last_antenna_idx); 134 mvm->scan_last_antenna_idx);
135 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;
136 136
@@ -290,11 +290,11 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
290 struct ieee80211_vif *vif) 290 struct ieee80211_vif *vif)
291{ 291{
292 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 292 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
293 bool *global_bound = data; 293 int *global_cnt = data;
294 294
295 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt && 295 if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
296 mvmvif->phy_ctxt->id < MAX_PHYS) 296 mvmvif->phy_ctxt->id < MAX_PHYS)
297 *global_bound = true; 297 *global_cnt += 1;
298} 298}
299 299
300static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 300static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
@@ -302,27 +302,31 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
302 int n_ssids, u32 flags, 302 int n_ssids, u32 flags,
303 struct iwl_mvm_scan_params *params) 303 struct iwl_mvm_scan_params *params)
304{ 304{
305 bool global_bound = false; 305 int global_cnt = 0;
306 enum ieee80211_band band; 306 enum ieee80211_band band;
307 u8 frag_passive_dwell = 0; 307 u8 frag_passive_dwell = 0;
308 308
309 ieee80211_iterate_active_interfaces_atomic(mvm->hw, 309 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
310 IEEE80211_IFACE_ITER_NORMAL, 310 IEEE80211_IFACE_ITER_NORMAL,
311 iwl_mvm_scan_condition_iterator, 311 iwl_mvm_scan_condition_iterator,
312 &global_bound); 312 &global_cnt);
313 313
314 if (!global_bound) 314 if (!global_cnt)
315 goto not_bound; 315 goto not_bound;
316 316
317 params->suspend_time = 30; 317 params->suspend_time = 30;
318 params->max_out_time = 170; 318 params->max_out_time = 120;
319 319
320 if (iwl_mvm_low_latency(mvm)) { 320 if (iwl_mvm_low_latency(mvm)) {
321 if (mvm->fw->ucode_capa.api[0] & 321 if (mvm->fw->ucode_capa.api[0] &
322 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) { 322 IWL_UCODE_TLV_API_FRAGMENTED_SCAN) {
323 params->suspend_time = 105; 323 params->suspend_time = 105;
324 params->max_out_time = 70; 324 /*
325 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;
326 } else { 330 } else {
327 params->suspend_time = 120; 331 params->suspend_time = 120;
328 params->max_out_time = 120; 332 params->max_out_time = 120;
@@ -539,6 +543,19 @@ int iwl_mvm_rx_scan_response(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
539 return 0; 543 return 0;
540} 544}
541 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
542int 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,
543 struct iwl_device_cmd *cmd) 560 struct iwl_device_cmd *cmd)
544{ 561{
@@ -687,7 +704,8 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
687 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 704 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
688 } 705 }
689 706
690 mvm->last_ebs_successful = !ebs_status; 707 if (ebs_status)
708 mvm->last_ebs_successful = false;
691 709
692 return 0; 710 return 0;
693} 711}
@@ -1480,6 +1498,11 @@ int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1480 if (req->n_ssids == 0) 1498 if (req->n_ssids == 0)
1481 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE; 1499 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
1482 1500
1501#ifdef CONFIG_IWLWIFI_DEBUGFS
1502 if (mvm->scan_iter_notif_enabled)
1503 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
1504#endif
1505
1483 cmd->scan_flags |= cpu_to_le32(flags); 1506 cmd->scan_flags |= cpu_to_le32(flags);
1484 1507
1485 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band); 1508 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
@@ -1641,7 +1664,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1641 SCAN_CONFIG_FLAG_SET_MAC_ADDR | 1664 SCAN_CONFIG_FLAG_SET_MAC_ADDR |
1642 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS| 1665 SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS|
1643 SCAN_CONFIG_N_CHANNELS(num_channels)); 1666 SCAN_CONFIG_N_CHANNELS(num_channels));
1644 scan_config->tx_chains = cpu_to_le32(mvm->fw->valid_tx_ant); 1667 scan_config->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
1645 scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm)); 1668 scan_config->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
1646 scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm); 1669 scan_config->legacy_rates = iwl_mvm_scan_config_rates(mvm);
1647 scan_config->out_of_channel_time = cpu_to_le32(170); 1670 scan_config->out_of_channel_time = cpu_to_le32(170);
@@ -1660,10 +1683,10 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
1660 1683
1661 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ]; 1684 band = &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
1662 for (i = 0; i < band->n_channels; i++, j++) 1685 for (i = 0; i < band->n_channels; i++, j++)
1663 scan_config->channel_array[j] = band->channels[i].center_freq; 1686 scan_config->channel_array[j] = band->channels[i].hw_value;
1664 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ]; 1687 band = &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];
1665 for (i = 0; i < band->n_channels; i++, j++) 1688 for (i = 0; i < band->n_channels; i++, j++)
1666 scan_config->channel_array[j] = band->channels[i].center_freq; 1689 scan_config->channel_array[j] = band->channels[i].hw_value;
1667 1690
1668 cmd.data[0] = scan_config; 1691 cmd.data[0] = scan_config;
1669 cmd.len[0] = cmd_size; 1692 cmd.len[0] = cmd_size;
@@ -1840,6 +1863,13 @@ int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1840 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL; 1863 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
1841 1864
1842 cmd->general_flags = cpu_to_le32(flags); 1865 cmd->general_flags = cpu_to_le32(flags);
1866
1867 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SINGLE_SCAN_EBS &&
1868 mvm->last_ebs_successful)
1869 cmd->channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
1870 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1871 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
1872
1843 cmd->n_channels = req->req.n_channels; 1873 cmd->n_channels = req->req.n_channels;
1844 1874
1845 for (i = 0; i < req->req.n_ssids; i++) 1875 for (i = 0; i < req->req.n_ssids; i++)
@@ -2003,7 +2033,9 @@ int iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
2003 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ? 2033 notif->ebs_status == IWL_SCAN_EBS_SUCCESS ?
2004 "success" : "failed"); 2034 "success" : "failed");
2005 2035
2006 mvm->last_ebs_successful = !notif->ebs_status; 2036 if (notif->ebs_status)
2037 mvm->last_ebs_successful = false;
2038
2007 mvm->scan_uid[uid_idx] = 0; 2039 mvm->scan_uid[uid_idx] = 0;
2008 2040
2009 if (!sched) { 2041 if (!sched) {
@@ -2036,10 +2068,14 @@ static bool iwl_scan_umac_done_check(struct iwl_notif_wait_data *notif_wait,
2036 2068
2037 /* 2069 /*
2038 * Clear scan uid of scans that was aborted from above and completed 2070 * Clear scan uid of scans that was aborted from above and completed
2039 * in FW so the RX handler does nothing. 2071 * in FW so the RX handler does nothing. Set last_ebs_successful here if
2072 * needed.
2040 */ 2073 */
2041 scan_done->mvm->scan_uid[uid_idx] = 0; 2074 scan_done->mvm->scan_uid[uid_idx] = 0;
2042 2075
2076 if (notif->ebs_status)
2077 scan_done->mvm->last_ebs_successful = false;
2078
2043 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type); 2079 return !iwl_mvm_find_scan_type(scan_done->mvm, scan_done->type);
2044} 2080}
2045 2081
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index d86fe432e51f..5c23cddaaae3 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),
@@ -209,6 +209,9 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm,
209{ 209{
210 unsigned long used_hw_queues; 210 unsigned long used_hw_queues;
211 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 211 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
212 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
213 mvm->cfg->base_params->wd_timeout :
214 IWL_WATCHDOG_DISABLED;
212 u32 ac; 215 u32 ac;
213 216
214 lockdep_assert_held(&mvm->mutex); 217 lockdep_assert_held(&mvm->mutex);
@@ -232,7 +235,7 @@ static int iwl_mvm_tdls_sta_init(struct iwl_mvm *mvm,
232 /* Found a place for all queues - enable them */ 235 /* Found a place for all queues - enable them */
233 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { 236 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
234 iwl_mvm_enable_ac_txq(mvm, mvmsta->hw_queue[ac], 237 iwl_mvm_enable_ac_txq(mvm, mvmsta->hw_queue[ac],
235 iwl_mvm_ac_to_tx_fifo[ac]); 238 iwl_mvm_ac_to_tx_fifo[ac], wdg_timeout);
236 mvmsta->tfd_queue_msk |= BIT(mvmsta->hw_queue[ac]); 239 mvmsta->tfd_queue_msk |= BIT(mvmsta->hw_queue[ac]);
237 } 240 }
238 241
@@ -250,8 +253,8 @@ static void iwl_mvm_tdls_sta_deinit(struct iwl_mvm *mvm,
250 253
251 /* disable the TDLS STA-specific queues */ 254 /* disable the TDLS STA-specific queues */
252 sta_msk = mvmsta->tfd_queue_msk; 255 sta_msk = mvmsta->tfd_queue_msk;
253 for_each_set_bit(i, &sta_msk, sizeof(sta_msk)) 256 for_each_set_bit(i, &sta_msk, sizeof(sta_msk) * BITS_PER_BYTE)
254 iwl_mvm_disable_txq(mvm, i); 257 iwl_mvm_disable_txq(mvm, i, 0);
255} 258}
256 259
257int iwl_mvm_add_sta(struct iwl_mvm *mvm, 260int iwl_mvm_add_sta(struct iwl_mvm *mvm,
@@ -259,7 +262,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
259 struct ieee80211_sta *sta) 262 struct ieee80211_sta *sta)
260{ 263{
261 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 264 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
262 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 265 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
263 int i, ret, sta_id; 266 int i, ret, sta_id;
264 267
265 lockdep_assert_held(&mvm->mutex); 268 lockdep_assert_held(&mvm->mutex);
@@ -464,8 +467,8 @@ void iwl_mvm_sta_drained_wk(struct work_struct *wk)
464 if (mvm->tfd_drained[sta_id]) { 467 if (mvm->tfd_drained[sta_id]) {
465 unsigned long i, msk = mvm->tfd_drained[sta_id]; 468 unsigned long i, msk = mvm->tfd_drained[sta_id];
466 469
467 for_each_set_bit(i, &msk, sizeof(msk)) 470 for_each_set_bit(i, &msk, sizeof(msk) * BITS_PER_BYTE)
468 iwl_mvm_disable_txq(mvm, i); 471 iwl_mvm_disable_txq(mvm, i, 0);
469 472
470 mvm->tfd_drained[sta_id] = 0; 473 mvm->tfd_drained[sta_id] = 0;
471 IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n", 474 IWL_DEBUG_TDLS(mvm, "Drained sta %d, with queues %ld\n",
@@ -481,7 +484,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
481 struct ieee80211_sta *sta) 484 struct ieee80211_sta *sta)
482{ 485{
483 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 486 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
484 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 487 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
485 int ret; 488 int ret;
486 489
487 lockdep_assert_held(&mvm->mutex); 490 lockdep_assert_held(&mvm->mutex);
@@ -626,13 +629,16 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
626 629
627int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) 630int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
628{ 631{
632 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
633 mvm->cfg->base_params->wd_timeout :
634 IWL_WATCHDOG_DISABLED;
629 int ret; 635 int ret;
630 636
631 lockdep_assert_held(&mvm->mutex); 637 lockdep_assert_held(&mvm->mutex);
632 638
633 /* Map Aux queue to fifo - needs to happen before adding Aux station */ 639 /* Map Aux queue to fifo - needs to happen before adding Aux station */
634 iwl_mvm_enable_ac_txq(mvm, mvm->aux_queue, 640 iwl_mvm_enable_ac_txq(mvm, mvm->aux_queue,
635 IWL_MVM_TX_FIFO_MCAST); 641 IWL_MVM_TX_FIFO_MCAST, wdg_timeout);
636 642
637 /* Allocate aux station and assign to it the aux queue */ 643 /* Allocate aux station and assign to it the aux queue */
638 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue), 644 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->aux_sta, BIT(mvm->aux_queue),
@@ -774,7 +780,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, 780int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
775 int tid, u16 ssn, bool start) 781 int tid, u16 ssn, bool start)
776{ 782{
777 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 783 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
778 struct iwl_mvm_add_sta_cmd cmd = {}; 784 struct iwl_mvm_add_sta_cmd cmd = {};
779 int ret; 785 int ret;
780 u32 status; 786 u32 status;
@@ -834,7 +840,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, 840static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
835 int tid, u8 queue, bool start) 841 int tid, u8 queue, bool start)
836{ 842{
837 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 843 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
838 struct iwl_mvm_add_sta_cmd cmd = {}; 844 struct iwl_mvm_add_sta_cmd cmd = {};
839 int ret; 845 int ret;
840 u32 status; 846 u32 status;
@@ -965,6 +971,9 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
965{ 971{
966 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 972 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
967 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid]; 973 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
974 unsigned int wdg_timeout = iwlmvm_mod_params.tfd_q_hang_detect ?
975 mvm->cfg->base_params->wd_timeout :
976 IWL_WATCHDOG_DISABLED;
968 int queue, fifo, ret; 977 int queue, fifo, ret;
969 u16 ssn; 978 u16 ssn;
970 979
@@ -988,7 +997,7 @@ int iwl_mvm_sta_tx_agg_oper(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
988 return -EIO; 997 return -EIO;
989 998
990 iwl_mvm_enable_agg_txq(mvm, queue, fifo, mvmsta->sta_id, tid, 999 iwl_mvm_enable_agg_txq(mvm, queue, fifo, mvmsta->sta_id, tid,
991 buf_size, ssn); 1000 buf_size, ssn, wdg_timeout);
992 1001
993 /* 1002 /*
994 * Even though in theory the peer could have different 1003 * Even though in theory the peer could have different
@@ -1058,7 +1067,7 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1058 1067
1059 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1068 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
1060 1069
1061 iwl_mvm_disable_txq(mvm, txq_id); 1070 iwl_mvm_disable_txq(mvm, txq_id, 0);
1062 return 0; 1071 return 0;
1063 case IWL_AGG_STARTING: 1072 case IWL_AGG_STARTING:
1064 case IWL_EMPTYING_HW_QUEUE_ADDBA: 1073 case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1116,7 +1125,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1116 1125
1117 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); 1126 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
1118 1127
1119 iwl_mvm_disable_txq(mvm, tid_data->txq_id); 1128 iwl_mvm_disable_txq(mvm, tid_data->txq_id, 0);
1120 } 1129 }
1121 1130
1122 mvm->queue_to_mac80211[tid_data->txq_id] = 1131 mvm->queue_to_mac80211[tid_data->txq_id] =
@@ -1144,10 +1153,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, 1153static u8 iwl_mvm_get_key_sta_id(struct ieee80211_vif *vif,
1145 struct ieee80211_sta *sta) 1154 struct ieee80211_sta *sta)
1146{ 1155{
1147 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1156 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1148 1157
1149 if (sta) { 1158 if (sta) {
1150 struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; 1159 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1151 1160
1152 return mvm_sta->sta_id; 1161 return mvm_sta->sta_id;
1153 } 1162 }
@@ -1196,6 +1205,7 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm,
1196 break; 1205 break;
1197 case WLAN_CIPHER_SUITE_WEP104: 1206 case WLAN_CIPHER_SUITE_WEP104:
1198 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES); 1207 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP_13BYTES);
1208 /* fall through */
1199 case WLAN_CIPHER_SUITE_WEP40: 1209 case WLAN_CIPHER_SUITE_WEP40:
1200 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP); 1210 key_flags |= cpu_to_le16(STA_KEY_FLG_WEP);
1201 memcpy(cmd.key + 3, keyconf->key, keyconf->keylen); 1211 memcpy(cmd.key + 3, keyconf->key, keyconf->keylen);
@@ -1280,7 +1290,7 @@ static inline u8 *iwl_mvm_get_mac_addr(struct iwl_mvm *mvm,
1280 struct ieee80211_vif *vif, 1290 struct ieee80211_vif *vif,
1281 struct ieee80211_sta *sta) 1291 struct ieee80211_sta *sta)
1282{ 1292{
1283 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv; 1293 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1284 1294
1285 if (sta) 1295 if (sta)
1286 return sta->addr; 1296 return sta->addr;
diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c
index c0e00bae5bd0..a87b506c8c72 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tdls.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c
@@ -64,6 +64,8 @@
64#include <linux/etherdevice.h> 64#include <linux/etherdevice.h>
65#include "mvm.h" 65#include "mvm.h"
66#include "time-event.h" 66#include "time-event.h"
67#include "iwl-io.h"
68#include "iwl-prph.h"
67 69
68#define TU_TO_US(x) (x * 1024) 70#define TU_TO_US(x) (x * 1024)
69#define TU_TO_MS(x) (TU_TO_US(x) / 1000) 71#define TU_TO_MS(x) (TU_TO_US(x) / 1000)
@@ -228,6 +230,8 @@ iwl_mvm_tdls_cs_state_str(enum iwl_mvm_tdls_cs_state state)
228 return "IDLE"; 230 return "IDLE";
229 case IWL_MVM_TDLS_SW_REQ_SENT: 231 case IWL_MVM_TDLS_SW_REQ_SENT:
230 return "REQ SENT"; 232 return "REQ SENT";
233 case IWL_MVM_TDLS_SW_RESP_RCVD:
234 return "RESP RECEIVED";
231 case IWL_MVM_TDLS_SW_REQ_RCVD: 235 case IWL_MVM_TDLS_SW_REQ_RCVD:
232 return "REQ RECEIVED"; 236 return "REQ RECEIVED";
233 case IWL_MVM_TDLS_SW_ACTIVE: 237 case IWL_MVM_TDLS_SW_ACTIVE:
@@ -248,6 +252,11 @@ static void iwl_mvm_tdls_update_cs_state(struct iwl_mvm *mvm,
248 iwl_mvm_tdls_cs_state_str(state)); 252 iwl_mvm_tdls_cs_state_str(state));
249 mvm->tdls_cs.state = state; 253 mvm->tdls_cs.state = state;
250 254
255 /* we only send requests to our switching peer - update sent time */
256 if (state == IWL_MVM_TDLS_SW_REQ_SENT)
257 mvm->tdls_cs.peer.sent_timestamp =
258 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG);
259
251 if (state == IWL_MVM_TDLS_SW_IDLE) 260 if (state == IWL_MVM_TDLS_SW_IDLE)
252 mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT; 261 mvm->tdls_cs.cur_sta_id = IWL_MVM_STATION_COUNT;
253} 262}
@@ -300,7 +309,7 @@ out:
300static int 309static int
301iwl_mvm_tdls_check_action(struct iwl_mvm *mvm, 310iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
302 enum iwl_tdls_channel_switch_type type, 311 enum iwl_tdls_channel_switch_type type,
303 const u8 *peer, bool peer_initiator) 312 const u8 *peer, bool peer_initiator, u32 timestamp)
304{ 313{
305 bool same_peer = false; 314 bool same_peer = false;
306 int ret = 0; 315 int ret = 0;
@@ -325,17 +334,30 @@ iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
325 ret = -EINVAL; 334 ret = -EINVAL;
326 break; 335 break;
327 case IWL_MVM_TDLS_SW_REQ_SENT: 336 case IWL_MVM_TDLS_SW_REQ_SENT:
337 /* only allow requests from the same peer */
338 if (!same_peer)
339 ret = -EBUSY;
340 else if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH &&
341 !peer_initiator)
342 /*
343 * We received a ch-switch request while an outgoing
344 * one is pending. Allow it if the peer is the link
345 * initiator.
346 */
347 ret = -EBUSY;
348 else if (type == TDLS_SEND_CHAN_SW_REQ)
349 /* wait for idle before sending another request */
350 ret = -EBUSY;
351 else if (timestamp <= mvm->tdls_cs.peer.sent_timestamp)
352 /* we got a stale response - ignore it */
353 ret = -EINVAL;
354 break;
355 case IWL_MVM_TDLS_SW_RESP_RCVD:
328 /* 356 /*
329 * We received a ch-switch request while an outgoing one is 357 * we are waiting for the FW to give an "active" notification,
330 * pending. Allow it to proceed if the other peer is the same 358 * so ignore requests in the meantime
331 * one we sent to, and we are not the link initiator.
332 */ 359 */
333 if (type == TDLS_SEND_CHAN_SW_RESP_AND_MOVE_CH) { 360 ret = -EBUSY;
334 if (!same_peer)
335 ret = -EBUSY;
336 else if (!peer_initiator) /* we are the initiator */
337 ret = -EBUSY;
338 }
339 break; 361 break;
340 case IWL_MVM_TDLS_SW_REQ_RCVD: 362 case IWL_MVM_TDLS_SW_REQ_RCVD:
341 /* as above, allow the link initiator to proceed */ 363 /* as above, allow the link initiator to proceed */
@@ -349,9 +371,12 @@ iwl_mvm_tdls_check_action(struct iwl_mvm *mvm,
349 } 371 }
350 break; 372 break;
351 case IWL_MVM_TDLS_SW_ACTIVE: 373 case IWL_MVM_TDLS_SW_ACTIVE:
352 /* we don't allow initiations during active channel switch */ 374 /*
353 if (type == TDLS_SEND_CHAN_SW_REQ) 375 * the only valid request when active is a request to return
354 ret = -EINVAL; 376 * to the base channel by the current off-channel peer
377 */
378 if (type != TDLS_MOVE_CH || !same_peer)
379 ret = -EBUSY;
355 break; 380 break;
356 } 381 }
357 382
@@ -384,7 +409,8 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm,
384 409
385 lockdep_assert_held(&mvm->mutex); 410 lockdep_assert_held(&mvm->mutex);
386 411
387 ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator); 412 ret = iwl_mvm_tdls_check_action(mvm, type, peer, peer_initiator,
413 timestamp);
388 if (ret) 414 if (ret)
389 return ret; 415 return ret;
390 416
@@ -473,6 +499,8 @@ iwl_mvm_tdls_config_channel_switch(struct iwl_mvm *mvm,
473 type == TDLS_SEND_CHAN_SW_REQ ? 499 type == TDLS_SEND_CHAN_SW_REQ ?
474 IWL_MVM_TDLS_SW_REQ_SENT : 500 IWL_MVM_TDLS_SW_REQ_SENT :
475 IWL_MVM_TDLS_SW_REQ_RCVD); 501 IWL_MVM_TDLS_SW_REQ_RCVD);
502 } else {
503 iwl_mvm_tdls_update_cs_state(mvm, IWL_MVM_TDLS_SW_RESP_RCVD);
476 } 504 }
477 505
478out: 506out:
@@ -657,12 +685,15 @@ iwl_mvm_tdls_recv_channel_switch(struct ieee80211_hw *hw,
657 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 685 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
658 enum iwl_tdls_channel_switch_type type; 686 enum iwl_tdls_channel_switch_type type;
659 unsigned int delay; 687 unsigned int delay;
688 const char *action_str =
689 params->action_code == WLAN_TDLS_CHANNEL_SWITCH_REQUEST ?
690 "REQ" : "RESP";
660 691
661 mutex_lock(&mvm->mutex); 692 mutex_lock(&mvm->mutex);
662 693
663 IWL_DEBUG_TDLS(mvm, 694 IWL_DEBUG_TDLS(mvm,
664 "Received TDLS ch switch action %d from %pM status %d\n", 695 "Received TDLS ch switch action %s from %pM status %d\n",
665 params->action_code, params->sta->addr, params->status); 696 action_str, params->sta->addr, params->status);
666 697
667 /* 698 /*
668 * we got a non-zero status from a peer we were switching to - move to 699 * we got a non-zero status from a peer we were switching to - move to
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 c59d07567d90..07304e1fd64a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -220,7 +220,7 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd,
220 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); 220 rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx);
221 221
222 mvm->mgmt_last_antenna_idx = 222 mvm->mgmt_last_antenna_idx =
223 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 223 iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm),
224 mvm->mgmt_last_antenna_idx); 224 mvm->mgmt_last_antenna_idx);
225 225
226 if (info->band == IEEE80211_BAND_2GHZ && 226 if (info->band == IEEE80211_BAND_2GHZ &&
@@ -507,7 +507,7 @@ static void iwl_mvm_check_ratid_empty(struct iwl_mvm *mvm,
507 IWL_DEBUG_TX_QUEUES(mvm, 507 IWL_DEBUG_TX_QUEUES(mvm,
508 "Can continue DELBA flow ssn = next_recl = %d\n", 508 "Can continue DELBA flow ssn = next_recl = %d\n",
509 tid_data->next_reclaimed); 509 tid_data->next_reclaimed);
510 iwl_mvm_disable_txq(mvm, tid_data->txq_id); 510 iwl_mvm_disable_txq(mvm, tid_data->txq_id, CMD_ASYNC);
511 tid_data->state = IWL_AGG_OFF; 511 tid_data->state = IWL_AGG_OFF;
512 /* 512 /*
513 * 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
@@ -667,7 +667,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
667 667
668 /* Single frame failure in an AMPDU queue => send BAR */ 668 /* Single frame failure in an AMPDU queue => send BAR */
669 if (txq_id >= mvm->first_agg_queue && 669 if (txq_id >= mvm->first_agg_queue &&
670 !(info->flags & IEEE80211_TX_STAT_ACK)) 670 !(info->flags & IEEE80211_TX_STAT_ACK) &&
671 !(info->flags & IEEE80211_TX_STAT_TX_FILTERED))
671 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; 672 info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
672 673
673 /* 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 */
@@ -930,6 +931,11 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
930 sta_id = ba_notif->sta_id; 931 sta_id = ba_notif->sta_id;
931 tid = ba_notif->tid; 932 tid = ba_notif->tid;
932 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
933 rcu_read_lock(); 939 rcu_read_lock();
934 940
935 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..8decf9953229 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -432,7 +432,7 @@ static void iwl_mvm_dump_umac_error_log(struct iwl_mvm *mvm)
432 mvm->status, table.valid); 432 mvm->status, table.valid);
433 } 433 }
434 434
435 IWL_ERR(mvm, "0x%08X | %-28s\n", table.error_id, 435 IWL_ERR(mvm, "0x%08X | %s\n", table.error_id,
436 desc_lookup(table.error_id)); 436 desc_lookup(table.error_id));
437 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1); 437 IWL_ERR(mvm, "0x%08X | umac branchlink1\n", table.blink1);
438 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2); 438 IWL_ERR(mvm, "0x%08X | umac branchlink2\n", table.blink2);
@@ -531,49 +531,50 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
531} 531}
532 532
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 unsigned int wdg_timeout)
535{ 536{
536 if (iwl_mvm_is_dqa_supported(mvm)) { 537 struct iwl_scd_txq_cfg_cmd cmd = {
537 struct iwl_scd_txq_cfg_cmd cmd = { 538 .scd_queue = queue,
538 .scd_queue = queue, 539 .enable = 1,
539 .enable = 1, 540 .window = cfg->frame_limit,
540 .window = cfg->frame_limit, 541 .sta_id = cfg->sta_id,
541 .sta_id = cfg->sta_id, 542 .ssn = cpu_to_le16(ssn),
542 .ssn = cpu_to_le16(ssn), 543 .tx_fifo = cfg->fifo,
543 .tx_fifo = cfg->fifo, 544 .aggregate = cfg->aggregate,
544 .aggregate = cfg->aggregate, 545 .tid = cfg->tid,
545 .flags = IWL_SCD_FLAGS_DQA_ENABLED, 546 };
546 .tid = cfg->tid, 547
547 .control = IWL_SCD_CONTROL_SET_SSN, 548 if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
548 }; 549 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, cfg,
549 int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, 550 wdg_timeout);
550 sizeof(cmd), &cmd); 551 return;
551 if (ret)
552 IWL_ERR(mvm,
553 "Failed to configure queue %d on FIFO %d\n",
554 queue, cfg->fifo);
555 } 552 }
556 553
557 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, 554 iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
558 iwl_mvm_is_dqa_supported(mvm) ? NULL : cfg); 555 WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), &cmd),
556 "Failed to configure queue %d on FIFO %d\n", queue, cfg->fifo);
559} 557}
560 558
561void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue) 559void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, u8 flags)
562{ 560{
563 iwl_trans_txq_disable(mvm->trans, queue, 561 struct iwl_scd_txq_cfg_cmd cmd = {
564 !iwl_mvm_is_dqa_supported(mvm)); 562 .scd_queue = queue,
565 563 .enable = 0,
566 if (iwl_mvm_is_dqa_supported(mvm)) { 564 };
567 struct iwl_scd_txq_cfg_cmd cmd = { 565 int ret;
568 .scd_queue = queue, 566
569 .enable = 0, 567 if (!iwl_mvm_is_scd_cfg_supported(mvm)) {
570 }; 568 iwl_trans_txq_disable(mvm->trans, queue, true);
571 int ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, CMD_ASYNC, 569 return;
572 sizeof(cmd), &cmd);
573 if (ret)
574 IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
575 queue, ret);
576 } 570 }
571
572 iwl_trans_txq_disable(mvm->trans, queue, false);
573 ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, flags,
574 sizeof(cmd), &cmd);
575 if (ret)
576 IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n",
577 queue, ret);
577} 578}
578 579
579/** 580/**
@@ -620,7 +621,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
620 lockdep_assert_held(&mvm->mutex); 621 lockdep_assert_held(&mvm->mutex);
621 622
622 /* SMPS is irrelevant for NICs that don't have at least 2 RX antenna */ 623 /* 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) 624 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
624 return; 625 return;
625 626
626 if (vif->type == NL80211_IFTYPE_AP) 627 if (vif->type == NL80211_IFTYPE_AP)
@@ -662,7 +663,7 @@ bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm)
662 663
663 lockdep_assert_held(&mvm->mutex); 664 lockdep_assert_held(&mvm->mutex);
664 665
665 if (num_of_ant(mvm->fw->valid_rx_ant) == 1) 666 if (num_of_ant(iwl_mvm_get_valid_rx_ant(mvm)) == 1)
666 return false; 667 return false;
667 668
668 if (mvm->cfg->rx_with_siso_diversity) 669 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..cae0eb8835ce 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -216,6 +216,7 @@ struct iwl_pcie_txq_scratch_buf {
216 * @need_update: indicates need to update read/write index 216 * @need_update: indicates need to update read/write index
217 * @active: stores if queue is active 217 * @active: stores if queue is active
218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID 218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID
219 * @wd_timeout: queue watchdog timeout (jiffies) - per queue
219 * 220 *
220 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 221 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
221 * descriptors) and required locking structures. 222 * descriptors) and required locking structures.
@@ -232,6 +233,7 @@ struct iwl_txq {
232 bool need_update; 233 bool need_update;
233 u8 active; 234 u8 active;
234 bool ampdu; 235 bool ampdu;
236 unsigned long wd_timeout;
235}; 237};
236 238
237static inline dma_addr_t 239static inline dma_addr_t
@@ -259,7 +261,6 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
259 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) 261 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
260 * @scd_set_active: should the transport configure the SCD for HCMD queue 262 * @scd_set_active: should the transport configure the SCD for HCMD queue
261 * @rx_page_order: page order for receive buffer size 263 * @rx_page_order: page order for receive buffer size
262 * @wd_timeout: queue watchdog timeout (jiffies)
263 * @reg_lock: protect hw register access 264 * @reg_lock: protect hw register access
264 * @cmd_in_flight: true when we have a host command in flight 265 * @cmd_in_flight: true when we have a host command in flight
265 * @fw_mon_phys: physical address of the buffer for the firmware monitor 266 * @fw_mon_phys: physical address of the buffer for the firmware monitor
@@ -302,6 +303,7 @@ struct iwl_trans_pcie {
302 303
303 u8 cmd_queue; 304 u8 cmd_queue;
304 u8 cmd_fifo; 305 u8 cmd_fifo;
306 unsigned int cmd_q_wdg_timeout;
305 u8 n_no_reclaim_cmds; 307 u8 n_no_reclaim_cmds;
306 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; 308 u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS];
307 309
@@ -312,12 +314,14 @@ struct iwl_trans_pcie {
312 314
313 const char *const *command_names; 315 const char *const *command_names;
314 316
315 /* queue watchdog */
316 unsigned long wd_timeout;
317
318 /*protect hw register */ 317 /*protect hw register */
319 spinlock_t reg_lock; 318 spinlock_t reg_lock;
320 bool cmd_in_flight; 319 bool cmd_in_flight;
320 bool ref_cmd_in_flight;
321
322 /* protect ref counter */
323 spinlock_t ref_lock;
324 u32 ref_count;
321 325
322 dma_addr_t fw_mon_phys; 326 dma_addr_t fw_mon_phys;
323 struct page *fw_mon_page; 327 struct page *fw_mon_page;
@@ -368,7 +372,8 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr);
368int iwl_pcie_tx_stop(struct iwl_trans *trans); 372int iwl_pcie_tx_stop(struct iwl_trans *trans);
369void iwl_pcie_tx_free(struct iwl_trans *trans); 373void iwl_pcie_tx_free(struct iwl_trans *trans);
370void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn, 374void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int queue, u16 ssn,
371 const struct iwl_trans_txq_scd_cfg *cfg); 375 const struct iwl_trans_txq_scd_cfg *cfg,
376 unsigned int wdg_timeout);
372void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue, 377void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue,
373 bool configure_scd); 378 bool configure_scd);
374int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, 379int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
@@ -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..69935aa5a1b3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -75,6 +75,7 @@
75#include "iwl-trans.h" 75#include "iwl-trans.h"
76#include "iwl-csr.h" 76#include "iwl-csr.h"
77#include "iwl-prph.h" 77#include "iwl-prph.h"
78#include "iwl-scd.h"
78#include "iwl-agn-hw.h" 79#include "iwl-agn-hw.h"
79#include "iwl-fw-error-dump.h" 80#include "iwl-fw-error-dump.h"
80#include "internal.h" 81#include "internal.h"
@@ -443,10 +444,25 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans)
443 return ret; 444 return ret;
444} 445}
445 446
446static void iwl_pcie_apm_stop(struct iwl_trans *trans) 447static void iwl_pcie_apm_stop(struct iwl_trans *trans, bool op_mode_leave)
447{ 448{
448 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); 449 IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n");
449 450
451 if (op_mode_leave) {
452 if (!test_bit(STATUS_DEVICE_ENABLED, &trans->status))
453 iwl_pcie_apm_init(trans);
454
455 /* inform ME that we are leaving */
456 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_7000)
457 iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG,
458 APMG_PCIDEV_STT_VAL_WAKE_ME);
459 else if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
460 iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG,
461 CSR_HW_IF_CONFIG_REG_PREPARE |
462 CSR_HW_IF_CONFIG_REG_ENABLE_PME);
463 mdelay(5);
464 }
465
450 clear_bit(STATUS_DEVICE_ENABLED, &trans->status); 466 clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
451 467
452 /* Stop device's DMA activity */ 468 /* Stop device's DMA activity */
@@ -707,6 +723,11 @@ static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
707 723
708 *first_ucode_section = last_read_idx; 724 *first_ucode_section = last_read_idx;
709 725
726 if (cpu == 1)
727 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFF);
728 else
729 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
730
710 return 0; 731 return 0;
711} 732}
712 733
@@ -893,8 +914,8 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
893 if (ret) 914 if (ret)
894 return ret; 915 return ret;
895 916
896 /* Notify FW loading is done */ 917 if (trans->dbg_dest_tlv)
897 iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF); 918 iwl_pcie_apply_destination(trans);
898 919
899 /* wait for image verification to complete */ 920 /* wait for image verification to complete */
900 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0, 921 ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
@@ -916,6 +937,7 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
916static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, 937static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
917 const struct fw_img *fw, bool run_in_rfkill) 938 const struct fw_img *fw, bool run_in_rfkill)
918{ 939{
940 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
919 int ret; 941 int ret;
920 bool hw_rfkill; 942 bool hw_rfkill;
921 943
@@ -945,6 +967,9 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
945 return ret; 967 return ret;
946 } 968 }
947 969
970 /* init ref_count to 1 (should be cleared when ucode is loaded) */
971 trans_pcie->ref_count = 1;
972
948 /* make sure rfkill handshake bits are cleared */ 973 /* make sure rfkill handshake bits are cleared */
949 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); 974 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
950 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, 975 iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR,
@@ -960,7 +985,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
960 985
961 /* Load the given image to the HW */ 986 /* Load the given image to the HW */
962 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) && 987 if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
963 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP)) 988 (CSR_HW_REV_STEP(trans->hw_rev) != SILICON_A_STEP))
964 return iwl_pcie_load_given_ucode_8000b(trans, fw); 989 return iwl_pcie_load_given_ucode_8000b(trans, fw);
965 else 990 else
966 return iwl_pcie_load_given_ucode(trans, fw); 991 return iwl_pcie_load_given_ucode(trans, fw);
@@ -1010,7 +1035,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1010 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1035 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1011 1036
1012 /* Stop the device, and put it in low power state */ 1037 /* Stop the device, and put it in low power state */
1013 iwl_pcie_apm_stop(trans); 1038 iwl_pcie_apm_stop(trans, false);
1014 1039
1015 /* stop and reset the on-board processor */ 1040 /* stop and reset the on-board processor */
1016 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); 1041 iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
@@ -1192,7 +1217,7 @@ static void iwl_trans_pcie_op_mode_leave(struct iwl_trans *trans)
1192 iwl_disable_interrupts(trans); 1217 iwl_disable_interrupts(trans);
1193 spin_unlock(&trans_pcie->irq_lock); 1218 spin_unlock(&trans_pcie->irq_lock);
1194 1219
1195 iwl_pcie_apm_stop(trans); 1220 iwl_pcie_apm_stop(trans, true);
1196 1221
1197 spin_lock(&trans_pcie->irq_lock); 1222 spin_lock(&trans_pcie->irq_lock);
1198 iwl_disable_interrupts(trans); 1223 iwl_disable_interrupts(trans);
@@ -1244,6 +1269,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1244 1269
1245 trans_pcie->cmd_queue = trans_cfg->cmd_queue; 1270 trans_pcie->cmd_queue = trans_cfg->cmd_queue;
1246 trans_pcie->cmd_fifo = trans_cfg->cmd_fifo; 1271 trans_pcie->cmd_fifo = trans_cfg->cmd_fifo;
1272 trans_pcie->cmd_q_wdg_timeout = trans_cfg->cmd_q_wdg_timeout;
1247 if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) 1273 if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS))
1248 trans_pcie->n_no_reclaim_cmds = 0; 1274 trans_pcie->n_no_reclaim_cmds = 0;
1249 else 1275 else
@@ -1258,9 +1284,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1258 else 1284 else
1259 trans_pcie->rx_page_order = get_order(4 * 1024); 1285 trans_pcie->rx_page_order = get_order(4 * 1024);
1260 1286
1261 trans_pcie->wd_timeout =
1262 msecs_to_jiffies(trans_cfg->queue_watchdog_timeout);
1263
1264 trans_pcie->command_names = trans_cfg->command_names; 1287 trans_pcie->command_names = trans_cfg->command_names;
1265 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; 1288 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
1266 trans_pcie->scd_set_active = trans_cfg->scd_set_active; 1289 trans_pcie->scd_set_active = trans_cfg->scd_set_active;
@@ -1540,6 +1563,38 @@ static void iwl_trans_pcie_set_bits_mask(struct iwl_trans *trans, u32 reg,
1540 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1563 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1541} 1564}
1542 1565
1566void iwl_trans_pcie_ref(struct iwl_trans *trans)
1567{
1568 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1569 unsigned long flags;
1570
1571 if (iwlwifi_mod_params.d0i3_disable)
1572 return;
1573
1574 spin_lock_irqsave(&trans_pcie->ref_lock, flags);
1575 IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
1576 trans_pcie->ref_count++;
1577 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1578}
1579
1580void iwl_trans_pcie_unref(struct iwl_trans *trans)
1581{
1582 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1583 unsigned long flags;
1584
1585 if (iwlwifi_mod_params.d0i3_disable)
1586 return;
1587
1588 spin_lock_irqsave(&trans_pcie->ref_lock, flags);
1589 IWL_DEBUG_RPM(trans, "ref_counter: %d\n", trans_pcie->ref_count);
1590 if (WARN_ON_ONCE(trans_pcie->ref_count == 0)) {
1591 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1592 return;
1593 }
1594 trans_pcie->ref_count--;
1595 spin_unlock_irqrestore(&trans_pcie->ref_lock, flags);
1596}
1597
1543static const char *get_csr_string(int cmd) 1598static const char *get_csr_string(int cmd)
1544{ 1599{
1545#define IWL_CMD(x) case x: return #x 1600#define IWL_CMD(x) case x: return #x
@@ -2264,6 +2319,9 @@ static const struct iwl_trans_ops trans_ops_pcie = {
2264 .release_nic_access = iwl_trans_pcie_release_nic_access, 2319 .release_nic_access = iwl_trans_pcie_release_nic_access,
2265 .set_bits_mask = iwl_trans_pcie_set_bits_mask, 2320 .set_bits_mask = iwl_trans_pcie_set_bits_mask,
2266 2321
2322 .ref = iwl_trans_pcie_ref,
2323 .unref = iwl_trans_pcie_unref,
2324
2267 .dump_data = iwl_trans_pcie_dump_data, 2325 .dump_data = iwl_trans_pcie_dump_data,
2268}; 2326};
2269 2327
@@ -2291,6 +2349,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2291 trans_pcie->trans = trans; 2349 trans_pcie->trans = trans;
2292 spin_lock_init(&trans_pcie->irq_lock); 2350 spin_lock_init(&trans_pcie->irq_lock);
2293 spin_lock_init(&trans_pcie->reg_lock); 2351 spin_lock_init(&trans_pcie->reg_lock);
2352 spin_lock_init(&trans_pcie->ref_lock);
2294 init_waitqueue_head(&trans_pcie->ucode_write_waitq); 2353 init_waitqueue_head(&trans_pcie->ucode_write_waitq);
2295 2354
2296 err = pci_enable_device(pdev); 2355 err = pci_enable_device(pdev);
@@ -2404,6 +2463,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2404 } 2463 }
2405 2464
2406 trans_pcie->inta_mask = CSR_INI_SET_MASK; 2465 trans_pcie->inta_mask = CSR_INI_SET_MASK;
2466 trans->d0i3_mode = IWL_D0I3_MODE_ON_SUSPEND;
2407 2467
2408 return trans; 2468 return trans;
2409 2469
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 8a6c7a084aa1..af0bce736358 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -147,7 +147,6 @@ static void iwl_pcie_free_dma_ptr(struct iwl_trans *trans,
147static void iwl_pcie_txq_stuck_timer(unsigned long data) 147static void iwl_pcie_txq_stuck_timer(unsigned long data)
148{ 148{
149 struct iwl_txq *txq = (void *)data; 149 struct iwl_txq *txq = (void *)data;
150 struct iwl_queue *q = &txq->q;
151 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; 150 struct iwl_trans_pcie *trans_pcie = txq->trans_pcie;
152 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); 151 struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie);
153 u32 scd_sram_addr = trans_pcie->scd_base_addr + 152 u32 scd_sram_addr = trans_pcie->scd_base_addr +
@@ -164,7 +163,7 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
164 spin_unlock(&txq->lock); 163 spin_unlock(&txq->lock);
165 164
166 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, 165 IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id,
167 jiffies_to_msecs(trans_pcie->wd_timeout)); 166 jiffies_to_msecs(txq->wd_timeout));
168 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", 167 IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n",
169 txq->q.read_ptr, txq->q.write_ptr); 168 txq->q.read_ptr, txq->q.write_ptr);
170 169
@@ -198,11 +197,6 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
198 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); 197 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
199 } 198 }
200 199
201 for (i = q->read_ptr; i != q->write_ptr;
202 i = iwl_queue_inc_wrap(i))
203 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
204 le32_to_cpu(txq->scratchbufs[i].scratch));
205
206 iwl_force_nmi(trans); 200 iwl_force_nmi(trans);
207} 201}
208 202
@@ -680,7 +674,8 @@ void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr)
680 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); 674 iwl_write_prph(trans, SCD_CHAINEXT_EN, 0);
681 675
682 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, 676 iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue,
683 trans_pcie->cmd_fifo); 677 trans_pcie->cmd_fifo,
678 trans_pcie->cmd_q_wdg_timeout);
684 679
685 /* Activate all Tx DMA/FIFO channels */ 680 /* Activate all Tx DMA/FIFO channels */
686 iwl_scd_activate_fifos(trans); 681 iwl_scd_activate_fifos(trans);
@@ -722,7 +717,12 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
722 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, 717 iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG,
723 trans_pcie->kw.dma >> 4); 718 trans_pcie->kw.dma >> 4);
724 719
725 iwl_pcie_tx_start(trans, trans_pcie->scd_base_addr); 720 /*
721 * Send 0 as the scd_base_addr since the device may have be reset
722 * while we were in WoWLAN in which case SCD_SRAM_BASE_ADDR will
723 * contain garbage.
724 */
725 iwl_pcie_tx_start(trans, 0);
726} 726}
727 727
728/* 728/*
@@ -898,6 +898,10 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
898 } 898 }
899 } 899 }
900 900
901 if (trans->cfg->base_params->num_of_queues > 20)
902 iwl_set_bits_prph(trans, SCD_GP_CTRL,
903 SCD_GP_CTRL_ENABLE_31_QUEUES);
904
901 return 0; 905 return 0;
902error: 906error:
903 /*Upon error, free only if we allocated something */ 907 /*Upon error, free only if we allocated something */
@@ -906,10 +910,9 @@ error:
906 return ret; 910 return ret;
907} 911}
908 912
909static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie, 913static inline void iwl_pcie_txq_progress(struct iwl_txq *txq)
910 struct iwl_txq *txq)
911{ 914{
912 if (!trans_pcie->wd_timeout) 915 if (!txq->wd_timeout)
913 return; 916 return;
914 917
915 /* 918 /*
@@ -919,7 +922,7 @@ static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie,
919 if (txq->q.read_ptr == txq->q.write_ptr) 922 if (txq->q.read_ptr == txq->q.write_ptr)
920 del_timer(&txq->stuck_timer); 923 del_timer(&txq->stuck_timer);
921 else 924 else
922 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 925 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
923} 926}
924 927
925/* Frees buffers until index _not_ inclusive */ 928/* Frees buffers until index _not_ inclusive */
@@ -981,21 +984,35 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
981 iwl_pcie_txq_free_tfd(trans, txq); 984 iwl_pcie_txq_free_tfd(trans, txq);
982 } 985 }
983 986
984 iwl_pcie_txq_progress(trans_pcie, txq); 987 iwl_pcie_txq_progress(txq);
985 988
986 if (iwl_queue_space(&txq->q) > txq->q.low_mark) 989 if (iwl_queue_space(&txq->q) > txq->q.low_mark)
987 iwl_wake_queue(trans, txq); 990 iwl_wake_queue(trans, txq);
991
992 if (q->read_ptr == q->write_ptr) {
993 IWL_DEBUG_RPM(trans, "Q %d - last tx reclaimed\n", q->id);
994 iwl_trans_pcie_unref(trans);
995 }
996
988out: 997out:
989 spin_unlock_bh(&txq->lock); 998 spin_unlock_bh(&txq->lock);
990} 999}
991 1000
992static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans) 1001static int iwl_pcie_set_cmd_in_flight(struct iwl_trans *trans,
1002 const struct iwl_host_cmd *cmd)
993{ 1003{
994 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1004 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
995 int ret; 1005 int ret;
996 1006
997 lockdep_assert_held(&trans_pcie->reg_lock); 1007 lockdep_assert_held(&trans_pcie->reg_lock);
998 1008
1009 if (!(cmd->flags & CMD_SEND_IN_IDLE) &&
1010 !trans_pcie->ref_cmd_in_flight) {
1011 trans_pcie->ref_cmd_in_flight = true;
1012 IWL_DEBUG_RPM(trans, "set ref_cmd_in_flight - ref\n");
1013 iwl_trans_pcie_ref(trans);
1014 }
1015
999 if (trans_pcie->cmd_in_flight) 1016 if (trans_pcie->cmd_in_flight)
1000 return 0; 1017 return 0;
1001 1018
@@ -1036,6 +1053,12 @@ static int iwl_pcie_clear_cmd_in_flight(struct iwl_trans *trans)
1036 1053
1037 lockdep_assert_held(&trans_pcie->reg_lock); 1054 lockdep_assert_held(&trans_pcie->reg_lock);
1038 1055
1056 if (trans_pcie->ref_cmd_in_flight) {
1057 trans_pcie->ref_cmd_in_flight = false;
1058 IWL_DEBUG_RPM(trans, "clear ref_cmd_in_flight - unref\n");
1059 iwl_trans_pcie_unref(trans);
1060 }
1061
1039 if (WARN_ON(!trans_pcie->cmd_in_flight)) 1062 if (WARN_ON(!trans_pcie->cmd_in_flight))
1040 return 0; 1063 return 0;
1041 1064
@@ -1089,7 +1112,7 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1089 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1112 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1090 } 1113 }
1091 1114
1092 iwl_pcie_txq_progress(trans_pcie, txq); 1115 iwl_pcie_txq_progress(txq);
1093} 1116}
1094 1117
1095static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, 1118static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
@@ -1122,14 +1145,18 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid,
1122#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid)) 1145#define BUILD_RAxTID(sta_id, tid) (((sta_id) << 4) + (tid))
1123 1146
1124void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, 1147void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1125 const struct iwl_trans_txq_scd_cfg *cfg) 1148 const struct iwl_trans_txq_scd_cfg *cfg,
1149 unsigned int wdg_timeout)
1126{ 1150{
1127 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1151 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1152 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
1128 int fifo = -1; 1153 int fifo = -1;
1129 1154
1130 if (test_and_set_bit(txq_id, trans_pcie->queue_used)) 1155 if (test_and_set_bit(txq_id, trans_pcie->queue_used))
1131 WARN_ONCE(1, "queue %d already used - expect issues", txq_id); 1156 WARN_ONCE(1, "queue %d already used - expect issues", txq_id);
1132 1157
1158 txq->wd_timeout = msecs_to_jiffies(wdg_timeout);
1159
1133 if (cfg) { 1160 if (cfg) {
1134 fifo = cfg->fifo; 1161 fifo = cfg->fifo;
1135 1162
@@ -1153,7 +1180,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1153 1180
1154 /* enable aggregations for the queue */ 1181 /* enable aggregations for the queue */
1155 iwl_scd_txq_enable_agg(trans, txq_id); 1182 iwl_scd_txq_enable_agg(trans, txq_id);
1156 trans_pcie->txq[txq_id].ampdu = true; 1183 txq->ampdu = true;
1157 } else { 1184 } else {
1158 /* 1185 /*
1159 * disable aggregations for the queue, this will also 1186 * disable aggregations for the queue, this will also
@@ -1162,20 +1189,20 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1162 */ 1189 */
1163 iwl_scd_txq_disable_agg(trans, txq_id); 1190 iwl_scd_txq_disable_agg(trans, txq_id);
1164 1191
1165 ssn = trans_pcie->txq[txq_id].q.read_ptr; 1192 ssn = txq->q.read_ptr;
1166 } 1193 }
1167 } 1194 }
1168 1195
1169 /* Place first TFD at index corresponding to start sequence number. 1196 /* Place first TFD at index corresponding to start sequence number.
1170 * Assumes that ssn_idx is valid (!= 0xFFF) */ 1197 * Assumes that ssn_idx is valid (!= 0xFFF) */
1171 trans_pcie->txq[txq_id].q.read_ptr = (ssn & 0xff); 1198 txq->q.read_ptr = (ssn & 0xff);
1172 trans_pcie->txq[txq_id].q.write_ptr = (ssn & 0xff); 1199 txq->q.write_ptr = (ssn & 0xff);
1200 iwl_write_direct32(trans, HBUS_TARG_WRPTR,
1201 (ssn & 0xff) | (txq_id << 8));
1173 1202
1174 if (cfg) { 1203 if (cfg) {
1175 u8 frame_limit = cfg->frame_limit; 1204 u8 frame_limit = cfg->frame_limit;
1176 1205
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); 1206 iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), ssn);
1180 1207
1181 /* Set up Tx window size and frame limit for this queue */ 1208 /* Set up Tx window size and frame limit for this queue */
@@ -1200,11 +1227,17 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1200 if (txq_id == trans_pcie->cmd_queue && 1227 if (txq_id == trans_pcie->cmd_queue &&
1201 trans_pcie->scd_set_active) 1228 trans_pcie->scd_set_active)
1202 iwl_scd_enable_set_active(trans, BIT(txq_id)); 1229 iwl_scd_enable_set_active(trans, BIT(txq_id));
1230
1231 IWL_DEBUG_TX_QUEUES(trans,
1232 "Activate queue %d on FIFO %d WrPtr: %d\n",
1233 txq_id, fifo, ssn & 0xff);
1234 } else {
1235 IWL_DEBUG_TX_QUEUES(trans,
1236 "Activate queue %d WrPtr: %d\n",
1237 txq_id, ssn & 0xff);
1203 } 1238 }
1204 1239
1205 trans_pcie->txq[txq_id].active = true; 1240 txq->active = true;
1206 IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
1207 txq_id, fifo, ssn & 0xff);
1208} 1241}
1209 1242
1210void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id, 1243void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
@@ -1469,11 +1502,11 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1469 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); 1502 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
1470 1503
1471 /* start timer if queue currently empty */ 1504 /* start timer if queue currently empty */
1472 if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) 1505 if (q->read_ptr == q->write_ptr && txq->wd_timeout)
1473 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1506 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1474 1507
1475 spin_lock_irqsave(&trans_pcie->reg_lock, flags); 1508 spin_lock_irqsave(&trans_pcie->reg_lock, flags);
1476 ret = iwl_pcie_set_cmd_in_flight(trans); 1509 ret = iwl_pcie_set_cmd_in_flight(trans, cmd);
1477 if (ret < 0) { 1510 if (ret < 0) {
1478 idx = ret; 1511 idx = ret;
1479 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1512 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
@@ -1819,9 +1852,12 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1819 wait_write_ptr = ieee80211_has_morefrags(fc); 1852 wait_write_ptr = ieee80211_has_morefrags(fc);
1820 1853
1821 /* start timer if queue currently empty */ 1854 /* start timer if queue currently empty */
1822 if (txq->need_update && q->read_ptr == q->write_ptr && 1855 if (q->read_ptr == q->write_ptr) {
1823 trans_pcie->wd_timeout) 1856 if (txq->wd_timeout)
1824 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1857 mod_timer(&txq->stuck_timer, jiffies + txq->wd_timeout);
1858 IWL_DEBUG_RPM(trans, "Q: %d first tx - take ref\n", q->id);
1859 iwl_trans_pcie_ref(trans);
1860 }
1825 1861
1826 /* Tell device the write index *just past* this latest filled TFD */ 1862 /* Tell device the write index *just past* this latest filled TFD */
1827 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr); 1863 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 34f09ef90bb3..a92985a6ea21 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -1616,10 +1616,10 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1616 1616
1617 lbs_deb_enter(LBS_DEB_CFG80211); 1617 lbs_deb_enter(LBS_DEB_CFG80211);
1618 1618
1619 sinfo->filled |= STATION_INFO_TX_BYTES | 1619 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES) |
1620 STATION_INFO_TX_PACKETS | 1620 BIT(NL80211_STA_INFO_TX_PACKETS) |
1621 STATION_INFO_RX_BYTES | 1621 BIT(NL80211_STA_INFO_RX_BYTES) |
1622 STATION_INFO_RX_PACKETS; 1622 BIT(NL80211_STA_INFO_RX_PACKETS);
1623 sinfo->tx_bytes = priv->dev->stats.tx_bytes; 1623 sinfo->tx_bytes = priv->dev->stats.tx_bytes;
1624 sinfo->tx_packets = priv->dev->stats.tx_packets; 1624 sinfo->tx_packets = priv->dev->stats.tx_packets;
1625 sinfo->rx_bytes = priv->dev->stats.rx_bytes; 1625 sinfo->rx_bytes = priv->dev->stats.rx_bytes;
@@ -1629,14 +1629,14 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
1629 ret = lbs_get_rssi(priv, &signal, &noise); 1629 ret = lbs_get_rssi(priv, &signal, &noise);
1630 if (ret == 0) { 1630 if (ret == 0) {
1631 sinfo->signal = signal; 1631 sinfo->signal = signal;
1632 sinfo->filled |= STATION_INFO_SIGNAL; 1632 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
1633 } 1633 }
1634 1634
1635 /* Convert priv->cur_rate from hw_value to NL80211 value */ 1635 /* Convert priv->cur_rate from hw_value to NL80211 value */
1636 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) { 1636 for (i = 0; i < ARRAY_SIZE(lbs_rates); i++) {
1637 if (priv->cur_rate == lbs_rates[i].hw_value) { 1637 if (priv->cur_rate == lbs_rates[i].hw_value) {
1638 sinfo->txrate.legacy = lbs_rates[i].bitrate; 1638 sinfo->txrate.legacy = lbs_rates[i].bitrate;
1639 sinfo->filled |= STATION_INFO_TX_BITRATE; 1639 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
1640 break; 1640 break;
1641 } 1641 }
1642 } 1642 }
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index ef58a8862d91..4a4c6586a8d2 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -625,22 +625,22 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
625 old_ps = data->ps; 625 old_ps = data->ps;
626 data->ps = val; 626 data->ps = val;
627 627
628 local_bh_disable();
628 if (val == PS_MANUAL_POLL) { 629 if (val == PS_MANUAL_POLL) {
629 ieee80211_iterate_active_interfaces(data->hw, 630 ieee80211_iterate_active_interfaces_atomic(
630 IEEE80211_IFACE_ITER_NORMAL, 631 data->hw, IEEE80211_IFACE_ITER_NORMAL,
631 hwsim_send_ps_poll, data); 632 hwsim_send_ps_poll, data);
632 data->ps_poll_pending = true; 633 data->ps_poll_pending = true;
633 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { 634 } else if (old_ps == PS_DISABLED && val != PS_DISABLED) {
634 ieee80211_iterate_active_interfaces(data->hw, 635 ieee80211_iterate_active_interfaces_atomic(
635 IEEE80211_IFACE_ITER_NORMAL, 636 data->hw, IEEE80211_IFACE_ITER_NORMAL,
636 hwsim_send_nullfunc_ps, 637 hwsim_send_nullfunc_ps, data);
637 data);
638 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { 638 } else if (old_ps != PS_DISABLED && val == PS_DISABLED) {
639 ieee80211_iterate_active_interfaces(data->hw, 639 ieee80211_iterate_active_interfaces_atomic(
640 IEEE80211_IFACE_ITER_NORMAL, 640 data->hw, IEEE80211_IFACE_ITER_NORMAL,
641 hwsim_send_nullfunc_no_ps, 641 hwsim_send_nullfunc_no_ps, data);
642 data);
643 } 642 }
643 local_bh_enable();
644 644
645 return 0; 645 return 0;
646} 646}
@@ -2149,14 +2149,14 @@ static int append_radio_msg(struct sk_buff *skb, int id,
2149 if (param->regd) { 2149 if (param->regd) {
2150 int i; 2150 int i;
2151 2151
2152 for (i = 0; hwsim_world_regdom_custom[i] != param->regd && 2152 for (i = 0; i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) {
2153 i < ARRAY_SIZE(hwsim_world_regdom_custom); i++) 2153 if (hwsim_world_regdom_custom[i] != param->regd)
2154 ; 2154 continue;
2155 2155
2156 if (i < ARRAY_SIZE(hwsim_world_regdom_custom)) {
2157 ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i); 2156 ret = nla_put_u32(skb, HWSIM_ATTR_REG_CUSTOM_REG, i);
2158 if (ret < 0) 2157 if (ret < 0)
2159 return ret; 2158 return ret;
2159 break;
2160 } 2160 }
2161 } 2161 }
2162 2162
@@ -2557,7 +2557,8 @@ static int mac80211_hwsim_get_radio(struct sk_buff *skb,
2557 if (res < 0) 2557 if (res < 0)
2558 goto out_err; 2558 goto out_err;
2559 2559
2560 return genlmsg_end(skb, hdr); 2560 genlmsg_end(skb, hdr);
2561 return 0;
2561 2562
2562out_err: 2563out_err:
2563 genlmsg_cancel(skb, hdr); 2564 genlmsg_cancel(skb, hdr);
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index 2668e83afbb6..3ab87a855122 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -21,6 +21,16 @@
21#include "fw.h" 21#include "fw.h"
22 22
23 23
24void mwifiex_init_11h_params(struct mwifiex_private *priv)
25{
26 priv->state_11h.is_11h_enabled = true;
27 priv->state_11h.is_11h_active = false;
28}
29
30inline int mwifiex_is_11h_active(struct mwifiex_private *priv)
31{
32 return priv->state_11h.is_11h_active;
33}
24/* This function appends 11h info to a buffer while joining an 34/* This function appends 11h info to a buffer while joining an
25 * infrastructure BSS 35 * infrastructure BSS
26 */ 36 */
@@ -39,7 +49,7 @@ mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer,
39 return; 49 return;
40 50
41 radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); 51 radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
42 sband = priv->wdev->wiphy->bands[radio_type]; 52 sband = priv->wdev.wiphy->bands[radio_type];
43 53
44 cap = (struct mwifiex_ie_types_pwr_capability *)*buffer; 54 cap = (struct mwifiex_ie_types_pwr_capability *)*buffer;
45 cap->header.type = cpu_to_le16(WLAN_EID_PWR_CAPABILITY); 55 cap->header.type = cpu_to_le16(WLAN_EID_PWR_CAPABILITY);
@@ -69,10 +79,14 @@ mwifiex_11h_process_infra_join(struct mwifiex_private *priv, u8 **buffer,
69} 79}
70 80
71/* Enable or disable the 11h extensions in the firmware */ 81/* Enable or disable the 11h extensions in the firmware */
72static int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag) 82int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag)
73{ 83{
74 u32 enable = flag; 84 u32 enable = flag;
75 85
86 /* enable master mode radar detection on AP interface */
87 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) && enable)
88 enable |= MWIFIEX_MASTER_RADAR_DET_MASK;
89
76 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB, 90 return mwifiex_send_cmd(priv, HostCmd_CMD_802_11_SNMP_MIB,
77 HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true); 91 HostCmd_ACT_GEN_SET, DOT11H_I, &enable, true);
78} 92}
@@ -91,11 +105,191 @@ void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
91 * bit 105 * bit
92 */ 106 */
93 mwifiex_11h_activate(priv, true); 107 mwifiex_11h_activate(priv, true);
108 priv->state_11h.is_11h_active = true;
94 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT; 109 bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_SPECTRUM_MGMT;
95 mwifiex_11h_process_infra_join(priv, buffer, bss_desc); 110 mwifiex_11h_process_infra_join(priv, buffer, bss_desc);
96 } else { 111 } else {
97 /* Deactivate 11h functions in the firmware */ 112 /* Deactivate 11h functions in the firmware */
98 mwifiex_11h_activate(priv, false); 113 mwifiex_11h_activate(priv, false);
114 priv->state_11h.is_11h_active = false;
99 bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT; 115 bss_desc->cap_info_bitmap &= ~WLAN_CAPABILITY_SPECTRUM_MGMT;
100 } 116 }
101} 117}
118
119/* This is DFS CAC work queue function.
120 * This delayed work emits CAC finished event for cfg80211 if
121 * CAC was started earlier.
122 */
123void mwifiex_dfs_cac_work_queue(struct work_struct *work)
124{
125 struct cfg80211_chan_def chandef;
126 struct delayed_work *delayed_work =
127 container_of(work, struct delayed_work, work);
128 struct mwifiex_private *priv =
129 container_of(delayed_work, struct mwifiex_private,
130 dfs_cac_work);
131
132 if (WARN_ON(!priv))
133 return;
134
135 chandef = priv->dfs_chandef;
136 if (priv->wdev.cac_started) {
137 dev_dbg(priv->adapter->dev,
138 "CAC timer finished; No radar detected\n");
139 cfg80211_cac_event(priv->netdev, &chandef,
140 NL80211_RADAR_CAC_FINISHED,
141 GFP_KERNEL);
142 }
143}
144
145/* This function prepares channel report request command to FW for
146 * starting radar detection.
147 */
148int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
149 struct host_cmd_ds_command *cmd,
150 void *data_buf)
151{
152 struct host_cmd_ds_chan_rpt_req *cr_req = &cmd->params.chan_rpt_req;
153 struct mwifiex_radar_params *radar_params = (void *)data_buf;
154
155 cmd->command = cpu_to_le16(HostCmd_CMD_CHAN_REPORT_REQUEST);
156 cmd->size = cpu_to_le16(S_DS_GEN);
157 le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_chan_rpt_req));
158
159 cr_req->chan_desc.start_freq = cpu_to_le16(MWIFIEX_A_BAND_START_FREQ);
160 cr_req->chan_desc.chan_num = radar_params->chandef->chan->hw_value;
161 cr_req->chan_desc.chan_width = radar_params->chandef->width;
162 cr_req->msec_dwell_time = cpu_to_le32(radar_params->cac_time_ms);
163
164 dev_dbg(priv->adapter->dev,
165 "11h: issuing DFS Radar check for channel=%d\n",
166 radar_params->chandef->chan->hw_value);
167
168 return 0;
169}
170
171/* This function is to abort ongoing CAC upon stopping AP operations
172 * or during unload.
173 */
174void mwifiex_abort_cac(struct mwifiex_private *priv)
175{
176 if (priv->wdev.cac_started) {
177 dev_dbg(priv->adapter->dev,
178 "Aborting delayed work for CAC.\n");
179 cancel_delayed_work_sync(&priv->dfs_cac_work);
180 cfg80211_cac_event(priv->netdev, &priv->dfs_chandef,
181 NL80211_RADAR_CAC_ABORTED, GFP_KERNEL);
182 }
183}
184
185/* This function handles channel report event from FW during CAC period.
186 * If radar is detected during CAC, driver indicates the same to cfg80211
187 * and also cancels ongoing delayed work.
188 */
189int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
190 struct sk_buff *skb)
191{
192 struct host_cmd_ds_chan_rpt_event *rpt_event;
193 struct mwifiex_ie_types_chan_rpt_data *rpt;
194 u8 *evt_buf;
195 u16 event_len, tlv_len;
196
197 rpt_event = (void *)(skb->data + sizeof(u32));
198 event_len = skb->len - (sizeof(struct host_cmd_ds_chan_rpt_event)+
199 sizeof(u32));
200
201 if (le32_to_cpu(rpt_event->result) != HostCmd_RESULT_OK) {
202 dev_err(priv->adapter->dev, "Error in channel report event\n");
203 return -1;
204 }
205
206 evt_buf = (void *)&rpt_event->tlvbuf;
207
208 while (event_len >= sizeof(struct mwifiex_ie_types_header)) {
209 rpt = (void *)&rpt_event->tlvbuf;
210 tlv_len = le16_to_cpu(rpt->header.len);
211
212 switch (le16_to_cpu(rpt->header.type)) {
213 case TLV_TYPE_CHANRPT_11H_BASIC:
214 if (rpt->map.radar) {
215 dev_notice(priv->adapter->dev,
216 "RADAR Detected on channel %d!\n",
217 priv->dfs_chandef.chan->hw_value);
218 cancel_delayed_work_sync(&priv->dfs_cac_work);
219 cfg80211_cac_event(priv->netdev,
220 &priv->dfs_chandef,
221 NL80211_RADAR_DETECTED,
222 GFP_KERNEL);
223 }
224 break;
225 default:
226 break;
227 }
228
229 evt_buf += (tlv_len + sizeof(rpt->header));
230 event_len -= (tlv_len + sizeof(rpt->header));
231 }
232
233 return 0;
234}
235
236/* Handler for radar detected event from FW.*/
237int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
238 struct sk_buff *skb)
239{
240 struct mwifiex_radar_det_event *rdr_event;
241
242 rdr_event = (void *)(skb->data + sizeof(u32));
243
244 if (le32_to_cpu(rdr_event->passed)) {
245 dev_notice(priv->adapter->dev,
246 "radar detected; indicating kernel\n");
247 cfg80211_radar_event(priv->adapter->wiphy, &priv->dfs_chandef,
248 GFP_KERNEL);
249 dev_dbg(priv->adapter->dev, "regdomain: %d\n",
250 rdr_event->reg_domain);
251 dev_dbg(priv->adapter->dev, "radar detection type: %d\n",
252 rdr_event->det_type);
253 } else {
254 dev_dbg(priv->adapter->dev, "false radar detection event!\n");
255 }
256
257 return 0;
258}
259
260/* This is work queue function for channel switch handling.
261 * This function takes care of updating new channel definitin to
262 * bss config structure, restart AP and indicate channel switch success
263 * to cfg80211.
264 */
265void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work)
266{
267 struct mwifiex_uap_bss_param *bss_cfg;
268 struct delayed_work *delayed_work =
269 container_of(work, struct delayed_work, work);
270 struct mwifiex_private *priv =
271 container_of(delayed_work, struct mwifiex_private,
272 dfs_chan_sw_work);
273
274 if (WARN_ON(!priv))
275 return;
276
277 bss_cfg = &priv->bss_cfg;
278 if (!bss_cfg->beacon_period) {
279 dev_err(priv->adapter->dev,
280 "channel switch: AP already stopped\n");
281 return;
282 }
283
284 mwifiex_uap_set_channel(bss_cfg, priv->dfs_chandef);
285
286 if (mwifiex_config_start_uap(priv, bss_cfg)) {
287 dev_dbg(priv->adapter->dev,
288 "Failed to start AP after channel switch\n");
289 return;
290 }
291
292 dev_notice(priv->adapter->dev,
293 "indicating channel switch completion to kernel\n");
294 cfg80211_ch_switch_notify(priv->netdev, &priv->dfs_chandef);
295}
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 9d4786e7ddff..543148d27b01 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -39,7 +39,7 @@ int mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
39{ 39{
40 uint16_t ht_ext_cap = le16_to_cpu(ht_cap->extended_ht_cap_info); 40 uint16_t ht_ext_cap = le16_to_cpu(ht_cap->extended_ht_cap_info);
41 struct ieee80211_supported_band *sband = 41 struct ieee80211_supported_band *sband =
42 priv->wdev->wiphy->bands[radio_type]; 42 priv->wdev.wiphy->bands[radio_type];
43 43
44 if (WARN_ON_ONCE(!sband)) { 44 if (WARN_ON_ONCE(!sband)) {
45 dev_err(priv->adapter->dev, "Invalid radio type!\n"); 45 dev_err(priv->adapter->dev, "Invalid radio type!\n");
@@ -314,7 +314,7 @@ mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
314 return ret_len; 314 return ret_len;
315 315
316 radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band); 316 radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
317 sband = priv->wdev->wiphy->bands[radio_type]; 317 sband = priv->wdev.wiphy->bands[radio_type];
318 318
319 if (bss_desc->bcn_ht_cap) { 319 if (bss_desc->bcn_ht_cap) {
320 ht_cap = (struct mwifiex_ie_types_htcap *) *buffer; 320 ht_cap = (struct mwifiex_ie_types_htcap *) *buffer;
@@ -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..a2e8817b56d8 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -45,7 +45,7 @@ static int mwifiex_11n_dispatch_amsdu_pkt(struct mwifiex_private *priv,
45 skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length)); 45 skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length));
46 46
47 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, 47 ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
48 priv->wdev->iftype, 0, false); 48 priv->wdev.iftype, 0, false);
49 49
50 while (!skb_queue_empty(&list)) { 50 while (!skb_queue_empty(&list)) {
51 rx_skb = __skb_dequeue(&list); 51 rx_skb = __skb_dequeue(&list);
@@ -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 4a66a6555366..41c8e25df954 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -590,77 +590,62 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
590 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 590 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
591 struct mwifiex_private *priv; 591 struct mwifiex_private *priv;
592 struct mwifiex_uap_bss_param *bss_cfg; 592 struct mwifiex_uap_bss_param *bss_cfg;
593 int ret, bss_started, i; 593 int ret;
594
595 for (i = 0; i < adapter->priv_num; i++) {
596 priv = adapter->priv[i];
597
598 switch (priv->bss_role) {
599 case MWIFIEX_BSS_ROLE_UAP:
600 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
601 GFP_KERNEL);
602 if (!bss_cfg)
603 return -ENOMEM;
604
605 mwifiex_set_sys_config_invalid_data(bss_cfg);
606
607 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
608 bss_cfg->rts_threshold = wiphy->rts_threshold;
609 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
610 bss_cfg->frag_threshold = wiphy->frag_threshold;
611 if (changed & WIPHY_PARAM_RETRY_LONG)
612 bss_cfg->retry_limit = wiphy->retry_long;
613
614 bss_started = priv->bss_started;
615
616 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
617 HostCmd_ACT_GEN_SET, 0,
618 NULL, true);
619 if (ret) {
620 wiphy_err(wiphy, "Failed to stop the BSS\n");
621 kfree(bss_cfg);
622 return ret;
623 }
624 594
625 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG, 595 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
626 HostCmd_ACT_GEN_SET,
627 UAP_BSS_PARAMS_I, bss_cfg,
628 false);
629 596
630 kfree(bss_cfg); 597 switch (priv->bss_role) {
598 case MWIFIEX_BSS_ROLE_UAP:
599 if (priv->bss_started) {
600 dev_err(adapter->dev,
601 "cannot change wiphy params when bss started");
602 return -EINVAL;
603 }
631 604
632 if (ret) { 605 bss_cfg = kzalloc(sizeof(*bss_cfg), GFP_KERNEL);
633 wiphy_err(wiphy, "Failed to set bss config\n"); 606 if (!bss_cfg)
634 return ret; 607 return -ENOMEM;
635 }
636 608
637 if (!bss_started) 609 mwifiex_set_sys_config_invalid_data(bss_cfg);
638 break;
639 610
640 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, 611 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
641 HostCmd_ACT_GEN_SET, 0, 612 bss_cfg->rts_threshold = wiphy->rts_threshold;
642 NULL, false); 613 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
643 if (ret) { 614 bss_cfg->frag_threshold = wiphy->frag_threshold;
644 wiphy_err(wiphy, "Failed to start BSS\n"); 615 if (changed & WIPHY_PARAM_RETRY_LONG)
645 return ret; 616 bss_cfg->retry_limit = wiphy->retry_long;
646 } 617
618 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
619 HostCmd_ACT_GEN_SET,
620 UAP_BSS_PARAMS_I, bss_cfg,
621 false);
622
623 kfree(bss_cfg);
624 if (ret) {
625 wiphy_err(wiphy, "Failed to set wiphy phy params\n");
626 return ret;
627 }
628 break;
647 629
648 break;
649 case MWIFIEX_BSS_ROLE_STA: 630 case MWIFIEX_BSS_ROLE_STA:
650 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 631 if (priv->media_connected) {
651 ret = mwifiex_set_rts(priv, 632 dev_err(adapter->dev,
652 wiphy->rts_threshold); 633 "cannot change wiphy params when connected");
653 if (ret) 634 return -EINVAL;
654 return ret;
655 }
656 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
657 ret = mwifiex_set_frag(priv,
658 wiphy->frag_threshold);
659 if (ret)
660 return ret;
661 }
662 break;
663 } 635 }
636 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
637 ret = mwifiex_set_rts(priv,
638 wiphy->rts_threshold);
639 if (ret)
640 return ret;
641 }
642 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
643 ret = mwifiex_set_frag(priv,
644 wiphy->frag_threshold);
645 if (ret)
646 return ret;
647 }
648 break;
664 } 649 }
665 650
666 return 0; 651 return 0;
@@ -671,9 +656,6 @@ mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
671{ 656{
672 u16 mode = P2P_MODE_DISABLE; 657 u16 mode = P2P_MODE_DISABLE;
673 658
674 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
675 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
676
677 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG, 659 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
678 HostCmd_ACT_GEN_SET, 0, &mode, true)) 660 HostCmd_ACT_GEN_SET, 0, &mode, true))
679 return -1; 661 return -1;
@@ -730,12 +712,249 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
730 HostCmd_ACT_GEN_SET, 0, &mode, true)) 712 HostCmd_ACT_GEN_SET, 0, &mode, true))
731 return -1; 713 return -1;
732 714
733 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 715 return 0;
734 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_UAP); 716}
717
718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
719{
720 priv->mgmt_frame_mask = 0;
721 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
722 HostCmd_ACT_GEN_SET, 0,
723 &priv->mgmt_frame_mask, false)) {
724 dev_warn(priv->adapter->dev,
725 "could not unregister mgmt frame rx\n");
726 return -1;
727 }
728
729 mwifiex_deauthenticate(priv, NULL);
730 mwifiex_free_priv(priv);
731 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
732 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
733 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
734
735 return 0;
736}
737
738static int
739mwifiex_init_new_priv_params(struct mwifiex_private *priv,
740 struct net_device *dev,
741 enum nl80211_iftype type)
742{
743 mwifiex_init_priv(priv);
744
745 priv->bss_mode = type;
746 priv->wdev.iftype = type;
747
748 mwifiex_init_priv_params(priv, priv->netdev);
749 priv->bss_started = 0;
750
751 switch (type) {
752 case NL80211_IFTYPE_STATION:
753 case NL80211_IFTYPE_ADHOC:
754 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
755 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
756 break;
757 case NL80211_IFTYPE_P2P_CLIENT:
758 case NL80211_IFTYPE_P2P_GO:
759 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
760 priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
761 break;
762 case NL80211_IFTYPE_AP:
763 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
764 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
765 break;
766 default:
767 dev_err(priv->adapter->dev,
768 "%s: changing to %d not supported\n",
769 dev->name, type);
770 return -EOPNOTSUPP;
771 }
735 772
736 return 0; 773 return 0;
737} 774}
738 775
776static int
777mwifiex_change_vif_to_p2p(struct net_device *dev,
778 enum nl80211_iftype curr_iftype,
779 enum nl80211_iftype type, u32 *flags,
780 struct vif_params *params)
781{
782 struct mwifiex_private *priv;
783 struct mwifiex_adapter *adapter;
784
785 priv = mwifiex_netdev_get_priv(dev);
786
787 if (!priv)
788 return -1;
789
790 adapter = priv->adapter;
791
792 if (adapter->curr_iface_comb.p2p_intf ==
793 adapter->iface_limit.p2p_intf) {
794 dev_err(adapter->dev,
795 "cannot create multiple P2P ifaces\n");
796 return -1;
797 }
798
799 dev_dbg(priv->adapter->dev, "%s: changing role to p2p\n", dev->name);
800
801 if (mwifiex_deinit_priv_params(priv))
802 return -1;
803 if (mwifiex_init_new_priv_params(priv, dev, type))
804 return -1;
805
806 switch (type) {
807 case NL80211_IFTYPE_P2P_CLIENT:
808 if (mwifiex_cfg80211_init_p2p_client(priv))
809 return -EFAULT;
810 break;
811 case NL80211_IFTYPE_P2P_GO:
812 if (mwifiex_cfg80211_init_p2p_go(priv))
813 return -EFAULT;
814 break;
815 default:
816 dev_err(priv->adapter->dev,
817 "%s: changing to %d not supported\n",
818 dev->name, type);
819 return -EOPNOTSUPP;
820 }
821
822 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
823 HostCmd_ACT_GEN_SET, 0, NULL, true))
824 return -1;
825
826 if (mwifiex_sta_init_cmd(priv, false, false))
827 return -1;
828
829 switch (curr_iftype) {
830 case NL80211_IFTYPE_STATION:
831 case NL80211_IFTYPE_ADHOC:
832 adapter->curr_iface_comb.sta_intf--;
833 break;
834 case NL80211_IFTYPE_AP:
835 adapter->curr_iface_comb.uap_intf--;
836 break;
837 default:
838 break;
839 }
840
841 adapter->curr_iface_comb.p2p_intf++;
842 dev->ieee80211_ptr->iftype = type;
843
844 return 0;
845}
846
847static int
848mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
849 enum nl80211_iftype curr_iftype,
850 enum nl80211_iftype type, u32 *flags,
851 struct vif_params *params)
852{
853 struct mwifiex_private *priv;
854 struct mwifiex_adapter *adapter;
855
856 priv = mwifiex_netdev_get_priv(dev);
857
858 if (!priv)
859 return -1;
860
861 adapter = priv->adapter;
862
863 if ((curr_iftype != NL80211_IFTYPE_P2P_CLIENT &&
864 curr_iftype != NL80211_IFTYPE_P2P_GO) &&
865 (adapter->curr_iface_comb.sta_intf ==
866 adapter->iface_limit.sta_intf)) {
867 dev_err(adapter->dev,
868 "cannot create multiple station/adhoc ifaces\n");
869 return -1;
870 }
871
872 if (type == NL80211_IFTYPE_STATION)
873 dev_notice(adapter->dev,
874 "%s: changing role to station\n", dev->name);
875 else
876 dev_notice(adapter->dev,
877 "%s: changing role to adhoc\n", dev->name);
878
879 if (mwifiex_deinit_priv_params(priv))
880 return -1;
881 if (mwifiex_init_new_priv_params(priv, dev, type))
882 return -1;
883 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
884 HostCmd_ACT_GEN_SET, 0, NULL, true))
885 return -1;
886 if (mwifiex_sta_init_cmd(priv, false, false))
887 return -1;
888
889 switch (curr_iftype) {
890 case NL80211_IFTYPE_P2P_CLIENT:
891 case NL80211_IFTYPE_P2P_GO:
892 adapter->curr_iface_comb.p2p_intf--;
893 break;
894 case NL80211_IFTYPE_AP:
895 adapter->curr_iface_comb.uap_intf--;
896 break;
897 default:
898 break;
899 }
900
901 adapter->curr_iface_comb.sta_intf++;
902 dev->ieee80211_ptr->iftype = type;
903 return 0;
904}
905
906static int
907mwifiex_change_vif_to_ap(struct net_device *dev,
908 enum nl80211_iftype curr_iftype,
909 enum nl80211_iftype type, u32 *flags,
910 struct vif_params *params)
911{
912 struct mwifiex_private *priv;
913 struct mwifiex_adapter *adapter;
914
915 priv = mwifiex_netdev_get_priv(dev);
916
917 if (!priv)
918 return -1;
919
920 adapter = priv->adapter;
921
922 if (adapter->curr_iface_comb.uap_intf ==
923 adapter->iface_limit.uap_intf) {
924 dev_err(adapter->dev,
925 "cannot create multiple AP ifaces\n");
926 return -1;
927 }
928
929 dev_notice(adapter->dev, "%s: changing role to AP\n", dev->name);
930
931 if (mwifiex_deinit_priv_params(priv))
932 return -1;
933 if (mwifiex_init_new_priv_params(priv, dev, type))
934 return -1;
935 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
936 HostCmd_ACT_GEN_SET, 0, NULL, true))
937 return -1;
938 if (mwifiex_sta_init_cmd(priv, false, false))
939 return -1;
940
941 switch (curr_iftype) {
942 case NL80211_IFTYPE_P2P_CLIENT:
943 case NL80211_IFTYPE_P2P_GO:
944 adapter->curr_iface_comb.p2p_intf--;
945 break;
946 case NL80211_IFTYPE_STATION:
947 case NL80211_IFTYPE_ADHOC:
948 adapter->curr_iface_comb.sta_intf--;
949 break;
950 default:
951 break;
952 }
953
954 adapter->curr_iface_comb.uap_intf++;
955 dev->ieee80211_ptr->iftype = type;
956 return 0;
957}
739/* 958/*
740 * CFG802.11 operation handler to change interface type. 959 * CFG802.11 operation handler to change interface type.
741 */ 960 */
@@ -745,19 +964,32 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
745 enum nl80211_iftype type, u32 *flags, 964 enum nl80211_iftype type, u32 *flags,
746 struct vif_params *params) 965 struct vif_params *params)
747{ 966{
748 int ret;
749 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 967 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
968 enum nl80211_iftype curr_iftype = dev->ieee80211_ptr->iftype;
750 969
751 switch (dev->ieee80211_ptr->iftype) { 970 switch (curr_iftype) {
752 case NL80211_IFTYPE_ADHOC: 971 case NL80211_IFTYPE_ADHOC:
753 switch (type) { 972 switch (type) {
754 case NL80211_IFTYPE_STATION: 973 case NL80211_IFTYPE_STATION:
755 break; 974 priv->bss_mode = type;
975 priv->sec_info.authentication_mode =
976 NL80211_AUTHTYPE_OPEN_SYSTEM;
977 dev->ieee80211_ptr->iftype = type;
978 mwifiex_deauthenticate(priv, NULL);
979 return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
980 HostCmd_ACT_GEN_SET, 0, NULL,
981 true);
982 case NL80211_IFTYPE_P2P_CLIENT:
983 case NL80211_IFTYPE_P2P_GO:
984 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
985 type, flags, params);
986 case NL80211_IFTYPE_AP:
987 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
988 flags, params);
756 case NL80211_IFTYPE_UNSPECIFIED: 989 case NL80211_IFTYPE_UNSPECIFIED:
757 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name); 990 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
758 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */ 991 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
759 return 0; 992 return 0;
760 case NL80211_IFTYPE_AP:
761 default: 993 default:
762 wiphy_err(wiphy, "%s: changing to %d not supported\n", 994 wiphy_err(wiphy, "%s: changing to %d not supported\n",
763 dev->name, type); 995 dev->name, type);
@@ -767,22 +999,25 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
767 case NL80211_IFTYPE_STATION: 999 case NL80211_IFTYPE_STATION:
768 switch (type) { 1000 switch (type) {
769 case NL80211_IFTYPE_ADHOC: 1001 case NL80211_IFTYPE_ADHOC:
770 break; 1002 priv->bss_mode = type;
771 case NL80211_IFTYPE_P2P_CLIENT: 1003 priv->sec_info.authentication_mode =
772 if (mwifiex_cfg80211_init_p2p_client(priv)) 1004 NL80211_AUTHTYPE_OPEN_SYSTEM;
773 return -EFAULT;
774 dev->ieee80211_ptr->iftype = type; 1005 dev->ieee80211_ptr->iftype = type;
775 return 0; 1006 mwifiex_deauthenticate(priv, NULL);
1007 return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1008 HostCmd_ACT_GEN_SET, 0, NULL,
1009 true);
1010 case NL80211_IFTYPE_P2P_CLIENT:
776 case NL80211_IFTYPE_P2P_GO: 1011 case NL80211_IFTYPE_P2P_GO:
777 if (mwifiex_cfg80211_init_p2p_go(priv)) 1012 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
778 return -EFAULT; 1013 type, flags, params);
779 dev->ieee80211_ptr->iftype = type; 1014 case NL80211_IFTYPE_AP:
780 return 0; 1015 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1016 flags, params);
781 case NL80211_IFTYPE_UNSPECIFIED: 1017 case NL80211_IFTYPE_UNSPECIFIED:
782 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); 1018 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
783 case NL80211_IFTYPE_STATION: /* This shouldn't happen */ 1019 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
784 return 0; 1020 return 0;
785 case NL80211_IFTYPE_AP:
786 default: 1021 default:
787 wiphy_err(wiphy, "%s: changing to %d not supported\n", 1022 wiphy_err(wiphy, "%s: changing to %d not supported\n",
788 dev->name, type); 1023 dev->name, type);
@@ -791,12 +1026,20 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
791 break; 1026 break;
792 case NL80211_IFTYPE_AP: 1027 case NL80211_IFTYPE_AP:
793 switch (type) { 1028 switch (type) {
1029 case NL80211_IFTYPE_ADHOC:
1030 case NL80211_IFTYPE_STATION:
1031 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1032 type, flags,
1033 params);
1034 break;
1035 case NL80211_IFTYPE_P2P_CLIENT:
1036 case NL80211_IFTYPE_P2P_GO:
1037 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
1038 type, flags, params);
794 case NL80211_IFTYPE_UNSPECIFIED: 1039 case NL80211_IFTYPE_UNSPECIFIED:
795 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name); 1040 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
796 case NL80211_IFTYPE_AP: /* This shouldn't happen */ 1041 case NL80211_IFTYPE_AP: /* This shouldn't happen */
797 return 0; 1042 return 0;
798 case NL80211_IFTYPE_ADHOC:
799 case NL80211_IFTYPE_STATION:
800 default: 1043 default:
801 wiphy_err(wiphy, "%s: changing to %d not supported\n", 1044 wiphy_err(wiphy, "%s: changing to %d not supported\n",
802 dev->name, type); 1045 dev->name, type);
@@ -807,11 +1050,30 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
807 case NL80211_IFTYPE_P2P_GO: 1050 case NL80211_IFTYPE_P2P_GO:
808 switch (type) { 1051 switch (type) {
809 case NL80211_IFTYPE_STATION: 1052 case NL80211_IFTYPE_STATION:
810 if (mwifiex_cfg80211_deinit_p2p(priv)) 1053 if (mwifiex_cfg80211_init_p2p_client(priv))
811 return -EFAULT; 1054 return -EFAULT;
812 dev->ieee80211_ptr->iftype = type; 1055 dev->ieee80211_ptr->iftype = type;
1056 break;
1057 case NL80211_IFTYPE_ADHOC:
1058 if (mwifiex_cfg80211_deinit_p2p(priv))
1059 return -EFAULT;
1060 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1061 type, flags,
1062 params);
1063 break;
1064 case NL80211_IFTYPE_AP:
1065 if (mwifiex_cfg80211_deinit_p2p(priv))
1066 return -EFAULT;
1067 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1068 flags, params);
1069 case NL80211_IFTYPE_UNSPECIFIED:
1070 wiphy_warn(wiphy, "%s: kept type as P2P\n", dev->name);
1071 case NL80211_IFTYPE_P2P_CLIENT:
1072 case NL80211_IFTYPE_P2P_GO:
813 return 0; 1073 return 0;
814 default: 1074 default:
1075 wiphy_err(wiphy, "%s: changing to %d not supported\n",
1076 dev->name, type);
815 return -EOPNOTSUPP; 1077 return -EOPNOTSUPP;
816 } 1078 }
817 break; 1079 break;
@@ -821,16 +1083,8 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
821 return -EOPNOTSUPP; 1083 return -EOPNOTSUPP;
822 } 1084 }
823 1085
824 dev->ieee80211_ptr->iftype = type;
825 priv->bss_mode = type;
826 mwifiex_deauthenticate(priv, NULL);
827
828 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
829
830 ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
831 HostCmd_ACT_GEN_SET, 0, NULL, true);
832 1086
833 return ret; 1087 return 0;
834} 1088}
835 1089
836static void 1090static void
@@ -856,16 +1110,16 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
856 /* HT or VHT */ 1110 /* HT or VHT */
857 switch (tx_htinfo & (BIT(3) | BIT(2))) { 1111 switch (tx_htinfo & (BIT(3) | BIT(2))) {
858 case 0: 1112 case 0:
859 /* This will be 20MHz */ 1113 rate->bw = RATE_INFO_BW_20;
860 break; 1114 break;
861 case (BIT(2)): 1115 case (BIT(2)):
862 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 1116 rate->bw = RATE_INFO_BW_40;
863 break; 1117 break;
864 case (BIT(3)): 1118 case (BIT(3)):
865 rate->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH; 1119 rate->bw = RATE_INFO_BW_80;
866 break; 1120 break;
867 case (BIT(3) | BIT(2)): 1121 case (BIT(3) | BIT(2)):
868 rate->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; 1122 rate->bw = RATE_INFO_BW_160;
869 break; 1123 break;
870 } 1124 }
871 1125
@@ -885,8 +1139,9 @@ mwifiex_parse_htinfo(struct mwifiex_private *priv, u8 tx_htinfo,
885 if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { 1139 if ((tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) {
886 rate->mcs = priv->tx_rate; 1140 rate->mcs = priv->tx_rate;
887 rate->flags |= RATE_INFO_FLAGS_MCS; 1141 rate->flags |= RATE_INFO_FLAGS_MCS;
1142 rate->bw = RATE_INFO_BW_20;
888 if (tx_htinfo & BIT(1)) 1143 if (tx_htinfo & BIT(1))
889 rate->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; 1144 rate->bw = RATE_INFO_BW_40;
890 if (tx_htinfo & BIT(2)) 1145 if (tx_htinfo & BIT(2))
891 rate->flags |= RATE_INFO_FLAGS_SHORT_GI; 1146 rate->flags |= RATE_INFO_FLAGS_SHORT_GI;
892 } 1147 }
@@ -910,10 +1165,10 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
910{ 1165{
911 u32 rate; 1166 u32 rate;
912 1167
913 sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | 1168 sinfo->filled = BIT(NL80211_STA_INFO_RX_BYTES) | BIT(NL80211_STA_INFO_TX_BYTES) |
914 STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | 1169 BIT(NL80211_STA_INFO_RX_PACKETS) | BIT(NL80211_STA_INFO_TX_PACKETS) |
915 STATION_INFO_TX_BITRATE | 1170 BIT(NL80211_STA_INFO_TX_BITRATE) |
916 STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; 1171 BIT(NL80211_STA_INFO_SIGNAL) | BIT(NL80211_STA_INFO_SIGNAL_AVG);
917 1172
918 /* Get signal information from the firmware */ 1173 /* Get signal information from the firmware */
919 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, 1174 if (mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO,
@@ -944,7 +1199,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
944 sinfo->txrate.legacy = rate * 5; 1199 sinfo->txrate.legacy = rate * 5;
945 1200
946 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 1201 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
947 sinfo->filled |= STATION_INFO_BSS_PARAM; 1202 sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
948 sinfo->bss_param.flags = 0; 1203 sinfo->bss_param.flags = 0;
949 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & 1204 if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap &
950 WLAN_CAPABILITY_SHORT_PREAMBLE) 1205 WLAN_CAPABILITY_SHORT_PREAMBLE)
@@ -1037,10 +1292,11 @@ mwifiex_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
1037 survey->channel = ieee80211_get_channel(wiphy, 1292 survey->channel = ieee80211_get_channel(wiphy,
1038 ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band)); 1293 ieee80211_channel_to_frequency(pchan_stats[idx].chan_num, band));
1039 survey->filled = SURVEY_INFO_NOISE_DBM | 1294 survey->filled = SURVEY_INFO_NOISE_DBM |
1040 SURVEY_INFO_CHANNEL_TIME | SURVEY_INFO_CHANNEL_TIME_BUSY; 1295 SURVEY_INFO_TIME |
1296 SURVEY_INFO_TIME_BUSY;
1041 survey->noise = pchan_stats[idx].noise; 1297 survey->noise = pchan_stats[idx].noise;
1042 survey->channel_time = pchan_stats[idx].cca_scan_dur; 1298 survey->time = pchan_stats[idx].cca_scan_dur;
1043 survey->channel_time_busy = pchan_stats[idx].cca_busy_dur; 1299 survey->time_busy = pchan_stats[idx].cca_busy_dur;
1044 1300
1045 return 0; 1301 return 0;
1046} 1302}
@@ -1395,10 +1651,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1395{ 1651{
1396 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1652 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1397 1653
1654 mwifiex_abort_cac(priv);
1655
1398 if (mwifiex_del_mgmt_ies(priv)) 1656 if (mwifiex_del_mgmt_ies(priv))
1399 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n"); 1657 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
1400 1658
1401 priv->ap_11n_enabled = 0; 1659 priv->ap_11n_enabled = 0;
1660 memset(&priv->bss_cfg, 0, sizeof(priv->bss_cfg));
1402 1661
1403 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, 1662 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1404 HostCmd_ACT_GEN_SET, 0, NULL, true)) { 1663 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
@@ -1420,12 +1679,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1420{ 1679{
1421 struct mwifiex_uap_bss_param *bss_cfg; 1680 struct mwifiex_uap_bss_param *bss_cfg;
1422 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1681 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1423 u8 config_bands = 0;
1424 1682
1425 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 1683 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
1426 return -1; 1684 return -1;
1427 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1428 return -1;
1429 1685
1430 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); 1686 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
1431 if (!bss_cfg) 1687 if (!bss_cfg)
@@ -1442,6 +1698,11 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1442 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len); 1698 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
1443 bss_cfg->ssid.ssid_len = params->ssid_len; 1699 bss_cfg->ssid.ssid_len = params->ssid_len;
1444 } 1700 }
1701 if (params->inactivity_timeout > 0) {
1702 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
1703 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout;
1704 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1705 }
1445 1706
1446 switch (params->hidden_ssid) { 1707 switch (params->hidden_ssid) {
1447 case NL80211_HIDDEN_SSID_NOT_IN_USE: 1708 case NL80211_HIDDEN_SSID_NOT_IN_USE:
@@ -1457,33 +1718,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1457 return -EINVAL; 1718 return -EINVAL;
1458 } 1719 }
1459 1720
1460 bss_cfg->channel = ieee80211_frequency_to_channel( 1721 mwifiex_uap_set_channel(bss_cfg, params->chandef);
1461 params->chandef.chan->center_freq);
1462
1463 /* Set appropriate bands */
1464 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1465 bss_cfg->band_cfg = BAND_CONFIG_BG;
1466 config_bands = BAND_B | BAND_G;
1467
1468 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1469 config_bands |= BAND_GN;
1470 } else {
1471 bss_cfg->band_cfg = BAND_CONFIG_A;
1472 config_bands = BAND_A;
1473
1474 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1475 config_bands |= BAND_AN;
1476
1477 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1478 config_bands |= BAND_AAC;
1479 }
1480
1481 if (!((config_bands | priv->adapter->fw_bands) &
1482 ~priv->adapter->fw_bands))
1483 priv->adapter->config_bands = config_bands;
1484
1485 mwifiex_set_uap_rates(bss_cfg, params); 1722 mwifiex_set_uap_rates(bss_cfg, params);
1486 mwifiex_send_domain_info_cmd_fw(wiphy);
1487 1723
1488 if (mwifiex_set_secure_params(priv, bss_cfg, params)) { 1724 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
1489 kfree(bss_cfg); 1725 kfree(bss_cfg);
@@ -1506,45 +1742,29 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1506 1742
1507 mwifiex_set_wmm_params(priv, bss_cfg, params); 1743 mwifiex_set_wmm_params(priv, bss_cfg, params);
1508 1744
1509 if (params->inactivity_timeout > 0) { 1745 if (mwifiex_is_11h_active(priv) &&
1510 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */ 1746 !cfg80211_chandef_dfs_required(wiphy, &params->chandef,
1511 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout; 1747 priv->bss_mode)) {
1512 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout; 1748 dev_dbg(priv->adapter->dev, "Disable 11h extensions in FW\n");
1749 if (mwifiex_11h_activate(priv, false)) {
1750 dev_err(priv->adapter->dev,
1751 "Failed to disable 11h extensions!!");
1752 return -1;
1753 }
1754 priv->state_11h.is_11h_active = true;
1513 } 1755 }
1514 1756
1515 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, 1757 if (mwifiex_config_start_uap(priv, bss_cfg)) {
1516 HostCmd_ACT_GEN_SET, 0, NULL, true)) { 1758 wiphy_err(wiphy, "Failed to start AP\n");
1517 wiphy_err(wiphy, "Failed to stop the BSS\n");
1518 kfree(bss_cfg); 1759 kfree(bss_cfg);
1519 return -1; 1760 return -1;
1520 } 1761 }
1521 1762
1522 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG, 1763 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1523 HostCmd_ACT_GEN_SET,
1524 UAP_BSS_PARAMS_I, bss_cfg, false)) {
1525 wiphy_err(wiphy, "Failed to set the SSID\n");
1526 kfree(bss_cfg);
1527 return -1; 1764 return -1;
1528 }
1529 1765
1766 memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg));
1530 kfree(bss_cfg); 1767 kfree(bss_cfg);
1531
1532 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
1533 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
1534 wiphy_err(wiphy, "Failed to start the BSS\n");
1535 return -1;
1536 }
1537
1538 if (priv->sec_info.wep_enabled)
1539 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
1540 else
1541 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1542
1543 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1544 HostCmd_ACT_GEN_SET, 0,
1545 &priv->curr_pkt_filter, true))
1546 return -1;
1547
1548 return 0; 1768 return 0;
1549} 1769}
1550 1770
@@ -1603,15 +1823,15 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1603 ie_len = ie_buf[1] + sizeof(struct ieee_types_header); 1823 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
1604 1824
1605 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 1825 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1606 chan = __ieee80211_get_channel(priv->wdev->wiphy, 1826 chan = __ieee80211_get_channel(priv->wdev.wiphy,
1607 ieee80211_channel_to_frequency(bss_info.bss_chan, 1827 ieee80211_channel_to_frequency(bss_info.bss_chan,
1608 band)); 1828 band));
1609 1829
1610 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, 1830 bss = cfg80211_inform_bss(priv->wdev.wiphy, chan,
1611 CFG80211_BSS_FTYPE_UNKNOWN, 1831 CFG80211_BSS_FTYPE_UNKNOWN,
1612 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 1832 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
1613 0, ie_buf, ie_len, 0, GFP_KERNEL); 1833 0, ie_buf, ie_len, 0, GFP_KERNEL);
1614 cfg80211_put_bss(priv->wdev->wiphy, bss); 1834 cfg80211_put_bss(priv->wdev.wiphy, bss);
1615 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); 1835 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
1616 1836
1617 return 0; 1837 return 0;
@@ -1732,12 +1952,12 @@ done:
1732 1952
1733 /* Find the BSS we want using available scan results */ 1953 /* Find the BSS we want using available scan results */
1734 if (mode == NL80211_IFTYPE_ADHOC) 1954 if (mode == NL80211_IFTYPE_ADHOC)
1735 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 1955 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1736 bssid, ssid, ssid_len, 1956 bssid, ssid, ssid_len,
1737 WLAN_CAPABILITY_IBSS, 1957 WLAN_CAPABILITY_IBSS,
1738 WLAN_CAPABILITY_IBSS); 1958 WLAN_CAPABILITY_IBSS);
1739 else 1959 else
1740 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 1960 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1741 bssid, ssid, ssid_len, 1961 bssid, ssid, ssid_len,
1742 WLAN_CAPABILITY_ESS, 1962 WLAN_CAPABILITY_ESS,
1743 WLAN_CAPABILITY_ESS); 1963 WLAN_CAPABILITY_ESS);
@@ -1784,6 +2004,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1784 struct cfg80211_connect_params *sme) 2004 struct cfg80211_connect_params *sme)
1785{ 2005{
1786 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 2006 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2007 struct mwifiex_adapter *adapter = priv->adapter;
1787 int ret; 2008 int ret;
1788 2009
1789 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) { 2010 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA) {
@@ -1793,11 +2014,18 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1793 return -EINVAL; 2014 return -EINVAL;
1794 } 2015 }
1795 2016
1796 if (priv->wdev && priv->wdev->current_bss) { 2017 if (priv->wdev.current_bss) {
1797 wiphy_warn(wiphy, "%s: already connected\n", dev->name); 2018 wiphy_warn(wiphy, "%s: already connected\n", dev->name);
1798 return -EALREADY; 2019 return -EALREADY;
1799 } 2020 }
1800 2021
2022 if (adapter->surprise_removed || adapter->is_cmd_timedout) {
2023 wiphy_err(wiphy,
2024 "%s: Ignore connection. Card removed or FW in bad state\n",
2025 dev->name);
2026 return -EFAULT;
2027 }
2028
1801 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 2029 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
1802 (char *) sme->ssid, sme->bssid); 2030 (char *) sme->ssid, sme->bssid);
1803 2031
@@ -1844,7 +2072,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1844static int mwifiex_set_ibss_params(struct mwifiex_private *priv, 2072static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1845 struct cfg80211_ibss_params *params) 2073 struct cfg80211_ibss_params *params)
1846{ 2074{
1847 struct wiphy *wiphy = priv->wdev->wiphy; 2075 struct wiphy *wiphy = priv->wdev.wiphy;
1848 struct mwifiex_adapter *adapter = priv->adapter; 2076 struct mwifiex_adapter *adapter = priv->adapter;
1849 int index = 0, i; 2077 int index = 0, i;
1850 u8 config_bands = 0; 2078 u8 config_bands = 0;
@@ -2169,6 +2397,7 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2169 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2170} 2398}
2171 2399
2400#define MWIFIEX_MAX_WQ_LEN 30
2172/* 2401/*
2173 * create a new virtual interface with the given name 2402 * create a new virtual interface with the given name
2174 */ 2403 */
@@ -2182,7 +2411,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2182 struct mwifiex_private *priv; 2411 struct mwifiex_private *priv;
2183 struct net_device *dev; 2412 struct net_device *dev;
2184 void *mdev_priv; 2413 void *mdev_priv;
2185 struct wireless_dev *wdev; 2414 char dfs_cac_str[MWIFIEX_MAX_WQ_LEN], dfs_chsw_str[MWIFIEX_MAX_WQ_LEN];
2186 2415
2187 if (!adapter) 2416 if (!adapter)
2188 return ERR_PTR(-EFAULT); 2417 return ERR_PTR(-EFAULT);
@@ -2191,20 +2420,22 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2191 case NL80211_IFTYPE_UNSPECIFIED: 2420 case NL80211_IFTYPE_UNSPECIFIED:
2192 case NL80211_IFTYPE_STATION: 2421 case NL80211_IFTYPE_STATION:
2193 case NL80211_IFTYPE_ADHOC: 2422 case NL80211_IFTYPE_ADHOC:
2194 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; 2423 if (adapter->curr_iface_comb.sta_intf ==
2195 if (priv->bss_mode) { 2424 adapter->iface_limit.sta_intf) {
2196 wiphy_err(wiphy, 2425 wiphy_err(wiphy,
2197 "cannot create multiple sta/adhoc ifaces\n"); 2426 "cannot create multiple sta/adhoc ifaces\n");
2198 return ERR_PTR(-EINVAL); 2427 return ERR_PTR(-EINVAL);
2199 } 2428 }
2200 2429
2201 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2430 priv = mwifiex_get_unused_priv(adapter);
2202 if (!wdev) 2431 if (!priv) {
2203 return ERR_PTR(-ENOMEM); 2432 wiphy_err(wiphy,
2433 "could not get free private struct\n");
2434 return ERR_PTR(-EFAULT);
2435 }
2204 2436
2205 wdev->wiphy = wiphy; 2437 priv->wdev.wiphy = wiphy;
2206 priv->wdev = wdev; 2438 priv->wdev.iftype = NL80211_IFTYPE_STATION;
2207 wdev->iftype = NL80211_IFTYPE_STATION;
2208 2439
2209 if (type == NL80211_IFTYPE_UNSPECIFIED) 2440 if (type == NL80211_IFTYPE_UNSPECIFIED)
2210 priv->bss_mode = NL80211_IFTYPE_STATION; 2441 priv->bss_mode = NL80211_IFTYPE_STATION;
@@ -2219,20 +2450,22 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2219 2450
2220 break; 2451 break;
2221 case NL80211_IFTYPE_AP: 2452 case NL80211_IFTYPE_AP:
2222 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; 2453 if (adapter->curr_iface_comb.uap_intf ==
2223 2454 adapter->iface_limit.uap_intf) {
2224 if (priv->bss_mode) { 2455 wiphy_err(wiphy,
2225 wiphy_err(wiphy, "Can't create multiple AP interfaces"); 2456 "cannot create multiple AP ifaces\n");
2226 return ERR_PTR(-EINVAL); 2457 return ERR_PTR(-EINVAL);
2227 } 2458 }
2228 2459
2229 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2460 priv = mwifiex_get_unused_priv(adapter);
2230 if (!wdev) 2461 if (!priv) {
2231 return ERR_PTR(-ENOMEM); 2462 wiphy_err(wiphy,
2463 "could not get free private struct\n");
2464 return ERR_PTR(-EFAULT);
2465 }
2232 2466
2233 priv->wdev = wdev; 2467 priv->wdev.wiphy = wiphy;
2234 wdev->wiphy = wiphy; 2468 priv->wdev.iftype = NL80211_IFTYPE_AP;
2235 wdev->iftype = NL80211_IFTYPE_AP;
2236 2469
2237 priv->bss_type = MWIFIEX_BSS_TYPE_UAP; 2470 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
2238 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 2471 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
@@ -2244,24 +2477,25 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2244 2477
2245 break; 2478 break;
2246 case NL80211_IFTYPE_P2P_CLIENT: 2479 case NL80211_IFTYPE_P2P_CLIENT:
2247 priv = adapter->priv[MWIFIEX_BSS_TYPE_P2P]; 2480 if (adapter->curr_iface_comb.p2p_intf ==
2248 2481 adapter->iface_limit.p2p_intf) {
2249 if (priv->bss_mode) { 2482 wiphy_err(wiphy,
2250 wiphy_err(wiphy, "Can't create multiple P2P ifaces"); 2483 "cannot create multiple P2P ifaces\n");
2251 return ERR_PTR(-EINVAL); 2484 return ERR_PTR(-EINVAL);
2252 } 2485 }
2253 2486
2254 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2487 priv = mwifiex_get_unused_priv(adapter);
2255 if (!wdev) 2488 if (!priv) {
2256 return ERR_PTR(-ENOMEM); 2489 wiphy_err(wiphy,
2257 2490 "could not get free private struct\n");
2258 priv->wdev = wdev; 2491 return ERR_PTR(-EFAULT);
2259 wdev->wiphy = wiphy; 2492 }
2260 2493
2494 priv->wdev.wiphy = wiphy;
2261 /* At start-up, wpa_supplicant tries to change the interface 2495 /* At start-up, wpa_supplicant tries to change the interface
2262 * to NL80211_IFTYPE_STATION if it is not managed mode. 2496 * to NL80211_IFTYPE_STATION if it is not managed mode.
2263 */ 2497 */
2264 wdev->iftype = NL80211_IFTYPE_P2P_CLIENT; 2498 priv->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
2265 priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT; 2499 priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT;
2266 2500
2267 /* Setting bss_type to P2P tells firmware that this interface 2501 /* Setting bss_type to P2P tells firmware that this interface
@@ -2277,8 +2511,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2277 priv->bss_num = 0; 2511 priv->bss_num = 0;
2278 2512
2279 if (mwifiex_cfg80211_init_p2p_client(priv)) { 2513 if (mwifiex_cfg80211_init_p2p_client(priv)) {
2280 wdev = ERR_PTR(-EFAULT); 2514 memset(&priv->wdev, 0, sizeof(priv->wdev));
2281 goto done; 2515 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2516 return ERR_PTR(-EFAULT);
2282 } 2517 }
2283 2518
2284 break; 2519 break;
@@ -2292,9 +2527,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2292 IEEE80211_NUM_ACS, 1); 2527 IEEE80211_NUM_ACS, 1);
2293 if (!dev) { 2528 if (!dev) {
2294 wiphy_err(wiphy, "no memory available for netdevice\n"); 2529 wiphy_err(wiphy, "no memory available for netdevice\n");
2530 memset(&priv->wdev, 0, sizeof(priv->wdev));
2531 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2295 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2532 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2296 wdev = ERR_PTR(-ENOMEM); 2533 return ERR_PTR(-ENOMEM);
2297 goto done;
2298 } 2534 }
2299 2535
2300 mwifiex_init_priv_params(priv, dev); 2536 mwifiex_init_priv_params(priv, dev);
@@ -2314,7 +2550,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2314 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv); 2550 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
2315 2551
2316 dev_net_set(dev, wiphy_net(wiphy)); 2552 dev_net_set(dev, wiphy_net(wiphy));
2317 dev->ieee80211_ptr = priv->wdev; 2553 dev->ieee80211_ptr = &priv->wdev;
2318 dev->ieee80211_ptr->iftype = priv->bss_mode; 2554 dev->ieee80211_ptr->iftype = priv->bss_mode;
2319 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN); 2555 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
2320 SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); 2556 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
@@ -2335,10 +2571,47 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2335 free_netdev(dev); 2571 free_netdev(dev);
2336 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2572 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2337 priv->netdev = NULL; 2573 priv->netdev = NULL;
2338 wdev = ERR_PTR(-EFAULT); 2574 memset(&priv->wdev, 0, sizeof(priv->wdev));
2339 goto done; 2575 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2576 return ERR_PTR(-EFAULT);
2577 }
2578
2579 strcpy(dfs_cac_str, "MWIFIEX_DFS_CAC");
2580 strcat(dfs_cac_str, name);
2581 priv->dfs_cac_workqueue = alloc_workqueue(dfs_cac_str,
2582 WQ_HIGHPRI |
2583 WQ_MEM_RECLAIM |
2584 WQ_UNBOUND, 1);
2585 if (!priv->dfs_cac_workqueue) {
2586 wiphy_err(wiphy, "cannot register virtual network device\n");
2587 free_netdev(dev);
2588 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2589 priv->netdev = NULL;
2590 memset(&priv->wdev, 0, sizeof(priv->wdev));
2591 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2592 return ERR_PTR(-ENOMEM);
2340 } 2593 }
2341 2594
2595 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
2596
2597 strcpy(dfs_chsw_str, "MWIFIEX_DFS_CHSW");
2598 strcat(dfs_chsw_str, name);
2599 priv->dfs_chan_sw_workqueue = alloc_workqueue(dfs_chsw_str,
2600 WQ_HIGHPRI | WQ_UNBOUND |
2601 WQ_MEM_RECLAIM, 1);
2602 if (!priv->dfs_chan_sw_workqueue) {
2603 wiphy_err(wiphy, "cannot register virtual network device\n");
2604 free_netdev(dev);
2605 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2606 priv->netdev = NULL;
2607 memset(&priv->wdev, 0, sizeof(priv->wdev));
2608 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2609 return ERR_PTR(-ENOMEM);
2610 }
2611
2612 INIT_DELAYED_WORK(&priv->dfs_chan_sw_work,
2613 mwifiex_dfs_chan_sw_work_queue);
2614
2342 sema_init(&priv->async_sem, 1); 2615 sema_init(&priv->async_sem, 1);
2343 2616
2344 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); 2617 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
@@ -2347,13 +2620,24 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2347 mwifiex_dev_debugfs_init(priv); 2620 mwifiex_dev_debugfs_init(priv);
2348#endif 2621#endif
2349 2622
2350done: 2623 switch (type) {
2351 if (IS_ERR(wdev)) { 2624 case NL80211_IFTYPE_UNSPECIFIED:
2352 kfree(priv->wdev); 2625 case NL80211_IFTYPE_STATION:
2353 priv->wdev = NULL; 2626 case NL80211_IFTYPE_ADHOC:
2627 adapter->curr_iface_comb.sta_intf++;
2628 break;
2629 case NL80211_IFTYPE_AP:
2630 adapter->curr_iface_comb.uap_intf++;
2631 break;
2632 case NL80211_IFTYPE_P2P_CLIENT:
2633 adapter->curr_iface_comb.p2p_intf++;
2634 break;
2635 default:
2636 wiphy_err(wiphy, "type not supported\n");
2637 return ERR_PTR(-EINVAL);
2354 } 2638 }
2355 2639
2356 return wdev; 2640 return &priv->wdev;
2357} 2641}
2358EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); 2642EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2359 2643
@@ -2363,12 +2647,13 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2363int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) 2647int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2364{ 2648{
2365 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 2649 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
2650 struct mwifiex_adapter *adapter = priv->adapter;
2366 2651
2367#ifdef CONFIG_DEBUG_FS 2652#ifdef CONFIG_DEBUG_FS
2368 mwifiex_dev_debugfs_remove(priv); 2653 mwifiex_dev_debugfs_remove(priv);
2369#endif 2654#endif
2370 2655
2371 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); 2656 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
2372 2657
2373 if (netif_carrier_ok(priv->netdev)) 2658 if (netif_carrier_ok(priv->netdev))
2374 netif_carrier_off(priv->netdev); 2659 netif_carrier_off(priv->netdev);
@@ -2376,16 +2661,48 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2376 if (wdev->netdev->reg_state == NETREG_REGISTERED) 2661 if (wdev->netdev->reg_state == NETREG_REGISTERED)
2377 unregister_netdevice(wdev->netdev); 2662 unregister_netdevice(wdev->netdev);
2378 2663
2664 if (priv->dfs_cac_workqueue) {
2665 flush_workqueue(priv->dfs_cac_workqueue);
2666 destroy_workqueue(priv->dfs_cac_workqueue);
2667 priv->dfs_cac_workqueue = NULL;
2668 }
2669
2670 if (priv->dfs_chan_sw_workqueue) {
2671 flush_workqueue(priv->dfs_chan_sw_workqueue);
2672 destroy_workqueue(priv->dfs_chan_sw_workqueue);
2673 priv->dfs_chan_sw_workqueue = NULL;
2674 }
2379 /* Clear the priv in adapter */ 2675 /* Clear the priv in adapter */
2380 priv->netdev->ieee80211_ptr = NULL; 2676 priv->netdev->ieee80211_ptr = NULL;
2381 priv->netdev = NULL; 2677 priv->netdev = NULL;
2382 kfree(wdev); 2678 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2383 priv->wdev = NULL;
2384 2679
2385 priv->media_connected = false; 2680 priv->media_connected = false;
2386 2681
2682 switch (priv->bss_mode) {
2683 case NL80211_IFTYPE_UNSPECIFIED:
2684 case NL80211_IFTYPE_STATION:
2685 case NL80211_IFTYPE_ADHOC:
2686 adapter->curr_iface_comb.sta_intf++;
2687 break;
2688 case NL80211_IFTYPE_AP:
2689 adapter->curr_iface_comb.uap_intf++;
2690 break;
2691 case NL80211_IFTYPE_P2P_CLIENT:
2692 case NL80211_IFTYPE_P2P_GO:
2693 adapter->curr_iface_comb.p2p_intf++;
2694 break;
2695 default:
2696 dev_err(adapter->dev, "del_virtual_intf: type not supported\n");
2697 break;
2698 }
2699
2387 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2700 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2388 2701
2702 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
2703 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP)
2704 kfree(priv->hist_data);
2705
2389 return 0; 2706 return 0;
2390} 2707}
2391EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf); 2708EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
@@ -2421,30 +2738,16 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
2421} 2738}
2422 2739
2423#ifdef CONFIG_PM 2740#ifdef CONFIG_PM
2424static int mwifiex_cfg80211_suspend(struct wiphy *wiphy, 2741static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2425 struct cfg80211_wowlan *wowlan) 2742 struct cfg80211_wowlan *wowlan)
2426{ 2743{
2427 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 2744 int i, filt_num = 0, ret = 0;
2428 struct mwifiex_ds_mef_cfg mef_cfg;
2429 struct mwifiex_mef_entry *mef_entry;
2430 int i, filt_num = 0, ret;
2431 bool first_pat = true; 2745 bool first_pat = true;
2432 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1]; 2746 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
2433 const u8 ipv4_mc_mac[] = {0x33, 0x33}; 2747 const u8 ipv4_mc_mac[] = {0x33, 0x33};
2434 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e}; 2748 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2435 struct mwifiex_private *priv = 2749 struct mwifiex_ds_mef_cfg mef_cfg;
2436 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 2750 struct mwifiex_mef_entry *mef_entry;
2437
2438 if (!wowlan) {
2439 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2440 return 0;
2441 }
2442
2443 if (!priv->media_connected) {
2444 dev_warn(adapter->dev,
2445 "Can not configure WOWLAN in disconnected state\n");
2446 return 0;
2447 }
2448 2751
2449 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL); 2752 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2450 if (!mef_entry) 2753 if (!mef_entry)
@@ -2459,9 +2762,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2459 for (i = 0; i < wowlan->n_patterns; i++) { 2762 for (i = 0; i < wowlan->n_patterns; i++) {
2460 memset(byte_seq, 0, sizeof(byte_seq)); 2763 memset(byte_seq, 0, sizeof(byte_seq));
2461 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i], 2764 if (!mwifiex_is_pattern_supported(&wowlan->patterns[i],
2462 byte_seq, 2765 byte_seq,
2463 MWIFIEX_MEF_MAX_BYTESEQ)) { 2766 MWIFIEX_MEF_MAX_BYTESEQ)) {
2464 wiphy_err(wiphy, "Pattern not supported\n"); 2767 dev_err(priv->adapter->dev, "Pattern not supported\n");
2465 kfree(mef_entry); 2768 kfree(mef_entry);
2466 return -EOPNOTSUPP; 2769 return -EOPNOTSUPP;
2467 } 2770 }
@@ -2485,9 +2788,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2485 2788
2486 mef_entry->filter[filt_num].repeat = 1; 2789 mef_entry->filter[filt_num].repeat = 1;
2487 mef_entry->filter[filt_num].offset = 2790 mef_entry->filter[filt_num].offset =
2488 wowlan->patterns[i].pkt_offset; 2791 wowlan->patterns[i].pkt_offset;
2489 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq, 2792 memcpy(mef_entry->filter[filt_num].byte_seq, byte_seq,
2490 sizeof(byte_seq)); 2793 sizeof(byte_seq));
2491 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2794 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2492 2795
2493 if (first_pat) 2796 if (first_pat)
@@ -2502,9 +2805,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2502 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2805 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST;
2503 mef_entry->filter[filt_num].repeat = 16; 2806 mef_entry->filter[filt_num].repeat = 16;
2504 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2807 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2505 ETH_ALEN); 2808 ETH_ALEN);
2506 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2809 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2507 ETH_ALEN; 2810 ETH_ALEN;
2508 mef_entry->filter[filt_num].offset = 28; 2811 mef_entry->filter[filt_num].offset = 28;
2509 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2812 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2510 if (filt_num) 2813 if (filt_num)
@@ -2513,9 +2816,9 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2513 filt_num++; 2816 filt_num++;
2514 mef_entry->filter[filt_num].repeat = 16; 2817 mef_entry->filter[filt_num].repeat = 16;
2515 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2818 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2516 ETH_ALEN); 2819 ETH_ALEN);
2517 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2820 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2518 ETH_ALEN; 2821 ETH_ALEN;
2519 mef_entry->filter[filt_num].offset = 56; 2822 mef_entry->filter[filt_num].offset = 56;
2520 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2823 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2521 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2824 mef_entry->filter[filt_num].filt_action = TYPE_OR;
@@ -2523,16 +2826,61 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2523 2826
2524 if (!mef_cfg.criteria) 2827 if (!mef_cfg.criteria)
2525 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST | 2828 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
2526 MWIFIEX_CRITERIA_UNICAST | 2829 MWIFIEX_CRITERIA_UNICAST |
2527 MWIFIEX_CRITERIA_MULTICAST; 2830 MWIFIEX_CRITERIA_MULTICAST;
2528 2831
2529 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG, 2832 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2530 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true); 2833 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true);
2531 2834
2532 kfree(mef_entry); 2835 kfree(mef_entry);
2533 return ret; 2836 return ret;
2534} 2837}
2535 2838
2839static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2840 struct cfg80211_wowlan *wowlan)
2841{
2842 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2843 struct mwifiex_ds_hs_cfg hs_cfg;
2844 int ret = 0;
2845 struct mwifiex_private *priv =
2846 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2847
2848 if (!wowlan) {
2849 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2850 return 0;
2851 }
2852
2853 if (!priv->media_connected) {
2854 dev_warn(adapter->dev,
2855 "Can not configure WOWLAN in disconnected state\n");
2856 return 0;
2857 }
2858
2859 if (wowlan->n_patterns || wowlan->magic_pkt) {
2860 ret = mwifiex_set_mef_filter(priv, wowlan);
2861 if (ret) {
2862 dev_err(adapter->dev, "Failed to set MEF filter\n");
2863 return ret;
2864 }
2865 }
2866
2867 if (wowlan->disconnect) {
2868 memset(&hs_cfg, 0, sizeof(hs_cfg));
2869 hs_cfg.is_invoke_hostcmd = false;
2870 hs_cfg.conditions = HS_CFG_COND_MAC_EVENT;
2871 hs_cfg.gpio = HS_CFG_GPIO_DEF;
2872 hs_cfg.gap = HS_CFG_GAP_DEF;
2873 ret = mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
2874 MWIFIEX_SYNC_CMD, &hs_cfg);
2875 if (ret) {
2876 dev_err(adapter->dev, "Failed to set HS params\n");
2877 return ret;
2878 }
2879 }
2880
2881 return ret;
2882}
2883
2536static int mwifiex_cfg80211_resume(struct wiphy *wiphy) 2884static int mwifiex_cfg80211_resume(struct wiphy *wiphy)
2537{ 2885{
2538 return 0; 2886 return 0;
@@ -2803,6 +3151,102 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
2803} 3151}
2804 3152
2805static int 3153static int
3154mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3155 struct cfg80211_csa_settings *params)
3156{
3157 struct ieee_types_header *chsw_ie;
3158 struct ieee80211_channel_sw_ie *channel_sw;
3159 int chsw_msec;
3160 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
3161
3162 if (priv->adapter->scan_processing) {
3163 dev_err(priv->adapter->dev,
3164 "radar detection: scan in process...\n");
3165 return -EBUSY;
3166 }
3167
3168 if (priv->wdev.cac_started)
3169 return -EBUSY;
3170
3171 if (cfg80211_chandef_identical(&params->chandef,
3172 &priv->dfs_chandef))
3173 return -EINVAL;
3174
3175 chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH,
3176 params->beacon_csa.tail,
3177 params->beacon_csa.tail_len);
3178 if (!chsw_ie) {
3179 dev_err(priv->adapter->dev,
3180 "Could not parse channel switch announcement IE\n");
3181 return -EINVAL;
3182 }
3183
3184 channel_sw = (void *)(chsw_ie + 1);
3185 if (channel_sw->mode) {
3186 if (netif_carrier_ok(priv->netdev))
3187 netif_carrier_off(priv->netdev);
3188 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
3189 }
3190
3191 if (mwifiex_del_mgmt_ies(priv))
3192 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
3193
3194 if (mwifiex_set_mgmt_ies(priv, &params->beacon_csa)) {
3195 wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
3196 return -EFAULT;
3197 }
3198
3199 memcpy(&priv->dfs_chandef, &params->chandef, sizeof(priv->dfs_chandef));
3200 memcpy(&priv->beacon_after, &params->beacon_after,
3201 sizeof(priv->beacon_after));
3202
3203 chsw_msec = max(channel_sw->count * priv->bss_cfg.beacon_period, 100);
3204 queue_delayed_work(priv->dfs_chan_sw_workqueue, &priv->dfs_chan_sw_work,
3205 msecs_to_jiffies(chsw_msec));
3206 return 0;
3207}
3208
3209static int
3210mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
3211 struct net_device *dev,
3212 struct cfg80211_chan_def *chandef,
3213 u32 cac_time_ms)
3214{
3215 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
3216 struct mwifiex_radar_params radar_params;
3217
3218 if (priv->adapter->scan_processing) {
3219 dev_err(priv->adapter->dev,
3220 "radar detection: scan already in process...\n");
3221 return -EBUSY;
3222 }
3223
3224 if (!mwifiex_is_11h_active(priv)) {
3225 dev_dbg(priv->adapter->dev, "Enable 11h extensions in FW\n");
3226 if (mwifiex_11h_activate(priv, true)) {
3227 dev_err(priv->adapter->dev,
3228 "Failed to activate 11h extensions!!");
3229 return -1;
3230 }
3231 priv->state_11h.is_11h_active = true;
3232 }
3233
3234 memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
3235 radar_params.chandef = chandef;
3236 radar_params.cac_time_ms = cac_time_ms;
3237
3238 memcpy(&priv->dfs_chandef, chandef, sizeof(priv->dfs_chandef));
3239
3240 if (mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST,
3241 HostCmd_ACT_GEN_SET, 0, &radar_params, true))
3242 return -1;
3243
3244 queue_delayed_work(priv->dfs_cac_workqueue, &priv->dfs_cac_work,
3245 msecs_to_jiffies(cac_time_ms));
3246 return 0;
3247}
3248
3249static int
2806mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, 3250mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
2807 const u8 *mac, 3251 const u8 *mac,
2808 struct station_parameters *params) 3252 struct station_parameters *params)
@@ -2866,11 +3310,13 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2866 .tdls_oper = mwifiex_cfg80211_tdls_oper, 3310 .tdls_oper = mwifiex_cfg80211_tdls_oper,
2867 .add_station = mwifiex_cfg80211_add_station, 3311 .add_station = mwifiex_cfg80211_add_station,
2868 .change_station = mwifiex_cfg80211_change_station, 3312 .change_station = mwifiex_cfg80211_change_station,
3313 .start_radar_detection = mwifiex_cfg80211_start_radar_detection,
3314 .channel_switch = mwifiex_cfg80211_channel_switch,
2869}; 3315};
2870 3316
2871#ifdef CONFIG_PM 3317#ifdef CONFIG_PM
2872static const struct wiphy_wowlan_support mwifiex_wowlan_support = { 3318static const struct wiphy_wowlan_support mwifiex_wowlan_support = {
2873 .flags = WIPHY_WOWLAN_MAGIC_PKT, 3319 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
2874 .n_patterns = MWIFIEX_MEF_MAX_FILTERS, 3320 .n_patterns = MWIFIEX_MEF_MAX_FILTERS,
2875 .pattern_min_len = 1, 3321 .pattern_min_len = 1,
2876 .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN, 3322 .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN,
@@ -2964,12 +3410,13 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2964 wiphy->cipher_suites = mwifiex_cipher_suites; 3410 wiphy->cipher_suites = mwifiex_cipher_suites;
2965 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 3411 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
2966 3412
2967 memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 3413 ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
2968 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 3414 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2969 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 3415 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2970 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 3416 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2971 WIPHY_FLAG_AP_UAPSD | 3417 WIPHY_FLAG_AP_UAPSD |
2972 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 3418 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3419 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
2973 3420
2974 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) 3421 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
2975 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 3422 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index b8242eb2be6f..e9df8826f124 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -322,9 +322,9 @@ mwifiex_get_cfp(struct mwifiex_private *priv, u8 band, u16 channel, u32 freq)
322 return cfp; 322 return cfp;
323 323
324 if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG) 324 if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
325 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ]; 325 sband = priv->wdev.wiphy->bands[IEEE80211_BAND_2GHZ];
326 else 326 else
327 sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ]; 327 sband = priv->wdev.wiphy->bands[IEEE80211_BAND_5GHZ];
328 328
329 if (!sband) { 329 if (!sband) {
330 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n", 330 dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d\n",
@@ -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..c5a14ff7eb82 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -315,22 +315,19 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
315 adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++; 315 adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
316 return -1; 316 return -1;
317 } 317 }
318 if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY)) 318
319 == MWIFIEX_BSS_ROLE_STA) { 319 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl))
320 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl)) 320 /* Response is not needed for sleep confirm command */
321 /* Response is not needed for sleep 321 adapter->ps_state = PS_STATE_SLEEP;
322 confirm command */ 322 else
323 adapter->ps_state = PS_STATE_SLEEP; 323 adapter->ps_state = PS_STATE_SLEEP_CFM;
324 else 324
325 adapter->ps_state = PS_STATE_SLEEP_CFM; 325 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl) &&
326 326 (adapter->is_hs_configured &&
327 if (!le16_to_cpu(sleep_cfm_buf->resp_ctrl) && 327 !adapter->sleep_period.period)) {
328 (adapter->is_hs_configured && 328 adapter->pm_wakeup_card_req = true;
329 !adapter->sleep_period.period)) { 329 mwifiex_hs_activated_event(mwifiex_get_priv
330 adapter->pm_wakeup_card_req = true; 330 (adapter, MWIFIEX_BSS_ROLE_ANY), true);
331 mwifiex_hs_activated_event(mwifiex_get_priv
332 (adapter, MWIFIEX_BSS_ROLE_STA), true);
333 }
334 } 331 }
335 332
336 return ret; 333 return ret;
@@ -450,6 +447,7 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
450 EVENT_GET_BSS_TYPE(eventcause)); 447 EVENT_GET_BSS_TYPE(eventcause));
451 if (!priv) 448 if (!priv)
452 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 449 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
450
453 /* Clear BSS_NO_BITS from event */ 451 /* Clear BSS_NO_BITS from event */
454 eventcause &= EVENT_ID_MASK; 452 eventcause &= EVENT_ID_MASK;
455 adapter->event_cause = eventcause; 453 adapter->event_cause = eventcause;
@@ -462,12 +460,6 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
462 } 460 }
463 461
464 dev_dbg(adapter->dev, "EVENT: cause: %#x\n", eventcause); 462 dev_dbg(adapter->dev, "EVENT: cause: %#x\n", eventcause);
465 if (eventcause == EVENT_PS_SLEEP || eventcause == EVENT_PS_AWAKE) {
466 /* Handle PS_SLEEP/AWAKE events on STA */
467 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
468 if (!priv)
469 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
470 }
471 463
472 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) 464 if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
473 ret = mwifiex_process_uap_event(priv); 465 ret = mwifiex_process_uap_event(priv);
@@ -1008,11 +1000,9 @@ mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
1008 list_for_each_entry_safe(cmd_node, tmp_node, 1000 list_for_each_entry_safe(cmd_node, tmp_node,
1009 &adapter->scan_pending_q, list) { 1001 &adapter->scan_pending_q, list) {
1010 list_del(&cmd_node->list); 1002 list_del(&cmd_node->list);
1011 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1012 1003
1013 cmd_node->wait_q_enabled = false; 1004 cmd_node->wait_q_enabled = false;
1014 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1005 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1015 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1016 } 1006 }
1017 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); 1007 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1018 1008
@@ -1070,12 +1060,8 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
1070 list_for_each_entry_safe(cmd_node, tmp_node, 1060 list_for_each_entry_safe(cmd_node, tmp_node,
1071 &adapter->scan_pending_q, list) { 1061 &adapter->scan_pending_q, list) {
1072 list_del(&cmd_node->list); 1062 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; 1063 cmd_node->wait_q_enabled = false;
1076 mwifiex_insert_cmd_to_free_q(adapter, cmd_node); 1064 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1077 spin_lock_irqsave(&adapter->scan_pending_q_lock,
1078 scan_pending_q_flags);
1079 } 1065 }
1080 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1066 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1081 scan_pending_q_flags); 1067 scan_pending_q_flags);
@@ -1588,9 +1574,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1588 le16_to_cpu(hw_spec->hw_if_version), 1574 le16_to_cpu(hw_spec->hw_if_version),
1589 le16_to_cpu(hw_spec->version)); 1575 le16_to_cpu(hw_spec->version));
1590 1576
1591 if (priv->curr_addr[0] == 0xff) 1577 ether_addr_copy(priv->adapter->perm_addr, hw_spec->permanent_addr);
1592 memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
1593
1594 adapter->region_code = le16_to_cpu(hw_spec->region_code); 1578 adapter->region_code = le16_to_cpu(hw_spec->region_code);
1595 1579
1596 for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++) 1580 for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++)
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..88d0eade6bb1 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,20 @@
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
107#define MWIFIEX_MAX_STA_NUM 1
108#define MWIFIEX_MAX_UAP_NUM 1
109#define MWIFIEX_MAX_P2P_NUM 1
110
111#define MWIFIEX_A_BAND_START_FREQ 5000
112
95enum mwifiex_bss_type { 113enum mwifiex_bss_type {
96 MWIFIEX_BSS_TYPE_STA = 0, 114 MWIFIEX_BSS_TYPE_STA = 0,
97 MWIFIEX_BSS_TYPE_UAP = 1, 115 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -204,4 +222,35 @@ struct mwifiex_chan_stats {
204 u16 cca_scan_dur; 222 u16 cca_scan_dur;
205 u16 cca_busy_dur; 223 u16 cca_busy_dur;
206} __packed; 224} __packed;
225
226#define MWIFIEX_HIST_MAX_SAMPLES 1048576
227#define MWIFIEX_MAX_RX_RATES 44
228#define MWIFIEX_MAX_AC_RX_RATES 74
229#define MWIFIEX_MAX_SNR 256
230#define MWIFIEX_MAX_NOISE_FLR 256
231#define MWIFIEX_MAX_SIG_STRENGTH 256
232
233struct mwifiex_histogram_data {
234 atomic_t rx_rate[MWIFIEX_MAX_AC_RX_RATES];
235 atomic_t snr[MWIFIEX_MAX_SNR];
236 atomic_t noise_flr[MWIFIEX_MAX_NOISE_FLR];
237 atomic_t sig_str[MWIFIEX_MAX_SIG_STRENGTH];
238 atomic_t num_samples;
239};
240
241struct mwifiex_iface_comb {
242 u8 sta_intf;
243 u8 uap_intf;
244 u8 p2p_intf;
245};
246
247struct mwifiex_radar_params {
248 struct cfg80211_chan_def *chandef;
249 u32 cac_time_ms;
250} __packed;
251
252struct mwifiex_11h_intf_state {
253 bool is_11h_enabled;
254 bool is_11h_active;
255} __packed;
207#endif /* !_MWIFIEX_DECL_H_ */ 256#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..df553e86a0ad 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -158,6 +158,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
158#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84) 158#define TLV_TYPE_POWER_GROUP (PROPRIETARY_TLV_BASE_ID + 84)
159#define TLV_TYPE_BSS_SCAN_RSP (PROPRIETARY_TLV_BASE_ID + 86) 159#define TLV_TYPE_BSS_SCAN_RSP (PROPRIETARY_TLV_BASE_ID + 86)
160#define TLV_TYPE_BSS_SCAN_INFO (PROPRIETARY_TLV_BASE_ID + 87) 160#define TLV_TYPE_BSS_SCAN_INFO (PROPRIETARY_TLV_BASE_ID + 87)
161#define TLV_TYPE_CHANRPT_11H_BASIC (PROPRIETARY_TLV_BASE_ID + 91)
161#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93) 162#define TLV_TYPE_UAP_RETRY_LIMIT (PROPRIETARY_TLV_BASE_ID + 93)
162#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94) 163#define TLV_TYPE_WAPI_IE (PROPRIETARY_TLV_BASE_ID + 94)
163#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104) 164#define TLV_TYPE_UAP_MGMT_FRAME (PROPRIETARY_TLV_BASE_ID + 104)
@@ -233,6 +234,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
233#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) 234#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
234#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) 235#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30))
235#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2)) 236#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2))
237#define GETSUPP_TXBASTREAMS(Dot11nDevCap) ((Dot11nDevCap >> 18) & 0xF)
236 238
237/* httxcfg bitmap 239/* httxcfg bitmap
238 * 0 reserved 240 * 0 reserved
@@ -335,6 +337,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
335#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf 337#define HostCmd_CMD_11N_ADDBA_RSP 0x00cf
336#define HostCmd_CMD_11N_DELBA 0x00d0 338#define HostCmd_CMD_11N_DELBA 0x00d0
337#define HostCmd_CMD_RECONFIGURE_TX_BUFF 0x00d9 339#define HostCmd_CMD_RECONFIGURE_TX_BUFF 0x00d9
340#define HostCmd_CMD_CHAN_REPORT_REQUEST 0x00dd
338#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df 341#define HostCmd_CMD_AMSDU_AGGR_CTRL 0x00df
339#define HostCmd_CMD_TXPWR_CFG 0x00d1 342#define HostCmd_CMD_TXPWR_CFG 0x00d1
340#define HostCmd_CMD_TX_RATE_CFG 0x00d6 343#define HostCmd_CMD_TX_RATE_CFG 0x00d6
@@ -492,6 +495,8 @@ enum P2P_MODES {
492#define EVENT_HOSTWAKE_STAIE 0x0000004d 495#define EVENT_HOSTWAKE_STAIE 0x0000004d
493#define EVENT_CHANNEL_SWITCH_ANN 0x00000050 496#define EVENT_CHANNEL_SWITCH_ANN 0x00000050
494#define EVENT_TDLS_GENERIC_EVENT 0x00000052 497#define EVENT_TDLS_GENERIC_EVENT 0x00000052
498#define EVENT_RADAR_DETECTED 0x00000053
499#define EVENT_CHANNEL_REPORT_RDY 0x00000054
495#define EVENT_EXT_SCAN_REPORT 0x00000058 500#define EVENT_EXT_SCAN_REPORT 0x00000058
496#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f 501#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
497#define EVENT_TX_STATUS_REPORT 0x00000074 502#define EVENT_TX_STATUS_REPORT 0x00000074
@@ -529,6 +534,8 @@ enum P2P_MODES {
529 534
530#define MWIFIEX_FW_V15 15 535#define MWIFIEX_FW_V15 15
531 536
537#define MWIFIEX_MASTER_RADAR_DET_MASK BIT(1)
538
532struct mwifiex_ie_types_header { 539struct mwifiex_ie_types_header {
533 __le16 type; 540 __le16 type;
534 __le16 len; 541 __le16 len;
@@ -1076,6 +1083,8 @@ struct host_cmd_ds_802_11_get_log {
1076 __le32 tx_frame; 1083 __le32 tx_frame;
1077 __le32 reserved; 1084 __le32 reserved;
1078 __le32 wep_icv_err_cnt[4]; 1085 __le32 wep_icv_err_cnt[4];
1086 __le32 bcn_rcv_cnt;
1087 __le32 bcn_miss_cnt;
1079}; 1088};
1080 1089
1081/* Enumeration for rate format */ 1090/* Enumeration for rate format */
@@ -1213,6 +1222,24 @@ struct host_cmd_ds_tdls_oper {
1213 u8 peer_mac[ETH_ALEN]; 1222 u8 peer_mac[ETH_ALEN];
1214} __packed; 1223} __packed;
1215 1224
1225struct mwifiex_chan_desc {
1226 __le16 start_freq;
1227 u8 chan_width;
1228 u8 chan_num;
1229} __packed;
1230
1231struct host_cmd_ds_chan_rpt_req {
1232 struct mwifiex_chan_desc chan_desc;
1233 __le32 msec_dwell_time;
1234} __packed;
1235
1236struct host_cmd_ds_chan_rpt_event {
1237 __le32 result;
1238 __le64 start_tsf;
1239 __le32 duration;
1240 u8 tlvbuf[0];
1241} __packed;
1242
1216struct mwifiex_fixed_bcn_param { 1243struct mwifiex_fixed_bcn_param {
1217 __le64 timestamp; 1244 __le64 timestamp;
1218 __le16 beacon_period; 1245 __le16 beacon_period;
@@ -1789,6 +1816,39 @@ struct mwifiex_ie_types_rssi_threshold {
1789 u8 evt_freq; 1816 u8 evt_freq;
1790} __packed; 1817} __packed;
1791 1818
1819#define MWIFIEX_DFS_REC_HDR_LEN 8
1820#define MWIFIEX_DFS_REC_HDR_NUM 10
1821#define MWIFIEX_BIN_COUNTER_LEN 7
1822
1823struct mwifiex_radar_det_event {
1824 __le32 detect_count;
1825 u8 reg_domain; /*1=fcc, 2=etsi, 3=mic*/
1826 u8 det_type; /*0=none, 1=pw(chirp), 2=pri(radar)*/
1827 __le16 pw_chirp_type;
1828 u8 pw_chirp_idx;
1829 u8 pw_value;
1830 u8 pri_radar_type;
1831 u8 pri_bincnt;
1832 u8 bin_counter[MWIFIEX_BIN_COUNTER_LEN];
1833 u8 num_dfs_records;
1834 u8 dfs_record_hdr[MWIFIEX_DFS_REC_HDR_NUM][MWIFIEX_DFS_REC_HDR_LEN];
1835 __le32 passed;
1836} __packed;
1837
1838struct meas_rpt_map {
1839 u8 rssi:3;
1840 u8 unmeasured:1;
1841 u8 radar:1;
1842 u8 unidentified_sig:1;
1843 u8 ofdm_preamble:1;
1844 u8 bss:1;
1845} __packed;
1846
1847struct mwifiex_ie_types_chan_rpt_data {
1848 struct mwifiex_ie_types_header header;
1849 struct meas_rpt_map map;
1850} __packed;
1851
1792struct host_cmd_ds_802_11_subsc_evt { 1852struct host_cmd_ds_802_11_subsc_evt {
1793 __le16 action; 1853 __le16 action;
1794 __le16 events; 1854 __le16 events;
@@ -1901,6 +1961,7 @@ struct host_cmd_ds_command {
1901 struct host_cmd_11ac_vht_cfg vht_cfg; 1961 struct host_cmd_11ac_vht_cfg vht_cfg;
1902 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 1962 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1903 struct host_cmd_ds_tdls_oper tdls_oper; 1963 struct host_cmd_ds_tdls_oper tdls_oper;
1964 struct host_cmd_ds_chan_rpt_req chan_rpt_req;
1904 } params; 1965 } params;
1905} __packed; 1966} __packed;
1906 1967
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index b933794758b7..f3b6ed249403 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -317,27 +317,27 @@ done:
317 return ret; 317 return ret;
318} 318}
319 319
320/* This function parses different IEs-tail IEs, beacon IEs, probe response IEs, 320/* This function parses head and tail IEs, from cfg80211_beacon_data and sets
321 * association response IEs from cfg80211_ap_settings function and sets these IE 321 * these IE to FW.
322 * to FW.
323 */ 322 */
324int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, 323static int mwifiex_uap_set_head_tail_ies(struct mwifiex_private *priv,
325 struct cfg80211_beacon_data *info) 324 struct cfg80211_beacon_data *info)
326{ 325{
327 struct mwifiex_ie *gen_ie; 326 struct mwifiex_ie *gen_ie;
328 struct ieee_types_header *rsn_ie, *wpa_ie = NULL; 327 struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL;
329 u16 rsn_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; 328 struct ieee_types_header *chsw_ie = NULL;
329 u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
330 const u8 *vendor_ie; 330 const u8 *vendor_ie;
331 331
332 if (info->tail && info->tail_len) { 332 gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL);
333 gen_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); 333 if (!gen_ie)
334 if (!gen_ie) 334 return -ENOMEM;
335 return -ENOMEM; 335 gen_ie->ie_index = cpu_to_le16(gen_idx);
336 gen_ie->ie_index = cpu_to_le16(rsn_idx); 336 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
337 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | 337 MGMT_MASK_PROBE_RESP |
338 MGMT_MASK_PROBE_RESP | 338 MGMT_MASK_ASSOC_RESP);
339 MGMT_MASK_ASSOC_RESP);
340 339
340 if (info->tail && info->tail_len) {
341 rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, 341 rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN,
342 info->tail, info->tail_len); 342 info->tail, info->tail_len);
343 if (rsn_ie) { 343 if (rsn_ie) {
@@ -358,19 +358,41 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
358 gen_ie->ie_length = cpu_to_le16(ie_len); 358 gen_ie->ie_length = cpu_to_le16(ie_len);
359 } 359 }
360 360
361 if (rsn_ie || wpa_ie) { 361 chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH,
362 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &rsn_idx, 362 info->tail, info->tail_len);
363 NULL, NULL, 363 if (chsw_ie) {
364 NULL, NULL)) { 364 memcpy(gen_ie->ie_buffer + ie_len,
365 kfree(gen_ie); 365 chsw_ie, chsw_ie->len + 2);
366 return -1; 366 ie_len += chsw_ie->len + 2;
367 } 367 gen_ie->ie_length = cpu_to_le16(ie_len);
368 priv->rsn_idx = rsn_idx;
369 } 368 }
369 }
370 370
371 kfree(gen_ie); 371 if (rsn_ie || wpa_ie || chsw_ie) {
372 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL,
373 NULL, NULL, NULL)) {
374 kfree(gen_ie);
375 return -1;
376 }
377 priv->gen_idx = gen_idx;
372 } 378 }
373 379
380 kfree(gen_ie);
381 return 0;
382}
383
384/* This function parses different IEs-head & tail IEs, beacon IEs,
385 * probe response IEs, association response IEs from cfg80211_ap_settings
386 * function and sets these IE to FW.
387 */
388int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
389 struct cfg80211_beacon_data *info)
390{
391 int ret;
392
393 ret = mwifiex_uap_set_head_tail_ies(priv, info);
394 return ret;
395
374 return mwifiex_set_mgmt_beacon_data_ies(priv, info); 396 return mwifiex_set_mgmt_beacon_data_ies(priv, info);
375} 397}
376 398
@@ -378,25 +400,25 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
378int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) 400int mwifiex_del_mgmt_ies(struct mwifiex_private *priv)
379{ 401{
380 struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL; 402 struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL;
381 struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL; 403 struct mwifiex_ie *ar_ie = NULL, *gen_ie = NULL;
382 int ret = 0; 404 int ret = 0;
383 405
384 if (priv->rsn_idx != MWIFIEX_AUTO_IDX_MASK) { 406 if (priv->gen_idx != MWIFIEX_AUTO_IDX_MASK) {
385 rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); 407 gen_ie = kmalloc(sizeof(*gen_ie), GFP_KERNEL);
386 if (!rsn_ie) 408 if (!gen_ie)
387 return -ENOMEM; 409 return -ENOMEM;
388 410
389 rsn_ie->ie_index = cpu_to_le16(priv->rsn_idx); 411 gen_ie->ie_index = cpu_to_le16(priv->gen_idx);
390 rsn_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK); 412 gen_ie->mgmt_subtype_mask = cpu_to_le16(MWIFIEX_DELETE_MASK);
391 rsn_ie->ie_length = 0; 413 gen_ie->ie_length = 0;
392 if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &priv->rsn_idx, 414 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &priv->gen_idx,
393 NULL, &priv->proberesp_idx, 415 NULL, &priv->proberesp_idx,
394 NULL, &priv->assocresp_idx)) { 416 NULL, &priv->assocresp_idx)) {
395 ret = -1; 417 ret = -1;
396 goto done; 418 goto done;
397 } 419 }
398 420
399 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK; 421 priv->gen_idx = MWIFIEX_AUTO_IDX_MASK;
400 } 422 }
401 423
402 if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) { 424 if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) {
@@ -440,7 +462,6 @@ done:
440 kfree(beacon_ie); 462 kfree(beacon_ie);
441 kfree(pr_ie); 463 kfree(pr_ie);
442 kfree(ar_ie); 464 kfree(ar_ie);
443 kfree(rsn_ie);
444 465
445 return ret; 466 return ret;
446} 467}
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 520ad4a3018b..b77ba743e1c4 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.
@@ -140,6 +152,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
140 priv->check_tdls_tx = false; 152 priv->check_tdls_tx = false;
141 memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID); 153 memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID);
142 154
155 mwifiex_init_11h_params(priv);
156
143 return mwifiex_add_bss_prio_tbl(priv); 157 return mwifiex_add_bss_prio_tbl(priv);
144} 158}
145 159
@@ -282,9 +296,16 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
282 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 296 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
283 adapter->arp_filter_size = 0; 297 adapter->arp_filter_size = 0;
284 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 298 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
285 adapter->ext_scan = true; 299 adapter->ext_scan = false;
286 adapter->key_api_major_ver = 0; 300 adapter->key_api_major_ver = 0;
287 adapter->key_api_minor_ver = 0; 301 adapter->key_api_minor_ver = 0;
302 memset(adapter->perm_addr, 0xff, ETH_ALEN);
303 adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM;
304 adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM;
305 adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM;
306
307 setup_timer(&adapter->wakeup_timer, wakeup_timer_fn,
308 (unsigned long)adapter);
288} 309}
289 310
290/* 311/*
@@ -391,7 +412,10 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
391 return; 412 return;
392 } 413 }
393 414
415 del_timer(&adapter->wakeup_timer);
394 mwifiex_cancel_all_pending_cmd(adapter); 416 mwifiex_cancel_all_pending_cmd(adapter);
417 wake_up_interruptible(&adapter->cmd_wait_q.wait);
418 wake_up_interruptible(&adapter->hs_activate_wait_q);
395 419
396 /* Free lock variables */ 420 /* Free lock variables */
397 mwifiex_free_lock_list(adapter); 421 mwifiex_free_lock_list(adapter);
@@ -411,6 +435,11 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
411 entry->mem_size = 0; 435 entry->mem_size = 0;
412 } 436 }
413 437
438 if (adapter->drv_info_dump) {
439 vfree(adapter->drv_info_dump);
440 adapter->drv_info_size = 0;
441 }
442
414 if (adapter->sleep_cfm) 443 if (adapter->sleep_cfm)
415 dev_kfree_skb_any(adapter->sleep_cfm); 444 dev_kfree_skb_any(adapter->sleep_cfm);
416} 445}
@@ -528,7 +557,8 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter)
528 557
529 for (i = 0; i < adapter->priv_num; i++) { 558 for (i = 0; i < adapter->priv_num; i++) {
530 if (adapter->priv[i]) { 559 if (adapter->priv[i]) {
531 ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta); 560 ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta,
561 true);
532 if (ret == -1) 562 if (ret == -1)
533 return -1; 563 return -1;
534 564
@@ -653,6 +683,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
653 priv = adapter->priv[i]; 683 priv = adapter->priv[i];
654 684
655 mwifiex_clean_auto_tdls(priv); 685 mwifiex_clean_auto_tdls(priv);
686 mwifiex_abort_cac(priv);
656 mwifiex_clean_txrx(priv); 687 mwifiex_clean_txrx(priv);
657 mwifiex_delete_bss_prio_tbl(priv); 688 mwifiex_delete_bss_prio_tbl(priv);
658 } 689 }
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..7e74b4fccddd 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
@@ -562,7 +562,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
562static int 562static int
563mwifiex_open(struct net_device *dev) 563mwifiex_open(struct net_device *dev)
564{ 564{
565 netif_tx_start_all_queues(dev); 565 netif_carrier_off(dev);
566
566 return 0; 567 return 0;
567} 568}
568 569
@@ -801,6 +802,114 @@ mwifiex_tx_timeout(struct net_device *dev)
801 } 802 }
802} 803}
803 804
805void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter)
806{
807 void *p;
808 char drv_version[64];
809 struct usb_card_rec *cardp;
810 struct sdio_mmc_card *sdio_card;
811 struct mwifiex_private *priv;
812 int i, idx;
813 struct netdev_queue *txq;
814 struct mwifiex_debug_info *debug_info;
815
816 if (adapter->drv_info_dump) {
817 vfree(adapter->drv_info_dump);
818 adapter->drv_info_size = 0;
819 }
820
821 dev_info(adapter->dev, "=== DRIVER INFO DUMP START===\n");
822
823 adapter->drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX);
824
825 if (!adapter->drv_info_dump)
826 return;
827
828 p = (char *)(adapter->drv_info_dump);
829 p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
830
831 mwifiex_drv_get_driver_version(adapter, drv_version,
832 sizeof(drv_version) - 1);
833 p += sprintf(p, "driver_version = %s\n", drv_version);
834
835 if (adapter->iface_type == MWIFIEX_USB) {
836 cardp = (struct usb_card_rec *)adapter->card;
837 p += sprintf(p, "tx_cmd_urb_pending = %d\n",
838 atomic_read(&cardp->tx_cmd_urb_pending));
839 p += sprintf(p, "tx_data_urb_pending = %d\n",
840 atomic_read(&cardp->tx_data_urb_pending));
841 p += sprintf(p, "rx_cmd_urb_pending = %d\n",
842 atomic_read(&cardp->rx_cmd_urb_pending));
843 p += sprintf(p, "rx_data_urb_pending = %d\n",
844 atomic_read(&cardp->rx_data_urb_pending));
845 }
846
847 p += sprintf(p, "tx_pending = %d\n",
848 atomic_read(&adapter->tx_pending));
849 p += sprintf(p, "rx_pending = %d\n",
850 atomic_read(&adapter->rx_pending));
851
852 if (adapter->iface_type == MWIFIEX_SDIO) {
853 sdio_card = (struct sdio_mmc_card *)adapter->card;
854 p += sprintf(p, "\nmp_rd_bitmap=0x%x curr_rd_port=0x%x\n",
855 sdio_card->mp_rd_bitmap, sdio_card->curr_rd_port);
856 p += sprintf(p, "mp_wr_bitmap=0x%x curr_wr_port=0x%x\n",
857 sdio_card->mp_wr_bitmap, sdio_card->curr_wr_port);
858 }
859
860 for (i = 0; i < adapter->priv_num; i++) {
861 if (!adapter->priv[i] || !adapter->priv[i]->netdev)
862 continue;
863 priv = adapter->priv[i];
864 p += sprintf(p, "\n[interface : \"%s\"]\n",
865 priv->netdev->name);
866 p += sprintf(p, "wmm_tx_pending[0] = %d\n",
867 atomic_read(&priv->wmm_tx_pending[0]));
868 p += sprintf(p, "wmm_tx_pending[1] = %d\n",
869 atomic_read(&priv->wmm_tx_pending[1]));
870 p += sprintf(p, "wmm_tx_pending[2] = %d\n",
871 atomic_read(&priv->wmm_tx_pending[2]));
872 p += sprintf(p, "wmm_tx_pending[3] = %d\n",
873 atomic_read(&priv->wmm_tx_pending[3]));
874 p += sprintf(p, "media_state=\"%s\"\n", !priv->media_connected ?
875 "Disconnected" : "Connected");
876 p += sprintf(p, "carrier %s\n", (netif_carrier_ok(priv->netdev)
877 ? "on" : "off"));
878 for (idx = 0; idx < priv->netdev->num_tx_queues; idx++) {
879 txq = netdev_get_tx_queue(priv->netdev, idx);
880 p += sprintf(p, "tx queue %d:%s ", idx,
881 netif_tx_queue_stopped(txq) ?
882 "stopped" : "started");
883 }
884 p += sprintf(p, "\n%s: num_tx_timeout = %d\n",
885 priv->netdev->name, priv->num_tx_timeout);
886 }
887
888 if (adapter->iface_type == MWIFIEX_SDIO) {
889 p += sprintf(p, "\n=== SDIO register DUMP===\n");
890 if (adapter->if_ops.reg_dump)
891 p += adapter->if_ops.reg_dump(adapter, p);
892 }
893
894 p += sprintf(p, "\n=== MORE DEBUG INFORMATION\n");
895 debug_info = kzalloc(sizeof(*debug_info), GFP_KERNEL);
896 if (debug_info) {
897 for (i = 0; i < adapter->priv_num; i++) {
898 if (!adapter->priv[i] || !adapter->priv[i]->netdev)
899 continue;
900 priv = adapter->priv[i];
901 mwifiex_get_debug_info(priv, debug_info);
902 p += mwifiex_debug_info_to_buffer(priv, p, debug_info);
903 break;
904 }
905 kfree(debug_info);
906 }
907
908 adapter->drv_info_size = p - adapter->drv_info_dump;
909 dev_info(adapter->dev, "=== DRIVER INFO DUMP END===\n");
910}
911EXPORT_SYMBOL_GPL(mwifiex_dump_drv_info);
912
804/* 913/*
805 * CFG802.11 network device handler for statistics retrieval. 914 * CFG802.11 network device handler for statistics retrieval.
806 */ 915 */
@@ -847,26 +956,34 @@ static const struct net_device_ops mwifiex_netdev_ops = {
847 * - Nick name : Set to null 956 * - Nick name : Set to null
848 * - Number of Tx timeout : Set to 0 957 * - Number of Tx timeout : Set to 0
849 * - Device address : Set to current address 958 * - Device address : Set to current address
959 * - Rx histogram statistc : Set to 0
850 * 960 *
851 * In addition, the CFG80211 work queue is also created. 961 * In addition, the CFG80211 work queue is also created.
852 */ 962 */
853void mwifiex_init_priv_params(struct mwifiex_private *priv, 963void mwifiex_init_priv_params(struct mwifiex_private *priv,
854 struct net_device *dev) 964 struct net_device *dev)
855{ 965{
856 dev->netdev_ops = &mwifiex_netdev_ops; 966 dev->netdev_ops = &mwifiex_netdev_ops;
857 dev->destructor = free_netdev; 967 dev->destructor = free_netdev;
858 /* Initialize private structure */ 968 /* Initialize private structure */
859 priv->current_key_index = 0; 969 priv->current_key_index = 0;
860 priv->media_connected = false; 970 priv->media_connected = false;
861 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
862 memset(priv->mgmt_ie, 0, 971 memset(priv->mgmt_ie, 0,
863 sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX); 972 sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX);
864 priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK; 973 priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK;
865 priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK; 974 priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK;
866 priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK; 975 priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK;
867 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK; 976 priv->gen_idx = MWIFIEX_AUTO_IDX_MASK;
868 priv->num_tx_timeout = 0; 977 priv->num_tx_timeout = 0;
978 ether_addr_copy(priv->curr_addr, priv->adapter->perm_addr);
869 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); 979 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
980
981 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
982 GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
983 priv->hist_data = kmalloc(sizeof(*priv->hist_data), GFP_KERNEL);
984 if (priv->hist_data)
985 mwifiex_hist_data_reset(priv);
986 }
870} 987}
871 988
872/* 989/*
@@ -1000,8 +1117,7 @@ err_init_fw:
1000 pr_debug("info: %s: unregister device\n", __func__); 1117 pr_debug("info: %s: unregister device\n", __func__);
1001 if (adapter->if_ops.unregister_dev) 1118 if (adapter->if_ops.unregister_dev)
1002 adapter->if_ops.unregister_dev(adapter); 1119 adapter->if_ops.unregister_dev(adapter);
1003 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) || 1120 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__); 1121 pr_debug("info: %s: shutdown mwifiex\n", __func__);
1006 adapter->init_wait_q_woken = false; 1122 adapter->init_wait_q_woken = false;
1007 1123
@@ -1052,6 +1168,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1052 1168
1053 adapter->surprise_removed = true; 1169 adapter->surprise_removed = true;
1054 1170
1171 mwifiex_terminate_workqueue(adapter);
1172
1055 /* Stop data */ 1173 /* Stop data */
1056 for (i = 0; i < adapter->priv_num; i++) { 1174 for (i = 0; i < adapter->priv_num; i++) {
1057 priv = adapter->priv[i]; 1175 priv = adapter->priv[i];
@@ -1086,16 +1204,15 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
1086 continue; 1204 continue;
1087 1205
1088 rtnl_lock(); 1206 rtnl_lock();
1089 if (priv->wdev && priv->netdev) 1207 if (priv->netdev &&
1090 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); 1208 priv->wdev.iftype != NL80211_IFTYPE_UNSPECIFIED)
1209 mwifiex_del_virtual_intf(adapter->wiphy, &priv->wdev);
1091 rtnl_unlock(); 1210 rtnl_unlock();
1092 } 1211 }
1093 1212
1094 wiphy_unregister(adapter->wiphy); 1213 wiphy_unregister(adapter->wiphy);
1095 wiphy_free(adapter->wiphy); 1214 wiphy_free(adapter->wiphy);
1096 1215
1097 mwifiex_terminate_workqueue(adapter);
1098
1099 /* Unregister device */ 1216 /* Unregister device */
1100 dev_dbg(adapter->dev, "info: unregister device\n"); 1217 dev_dbg(adapter->dev, "info: unregister device\n");
1101 if (adapter->if_ops.unregister_dev) 1218 if (adapter->if_ops.unregister_dev)
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index e66993cb5daf..f0a6af179af0 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
@@ -543,13 +547,12 @@ struct mwifiex_private {
543 u32 curr_bcn_size; 547 u32 curr_bcn_size;
544 /* spin lock for beacon buffer */ 548 /* spin lock for beacon buffer */
545 spinlock_t curr_bcn_buf_lock; 549 spinlock_t curr_bcn_buf_lock;
546 struct wireless_dev *wdev; 550 struct wireless_dev wdev;
547 struct mwifiex_chan_freq_power cfp; 551 struct mwifiex_chan_freq_power cfp;
548 char version_str[128]; 552 char version_str[128];
549#ifdef CONFIG_DEBUG_FS 553#ifdef CONFIG_DEBUG_FS
550 struct dentry *dfs_dev_dir; 554 struct dentry *dfs_dev_dir;
551#endif 555#endif
552 u8 nick_name[16];
553 u16 current_key_index; 556 u16 current_key_index;
554 struct semaphore async_sem; 557 struct semaphore async_sem;
555 struct cfg80211_scan_request *scan_request; 558 struct cfg80211_scan_request *scan_request;
@@ -564,7 +567,7 @@ struct mwifiex_private {
564 u16 beacon_idx; 567 u16 beacon_idx;
565 u16 proberesp_idx; 568 u16 proberesp_idx;
566 u16 assocresp_idx; 569 u16 assocresp_idx;
567 u16 rsn_idx; 570 u16 gen_idx;
568 u8 ap_11n_enabled; 571 u8 ap_11n_enabled;
569 u8 ap_11ac_enabled; 572 u8 ap_11ac_enabled;
570 u32 mgmt_frame_mask; 573 u32 mgmt_frame_mask;
@@ -574,6 +577,7 @@ struct mwifiex_private {
574 unsigned long csa_expire_time; 577 unsigned long csa_expire_time;
575 u8 del_list_idx; 578 u8 del_list_idx;
576 bool hs2_enabled; 579 bool hs2_enabled;
580 struct mwifiex_uap_bss_param bss_cfg;
577 struct station_parameters *sta_params; 581 struct station_parameters *sta_params;
578 struct sk_buff_head tdls_txq; 582 struct sk_buff_head tdls_txq;
579 u8 check_tdls_tx; 583 u8 check_tdls_tx;
@@ -582,6 +586,16 @@ 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;
591 struct cfg80211_chan_def dfs_chandef;
592 struct workqueue_struct *dfs_cac_workqueue;
593 struct delayed_work dfs_cac_work;
594 struct timer_list dfs_chan_switch_timer;
595 struct workqueue_struct *dfs_chan_sw_workqueue;
596 struct delayed_work dfs_chan_sw_work;
597 struct cfg80211_beacon_data beacon_after;
598 struct mwifiex_11h_intf_state state_11h;
585}; 599};
586 600
587enum mwifiex_ba_status { 601enum mwifiex_ba_status {
@@ -717,6 +731,7 @@ struct mwifiex_if_ops {
717 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); 731 int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
718 void (*card_reset) (struct mwifiex_adapter *); 732 void (*card_reset) (struct mwifiex_adapter *);
719 void (*fw_dump)(struct mwifiex_adapter *); 733 void (*fw_dump)(struct mwifiex_adapter *);
734 int (*reg_dump)(struct mwifiex_adapter *, char *);
720 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 735 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
721 void (*iface_work)(struct work_struct *work); 736 void (*iface_work)(struct work_struct *work);
722 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); 737 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
@@ -724,6 +739,8 @@ struct mwifiex_if_ops {
724 739
725struct mwifiex_adapter { 740struct mwifiex_adapter {
726 u8 iface_type; 741 u8 iface_type;
742 struct mwifiex_iface_comb iface_limit;
743 struct mwifiex_iface_comb curr_iface_comb;
727 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; 744 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
728 u8 priv_num; 745 u8 priv_num;
729 const struct firmware *firmware; 746 const struct firmware *firmware;
@@ -731,6 +748,7 @@ struct mwifiex_adapter {
731 int winner; 748 int winner;
732 struct device *dev; 749 struct device *dev;
733 struct wiphy *wiphy; 750 struct wiphy *wiphy;
751 u8 perm_addr[ETH_ALEN];
734 bool surprise_removed; 752 bool surprise_removed;
735 u32 fw_release_number; 753 u32 fw_release_number;
736 u16 init_wait_q_woken; 754 u16 init_wait_q_woken;
@@ -744,6 +762,8 @@ struct mwifiex_adapter {
744 struct work_struct main_work; 762 struct work_struct main_work;
745 struct workqueue_struct *rx_workqueue; 763 struct workqueue_struct *rx_workqueue;
746 struct work_struct rx_work; 764 struct work_struct rx_work;
765 struct workqueue_struct *dfs_workqueue;
766 struct work_struct dfs_work;
747 bool rx_work_enabled; 767 bool rx_work_enabled;
748 bool rx_processing; 768 bool rx_processing;
749 bool delay_main_work; 769 bool delay_main_work;
@@ -823,6 +843,7 @@ struct mwifiex_adapter {
823 u16 gen_null_pkt; 843 u16 gen_null_pkt;
824 u16 pps_uapsd_mode; 844 u16 pps_uapsd_mode;
825 u32 pm_wakeup_fw_try; 845 u32 pm_wakeup_fw_try;
846 struct timer_list wakeup_timer;
826 u8 is_hs_configured; 847 u8 is_hs_configured;
827 struct mwifiex_hs_config_param hs_cfg; 848 struct mwifiex_hs_config_param hs_cfg;
828 u8 hs_activated; 849 u8 hs_activated;
@@ -865,6 +886,8 @@ struct mwifiex_adapter {
865 struct memory_type_mapping *mem_type_mapping_tbl; 886 struct memory_type_mapping *mem_type_mapping_tbl;
866 u8 num_mem_types; 887 u8 num_mem_types;
867 u8 curr_mem_idx; 888 u8 curr_mem_idx;
889 void *drv_info_dump;
890 u32 drv_info_size;
868 bool scan_chan_gap_enabled; 891 bool scan_chan_gap_enabled;
869 struct sk_buff_head rx_data_q; 892 struct sk_buff_head rx_data_q;
870 struct mwifiex_chan_stats *chan_stats; 893 struct mwifiex_chan_stats *chan_stats;
@@ -979,7 +1002,7 @@ void mwifiex_wmm_del_peer_ra_list(struct mwifiex_private *priv,
979 const u8 *ra_addr); 1002 const u8 *ra_addr);
980void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb); 1003void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
981void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb); 1004void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb);
982int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta); 1005int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta, bool init);
983int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, 1006int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
984 struct mwifiex_scan_cmd_config *scan_cfg); 1007 struct mwifiex_scan_cmd_config *scan_cfg);
985void mwifiex_queue_scan_cmd(struct mwifiex_private *priv, 1008void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
@@ -1140,6 +1163,25 @@ mwifiex_get_priv(struct mwifiex_adapter *adapter,
1140} 1163}
1141 1164
1142/* 1165/*
1166 * This function returns the first available unused private structure pointer.
1167 */
1168static inline struct mwifiex_private *
1169mwifiex_get_unused_priv(struct mwifiex_adapter *adapter)
1170{
1171 int i;
1172
1173 for (i = 0; i < adapter->priv_num; i++) {
1174 if (adapter->priv[i]) {
1175 if (adapter->priv[i]->bss_mode ==
1176 NL80211_IFTYPE_UNSPECIFIED)
1177 break;
1178 }
1179 }
1180
1181 return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
1182}
1183
1184/*
1143 * This function returns the driver private structure of a network device. 1185 * This function returns the driver private structure of a network device.
1144 */ 1186 */
1145static inline struct mwifiex_private * 1187static inline struct mwifiex_private *
@@ -1230,8 +1272,6 @@ int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1230 struct ieee80211_channel *chan, 1272 struct ieee80211_channel *chan,
1231 unsigned int duration); 1273 unsigned int duration);
1232 1274
1233int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
1234
1235int mwifiex_get_stats_info(struct mwifiex_private *priv, 1275int mwifiex_get_stats_info(struct mwifiex_private *priv,
1236 struct mwifiex_ds_get_stats *log); 1276 struct mwifiex_ds_get_stats *log);
1237 1277
@@ -1291,9 +1331,17 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv,
1291 struct cfg80211_beacon_data *data); 1331 struct cfg80211_beacon_data *data);
1292int mwifiex_del_mgmt_ies(struct mwifiex_private *priv); 1332int mwifiex_del_mgmt_ies(struct mwifiex_private *priv);
1293u8 *mwifiex_11d_code_2_region(u8 code); 1333u8 *mwifiex_11d_code_2_region(u8 code);
1334void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
1335 struct cfg80211_chan_def chandef);
1336int mwifiex_config_start_uap(struct mwifiex_private *priv,
1337 struct mwifiex_uap_bss_param *bss_cfg);
1294void mwifiex_uap_del_sta_data(struct mwifiex_private *priv, 1338void mwifiex_uap_del_sta_data(struct mwifiex_private *priv,
1295 struct mwifiex_sta_node *node); 1339 struct mwifiex_sta_node *node);
1296 1340
1341void mwifiex_init_11h_params(struct mwifiex_private *priv);
1342int mwifiex_is_11h_active(struct mwifiex_private *priv);
1343int mwifiex_11h_activate(struct mwifiex_private *priv, bool flag);
1344
1297void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer, 1345void mwifiex_11h_process_join(struct mwifiex_private *priv, u8 **buffer,
1298 struct mwifiex_bssdescriptor *bss_desc); 1346 struct mwifiex_bssdescriptor *bss_desc);
1299int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv); 1347int mwifiex_11h_handle_event_chanswann(struct mwifiex_private *priv);
@@ -1324,6 +1372,8 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
1324 u8 *buf, int len); 1372 u8 *buf, int len);
1325int mwifiex_tdls_oper(struct mwifiex_private *priv, const u8 *peer, u8 action); 1373int 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); 1374int mwifiex_get_tdls_link_status(struct mwifiex_private *priv, const u8 *mac);
1375int mwifiex_get_tdls_list(struct mwifiex_private *priv,
1376 struct tdls_peer_info *buf);
1327void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); 1377void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
1328bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); 1378bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
1329u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, 1379u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
@@ -1340,6 +1390,11 @@ void mwifiex_check_auto_tdls(unsigned long context);
1340void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac); 1390void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac);
1341void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv); 1391void mwifiex_setup_auto_tdls_timer(struct mwifiex_private *priv);
1342void mwifiex_clean_auto_tdls(struct mwifiex_private *priv); 1392void mwifiex_clean_auto_tdls(struct mwifiex_private *priv);
1393int mwifiex_cmd_issue_chan_report_request(struct mwifiex_private *priv,
1394 struct host_cmd_ds_command *cmd,
1395 void *data_buf);
1396int mwifiex_11h_handle_chanrpt_ready(struct mwifiex_private *priv,
1397 struct sk_buff *skb);
1343 1398
1344void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, 1399void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
1345 void *event_body); 1400 void *event_body);
@@ -1347,6 +1402,21 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
1347struct sk_buff * 1402struct sk_buff *
1348mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv, 1403mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
1349 struct sk_buff *skb, u8 flag, u64 *cookie); 1404 struct sk_buff *skb, u8 flag, u64 *cookie);
1405void mwifiex_dfs_cac_work_queue(struct work_struct *work);
1406void mwifiex_dfs_chan_sw_work_queue(struct work_struct *work);
1407void mwifiex_abort_cac(struct mwifiex_private *priv);
1408int mwifiex_11h_handle_radar_detected(struct mwifiex_private *priv,
1409 struct sk_buff *skb);
1410
1411void mwifiex_hist_data_set(struct mwifiex_private *priv, u8 rx_rate, s8 snr,
1412 s8 nflr);
1413void mwifiex_hist_data_reset(struct mwifiex_private *priv);
1414void mwifiex_hist_data_add(struct mwifiex_private *priv,
1415 u8 rx_rate, s8 snr, s8 nflr);
1416u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1417 u8 rx_rate, u8 ht_info);
1418
1419void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1350 1420
1351#ifdef CONFIG_DEBUG_FS 1421#ifdef CONFIG_DEBUG_FS
1352void mwifiex_debugfs_init(void); 1422void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index c3a20f94f3c9..a5828da59365 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -204,6 +204,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
204 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 204 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
205 card->pcie.tx_buf_size = data->tx_buf_size; 205 card->pcie.tx_buf_size = data->tx_buf_size;
206 card->pcie.supports_fw_dump = data->supports_fw_dump; 206 card->pcie.supports_fw_dump = data->supports_fw_dump;
207 card->pcie.can_ext_scan = data->can_ext_scan;
207 } 208 }
208 209
209 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 210 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -1952,8 +1953,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1952 offset += txlen; 1953 offset += txlen;
1953 } while (true); 1954 } while (true);
1954 1955
1955 dev_dbg(adapter->dev, "info:\nFW download over, size %d bytes\n", 1956 dev_notice(adapter->dev,
1956 offset); 1957 "info: FW download over, size %d bytes\n", offset);
1957 1958
1958 ret = 0; 1959 ret = 0;
1959 1960
@@ -2064,6 +2065,7 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
2064 * state until cookie is set */ 2065 * state until cookie is set */
2065 adapter->ps_state = PS_STATE_AWAKE; 2066 adapter->ps_state = PS_STATE_AWAKE;
2066 adapter->pm_wakeup_fw_try = false; 2067 adapter->pm_wakeup_fw_try = false;
2068 del_timer(&adapter->wakeup_timer);
2067 } 2069 }
2068 } 2070 }
2069} 2071}
@@ -2562,6 +2564,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2562 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl; 2564 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2563 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl); 2565 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
2564 strcpy(adapter->fw_name, card->pcie.firmware); 2566 strcpy(adapter->fw_name, card->pcie.firmware);
2567 adapter->ext_scan = card->pcie.can_ext_scan;
2565 2568
2566 return 0; 2569 return 0;
2567} 2570}
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 200e8b0cb582..666d40e9dbc3 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -206,6 +206,7 @@ struct mwifiex_pcie_device {
206 u16 blksz_fw_dl; 206 u16 blksz_fw_dl;
207 u16 tx_buf_size; 207 u16 tx_buf_size;
208 bool supports_fw_dump; 208 bool supports_fw_dump;
209 bool can_ext_scan;
209}; 210};
210 211
211static const struct mwifiex_pcie_device mwifiex_pcie8766 = { 212static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
@@ -214,6 +215,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
214 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 215 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
215 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 216 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
216 .supports_fw_dump = false, 217 .supports_fw_dump = false,
218 .can_ext_scan = true,
217}; 219};
218 220
219static const struct mwifiex_pcie_device mwifiex_pcie8897 = { 221static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
@@ -222,6 +224,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
222 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 224 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
223 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 225 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
224 .supports_fw_dump = true, 226 .supports_fw_dump = true,
227 .can_ext_scan = true,
225}; 228};
226 229
227struct mwifiex_evt_buf_desc { 230struct mwifiex_evt_buf_desc {
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 984a7a4fa93b..0ffdb7c5afd2 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -496,10 +496,10 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
496 496
497 for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) { 497 for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
498 498
499 if (!priv->wdev->wiphy->bands[band]) 499 if (!priv->wdev.wiphy->bands[band])
500 continue; 500 continue;
501 501
502 sband = priv->wdev->wiphy->bands[band]; 502 sband = priv->wdev.wiphy->bands[band];
503 503
504 for (i = 0; (i < sband->n_channels) ; i++) { 504 for (i = 0; (i < sband->n_channels) ; i++) {
505 ch = &sband->channels[i]; 505 ch = &sband->channels[i];
@@ -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);
@@ -1727,10 +1733,10 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1727 1733
1728 freq = cfp ? cfp->freq : 0; 1734 freq = cfp ? cfp->freq : 0;
1729 1735
1730 chan = ieee80211_get_channel(priv->wdev->wiphy, freq); 1736 chan = ieee80211_get_channel(priv->wdev.wiphy, freq);
1731 1737
1732 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { 1738 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1733 bss = cfg80211_inform_bss(priv->wdev->wiphy, 1739 bss = cfg80211_inform_bss(priv->wdev.wiphy,
1734 chan, CFG80211_BSS_FTYPE_UNKNOWN, 1740 chan, CFG80211_BSS_FTYPE_UNKNOWN,
1735 bssid, timestamp, 1741 bssid, timestamp,
1736 cap_info_bitmap, beacon_period, 1742 cap_info_bitmap, beacon_period,
@@ -1742,7 +1748,7 @@ mwifiex_parse_single_response_buf(struct mwifiex_private *priv, u8 **bss_info,
1742 !memcmp(bssid, priv->curr_bss_params.bss_descriptor 1748 !memcmp(bssid, priv->curr_bss_params.bss_descriptor
1743 .mac_address, ETH_ALEN)) 1749 .mac_address, ETH_ALEN))
1744 mwifiex_update_curr_bss_params(priv, bss); 1750 mwifiex_update_curr_bss_params(priv, bss);
1745 cfg80211_put_bss(priv->wdev->wiphy, bss); 1751 cfg80211_put_bss(priv->wdev.wiphy, bss);
1746 } 1752 }
1747 } else { 1753 } else {
1748 dev_dbg(adapter->dev, "missing BSS channel IE\n"); 1754 dev_dbg(adapter->dev, "missing BSS channel IE\n");
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 933dae137850..91e36cda9543 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -107,6 +107,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size; 107 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;
108 card->supports_fw_dump = data->supports_fw_dump; 108 card->supports_fw_dump = data->supports_fw_dump;
109 card->auto_tdls = data->auto_tdls; 109 card->auto_tdls = data->auto_tdls;
110 card->can_ext_scan = data->can_ext_scan;
110 } 111 }
111 112
112 sdio_claim_host(func); 113 sdio_claim_host(func);
@@ -282,6 +283,9 @@ static int mwifiex_sdio_suspend(struct device *dev)
282#define SDIO_DEVICE_ID_MARVELL_8897 (0x912d) 283#define SDIO_DEVICE_ID_MARVELL_8897 (0x912d)
283/* Device ID for SD8887 */ 284/* Device ID for SD8887 */
284#define SDIO_DEVICE_ID_MARVELL_8887 (0x9135) 285#define SDIO_DEVICE_ID_MARVELL_8887 (0x9135)
286/* Device ID for SD8801 */
287#define SDIO_DEVICE_ID_MARVELL_8801 (0x9139)
288
285 289
286/* WLAN IDs */ 290/* WLAN IDs */
287static const struct sdio_device_id mwifiex_ids[] = { 291static const struct sdio_device_id mwifiex_ids[] = {
@@ -295,6 +299,8 @@ static const struct sdio_device_id mwifiex_ids[] = {
295 .driver_data = (unsigned long) &mwifiex_sdio_sd8897}, 299 .driver_data = (unsigned long) &mwifiex_sdio_sd8897},
296 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887), 300 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887),
297 .driver_data = (unsigned long)&mwifiex_sdio_sd8887}, 301 .driver_data = (unsigned long)&mwifiex_sdio_sd8887},
302 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8801),
303 .driver_data = (unsigned long)&mwifiex_sdio_sd8801},
298 {}, 304 {},
299}; 305};
300 306
@@ -986,8 +992,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
986 offset += txlen; 992 offset += txlen;
987 } while (true); 993 } while (true);
988 994
989 dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n", 995 dev_notice(adapter->dev,
990 offset); 996 "info: FW download over, size %d bytes\n", offset);
991 997
992 ret = 0; 998 ret = 0;
993done: 999done:
@@ -1882,6 +1888,7 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
1882 } 1888 }
1883 1889
1884 adapter->auto_tdls = card->auto_tdls; 1890 adapter->auto_tdls = card->auto_tdls;
1891 adapter->ext_scan = card->can_ext_scan;
1885 return ret; 1892 return ret;
1886} 1893}
1887 1894
@@ -1958,8 +1965,8 @@ static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1958 1965
1959 pr_err("Resetting card...\n"); 1966 pr_err("Resetting card...\n");
1960 mmc_remove_host(target); 1967 mmc_remove_host(target);
1961 /* 20ms delay is based on experiment with sdhci controller */ 1968 /* 200ms delay is based on experiment with sdhci controller */
1962 mdelay(20); 1969 mdelay(200);
1963 target->rescan_entered = 0; /* rescan non-removable cards */ 1970 target->rescan_entered = 0; /* rescan non-removable cards */
1964 mmc_add_host(target); 1971 mmc_add_host(target);
1965} 1972}
@@ -2023,6 +2030,8 @@ static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2023 u32 memory_size; 2030 u32 memory_size;
2024 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL }; 2031 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
2025 2032
2033 mwifiex_dump_drv_info(adapter);
2034
2026 if (!card->supports_fw_dump) 2035 if (!card->supports_fw_dump)
2027 return; 2036 return;
2028 2037
@@ -2166,6 +2175,99 @@ static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2166 schedule_work(&adapter->iface_work); 2175 schedule_work(&adapter->iface_work);
2167} 2176}
2168 2177
2178/* Function to dump SDIO function registers and SDIO scratch registers in case
2179 * of FW crash
2180 */
2181static int
2182mwifiex_sdio_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)
2183{
2184 char *p = drv_buf;
2185 struct sdio_mmc_card *cardp = adapter->card;
2186 int ret = 0;
2187 u8 count, func, data, index = 0, size = 0;
2188 u8 reg, reg_start, reg_end;
2189 char buf[256], *ptr;
2190
2191 if (!p)
2192 return 0;
2193
2194 dev_info(adapter->dev, "SDIO register DUMP START\n");
2195
2196 mwifiex_pm_wakeup_card(adapter);
2197
2198 sdio_claim_host(cardp->func);
2199
2200 for (count = 0; count < 5; count++) {
2201 memset(buf, 0, sizeof(buf));
2202 ptr = buf;
2203
2204 switch (count) {
2205 case 0:
2206 /* Read the registers of SDIO function0 */
2207 func = count;
2208 reg_start = 0;
2209 reg_end = 9;
2210 break;
2211 case 1:
2212 /* Read the registers of SDIO function1 */
2213 func = count;
2214 reg_start = cardp->reg->func1_dump_reg_start;
2215 reg_end = cardp->reg->func1_dump_reg_end;
2216 break;
2217 case 2:
2218 index = 0;
2219 func = 1;
2220 reg_start = cardp->reg->func1_spec_reg_table[index++];
2221 size = cardp->reg->func1_spec_reg_num;
2222 reg_end = cardp->reg->func1_spec_reg_table[size-1];
2223 break;
2224 default:
2225 /* Read the scratch registers of SDIO function1 */
2226 if (count == 4)
2227 mdelay(100);
2228 func = 1;
2229 reg_start = cardp->reg->func1_scratch_reg;
2230 reg_end = reg_start + MWIFIEX_SDIO_SCRATCH_SIZE;
2231 }
2232
2233 if (count != 2)
2234 ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ",
2235 func, reg_start, reg_end);
2236 else
2237 ptr += sprintf(ptr, "SDIO Func%d: ", func);
2238
2239 for (reg = reg_start; reg <= reg_end;) {
2240 if (func == 0)
2241 data = sdio_f0_readb(cardp->func, reg, &ret);
2242 else
2243 data = sdio_readb(cardp->func, reg, &ret);
2244
2245 if (count == 2)
2246 ptr += sprintf(ptr, "(%#x) ", reg);
2247 if (!ret) {
2248 ptr += sprintf(ptr, "%02x ", data);
2249 } else {
2250 ptr += sprintf(ptr, "ERR");
2251 break;
2252 }
2253
2254 if (count == 2 && reg < reg_end)
2255 reg = cardp->reg->func1_spec_reg_table[index++];
2256 else
2257 reg++;
2258 }
2259
2260 dev_info(adapter->dev, "%s\n", buf);
2261 p += sprintf(p, "%s\n", buf);
2262 }
2263
2264 sdio_release_host(cardp->func);
2265
2266 dev_info(adapter->dev, "SDIO register DUMP END\n");
2267
2268 return p - drv_buf;
2269}
2270
2169static struct mwifiex_if_ops sdio_ops = { 2271static struct mwifiex_if_ops sdio_ops = {
2170 .init_if = mwifiex_init_sdio, 2272 .init_if = mwifiex_init_sdio,
2171 .cleanup_if = mwifiex_cleanup_sdio, 2273 .cleanup_if = mwifiex_cleanup_sdio,
@@ -2188,6 +2290,7 @@ static struct mwifiex_if_ops sdio_ops = {
2188 .card_reset = mwifiex_sdio_card_reset, 2290 .card_reset = mwifiex_sdio_card_reset,
2189 .iface_work = mwifiex_sdio_work, 2291 .iface_work = mwifiex_sdio_work,
2190 .fw_dump = mwifiex_sdio_fw_dump, 2292 .fw_dump = mwifiex_sdio_fw_dump,
2293 .reg_dump = mwifiex_sdio_reg_dump,
2191}; 2294};
2192 2295
2193/* 2296/*
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 54c07156dd78..957cca246618 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -34,6 +34,7 @@
34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin" 34#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
35#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin" 35#define SD8897_DEFAULT_FW_NAME "mrvl/sd8897_uapsta.bin"
36#define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin" 36#define SD8887_DEFAULT_FW_NAME "mrvl/sd8887_uapsta.bin"
37#define SD8801_DEFAULT_FW_NAME "mrvl/sd8801_uapsta.bin"
37 38
38#define BLOCK_MODE 1 39#define BLOCK_MODE 1
39#define BYTE_MODE 0 40#define BYTE_MODE 0
@@ -44,6 +45,9 @@
44 45
45#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000 46#define MWIFIEX_SDIO_BYTE_MODE_MASK 0x80000000
46 47
48#define MWIFIEX_MAX_FUNC2_REG_NUM 13
49#define MWIFIEX_SDIO_SCRATCH_SIZE 10
50
47#define SDIO_MPA_ADDR_BASE 0x1000 51#define SDIO_MPA_ADDR_BASE 0x1000
48#define CTRL_PORT 0 52#define CTRL_PORT 0
49#define CTRL_PORT_MASK 0x0001 53#define CTRL_PORT_MASK 0x0001
@@ -219,6 +223,11 @@ struct mwifiex_sdio_card_reg {
219 u8 fw_dump_ctrl; 223 u8 fw_dump_ctrl;
220 u8 fw_dump_start; 224 u8 fw_dump_start;
221 u8 fw_dump_end; 225 u8 fw_dump_end;
226 u8 func1_dump_reg_start;
227 u8 func1_dump_reg_end;
228 u8 func1_scratch_reg;
229 u8 func1_spec_reg_num;
230 u8 func1_spec_reg_table[MWIFIEX_MAX_FUNC2_REG_NUM];
222}; 231};
223 232
224struct sdio_mmc_card { 233struct sdio_mmc_card {
@@ -247,6 +256,7 @@ struct sdio_mmc_card {
247 256
248 u8 *mp_regs; 257 u8 *mp_regs;
249 u8 auto_tdls; 258 u8 auto_tdls;
259 bool can_ext_scan;
250 260
251 struct mwifiex_sdio_mpa_tx mpa_tx; 261 struct mwifiex_sdio_mpa_tx mpa_tx;
252 struct mwifiex_sdio_mpa_rx mpa_rx; 262 struct mwifiex_sdio_mpa_rx mpa_rx;
@@ -264,6 +274,7 @@ struct mwifiex_sdio_device {
264 u32 mp_tx_agg_buf_size; 274 u32 mp_tx_agg_buf_size;
265 u32 mp_rx_agg_buf_size; 275 u32 mp_rx_agg_buf_size;
266 u8 auto_tdls; 276 u8 auto_tdls;
277 bool can_ext_scan;
267}; 278};
268 279
269static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = { 280static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
@@ -291,6 +302,11 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {
291 .rd_len_p0_l = 0x08, 302 .rd_len_p0_l = 0x08,
292 .rd_len_p0_u = 0x09, 303 .rd_len_p0_u = 0x09,
293 .card_misc_cfg_reg = 0x6c, 304 .card_misc_cfg_reg = 0x6c,
305 .func1_dump_reg_start = 0x0,
306 .func1_dump_reg_end = 0x9,
307 .func1_scratch_reg = 0x60,
308 .func1_spec_reg_num = 5,
309 .func1_spec_reg_table = {0x28, 0x30, 0x34, 0x38, 0x3c},
294}; 310};
295 311
296static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = { 312static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
@@ -335,6 +351,12 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
335 .fw_dump_ctrl = 0xe2, 351 .fw_dump_ctrl = 0xe2,
336 .fw_dump_start = 0xe3, 352 .fw_dump_start = 0xe3,
337 .fw_dump_end = 0xea, 353 .fw_dump_end = 0xea,
354 .func1_dump_reg_start = 0x0,
355 .func1_dump_reg_end = 0xb,
356 .func1_scratch_reg = 0xc0,
357 .func1_spec_reg_num = 8,
358 .func1_spec_reg_table = {0x4C, 0x50, 0x54, 0x55, 0x58,
359 0x59, 0x5c, 0x5d},
338}; 360};
339 361
340static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = { 362static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = {
@@ -376,6 +398,13 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = {
376 .cmd_cfg_1 = 0xc5, 398 .cmd_cfg_1 = 0xc5,
377 .cmd_cfg_2 = 0xc6, 399 .cmd_cfg_2 = 0xc6,
378 .cmd_cfg_3 = 0xc7, 400 .cmd_cfg_3 = 0xc7,
401 .func1_dump_reg_start = 0x10,
402 .func1_dump_reg_end = 0x17,
403 .func1_scratch_reg = 0x90,
404 .func1_spec_reg_num = 13,
405 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D, 0x60,
406 0x61, 0x62, 0x64, 0x65, 0x66,
407 0x68, 0x69, 0x6a},
379}; 408};
380 409
381static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { 410static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
@@ -390,6 +419,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
390 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 419 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
391 .supports_fw_dump = false, 420 .supports_fw_dump = false,
392 .auto_tdls = false, 421 .auto_tdls = false,
422 .can_ext_scan = false,
393}; 423};
394 424
395static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { 425static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -404,6 +434,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
404 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 434 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
405 .supports_fw_dump = false, 435 .supports_fw_dump = false,
406 .auto_tdls = false, 436 .auto_tdls = false,
437 .can_ext_scan = true,
407}; 438};
408 439
409static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { 440static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -418,6 +449,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
418 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 449 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
419 .supports_fw_dump = false, 450 .supports_fw_dump = false,
420 .auto_tdls = false, 451 .auto_tdls = false,
452 .can_ext_scan = true,
421}; 453};
422 454
423static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { 455static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -432,6 +464,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
432 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 464 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
433 .supports_fw_dump = true, 465 .supports_fw_dump = true,
434 .auto_tdls = false, 466 .auto_tdls = false,
467 .can_ext_scan = true,
435}; 468};
436 469
437static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { 470static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
@@ -446,6 +479,22 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
446 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 479 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
447 .supports_fw_dump = false, 480 .supports_fw_dump = false,
448 .auto_tdls = true, 481 .auto_tdls = true,
482 .can_ext_scan = true,
483};
484
485static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
486 .firmware = SD8801_DEFAULT_FW_NAME,
487 .reg = &mwifiex_reg_sd87xx,
488 .max_ports = 16,
489 .mp_agg_pkt_limit = 8,
490 .supports_sdio_new_mode = false,
491 .has_control_mask = true,
492 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
493 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
494 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
495 .supports_fw_dump = false,
496 .auto_tdls = false,
497 .can_ext_scan = true,
449}; 498};
450 499
451/* 500/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 1c2ca291d1f5..f7d204ffd6e9 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 *
@@ -1893,6 +1897,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1893 case HostCmd_CMD_TDLS_OPER: 1897 case HostCmd_CMD_TDLS_OPER:
1894 ret = mwifiex_cmd_tdls_oper(priv, cmd_ptr, data_buf); 1898 ret = mwifiex_cmd_tdls_oper(priv, cmd_ptr, data_buf);
1895 break; 1899 break;
1900 case HostCmd_CMD_CHAN_REPORT_REQUEST:
1901 ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr,
1902 data_buf);
1903 break;
1896 default: 1904 default:
1897 dev_err(priv->adapter->dev, 1905 dev_err(priv->adapter->dev,
1898 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1906 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
@@ -1907,6 +1915,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1907 * 1915 *
1908 * This is called after firmware download to bring the card to 1916 * This is called after firmware download to bring the card to
1909 * working state. 1917 * working state.
1918 * Function is also called during reinitialization of virtual
1919 * interfaces.
1910 * 1920 *
1911 * The following commands are issued sequentially - 1921 * The following commands are issued sequentially -
1912 * - Set PCI-Express host buffer configuration (PCIE only) 1922 * - Set PCI-Express host buffer configuration (PCIE only)
@@ -1921,7 +1931,7 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1921 * - Set 11d control 1931 * - Set 11d control
1922 * - Set MAC control (this must be the last command to initialize firmware) 1932 * - Set MAC control (this must be the last command to initialize firmware)
1923 */ 1933 */
1924int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) 1934int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
1925{ 1935{
1926 struct mwifiex_adapter *adapter = priv->adapter; 1936 struct mwifiex_adapter *adapter = priv->adapter;
1927 int ret; 1937 int ret;
@@ -2031,7 +2041,8 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2031 if (ret) 2041 if (ret)
2032 return -1; 2042 return -1;
2033 2043
2034 if (first_sta && priv->adapter->iface_type != MWIFIEX_USB && 2044 if (!disable_auto_ds &&
2045 first_sta && priv->adapter->iface_type != MWIFIEX_USB &&
2035 priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 2046 priv->bss_type != MWIFIEX_BSS_TYPE_UAP) {
2036 /* Enable auto deep sleep */ 2047 /* Enable auto deep sleep */
2037 auto_ds.auto_ds = DEEP_SLEEP_ON; 2048 auto_ds.auto_ds = DEEP_SLEEP_ON;
@@ -2054,9 +2065,6 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2054 "11D: failed to enable 11D\n"); 2065 "11D: failed to enable 11D\n");
2055 } 2066 }
2056 2067
2057 /* set last_init_cmd before sending the command */
2058 priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
2059
2060 /* Send cmd to FW to configure 11n specific configuration 2068 /* Send cmd to FW to configure 11n specific configuration
2061 * (Short GI, Channel BW, Green field support etc.) for transmit 2069 * (Short GI, Channel BW, Green field support etc.) for transmit
2062 */ 2070 */
@@ -2064,7 +2072,11 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
2064 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG, 2072 ret = mwifiex_send_cmd(priv, HostCmd_CMD_11N_CFG,
2065 HostCmd_ACT_GEN_SET, 0, &tx_cfg, true); 2073 HostCmd_ACT_GEN_SET, 0, &tx_cfg, true);
2066 2074
2067 ret = -EINPROGRESS; 2075 if (init) {
2076 /* set last_init_cmd before sending the command */
2077 priv->adapter->last_init_cmd = HostCmd_CMD_11N_CFG;
2078 ret = -EINPROGRESS;
2079 }
2068 2080
2069 return ret; 2081 return ret;
2070} 2082}
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index b65e1014b0fc..5f8da5924666 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;
@@ -1103,6 +1105,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1103 case HostCmd_CMD_UAP_SYS_CONFIG: 1105 case HostCmd_CMD_UAP_SYS_CONFIG:
1104 break; 1106 break;
1105 case HostCmd_CMD_UAP_BSS_START: 1107 case HostCmd_CMD_UAP_BSS_START:
1108 adapter->tx_lock_flag = false;
1109 adapter->pps_uapsd_mode = false;
1110 adapter->delay_null_pkt = false;
1106 priv->bss_started = 1; 1111 priv->bss_started = 1;
1107 break; 1112 break;
1108 case HostCmd_CMD_UAP_BSS_STOP: 1113 case HostCmd_CMD_UAP_BSS_STOP:
@@ -1117,6 +1122,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1117 case HostCmd_CMD_TDLS_OPER: 1122 case HostCmd_CMD_TDLS_OPER:
1118 ret = mwifiex_ret_tdls_oper(priv, resp); 1123 ret = mwifiex_ret_tdls_oper(priv, resp);
1119 break; 1124 break;
1125 case HostCmd_CMD_CHAN_REPORT_REQUEST:
1126 break;
1120 default: 1127 default:
1121 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 1128 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
1122 resp->command); 1129 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index b8c171df6223..80ffe7412496 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,7 @@ 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 del_timer_sync(&adapter->wakeup_timer);
311 break; 316 break;
312 } 317 }
313 if (!mwifiex_send_null_packet 318 if (!mwifiex_send_null_packet
@@ -322,6 +327,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
322 adapter->ps_state = PS_STATE_AWAKE; 327 adapter->ps_state = PS_STATE_AWAKE;
323 adapter->pm_wakeup_card_req = false; 328 adapter->pm_wakeup_card_req = false;
324 adapter->pm_wakeup_fw_try = false; 329 adapter->pm_wakeup_fw_try = false;
330 del_timer_sync(&adapter->wakeup_timer);
325 331
326 break; 332 break;
327 333
@@ -480,7 +486,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
480 486
481 case EVENT_REMAIN_ON_CHAN_EXPIRED: 487 case EVENT_REMAIN_ON_CHAN_EXPIRED:
482 dev_dbg(adapter->dev, "event: Remain on channel expired\n"); 488 dev_dbg(adapter->dev, "event: Remain on channel expired\n");
483 cfg80211_remain_on_channel_expired(priv->wdev, 489 cfg80211_remain_on_channel_expired(&priv->wdev,
484 priv->roc_cfg.cookie, 490 priv->roc_cfg.cookie,
485 &priv->roc_cfg.chan, 491 &priv->roc_cfg.chan,
486 GFP_ATOMIC); 492 GFP_ATOMIC);
@@ -509,6 +515,16 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
509 mwifiex_parse_tx_status_event(priv, adapter->event_body); 515 mwifiex_parse_tx_status_event(priv, adapter->event_body);
510 break; 516 break;
511 517
518 case EVENT_CHANNEL_REPORT_RDY:
519 dev_dbg(adapter->dev, "event: Channel Report\n");
520 ret = mwifiex_11h_handle_chanrpt_ready(priv,
521 adapter->event_skb);
522 break;
523 case EVENT_RADAR_DETECTED:
524 dev_dbg(adapter->dev, "event: Radar detected\n");
525 ret = mwifiex_11h_handle_radar_detected(priv,
526 adapter->event_skb);
527 break;
512 default: 528 default:
513 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 529 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
514 eventcause); 530 eventcause);
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 1626868a4b5c..0599e41e253c 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -219,7 +219,7 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
219 219
220 if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) { 220 if (!strncmp(priv->adapter->country_code, &country_ie[2], 2)) {
221 rcu_read_unlock(); 221 rcu_read_unlock();
222 wiphy_dbg(priv->wdev->wiphy, 222 wiphy_dbg(priv->wdev.wiphy,
223 "11D: skip setting domain info in FW\n"); 223 "11D: skip setting domain info in FW\n");
224 return 0; 224 return 0;
225 } 225 }
@@ -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
@@ -1131,36 +1135,6 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1131 return roc_cfg.status; 1135 return roc_cfg.status;
1132} 1136}
1133 1137
1134int
1135mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1136{
1137 if (GET_BSS_ROLE(priv) == bss_role) {
1138 dev_dbg(priv->adapter->dev,
1139 "info: already in the desired role.\n");
1140 return 0;
1141 }
1142
1143 mwifiex_free_priv(priv);
1144 mwifiex_init_priv(priv);
1145
1146 priv->bss_role = bss_role;
1147 switch (bss_role) {
1148 case MWIFIEX_BSS_ROLE_UAP:
1149 priv->bss_mode = NL80211_IFTYPE_AP;
1150 break;
1151 case MWIFIEX_BSS_ROLE_STA:
1152 case MWIFIEX_BSS_ROLE_ANY:
1153 default:
1154 priv->bss_mode = NL80211_IFTYPE_STATION;
1155 break;
1156 }
1157
1158 mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1159 HostCmd_ACT_GEN_SET, 0, NULL, true);
1160
1161 return mwifiex_sta_init_cmd(priv, false);
1162}
1163
1164/* 1138/*
1165 * Sends IOCTL request to get statistics information. 1139 * Sends IOCTL request to get statistics information.
1166 * 1140 *
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..5ce2d9a4f919 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 */
@@ -182,9 +183,13 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
182 } 183 }
183 switch (ret) { 184 switch (ret) {
184 case -EBUSY: 185 case -EBUSY:
185 adapter->data_sent = true; 186 dev_kfree_skb_any(skb);
186 /* Fall through FAILURE handling */ 187 dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
188 __func__, ret);
189 adapter->dbg.num_tx_host_to_card_failure++;
190 break;
187 case -1: 191 case -1:
192 adapter->data_sent = false;
188 dev_kfree_skb_any(skb); 193 dev_kfree_skb_any(skb);
189 dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n", 194 dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
190 __func__, ret); 195 __func__, ret);
@@ -197,6 +202,7 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
197 adapter->tx_lock_flag = true; 202 adapter->tx_lock_flag = true;
198 break; 203 break;
199 case -EINPROGRESS: 204 case -EINPROGRESS:
205 adapter->tx_lock_flag = true;
200 break; 206 break;
201 default: 207 default:
202 break; 208 break;
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/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 6ae133333363..ac93557cbdc9 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -227,7 +227,7 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
227 /* consumes ack_skb */ 227 /* consumes ack_skb */
228 skb_complete_wifi_ack(ack_skb, !tx_status->status); 228 skb_complete_wifi_ack(ack_skb, !tx_status->status);
229 } else { 229 } else {
230 cfg80211_mgmt_tx_status(priv->wdev, tx_info->cookie, 230 cfg80211_mgmt_tx_status(&priv->wdev, tx_info->cookie,
231 ack_skb->data, ack_skb->len, 231 ack_skb->data, ack_skb->len,
232 !tx_status->status, GFP_ATOMIC); 232 !tx_status->status, GFP_ATOMIC);
233 dev_kfree_skb_any(ack_skb); 233 dev_kfree_skb_any(ack_skb);
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 0f347fdefa0a..f5c2af01ba0a 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -761,6 +761,11 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
761 if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf)) 761 if (mwifiex_cmd_uap_sta_deauth(priv, cmd, data_buf))
762 return -1; 762 return -1;
763 break; 763 break;
764 case HostCmd_CMD_CHAN_REPORT_REQUEST:
765 if (mwifiex_cmd_issue_chan_report_request(priv, cmd_buf,
766 data_buf))
767 return -1;
768 break;
764 default: 769 default:
765 dev_err(priv->adapter->dev, 770 dev_err(priv->adapter->dev,
766 "PREP_CMD: unknown cmd %#x\n", cmd_no); 771 "PREP_CMD: unknown cmd %#x\n", cmd_no);
@@ -769,3 +774,68 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no,
769 774
770 return 0; 775 return 0;
771} 776}
777
778void mwifiex_uap_set_channel(struct mwifiex_uap_bss_param *bss_cfg,
779 struct cfg80211_chan_def chandef)
780{
781 u8 config_bands = 0;
782
783 bss_cfg->channel = ieee80211_frequency_to_channel(
784 chandef.chan->center_freq);
785
786 /* Set appropriate bands */
787 if (chandef.chan->band == IEEE80211_BAND_2GHZ) {
788 bss_cfg->band_cfg = BAND_CONFIG_BG;
789 config_bands = BAND_B | BAND_G;
790
791 if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
792 config_bands |= BAND_GN;
793 } else {
794 bss_cfg->band_cfg = BAND_CONFIG_A;
795 config_bands = BAND_A;
796
797 if (chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
798 config_bands |= BAND_AN;
799
800 if (chandef.width > NL80211_CHAN_WIDTH_40)
801 config_bands |= BAND_AAC;
802 }
803}
804
805int mwifiex_config_start_uap(struct mwifiex_private *priv,
806 struct mwifiex_uap_bss_param *bss_cfg)
807{
808 if (mwifiex_del_mgmt_ies(priv))
809 dev_err(priv->adapter->dev, "Failed to delete mgmt IEs!\n");
810
811 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
812 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
813 dev_err(priv->adapter->dev, "Failed to stop the BSS\n");
814 return -1;
815 }
816
817 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
818 HostCmd_ACT_GEN_SET,
819 UAP_BSS_PARAMS_I, bss_cfg, false)) {
820 dev_err(priv->adapter->dev, "Failed to set the SSID\n");
821 return -1;
822 }
823
824 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
825 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
826 dev_err(priv->adapter->dev, "Failed to start the BSS\n");
827 return -1;
828 }
829
830 if (priv->sec_info.wep_enabled)
831 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
832 else
833 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
834
835 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
836 HostCmd_ACT_GEN_SET, 0,
837 &priv->curr_pkt_filter, true))
838 return -1;
839
840 return 0;
841}
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index c54a537e31fb..f4794cdc36d2 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -68,7 +68,6 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
68 len = ETH_ALEN; 68 len = ETH_ALEN;
69 69
70 if (len != -1) { 70 if (len != -1) {
71 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
72 sinfo.assoc_req_ies = &event->data[len]; 71 sinfo.assoc_req_ies = &event->data[len];
73 len = (u8 *)sinfo.assoc_req_ies - 72 len = (u8 *)sinfo.assoc_req_ies -
74 (u8 *)&event->frame_control; 73 (u8 *)&event->frame_control;
@@ -132,6 +131,8 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
132 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); 131 dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause);
133 memcpy(priv->netdev->dev_addr, adapter->event_body + 2, 132 memcpy(priv->netdev->dev_addr, adapter->event_body + 2,
134 ETH_ALEN); 133 ETH_ALEN);
134 if (priv->hist_data)
135 mwifiex_hist_data_reset(priv);
135 break; 136 break;
136 case EVENT_UAP_MIC_COUNTERMEASURES: 137 case EVENT_UAP_MIC_COUNTERMEASURES:
137 /* For future development */ 138 /* For future development */
@@ -177,6 +178,53 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv)
177 dev_dbg(adapter->dev, "event: TX_STATUS Report\n"); 178 dev_dbg(adapter->dev, "event: TX_STATUS Report\n");
178 mwifiex_parse_tx_status_event(priv, adapter->event_body); 179 mwifiex_parse_tx_status_event(priv, adapter->event_body);
179 break; 180 break;
181 case EVENT_PS_SLEEP:
182 dev_dbg(adapter->dev, "info: EVENT: SLEEP\n");
183
184 adapter->ps_state = PS_STATE_PRE_SLEEP;
185
186 mwifiex_check_ps_cond(adapter);
187 break;
188
189 case EVENT_PS_AWAKE:
190 dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
191 if (!adapter->pps_uapsd_mode &&
192 priv->media_connected && adapter->sleep_period.period) {
193 adapter->pps_uapsd_mode = true;
194 dev_dbg(adapter->dev,
195 "event: PPS/UAPSD mode activated\n");
196 }
197 adapter->tx_lock_flag = false;
198 if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
199 if (mwifiex_check_last_packet_indication(priv)) {
200 if (adapter->data_sent) {
201 adapter->ps_state = PS_STATE_AWAKE;
202 adapter->pm_wakeup_card_req = false;
203 adapter->pm_wakeup_fw_try = false;
204 break;
205 }
206 if (!mwifiex_send_null_packet
207 (priv,
208 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
209 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
210 adapter->ps_state =
211 PS_STATE_SLEEP;
212 return 0;
213 }
214 }
215 adapter->ps_state = PS_STATE_AWAKE;
216 adapter->pm_wakeup_card_req = false;
217 adapter->pm_wakeup_fw_try = false;
218 break;
219
220 case EVENT_CHANNEL_REPORT_RDY:
221 dev_dbg(adapter->dev, "event: Channel Report\n");
222 mwifiex_11h_handle_chanrpt_ready(priv, adapter->event_skb);
223 break;
224 case EVENT_RADAR_DETECTED:
225 dev_dbg(adapter->dev, "event: Radar detected\n");
226 mwifiex_11h_handle_radar_detected(priv, adapter->event_skb);
227 break;
180 default: 228 default:
181 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 229 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
182 eventcause); 230 eventcause);
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..223873022ffe 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -37,6 +37,11 @@ static struct usb_device_id mwifiex_usb_table[] = {
37 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2, 37 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2,
38 USB_CLASS_VENDOR_SPEC, 38 USB_CLASS_VENDOR_SPEC,
39 USB_SUBCLASS_VENDOR_SPEC, 0xff)}, 39 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
40 /* 8801 */
41 {USB_DEVICE(USB8XXX_VID, USB8801_PID_1)},
42 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8801_PID_2,
43 USB_CLASS_VENDOR_SPEC,
44 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
40 /* 8897 */ 45 /* 8897 */
41 {USB_DEVICE(USB8XXX_VID, USB8897_PID_1)}, 46 {USB_DEVICE(USB8XXX_VID, USB8897_PID_1)},
42 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8897_PID_2, 47 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8897_PID_2,
@@ -361,11 +366,13 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
361 switch (id_product) { 366 switch (id_product) {
362 case USB8766_PID_1: 367 case USB8766_PID_1:
363 case USB8797_PID_1: 368 case USB8797_PID_1:
369 case USB8801_PID_1:
364 case USB8897_PID_1: 370 case USB8897_PID_1:
365 card->usb_boot_state = USB8XXX_FW_DNLD; 371 card->usb_boot_state = USB8XXX_FW_DNLD;
366 break; 372 break;
367 case USB8766_PID_2: 373 case USB8766_PID_2:
368 case USB8797_PID_2: 374 case USB8797_PID_2:
375 case USB8801_PID_2:
369 case USB8897_PID_2: 376 case USB8897_PID_2:
370 card->usb_boot_state = USB8XXX_FW_READY; 377 card->usb_boot_state = USB8XXX_FW_READY;
371 break; 378 break;
@@ -792,11 +799,19 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
792 case USB8897_PID_2: 799 case USB8897_PID_2:
793 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K; 800 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
794 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME); 801 strcpy(adapter->fw_name, USB8897_DEFAULT_FW_NAME);
802 adapter->ext_scan = true;
795 break; 803 break;
796 case USB8766_PID_1: 804 case USB8766_PID_1:
797 case USB8766_PID_2: 805 case USB8766_PID_2:
798 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K; 806 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
799 strcpy(adapter->fw_name, USB8766_DEFAULT_FW_NAME); 807 strcpy(adapter->fw_name, USB8766_DEFAULT_FW_NAME);
808 adapter->ext_scan = true;
809 break;
810 case USB8801_PID_1:
811 case USB8801_PID_2:
812 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
813 strcpy(adapter->fw_name, USB8801_DEFAULT_FW_NAME);
814 adapter->ext_scan = false;
800 break; 815 break;
801 case USB8797_PID_1: 816 case USB8797_PID_1:
802 case USB8797_PID_2: 817 case USB8797_PID_2:
@@ -930,7 +945,8 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
930 } while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries); 945 } while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries);
931 946
932cleanup: 947cleanup:
933 dev_dbg(adapter->dev, "%s: %d bytes downloaded\n", __func__, tlen); 948 dev_notice(adapter->dev,
949 "info: FW download over, size %d bytes\n", tlen);
934 950
935 kfree(recv_buff); 951 kfree(recv_buff);
936 kfree(fwdata); 952 kfree(fwdata);
@@ -990,6 +1006,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
990{ 1006{
991 /* Simulation of HS_AWAKE event */ 1007 /* Simulation of HS_AWAKE event */
992 adapter->pm_wakeup_fw_try = false; 1008 adapter->pm_wakeup_fw_try = false;
1009 del_timer_sync(&adapter->wakeup_timer);
993 adapter->pm_wakeup_card_req = false; 1010 adapter->pm_wakeup_card_req = false;
994 adapter->ps_state = PS_STATE_AWAKE; 1011 adapter->ps_state = PS_STATE_AWAKE;
995 1012
@@ -1010,6 +1027,13 @@ static void mwifiex_usb_submit_rem_rx_urbs(struct mwifiex_adapter *adapter)
1010 } 1027 }
1011} 1028}
1012 1029
1030/* This function is called after the card has woken up. */
1031static inline int
1032mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
1033{
1034 return 0;
1035}
1036
1013static struct mwifiex_if_ops usb_ops = { 1037static struct mwifiex_if_ops usb_ops = {
1014 .register_dev = mwifiex_register_dev, 1038 .register_dev = mwifiex_register_dev,
1015 .unregister_dev = mwifiex_unregister_dev, 1039 .unregister_dev = mwifiex_unregister_dev,
@@ -1074,4 +1098,5 @@ MODULE_VERSION(USB_VERSION);
1074MODULE_LICENSE("GPL v2"); 1098MODULE_LICENSE("GPL v2");
1075MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME); 1099MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME);
1076MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME); 1100MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME);
1101MODULE_FIRMWARE(USB8801_DEFAULT_FW_NAME);
1077MODULE_FIRMWARE(USB8897_DEFAULT_FW_NAME); 1102MODULE_FIRMWARE(USB8897_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index a7cbba1355af..57e1a5736318 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -30,6 +30,9 @@
30#define USB8797_PID_2 0x2044 30#define USB8797_PID_2 0x2044
31#define USB8897_PID_1 0x2045 31#define USB8897_PID_1 0x2045
32#define USB8897_PID_2 0x2046 32#define USB8897_PID_2 0x2046
33#define USB8801_PID_1 0x2049
34#define USB8801_PID_2 0x204a
35
33 36
34#define USB8XXX_FW_DNLD 1 37#define USB8XXX_FW_DNLD 1
35#define USB8XXX_FW_READY 2 38#define USB8XXX_FW_READY 2
@@ -41,6 +44,7 @@
41 44
42#define USB8766_DEFAULT_FW_NAME "mrvl/usb8766_uapsta.bin" 45#define USB8766_DEFAULT_FW_NAME "mrvl/usb8766_uapsta.bin"
43#define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin" 46#define USB8797_DEFAULT_FW_NAME "mrvl/usb8797_uapsta.bin"
47#define USB8801_DEFAULT_FW_NAME "mrvl/usb8801_uapsta.bin"
44#define USB8897_DEFAULT_FW_NAME "mrvl/usb8897_uapsta.bin" 48#define USB8897_DEFAULT_FW_NAME "mrvl/usb8897_uapsta.bin"
45 49
46#define FW_DNLD_TX_BUF_SIZE 620 50#define FW_DNLD_TX_BUF_SIZE 620
@@ -96,11 +100,4 @@ struct fw_data {
96 u8 data[1]; 100 u8 data[1];
97}; 101};
98 102
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 */ 103#endif /*_MWIFIEX_USB_H */
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index b1768fbf98f2..308550611f22 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)
@@ -208,7 +387,7 @@ mwifiex_process_mgmt_packet(struct mwifiex_private *priv,
208 pkt_len -= ETH_ALEN + sizeof(pkt_len); 387 pkt_len -= ETH_ALEN + sizeof(pkt_len);
209 rx_pd->rx_pkt_length = cpu_to_le16(pkt_len); 388 rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
210 389
211 cfg80211_rx_mgmt(priv->wdev, priv->roc_cfg.chan.center_freq, 390 cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
212 CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len, 391 CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len,
213 0); 392 0);
214 393
@@ -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/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index ffffd2c5a76e..ef717acec8b7 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1228,6 +1228,9 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1228 case -EINPROGRESS: 1228 case -EINPROGRESS:
1229 if (adapter->iface_type != MWIFIEX_PCIE) 1229 if (adapter->iface_type != MWIFIEX_PCIE)
1230 adapter->data_sent = false; 1230 adapter->data_sent = false;
1231 break;
1232 case 0:
1233 mwifiex_write_data_complete(adapter, skb, 0, ret);
1231 default: 1234 default:
1232 break; 1235 break;
1233 } 1236 }
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b8d1e04aa9b9..f9b1218c761a 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -3098,14 +3098,14 @@ static void mwl8k_update_survey(struct mwl8k_priv *priv,
3098 3098
3099 cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG); 3099 cca_cnt = ioread32(priv->regs + NOK_CCA_CNT_REG);
3100 cca_cnt /= 1000; /* uSecs to mSecs */ 3100 cca_cnt /= 1000; /* uSecs to mSecs */
3101 survey->channel_time_busy = (u64) cca_cnt; 3101 survey->time_busy = (u64) cca_cnt;
3102 3102
3103 rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG); 3103 rx_rdy = ioread32(priv->regs + BBU_RXRDY_CNT_REG);
3104 rx_rdy /= 1000; /* uSecs to mSecs */ 3104 rx_rdy /= 1000; /* uSecs to mSecs */
3105 survey->channel_time_rx = (u64) rx_rdy; 3105 survey->time_rx = (u64) rx_rdy;
3106 3106
3107 priv->channel_time = jiffies - priv->channel_time; 3107 priv->channel_time = jiffies - priv->channel_time;
3108 survey->channel_time = jiffies_to_msecs(priv->channel_time); 3108 survey->time = jiffies_to_msecs(priv->channel_time);
3109 3109
3110 survey->channel = channel; 3110 survey->channel = channel;
3111 3111
@@ -3115,9 +3115,9 @@ static void mwl8k_update_survey(struct mwl8k_priv *priv,
3115 survey->noise = nf * -1; 3115 survey->noise = nf * -1;
3116 3116
3117 survey->filled = SURVEY_INFO_NOISE_DBM | 3117 survey->filled = SURVEY_INFO_NOISE_DBM |
3118 SURVEY_INFO_CHANNEL_TIME | 3118 SURVEY_INFO_TIME |
3119 SURVEY_INFO_CHANNEL_TIME_BUSY | 3119 SURVEY_INFO_TIME_BUSY |
3120 SURVEY_INFO_CHANNEL_TIME_RX; 3120 SURVEY_INFO_TIME_RX;
3121} 3121}
3122 3122
3123/* 3123/*
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/main.c b/drivers/net/wireless/orinoco/main.c
index 38ec8d19ac29..c410180479e6 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -2342,7 +2342,7 @@ void free_orinocodev(struct orinoco_private *priv)
2342 list_for_each_entry_safe(sd, sdtemp, &priv->scan_list, list) { 2342 list_for_each_entry_safe(sd, sdtemp, &priv->scan_list, list) {
2343 list_del(&sd->list); 2343 list_del(&sd->list);
2344 2344
2345 if ((sd->len > 0) && sd->buf) 2345 if (sd->len > 0)
2346 kfree(sd->buf); 2346 kfree(sd->buf);
2347 kfree(sd); 2347 kfree(sd);
2348 } 2348 }
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index b6bdad632842..74219d59d7e1 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -94,7 +94,7 @@ static int orinoco_pci_cor_reset(struct orinoco_private *priv)
94 mdelay(HERMES_PCI_COR_OFFT); 94 mdelay(HERMES_PCI_COR_OFFT);
95 95
96 /* The card is ready when it's no longer busy */ 96 /* The card is ready when it's no longer busy */
97 timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000); 97 timeout = jiffies + msecs_to_jiffies(HERMES_PCI_COR_BUSYT);
98 reg = hermes_read_regn(hw, CMD); 98 reg = hermes_read_regn(hw, CMD);
99 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) { 99 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
100 mdelay(1); 100 mdelay(1);
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index b8f6e5c431ae..8b045236b6e0 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -121,7 +121,7 @@ static int orinoco_plx_cor_reset(struct orinoco_private *priv)
121 mdelay(1); 121 mdelay(1);
122 122
123 /* Just in case, wait more until the card is no longer busy */ 123 /* Just in case, wait more until the card is no longer busy */
124 timeout = jiffies + (PLX_RESET_TIME * HZ / 1000); 124 timeout = jiffies + msecs_to_jiffies(PLX_RESET_TIME);
125 reg = hermes_read_regn(hw, CMD); 125 reg = hermes_read_regn(hw, CMD);
126 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) { 126 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
127 mdelay(1); 127 mdelay(1);
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 79d0e33b625e..20ce569b8a43 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -71,7 +71,7 @@ static int orinoco_tmd_cor_reset(struct orinoco_private *priv)
71 mdelay(1); 71 mdelay(1);
72 72
73 /* Just in case, wait more until the card is no longer busy */ 73 /* Just in case, wait more until the card is no longer busy */
74 timeout = jiffies + (TMD_RESET_TIME * HZ / 1000); 74 timeout = jiffies + msecs_to_jiffies(TMD_RESET_TIME);
75 reg = hermes_read_regn(hw, CMD); 75 reg = hermes_read_regn(hw, CMD);
76 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) { 76 while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
77 mdelay(1); 77 mdelay(1);
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/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 0fe67d2da208..2fe713eda7ad 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -196,9 +196,9 @@ static int p54_generate_band(struct ieee80211_hw *dev,
196 dest->max_power = chan->max_power; 196 dest->max_power = chan->max_power;
197 priv->survey[*chan_num].channel = &tmp->channels[j]; 197 priv->survey[*chan_num].channel = &tmp->channels[j];
198 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM | 198 priv->survey[*chan_num].filled = SURVEY_INFO_NOISE_DBM |
199 SURVEY_INFO_CHANNEL_TIME | 199 SURVEY_INFO_TIME |
200 SURVEY_INFO_CHANNEL_TIME_BUSY | 200 SURVEY_INFO_TIME_BUSY |
201 SURVEY_INFO_CHANNEL_TIME_TX; 201 SURVEY_INFO_TIME_TX;
202 dest->hw_value = (*chan_num); 202 dest->hw_value = (*chan_num);
203 j++; 203 j++;
204 (*chan_num)++; 204 (*chan_num)++;
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/main.c b/drivers/net/wireless/p54/main.c
index 97aeff0edb84..b9250d75d253 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -305,9 +305,9 @@ static void p54_reset_stats(struct p54_common *priv)
305 struct survey_info *info = &priv->survey[chan->hw_value]; 305 struct survey_info *info = &priv->survey[chan->hw_value];
306 306
307 /* only reset channel statistics, don't touch .filled, etc. */ 307 /* only reset channel statistics, don't touch .filled, etc. */
308 info->channel_time = 0; 308 info->time = 0;
309 info->channel_time_busy = 0; 309 info->time_busy = 0;
310 info->channel_time_tx = 0; 310 info->time_tx = 0;
311 } 311 }
312 312
313 priv->update_stats = true; 313 priv->update_stats = true;
@@ -575,6 +575,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
575 key->hw_key_idx = 0xff; 575 key->hw_key_idx = 0xff;
576 goto out_unlock; 576 goto out_unlock;
577 } 577 }
578
579 key->flags |= IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
578 } else { 580 } else {
579 slot = key->hw_key_idx; 581 slot = key->hw_key_idx;
580 582
@@ -634,7 +636,7 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
634 636
635 if (in_use) { 637 if (in_use) {
636 /* test if the reported statistics are valid. */ 638 /* test if the reported statistics are valid. */
637 if (survey->channel_time != 0) { 639 if (survey->time != 0) {
638 survey->filled |= SURVEY_INFO_IN_USE; 640 survey->filled |= SURVEY_INFO_IN_USE;
639 } else { 641 } else {
640 /* 642 /*
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/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 153c61539ec8..24e5ff9a9272 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -587,13 +587,13 @@ static void p54_rx_stats(struct p54_common *priv, struct sk_buff *skb)
587 if (chan) { 587 if (chan) {
588 struct survey_info *survey = &priv->survey[chan->hw_value]; 588 struct survey_info *survey = &priv->survey[chan->hw_value];
589 survey->noise = clamp(priv->noise, -128, 127); 589 survey->noise = clamp(priv->noise, -128, 127);
590 survey->channel_time = priv->survey_raw.active; 590 survey->time = priv->survey_raw.active;
591 survey->channel_time_tx = priv->survey_raw.tx; 591 survey->time_tx = priv->survey_raw.tx;
592 survey->channel_time_busy = priv->survey_raw.tx + 592 survey->time_busy = priv->survey_raw.tx +
593 priv->survey_raw.cca; 593 priv->survey_raw.cca;
594 do_div(survey->channel_time, 1024); 594 do_div(survey->time, 1024);
595 do_div(survey->channel_time_tx, 1024); 595 do_div(survey->time_tx, 1024);
596 do_div(survey->channel_time_busy, 1024); 596 do_div(survey->time_busy, 1024);
597 } 597 }
598 598
599 tmp = p54_find_and_unlink_skb(priv, hdr->req_id); 599 tmp = p54_find_and_unlink_skb(priv, hdr->req_id);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 1a4facd1fbf3..60d44ce9c017 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2478,7 +2478,7 @@ static void rndis_fill_station_info(struct usbnet *usbdev,
2478 ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len); 2478 ret = rndis_query_oid(usbdev, RNDIS_OID_GEN_LINK_SPEED, &linkspeed, &len);
2479 if (ret == 0) { 2479 if (ret == 0) {
2480 sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000; 2480 sinfo->txrate.legacy = le32_to_cpu(linkspeed) / 1000;
2481 sinfo->filled |= STATION_INFO_TX_BITRATE; 2481 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2482 } 2482 }
2483 2483
2484 len = sizeof(rssi); 2484 len = sizeof(rssi);
@@ -2486,7 +2486,7 @@ static void rndis_fill_station_info(struct usbnet *usbdev,
2486 &rssi, &len); 2486 &rssi, &len);
2487 if (ret == 0) { 2487 if (ret == 0) {
2488 sinfo->signal = level_to_qual(le32_to_cpu(rssi)); 2488 sinfo->signal = level_to_qual(le32_to_cpu(rssi));
2489 sinfo->filled |= STATION_INFO_SIGNAL; 2489 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2490 } 2490 }
2491} 2491}
2492 2492
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 4834a9abc171..b6cc9ff47fc2 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -172,7 +172,6 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
172 (struct rsi_91x_sdiodev *)adapter->rsi_dev; 172 (struct rsi_91x_sdiodev *)adapter->rsi_dev;
173 u32 len; 173 u32 len;
174 u32 num_blocks; 174 u32 num_blocks;
175 const u8 *fw;
176 const struct firmware *fw_entry = NULL; 175 const struct firmware *fw_entry = NULL;
177 u32 block_size = dev->tx_blk_size; 176 u32 block_size = dev->tx_blk_size;
178 int status = 0; 177 int status = 0;
@@ -201,7 +200,6 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
201 return status; 200 return status;
202 } 201 }
203 202
204 fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
205 len = fw_entry->size; 203 len = fw_entry->size;
206 204
207 if (len % 4) 205 if (len % 4)
@@ -212,7 +210,7 @@ static int rsi_load_ta_instructions(struct rsi_common *common)
212 rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); 210 rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
213 rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); 211 rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
214 212
215 status = rsi_copy_to_card(common, fw, len, num_blocks); 213 status = rsi_copy_to_card(common, fw_entry->data, len, num_blocks);
216 release_firmware(fw_entry); 214 release_firmware(fw_entry);
217 return status; 215 return status;
218} 216}
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 81ee481487cf..be2d54f257b1 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -8020,13 +8020,13 @@ int rt2800_get_survey(struct ieee80211_hw *hw, int idx,
8020 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext); 8020 rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &busy_ext);
8021 8021
8022 if (idle || busy) { 8022 if (idle || busy) {
8023 survey->filled = SURVEY_INFO_CHANNEL_TIME | 8023 survey->filled = SURVEY_INFO_TIME |
8024 SURVEY_INFO_CHANNEL_TIME_BUSY | 8024 SURVEY_INFO_TIME_BUSY |
8025 SURVEY_INFO_CHANNEL_TIME_EXT_BUSY; 8025 SURVEY_INFO_TIME_EXT_BUSY;
8026 8026
8027 survey->channel_time = (idle + busy) / 1000; 8027 survey->time = (idle + busy) / 1000;
8028 survey->channel_time_busy = busy / 1000; 8028 survey->time_busy = busy / 1000;
8029 survey->channel_time_ext_busy = busy_ext / 1000; 8029 survey->time_ext_busy = busy_ext / 1000;
8030 } 8030 }
8031 8031
8032 if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 8032 if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
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/base.c b/drivers/net/wireless/rtlwifi/base.c
index 40b6d1d006d7..1d4677460711 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -867,63 +867,135 @@ static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw,
867 * 867 *
868 * B/G rate: 868 * B/G rate:
869 * (rx_status->flag & RX_FLAG_HT) = 0, 869 * (rx_status->flag & RX_FLAG_HT) = 0,
870 * DESC92_RATE1M-->DESC92_RATE54M ==> idx is 0-->11, 870 * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11,
871 * 871 *
872 * N rate: 872 * N rate:
873 * (rx_status->flag & RX_FLAG_HT) = 1, 873 * (rx_status->flag & RX_FLAG_HT) = 1,
874 * DESC92_RATEMCS0-->DESC92_RATEMCS15 ==> idx is 0-->15 874 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
875 * 875 *
876 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ 876 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
877 * A rate: 877 * A rate:
878 * (rx_status->flag & RX_FLAG_HT) = 0, 878 * (rx_status->flag & RX_FLAG_HT) = 0,
879 * DESC92_RATE6M-->DESC92_RATE54M ==> idx is 0-->7, 879 * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7,
880 * 880 *
881 * N rate: 881 * N rate:
882 * (rx_status->flag & RX_FLAG_HT) = 1, 882 * (rx_status->flag & RX_FLAG_HT) = 1,
883 * DESC92_RATEMCS0-->DESC92_RATEMCS15 ==> idx is 0-->15 883 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
884 *
885 * VHT rates:
886 * DESC_RATEVHT1SS_MCS0-->DESC_RATEVHT1SS_MCS9 ==> idx is 0-->9
887 * DESC_RATEVHT2SS_MCS0-->DESC_RATEVHT2SS_MCS9 ==> idx is 0-->9
884 */ 888 */
885int rtlwifi_rate_mapping(struct ieee80211_hw *hw, 889int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht,
886 bool isht, u8 desc_rate, bool first_ampdu) 890 u8 desc_rate)
887{ 891{
888 int rate_idx; 892 int rate_idx;
889 893
894 if (isvht) {
895 switch (desc_rate) {
896 case DESC_RATEVHT1SS_MCS0:
897 rate_idx = 0;
898 break;
899 case DESC_RATEVHT1SS_MCS1:
900 rate_idx = 1;
901 break;
902 case DESC_RATEVHT1SS_MCS2:
903 rate_idx = 2;
904 break;
905 case DESC_RATEVHT1SS_MCS3:
906 rate_idx = 3;
907 break;
908 case DESC_RATEVHT1SS_MCS4:
909 rate_idx = 4;
910 break;
911 case DESC_RATEVHT1SS_MCS5:
912 rate_idx = 5;
913 break;
914 case DESC_RATEVHT1SS_MCS6:
915 rate_idx = 6;
916 break;
917 case DESC_RATEVHT1SS_MCS7:
918 rate_idx = 7;
919 break;
920 case DESC_RATEVHT1SS_MCS8:
921 rate_idx = 8;
922 break;
923 case DESC_RATEVHT1SS_MCS9:
924 rate_idx = 9;
925 break;
926 case DESC_RATEVHT2SS_MCS0:
927 rate_idx = 0;
928 break;
929 case DESC_RATEVHT2SS_MCS1:
930 rate_idx = 1;
931 break;
932 case DESC_RATEVHT2SS_MCS2:
933 rate_idx = 2;
934 break;
935 case DESC_RATEVHT2SS_MCS3:
936 rate_idx = 3;
937 break;
938 case DESC_RATEVHT2SS_MCS4:
939 rate_idx = 4;
940 break;
941 case DESC_RATEVHT2SS_MCS5:
942 rate_idx = 5;
943 break;
944 case DESC_RATEVHT2SS_MCS6:
945 rate_idx = 6;
946 break;
947 case DESC_RATEVHT2SS_MCS7:
948 rate_idx = 7;
949 break;
950 case DESC_RATEVHT2SS_MCS8:
951 rate_idx = 8;
952 break;
953 case DESC_RATEVHT2SS_MCS9:
954 rate_idx = 9;
955 break;
956 default:
957 rate_idx = 0;
958 break;
959 }
960 return rate_idx;
961 }
890 if (false == isht) { 962 if (false == isht) {
891 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) { 963 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
892 switch (desc_rate) { 964 switch (desc_rate) {
893 case DESC92_RATE1M: 965 case DESC_RATE1M:
894 rate_idx = 0; 966 rate_idx = 0;
895 break; 967 break;
896 case DESC92_RATE2M: 968 case DESC_RATE2M:
897 rate_idx = 1; 969 rate_idx = 1;
898 break; 970 break;
899 case DESC92_RATE5_5M: 971 case DESC_RATE5_5M:
900 rate_idx = 2; 972 rate_idx = 2;
901 break; 973 break;
902 case DESC92_RATE11M: 974 case DESC_RATE11M:
903 rate_idx = 3; 975 rate_idx = 3;
904 break; 976 break;
905 case DESC92_RATE6M: 977 case DESC_RATE6M:
906 rate_idx = 4; 978 rate_idx = 4;
907 break; 979 break;
908 case DESC92_RATE9M: 980 case DESC_RATE9M:
909 rate_idx = 5; 981 rate_idx = 5;
910 break; 982 break;
911 case DESC92_RATE12M: 983 case DESC_RATE12M:
912 rate_idx = 6; 984 rate_idx = 6;
913 break; 985 break;
914 case DESC92_RATE18M: 986 case DESC_RATE18M:
915 rate_idx = 7; 987 rate_idx = 7;
916 break; 988 break;
917 case DESC92_RATE24M: 989 case DESC_RATE24M:
918 rate_idx = 8; 990 rate_idx = 8;
919 break; 991 break;
920 case DESC92_RATE36M: 992 case DESC_RATE36M:
921 rate_idx = 9; 993 rate_idx = 9;
922 break; 994 break;
923 case DESC92_RATE48M: 995 case DESC_RATE48M:
924 rate_idx = 10; 996 rate_idx = 10;
925 break; 997 break;
926 case DESC92_RATE54M: 998 case DESC_RATE54M:
927 rate_idx = 11; 999 rate_idx = 11;
928 break; 1000 break;
929 default: 1001 default:
@@ -932,28 +1004,28 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
932 } 1004 }
933 } else { 1005 } else {
934 switch (desc_rate) { 1006 switch (desc_rate) {
935 case DESC92_RATE6M: 1007 case DESC_RATE6M:
936 rate_idx = 0; 1008 rate_idx = 0;
937 break; 1009 break;
938 case DESC92_RATE9M: 1010 case DESC_RATE9M:
939 rate_idx = 1; 1011 rate_idx = 1;
940 break; 1012 break;
941 case DESC92_RATE12M: 1013 case DESC_RATE12M:
942 rate_idx = 2; 1014 rate_idx = 2;
943 break; 1015 break;
944 case DESC92_RATE18M: 1016 case DESC_RATE18M:
945 rate_idx = 3; 1017 rate_idx = 3;
946 break; 1018 break;
947 case DESC92_RATE24M: 1019 case DESC_RATE24M:
948 rate_idx = 4; 1020 rate_idx = 4;
949 break; 1021 break;
950 case DESC92_RATE36M: 1022 case DESC_RATE36M:
951 rate_idx = 5; 1023 rate_idx = 5;
952 break; 1024 break;
953 case DESC92_RATE48M: 1025 case DESC_RATE48M:
954 rate_idx = 6; 1026 rate_idx = 6;
955 break; 1027 break;
956 case DESC92_RATE54M: 1028 case DESC_RATE54M:
957 rate_idx = 7; 1029 rate_idx = 7;
958 break; 1030 break;
959 default: 1031 default:
@@ -963,52 +1035,52 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw,
963 } 1035 }
964 } else { 1036 } else {
965 switch (desc_rate) { 1037 switch (desc_rate) {
966 case DESC92_RATEMCS0: 1038 case DESC_RATEMCS0:
967 rate_idx = 0; 1039 rate_idx = 0;
968 break; 1040 break;
969 case DESC92_RATEMCS1: 1041 case DESC_RATEMCS1:
970 rate_idx = 1; 1042 rate_idx = 1;
971 break; 1043 break;
972 case DESC92_RATEMCS2: 1044 case DESC_RATEMCS2:
973 rate_idx = 2; 1045 rate_idx = 2;
974 break; 1046 break;
975 case DESC92_RATEMCS3: 1047 case DESC_RATEMCS3:
976 rate_idx = 3; 1048 rate_idx = 3;
977 break; 1049 break;
978 case DESC92_RATEMCS4: 1050 case DESC_RATEMCS4:
979 rate_idx = 4; 1051 rate_idx = 4;
980 break; 1052 break;
981 case DESC92_RATEMCS5: 1053 case DESC_RATEMCS5:
982 rate_idx = 5; 1054 rate_idx = 5;
983 break; 1055 break;
984 case DESC92_RATEMCS6: 1056 case DESC_RATEMCS6:
985 rate_idx = 6; 1057 rate_idx = 6;
986 break; 1058 break;
987 case DESC92_RATEMCS7: 1059 case DESC_RATEMCS7:
988 rate_idx = 7; 1060 rate_idx = 7;
989 break; 1061 break;
990 case DESC92_RATEMCS8: 1062 case DESC_RATEMCS8:
991 rate_idx = 8; 1063 rate_idx = 8;
992 break; 1064 break;
993 case DESC92_RATEMCS9: 1065 case DESC_RATEMCS9:
994 rate_idx = 9; 1066 rate_idx = 9;
995 break; 1067 break;
996 case DESC92_RATEMCS10: 1068 case DESC_RATEMCS10:
997 rate_idx = 10; 1069 rate_idx = 10;
998 break; 1070 break;
999 case DESC92_RATEMCS11: 1071 case DESC_RATEMCS11:
1000 rate_idx = 11; 1072 rate_idx = 11;
1001 break; 1073 break;
1002 case DESC92_RATEMCS12: 1074 case DESC_RATEMCS12:
1003 rate_idx = 12; 1075 rate_idx = 12;
1004 break; 1076 break;
1005 case DESC92_RATEMCS13: 1077 case DESC_RATEMCS13:
1006 rate_idx = 13; 1078 rate_idx = 13;
1007 break; 1079 break;
1008 case DESC92_RATEMCS14: 1080 case DESC_RATEMCS14:
1009 rate_idx = 14; 1081 rate_idx = 14;
1010 break; 1082 break;
1011 case DESC92_RATEMCS15: 1083 case DESC_RATEMCS15:
1012 rate_idx = 15; 1084 rate_idx = 15;
1013 break; 1085 break;
1014 default: 1086 default:
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index 982f2450feea..c6cb49c3ee32 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -123,8 +123,8 @@ void rtl_watch_dog_timer_callback(unsigned long data);
123void rtl_deinit_deferred_work(struct ieee80211_hw *hw); 123void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
124 124
125bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); 125bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
126int rtlwifi_rate_mapping(struct ieee80211_hw *hw, 126int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht,
127 bool isht, u8 desc_rate, bool first_ampdu); 127 bool isvht, u8 desc_rate);
128bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); 128bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
129u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); 129u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
130 130
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 5fc6f52641bd..a31a12775f1a 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -95,7 +95,8 @@ void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
95} 95}
96EXPORT_SYMBOL(rtl_bb_delay); 96EXPORT_SYMBOL(rtl_bb_delay);
97 97
98void rtl_fw_cb(const struct firmware *firmware, void *context) 98static void rtl_fw_do_work(const struct firmware *firmware, void *context,
99 bool is_wow)
99{ 100{
100 struct ieee80211_hw *hw = context; 101 struct ieee80211_hw *hw = context;
101 struct rtl_priv *rtlpriv = rtl_priv(hw); 102 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -125,12 +126,31 @@ found_alt:
125 release_firmware(firmware); 126 release_firmware(firmware);
126 return; 127 return;
127 } 128 }
128 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); 129 if (!is_wow) {
130 memcpy(rtlpriv->rtlhal.pfirmware, firmware->data,
131 firmware->size);
132 rtlpriv->rtlhal.fwsize = firmware->size;
133 } else {
134 memcpy(rtlpriv->rtlhal.wowlan_firmware, firmware->data,
135 firmware->size);
136 rtlpriv->rtlhal.wowlan_fwsize = firmware->size;
137 }
129 rtlpriv->rtlhal.fwsize = firmware->size; 138 rtlpriv->rtlhal.fwsize = firmware->size;
130 release_firmware(firmware); 139 release_firmware(firmware);
131} 140}
141
142void rtl_fw_cb(const struct firmware *firmware, void *context)
143{
144 rtl_fw_do_work(firmware, context, false);
145}
132EXPORT_SYMBOL(rtl_fw_cb); 146EXPORT_SYMBOL(rtl_fw_cb);
133 147
148void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context)
149{
150 rtl_fw_do_work(firmware, context, true);
151}
152EXPORT_SYMBOL(rtl_wowlan_fw_cb);
153
134/*mutex for start & stop is must here. */ 154/*mutex for start & stop is must here. */
135static int rtl_op_start(struct ieee80211_hw *hw) 155static int rtl_op_start(struct ieee80211_hw *hw)
136{ 156{
@@ -990,6 +1010,16 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw,
990 return 0; 1010 return 0;
991} 1011}
992 1012
1013static void send_beacon_frame(struct ieee80211_hw *hw,
1014 struct ieee80211_vif *vif)
1015{
1016 struct rtl_priv *rtlpriv = rtl_priv(hw);
1017 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
1018
1019 if (skb)
1020 rtlpriv->intf_ops->adapter_tx(hw, NULL, skb, NULL);
1021}
1022
993static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, 1023static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
994 struct ieee80211_vif *vif, 1024 struct ieee80211_vif *vif,
995 struct ieee80211_bss_conf *bss_conf, 1025 struct ieee80211_bss_conf *bss_conf,
@@ -1020,6 +1050,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
1020 1050
1021 if (rtlpriv->cfg->ops->linked_set_reg) 1051 if (rtlpriv->cfg->ops->linked_set_reg)
1022 rtlpriv->cfg->ops->linked_set_reg(hw); 1052 rtlpriv->cfg->ops->linked_set_reg(hw);
1053 send_beacon_frame(hw, vif);
1023 } 1054 }
1024 } 1055 }
1025 if ((changed & BSS_CHANGED_BEACON_ENABLED && 1056 if ((changed & BSS_CHANGED_BEACON_ENABLED &&
@@ -1851,3 +1882,40 @@ bool rtl_btc_status_false(void)
1851 return false; 1882 return false;
1852} 1883}
1853EXPORT_SYMBOL_GPL(rtl_btc_status_false); 1884EXPORT_SYMBOL_GPL(rtl_btc_status_false);
1885
1886void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igvalue)
1887{
1888 struct rtl_priv *rtlpriv = rtl_priv(hw);
1889 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1890
1891 dm_digtable->dig_enable_flag = true;
1892 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
1893 dm_digtable->cur_igvalue = cur_igvalue;
1894 dm_digtable->pre_igvalue = 0;
1895 dm_digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
1896 dm_digtable->presta_cstate = DIG_STA_DISCONNECT;
1897 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
1898 dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
1899 dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
1900 dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
1901 dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
1902 dm_digtable->rx_gain_max = DM_DIG_MAX;
1903 dm_digtable->rx_gain_min = DM_DIG_MIN;
1904 dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
1905 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
1906 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
1907 dm_digtable->pre_cck_cca_thres = 0xff;
1908 dm_digtable->cur_cck_cca_thres = 0x83;
1909 dm_digtable->forbidden_igi = DM_DIG_MIN;
1910 dm_digtable->large_fa_hit = 0;
1911 dm_digtable->recover_cnt = 0;
1912 dm_digtable->dig_min_0 = 0x25;
1913 dm_digtable->dig_min_1 = 0x25;
1914 dm_digtable->media_connect_0 = false;
1915 dm_digtable->media_connect_1 = false;
1916 rtlpriv->dm.dm_initialgain_enable = true;
1917 dm_digtable->bt30_cur_igi = 0x32;
1918 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
1919 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI;
1920}
1921EXPORT_SYMBOL(rtl_dm_diginit);
diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h
index 624e1dc16d31..7b64e34f421e 100644
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -35,13 +35,55 @@
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);
80void rtl_wowlan_fw_cb(const struct firmware *firmware, void *context);
40void rtl_addr_delay(u32 addr); 81void rtl_addr_delay(u32 addr);
41void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr, 82void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
42 u32 mask, u32 data); 83 u32 mask, u32 data);
43void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data); 84void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data);
44bool 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);
45bool rtl_btc_status_false(void); 86bool rtl_btc_status_false(void);
87void rtl_dm_diginit(struct ieee80211_hw *hw, u32 cur_igval);
46 88
47#endif 89#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index c70efb9a6e78..ec456f0d972e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -578,6 +578,13 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
578 else 578 else
579 entry = (u8 *)(&ring->desc[ring->idx]); 579 entry = (u8 *)(&ring->desc[ring->idx]);
580 580
581 if (rtlpriv->cfg->ops->get_available_desc &&
582 rtlpriv->cfg->ops->get_available_desc(hw, prio) <= 1) {
583 RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_DMESG,
584 "no available desc!\n");
585 return;
586 }
587
581 if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx)) 588 if (!rtlpriv->cfg->ops->is_tx_desc_closed(hw, prio, ring->idx))
582 return; 589 return;
583 ring->idx = (ring->idx + 1) % ring->entries; 590 ring->idx = (ring->idx + 1) % ring->entries;
@@ -641,10 +648,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
641 648
642 ieee80211_tx_status_irqsafe(hw, skb); 649 ieee80211_tx_status_irqsafe(hw, skb);
643 650
644 if ((ring->entries - skb_queue_len(&ring->queue)) 651 if ((ring->entries - skb_queue_len(&ring->queue)) <= 4) {
645 == 2) {
646 652
647 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 653 RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG,
648 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", 654 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",
649 prio, ring->idx, 655 prio, ring->idx,
650 skb_queue_len(&ring->queue)); 656 skb_queue_len(&ring->queue));
@@ -793,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
793 rx_remained_cnt = 799 rx_remained_cnt =
794 rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw, 800 rtlpriv->cfg->ops->rx_desc_buff_remained_cnt(hw,
795 hw_queue); 801 hw_queue);
796 if (rx_remained_cnt < 1) 802 if (rx_remained_cnt == 0)
797 return; 803 return;
798 804
799 } else { /* rx descriptor */ 805 } else { /* rx descriptor */
@@ -848,18 +854,18 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
848 else 854 else
849 skb_reserve(skb, stats.rx_drvinfo_size + 855 skb_reserve(skb, stats.rx_drvinfo_size +
850 stats.rx_bufshift); 856 stats.rx_bufshift);
851
852 } else { 857 } else {
853 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 858 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
854 "skb->end - skb->tail = %d, len is %d\n", 859 "skb->end - skb->tail = %d, len is %d\n",
855 skb->end - skb->tail, len); 860 skb->end - skb->tail, len);
856 break; 861 dev_kfree_skb_any(skb);
862 goto new_trx_end;
857 } 863 }
858 /* handle command packet here */ 864 /* handle command packet here */
859 if (rtlpriv->cfg->ops->rx_command_packet && 865 if (rtlpriv->cfg->ops->rx_command_packet &&
860 rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) { 866 rtlpriv->cfg->ops->rx_command_packet(hw, stats, skb)) {
861 dev_kfree_skb_any(skb); 867 dev_kfree_skb_any(skb);
862 goto end; 868 goto new_trx_end;
863 } 869 }
864 870
865 /* 871 /*
@@ -909,6 +915,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
909 } else { 915 } else {
910 dev_kfree_skb_any(skb); 916 dev_kfree_skb_any(skb);
911 } 917 }
918new_trx_end:
912 if (rtlpriv->use_new_trx_flow) { 919 if (rtlpriv->use_new_trx_flow) {
913 rtlpci->rx_ring[hw_queue].next_rx_rp += 1; 920 rtlpci->rx_ring[hw_queue].next_rx_rp += 1;
914 rtlpci->rx_ring[hw_queue].next_rx_rp %= 921 rtlpci->rx_ring[hw_queue].next_rx_rp %=
@@ -924,7 +931,6 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
924 rtlpriv->enter_ps = false; 931 rtlpriv->enter_ps = false;
925 schedule_work(&rtlpriv->works.lps_change_work); 932 schedule_work(&rtlpriv->works.lps_change_work);
926 } 933 }
927end:
928 skb = new_skb; 934 skb = new_skb;
929no_new: 935no_new:
930 if (rtlpriv->use_new_trx_flow) { 936 if (rtlpriv->use_new_trx_flow) {
@@ -1688,6 +1694,15 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1688 } 1694 }
1689 } 1695 }
1690 1696
1697 if (rtlpriv->cfg->ops->get_available_desc &&
1698 rtlpriv->cfg->ops->get_available_desc(hw, hw_queue) == 0) {
1699 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1700 "get_available_desc fail\n");
1701 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock,
1702 flags);
1703 return skb->len;
1704 }
1705
1691 if (ieee80211_is_data_qos(fc)) { 1706 if (ieee80211_is_data_qos(fc)) {
1692 tid = rtl_get_tid(skb); 1707 tid = rtl_get_tid(skb);
1693 if (sta) { 1708 if (sta) {
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index 5e832306dba9..d4567d12e07e 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -325,4 +325,11 @@ static inline void pci_write32_async(struct rtl_priv *rtlpriv,
325 writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); 325 writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
326} 326}
327 327
328static inline u16 calc_fifo_space(u16 rp, u16 wp)
329{
330 if (rp <= wp)
331 return RTL_PCI_MAX_RX_COUNT - 1 + rp - wp;
332 return rp - wp - 1;
333}
334
328#endif 335#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/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index df549c96adef..791efbe6b18c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -47,164 +47,6 @@ static u8 _rtl88ee_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
47 return skb->priority; 47 return skb->priority;
48} 48}
49 49
50/* mac80211's rate_idx is like this:
51 *
52 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
53 *
54 * B/G rate:
55 * (rx_status->flag & RX_FLAG_HT) = 0,
56 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
57 *
58 * N rate:
59 * (rx_status->flag & RX_FLAG_HT) = 1,
60 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
61 *
62 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
63 * A rate:
64 * (rx_status->flag & RX_FLAG_HT) = 0,
65 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
66 *
67 * N rate:
68 * (rx_status->flag & RX_FLAG_HT) = 1,
69 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
70 */
71static int _rtl88ee_rate_mapping(struct ieee80211_hw *hw,
72 bool isht, u8 desc_rate)
73{
74 int rate_idx;
75
76 if (!isht) {
77 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
78 switch (desc_rate) {
79 case DESC92C_RATE1M:
80 rate_idx = 0;
81 break;
82 case DESC92C_RATE2M:
83 rate_idx = 1;
84 break;
85 case DESC92C_RATE5_5M:
86 rate_idx = 2;
87 break;
88 case DESC92C_RATE11M:
89 rate_idx = 3;
90 break;
91 case DESC92C_RATE6M:
92 rate_idx = 4;
93 break;
94 case DESC92C_RATE9M:
95 rate_idx = 5;
96 break;
97 case DESC92C_RATE12M:
98 rate_idx = 6;
99 break;
100 case DESC92C_RATE18M:
101 rate_idx = 7;
102 break;
103 case DESC92C_RATE24M:
104 rate_idx = 8;
105 break;
106 case DESC92C_RATE36M:
107 rate_idx = 9;
108 break;
109 case DESC92C_RATE48M:
110 rate_idx = 10;
111 break;
112 case DESC92C_RATE54M:
113 rate_idx = 11;
114 break;
115 default:
116 rate_idx = 0;
117 break;
118 }
119 } else {
120 switch (desc_rate) {
121 case DESC92C_RATE6M:
122 rate_idx = 0;
123 break;
124 case DESC92C_RATE9M:
125 rate_idx = 1;
126 break;
127 case DESC92C_RATE12M:
128 rate_idx = 2;
129 break;
130 case DESC92C_RATE18M:
131 rate_idx = 3;
132 break;
133 case DESC92C_RATE24M:
134 rate_idx = 4;
135 break;
136 case DESC92C_RATE36M:
137 rate_idx = 5;
138 break;
139 case DESC92C_RATE48M:
140 rate_idx = 6;
141 break;
142 case DESC92C_RATE54M:
143 rate_idx = 7;
144 break;
145 default:
146 rate_idx = 0;
147 break;
148 }
149 }
150 } else {
151 switch (desc_rate) {
152 case DESC92C_RATEMCS0:
153 rate_idx = 0;
154 break;
155 case DESC92C_RATEMCS1:
156 rate_idx = 1;
157 break;
158 case DESC92C_RATEMCS2:
159 rate_idx = 2;
160 break;
161 case DESC92C_RATEMCS3:
162 rate_idx = 3;
163 break;
164 case DESC92C_RATEMCS4:
165 rate_idx = 4;
166 break;
167 case DESC92C_RATEMCS5:
168 rate_idx = 5;
169 break;
170 case DESC92C_RATEMCS6:
171 rate_idx = 6;
172 break;
173 case DESC92C_RATEMCS7:
174 rate_idx = 7;
175 break;
176 case DESC92C_RATEMCS8:
177 rate_idx = 8;
178 break;
179 case DESC92C_RATEMCS9:
180 rate_idx = 9;
181 break;
182 case DESC92C_RATEMCS10:
183 rate_idx = 10;
184 break;
185 case DESC92C_RATEMCS11:
186 rate_idx = 11;
187 break;
188 case DESC92C_RATEMCS12:
189 rate_idx = 12;
190 break;
191 case DESC92C_RATEMCS13:
192 rate_idx = 13;
193 break;
194 case DESC92C_RATEMCS14:
195 rate_idx = 14;
196 break;
197 case DESC92C_RATEMCS15:
198 rate_idx = 15;
199 break;
200 default:
201 rate_idx = 0;
202 break;
203 }
204 }
205 return rate_idx;
206}
207
208static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw, 50static void _rtl88ee_query_rxphystatus(struct ieee80211_hw *hw,
209 struct rtl_stats *pstatus, u8 *pdesc, 51 struct rtl_stats *pstatus, u8 *pdesc,
210 struct rx_fwinfo_88e *p_drvinfo, 52 struct rx_fwinfo_88e *p_drvinfo,
@@ -630,8 +472,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
630 * are use (RX_FLAG_HT) 472 * are use (RX_FLAG_HT)
631 * Notice: this is diff with windows define 473 * Notice: this is diff with windows define
632 */ 474 */
633 rx_status->rate_idx = _rtl88ee_rate_mapping(hw, 475 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
634 status->is_ht, status->rate); 476 false, status->rate);
635 477
636 rx_status->mactime = status->timestamp_low; 478 rx_status->mactime = status->timestamp_low;
637 if (phystatus == true) { 479 if (phystatus == true) {
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/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
index b64ae45dc674..e9f4281f5067 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
@@ -37,6 +37,7 @@
37#define FW_8192C_POLLING_DELAY 5 37#define FW_8192C_POLLING_DELAY 5
38#define FW_8192C_POLLING_TIMEOUT_COUNT 100 38#define FW_8192C_POLLING_TIMEOUT_COUNT 100
39#define NORMAL_CHIP BIT(4) 39#define NORMAL_CHIP BIT(4)
40#define H2C_92C_KEEP_ALIVE_CTRL 48
40 41
41#define IS_FW_HEADER_EXIST(_pfwhdr) \ 42#define IS_FW_HEADER_EXIST(_pfwhdr) \
42 ((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\ 43 ((le16_to_cpu(_pfwhdr->signature)&0xFFF0) == 0x92C0 ||\
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/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index 5c646d5f7bb8..303b299376c9 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -544,8 +544,13 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
544 (u8 *)(&fw_current_inps)); 544 (u8 *)(&fw_current_inps));
545 } 545 }
546 break; } 546 break; }
547 case HW_VAR_KEEP_ALIVE: 547 case HW_VAR_KEEP_ALIVE: {
548 break; 548 u8 array[2];
549
550 array[0] = 0xff;
551 array[1] = *((u8 *)val);
552 rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2, array);
553 break; }
549 default: 554 default:
550 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 555 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
551 "switch case %d not processed\n", variable); 556 "switch case %d not processed\n", variable);
@@ -1156,47 +1161,35 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1156 struct rtl_priv *rtlpriv = rtl_priv(hw); 1161 struct rtl_priv *rtlpriv = rtl_priv(hw);
1157 u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 1162 u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1158 enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 1163 enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1159 bt_msr &= 0xfc; 1164 u8 mode = MSR_NOLINK;
1160 1165
1161 if (type == NL80211_IFTYPE_UNSPECIFIED || 1166 bt_msr &= 0xfc;
1162 type == NL80211_IFTYPE_STATION) {
1163 _rtl92ce_stop_tx_beacon(hw);
1164 _rtl92ce_enable_bcn_sub_func(hw);
1165 } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP ||
1166 type == NL80211_IFTYPE_MESH_POINT) {
1167 _rtl92ce_resume_tx_beacon(hw);
1168 _rtl92ce_disable_bcn_sub_func(hw);
1169 } else {
1170 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1171 "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n",
1172 type);
1173 }
1174 1167
1175 switch (type) { 1168 switch (type) {
1176 case NL80211_IFTYPE_UNSPECIFIED: 1169 case NL80211_IFTYPE_UNSPECIFIED:
1177 bt_msr |= MSR_NOLINK; 1170 mode = MSR_NOLINK;
1178 ledaction = LED_CTL_LINK;
1179 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1171 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1180 "Set Network type to NO LINK!\n"); 1172 "Set Network type to NO LINK!\n");
1181 break; 1173 break;
1182 case NL80211_IFTYPE_ADHOC: 1174 case NL80211_IFTYPE_ADHOC:
1183 bt_msr |= MSR_ADHOC; 1175 mode = MSR_ADHOC;
1184 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1176 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1185 "Set Network type to Ad Hoc!\n"); 1177 "Set Network type to Ad Hoc!\n");
1186 break; 1178 break;
1187 case NL80211_IFTYPE_STATION: 1179 case NL80211_IFTYPE_STATION:
1188 bt_msr |= MSR_INFRA; 1180 mode = MSR_INFRA;
1189 ledaction = LED_CTL_LINK; 1181 ledaction = LED_CTL_LINK;
1190 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1182 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1191 "Set Network type to STA!\n"); 1183 "Set Network type to STA!\n");
1192 break; 1184 break;
1193 case NL80211_IFTYPE_AP: 1185 case NL80211_IFTYPE_AP:
1194 bt_msr |= MSR_AP; 1186 mode = MSR_AP;
1187 ledaction = LED_CTL_LINK;
1195 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1188 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1196 "Set Network type to AP!\n"); 1189 "Set Network type to AP!\n");
1197 break; 1190 break;
1198 case NL80211_IFTYPE_MESH_POINT: 1191 case NL80211_IFTYPE_MESH_POINT:
1199 bt_msr |= MSR_ADHOC; 1192 mode = MSR_ADHOC;
1200 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1193 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1201 "Set Network type to Mesh Point!\n"); 1194 "Set Network type to Mesh Point!\n");
1202 break; 1195 break;
@@ -1207,9 +1200,32 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1207 1200
1208 } 1201 }
1209 1202
1210 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1203 /* MSR_INFRA == Link in infrastructure network;
1204 * MSR_ADHOC == Link in ad hoc network;
1205 * Therefore, check link state is necessary.
1206 *
1207 * MSR_AP == AP mode; link state does not matter here.
1208 */
1209 if (mode != MSR_AP &&
1210 rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1211 mode = MSR_NOLINK;
1212 ledaction = LED_CTL_NO_LINK;
1213 }
1214 if (mode == MSR_NOLINK || mode == MSR_INFRA) {
1215 _rtl92ce_stop_tx_beacon(hw);
1216 _rtl92ce_enable_bcn_sub_func(hw);
1217 } else if (mode == MSR_ADHOC || mode == MSR_AP) {
1218 _rtl92ce_resume_tx_beacon(hw);
1219 _rtl92ce_disable_bcn_sub_func(hw);
1220 } else {
1221 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1222 "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n",
1223 mode);
1224 }
1225 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1226
1211 rtlpriv->cfg->ops->led_control(hw, ledaction); 1227 rtlpriv->cfg->ops->led_control(hw, ledaction);
1212 if ((bt_msr & MSR_MASK) == MSR_AP) 1228 if (mode == MSR_AP)
1213 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1229 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1214 else 1230 else
1215 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1231 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
@@ -1833,7 +1849,6 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
1833 u32 ratr_value; 1849 u32 ratr_value;
1834 u8 ratr_index = 0; 1850 u8 ratr_index = 0;
1835 u8 nmode = mac->ht_enable; 1851 u8 nmode = mac->ht_enable;
1836 u8 mimo_ps = IEEE80211_SMPS_OFF;
1837 u16 shortgi_rate; 1852 u16 shortgi_rate;
1838 u32 tmp_ratr_value; 1853 u32 tmp_ratr_value;
1839 u8 curtxbw_40mhz = mac->bw_40; 1854 u8 curtxbw_40mhz = mac->bw_40;
@@ -1842,6 +1857,7 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
1842 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1857 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1843 1 : 0; 1858 1 : 0;
1844 enum wireless_mode wirelessmode = mac->mode; 1859 enum wireless_mode wirelessmode = mac->mode;
1860 u32 ratr_mask;
1845 1861
1846 if (rtlhal->current_bandtype == BAND_ON_5G) 1862 if (rtlhal->current_bandtype == BAND_ON_5G)
1847 ratr_value = sta->supp_rates[1] << 4; 1863 ratr_value = sta->supp_rates[1] << 4;
@@ -1865,19 +1881,13 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
1865 case WIRELESS_MODE_N_24G: 1881 case WIRELESS_MODE_N_24G:
1866 case WIRELESS_MODE_N_5G: 1882 case WIRELESS_MODE_N_5G:
1867 nmode = 1; 1883 nmode = 1;
1868 if (mimo_ps == IEEE80211_SMPS_STATIC) { 1884 if (get_rf_type(rtlphy) == RF_1T2R ||
1869 ratr_value &= 0x0007F005; 1885 get_rf_type(rtlphy) == RF_1T1R)
1870 } else { 1886 ratr_mask = 0x000ff005;
1871 u32 ratr_mask; 1887 else
1872 1888 ratr_mask = 0x0f0ff005;
1873 if (get_rf_type(rtlphy) == RF_1T2R ||
1874 get_rf_type(rtlphy) == RF_1T1R)
1875 ratr_mask = 0x000ff005;
1876 else
1877 ratr_mask = 0x0f0ff005;
1878 1889
1879 ratr_value &= ratr_mask; 1890 ratr_value &= ratr_mask;
1880 }
1881 break; 1891 break;
1882 default: 1892 default:
1883 if (rtlphy->rf_type == RF_1T2R) 1893 if (rtlphy->rf_type == RF_1T2R)
@@ -1930,17 +1940,16 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
1930 struct rtl_sta_info *sta_entry = NULL; 1940 struct rtl_sta_info *sta_entry = NULL;
1931 u32 ratr_bitmap; 1941 u32 ratr_bitmap;
1932 u8 ratr_index; 1942 u8 ratr_index;
1933 u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; 1943 u8 curtxbw_40mhz = (sta->ht_cap.cap &
1934 u8 curshortgi_40mhz = curtxbw_40mhz && 1944 IEEE80211_HT_CAP_SUP_WIDTH_20_40) ? 1 : 0;
1935 (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 1945 u8 curshortgi_40mhz = (sta->ht_cap.cap &
1936 1 : 0; 1946 IEEE80211_HT_CAP_SGI_40) ? 1 : 0;
1937 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 1947 u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1938 1 : 0; 1948 1 : 0;
1939 enum wireless_mode wirelessmode = 0; 1949 enum wireless_mode wirelessmode = 0;
1940 bool shortgi = false; 1950 bool shortgi = false;
1941 u8 rate_mask[5]; 1951 u8 rate_mask[5];
1942 u8 macid = 0; 1952 u8 macid = 0;
1943 u8 mimo_ps = IEEE80211_SMPS_OFF;
1944 1953
1945 sta_entry = (struct rtl_sta_info *) sta->drv_priv; 1954 sta_entry = (struct rtl_sta_info *) sta->drv_priv;
1946 wirelessmode = sta_entry->wireless_mode; 1955 wirelessmode = sta_entry->wireless_mode;
@@ -1985,47 +1994,38 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
1985 case WIRELESS_MODE_N_5G: 1994 case WIRELESS_MODE_N_5G:
1986 ratr_index = RATR_INX_WIRELESS_NGB; 1995 ratr_index = RATR_INX_WIRELESS_NGB;
1987 1996
1988 if (mimo_ps == IEEE80211_SMPS_STATIC) { 1997 if (rtlphy->rf_type == RF_1T2R ||
1989 if (rssi_level == 1) 1998 rtlphy->rf_type == RF_1T1R) {
1990 ratr_bitmap &= 0x00070000; 1999 if (curtxbw_40mhz) {
1991 else if (rssi_level == 2) 2000 if (rssi_level == 1)
1992 ratr_bitmap &= 0x0007f000; 2001 ratr_bitmap &= 0x000f0000;
1993 else 2002 else if (rssi_level == 2)
1994 ratr_bitmap &= 0x0007f005; 2003 ratr_bitmap &= 0x000ff000;
2004 else
2005 ratr_bitmap &= 0x000ff015;
2006 } else {
2007 if (rssi_level == 1)
2008 ratr_bitmap &= 0x000f0000;
2009 else if (rssi_level == 2)
2010 ratr_bitmap &= 0x000ff000;
2011 else
2012 ratr_bitmap &= 0x000ff005;
2013 }
1995 } else { 2014 } else {
1996 if (rtlphy->rf_type == RF_1T2R || 2015 if (curtxbw_40mhz) {
1997 rtlphy->rf_type == RF_1T1R) { 2016 if (rssi_level == 1)
1998 if (curtxbw_40mhz) { 2017 ratr_bitmap &= 0x0f0f0000;
1999 if (rssi_level == 1) 2018 else if (rssi_level == 2)
2000 ratr_bitmap &= 0x000f0000; 2019 ratr_bitmap &= 0x0f0ff000;
2001 else if (rssi_level == 2) 2020 else
2002 ratr_bitmap &= 0x000ff000; 2021 ratr_bitmap &= 0x0f0ff015;
2003 else
2004 ratr_bitmap &= 0x000ff015;
2005 } else {
2006 if (rssi_level == 1)
2007 ratr_bitmap &= 0x000f0000;
2008 else if (rssi_level == 2)
2009 ratr_bitmap &= 0x000ff000;
2010 else
2011 ratr_bitmap &= 0x000ff005;
2012 }
2013 } else { 2022 } else {
2014 if (curtxbw_40mhz) { 2023 if (rssi_level == 1)
2015 if (rssi_level == 1) 2024 ratr_bitmap &= 0x0f0f0000;
2016 ratr_bitmap &= 0x0f0f0000; 2025 else if (rssi_level == 2)
2017 else if (rssi_level == 2) 2026 ratr_bitmap &= 0x0f0ff000;
2018 ratr_bitmap &= 0x0f0ff000; 2027 else
2019 else 2028 ratr_bitmap &= 0x0f0ff005;
2020 ratr_bitmap &= 0x0f0ff015;
2021 } else {
2022 if (rssi_level == 1)
2023 ratr_bitmap &= 0x0f0f0000;
2024 else if (rssi_level == 2)
2025 ratr_bitmap &= 0x0f0ff000;
2026 else
2027 ratr_bitmap &= 0x0f0ff005;
2028 }
2029 } 2029 }
2030 } 2030 }
2031 2031
@@ -2058,9 +2058,6 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
2058 "Rate_index:%x, ratr_val:%x, %5phC\n", 2058 "Rate_index:%x, ratr_val:%x, %5phC\n",
2059 ratr_index, ratr_bitmap, rate_mask); 2059 ratr_index, ratr_bitmap, rate_mask);
2060 rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); 2060 rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
2061
2062 if (macid != 0)
2063 sta_entry->ratr_index = ratr_index;
2064} 2061}
2065 2062
2066void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw, 2063void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index bc5ca989b915..1ee5a6ae9960 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -518,11 +518,12 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
518 } 518 }
519 case ERFSLEEP:{ 519 case ERFSLEEP:{
520 if (ppsc->rfpwr_state == ERFOFF) 520 if (ppsc->rfpwr_state == ERFOFF)
521 return false; 521 break;
522 for (queue_id = 0, i = 0; 522 for (queue_id = 0, i = 0;
523 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 523 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
524 ring = &pcipriv->dev.tx_ring[queue_id]; 524 ring = &pcipriv->dev.tx_ring[queue_id];
525 if (skb_queue_len(&ring->queue) == 0) { 525 if (queue_id == BEACON_QUEUE ||
526 skb_queue_len(&ring->queue) == 0) {
526 queue_id++; 527 queue_id++;
527 continue; 528 continue;
528 } else { 529 } else {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index dd5aa089126a..de6cb6c3a48c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -334,21 +334,21 @@ static struct rtl_hal_cfg rtl92ce_hal_cfg = {
334 .maps[RTL_IMR_ROK] = IMR_ROK, 334 .maps[RTL_IMR_ROK] = IMR_ROK,
335 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 335 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
336 336
337 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, 337 .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
338 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, 338 .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
339 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, 339 .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
340 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, 340 .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
341 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, 341 .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
342 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, 342 .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
343 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, 343 .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
344 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, 344 .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
345 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, 345 .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
346 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, 346 .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
347 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, 347 .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
348 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, 348 .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
349 349
350 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, 350 .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
351 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 351 .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
352}; 352};
353 353
354static const struct pci_device_id rtl92ce_pci_ids[] = { 354static const struct pci_device_id rtl92ce_pci_ids[] = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index e88dcd0e0af1..84ddd4d07a1d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -257,8 +257,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
257 pstats->recvsignalpower = rx_pwr_all; 257 pstats->recvsignalpower = rx_pwr_all;
258 258
259 /* (3)EVM of HT rate */ 259 /* (3)EVM of HT rate */
260 if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 && 260 if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 &&
261 pstats->rate <= DESC92_RATEMCS15) 261 pstats->rate <= DESC_RATEMCS15)
262 max_spatial_stream = 2; 262 max_spatial_stream = 2;
263 else 263 else
264 max_spatial_stream = 1; 264 max_spatial_stream = 1;
@@ -400,9 +400,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
400 * are use (RX_FLAG_HT) 400 * are use (RX_FLAG_HT)
401 * Notice: this is diff with windows define 401 * Notice: this is diff with windows define
402 */ 402 */
403 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 403 rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
404 stats->is_ht, stats->rate, 404 false, stats->rate);
405 stats->isfirst_ampdu);
406 405
407 rx_status->mactime = stats->timestamp_low; 406 rx_status->mactime = stats->timestamp_low;
408 if (phystatus) { 407 if (phystatus) {
@@ -501,7 +500,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
501 SET_TX_DESC_RTS_BW(pdesc, 0); 500 SET_TX_DESC_RTS_BW(pdesc, 0);
502 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc); 501 SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
503 SET_TX_DESC_RTS_SHORT(pdesc, 502 SET_TX_DESC_RTS_SHORT(pdesc,
504 ((tcb_desc->rts_rate <= DESC92_RATE54M) ? 503 ((tcb_desc->rts_rate <= DESC_RATE54M) ?
505 (tcb_desc->rts_use_shortpreamble ? 1 : 0) 504 (tcb_desc->rts_use_shortpreamble ? 1 : 0)
506 : (tcb_desc->rts_use_shortgi ? 1 : 0))); 505 : (tcb_desc->rts_use_shortgi ? 1 : 0)));
507 506
@@ -624,7 +623,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
624 if (firstseg) 623 if (firstseg)
625 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); 624 SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
626 625
627 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); 626 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
628 627
629 SET_TX_DESC_SEQ(pdesc, 0); 628 SET_TX_DESC_SEQ(pdesc, 0);
630 629
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 551321728ae0..fe4b699a12f5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1000,6 +1000,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1000 local_save_flags(flags); 1000 local_save_flags(flags);
1001 local_irq_enable(); 1001 local_irq_enable();
1002 1002
1003 rtlhal->fw_ready = false;
1003 rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; 1004 rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
1004 err = _rtl92cu_init_mac(hw); 1005 err = _rtl92cu_init_mac(hw);
1005 if (err) { 1006 if (err) {
@@ -1013,6 +1014,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1013 err = 1; 1014 err = 1;
1014 goto exit; 1015 goto exit;
1015 } 1016 }
1017
1018 rtlhal->fw_ready = true;
1016 rtlhal->last_hmeboxnum = 0; /* h2c */ 1019 rtlhal->last_hmeboxnum = 0; /* h2c */
1017 _rtl92cu_phy_param_tab_init(hw); 1020 _rtl92cu_phy_param_tab_init(hw);
1018 rtl92cu_phy_mac_config(hw); 1021 rtl92cu_phy_mac_config(hw);
@@ -1509,6 +1512,7 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
1509 /* TODO: Modify later (Find the right parameters) 1512 /* TODO: Modify later (Find the right parameters)
1510 * NOTE: Fix test chip's bug (about contention windows's randomness) */ 1513 * NOTE: Fix test chip's bug (about contention windows's randomness) */
1511 if ((mac->opmode == NL80211_IFTYPE_ADHOC) || 1514 if ((mac->opmode == NL80211_IFTYPE_ADHOC) ||
1515 (mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
1512 (mac->opmode == NL80211_IFTYPE_AP)) { 1516 (mac->opmode == NL80211_IFTYPE_AP)) {
1513 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); 1517 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50);
1514 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); 1518 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index c2d8ec6afcda..133e395b7401 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -880,8 +880,8 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw,
880 pstats->rxpower = rx_pwr_all; 880 pstats->rxpower = rx_pwr_all;
881 pstats->recvsignalpower = rx_pwr_all; 881 pstats->recvsignalpower = rx_pwr_all;
882 if (GET_RX_DESC_RX_MCS(pdesc) && 882 if (GET_RX_DESC_RX_MCS(pdesc) &&
883 GET_RX_DESC_RX_MCS(pdesc) >= DESC92_RATEMCS8 && 883 GET_RX_DESC_RX_MCS(pdesc) >= DESC_RATEMCS8 &&
884 GET_RX_DESC_RX_MCS(pdesc) <= DESC92_RATEMCS15) 884 GET_RX_DESC_RX_MCS(pdesc) <= DESC_RATEMCS15)
885 max_spatial_stream = 2; 885 max_spatial_stream = 2;
886 else 886 else
887 max_spatial_stream = 1; 887 max_spatial_stream = 1;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index e06bafee37f9..90a714c189a8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -257,20 +257,20 @@ static struct rtl_hal_cfg rtl92cu_hal_cfg = {
257 .maps[RTL_IMR_ROK] = IMR_ROK, 257 .maps[RTL_IMR_ROK] = IMR_ROK,
258 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 258 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
259 259
260 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, 260 .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
261 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, 261 .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
262 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, 262 .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
263 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, 263 .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
264 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, 264 .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
265 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, 265 .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
266 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, 266 .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
267 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, 267 .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
268 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, 268 .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
269 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, 269 .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
270 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, 270 .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
271 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, 271 .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
272 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, 272 .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
273 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 273 .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
274}; 274};
275 275
276#define USB_VENDER_ID_REALTEK 0x0bda 276#define USB_VENDER_ID_REALTEK 0x0bda
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
index f383d5f1fed5..cbead007171f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
@@ -325,6 +325,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
325 && (GET_RX_DESC_FAGGR(pdesc) == 1)); 325 && (GET_RX_DESC_FAGGR(pdesc) == 1));
326 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); 326 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
327 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); 327 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
328 stats->is_ht = (bool)GET_RX_DESC_RX_HT(pdesc);
328 rx_status->freq = hw->conf.chandef.chan->center_freq; 329 rx_status->freq = hw->conf.chandef.chan->center_freq;
329 rx_status->band = hw->conf.chandef.chan->band; 330 rx_status->band = hw->conf.chandef.chan->band;
330 if (GET_RX_DESC_CRC32(pdesc)) 331 if (GET_RX_DESC_CRC32(pdesc))
@@ -338,10 +339,8 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
338 rx_status->flag |= RX_FLAG_MACTIME_START; 339 rx_status->flag |= RX_FLAG_MACTIME_START;
339 if (stats->decrypted) 340 if (stats->decrypted)
340 rx_status->flag |= RX_FLAG_DECRYPTED; 341 rx_status->flag |= RX_FLAG_DECRYPTED;
341 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 342 rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
342 (bool)GET_RX_DESC_RX_HT(pdesc), 343 false, stats->rate);
343 (u8)GET_RX_DESC_RX_MCS(pdesc),
344 (bool)GET_RX_DESC_PAGGR(pdesc));
345 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 344 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
346 if (phystatus) { 345 if (phystatus) {
347 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + 346 p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
@@ -393,6 +392,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
393 && (GET_RX_DESC_FAGGR(rxdesc) == 1)); 392 && (GET_RX_DESC_FAGGR(rxdesc) == 1));
394 stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc); 393 stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc);
395 stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); 394 stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc);
395 stats.is_ht = (bool)GET_RX_DESC_RX_HT(rxdesc);
396 /* TODO: is center_freq changed when doing scan? */ 396 /* TODO: is center_freq changed when doing scan? */
397 /* TODO: Shall we add protection or just skip those two step? */ 397 /* TODO: Shall we add protection or just skip those two step? */
398 rx_status->freq = hw->conf.chandef.chan->center_freq; 398 rx_status->freq = hw->conf.chandef.chan->center_freq;
@@ -406,10 +406,8 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
406 if (GET_RX_DESC_RX_HT(rxdesc)) 406 if (GET_RX_DESC_RX_HT(rxdesc))
407 rx_status->flag |= RX_FLAG_HT; 407 rx_status->flag |= RX_FLAG_HT;
408 /* Data rate */ 408 /* Data rate */
409 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 409 rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats.is_ht,
410 (bool)GET_RX_DESC_RX_HT(rxdesc), 410 false, stats.rate);
411 (u8)GET_RX_DESC_RX_MCS(rxdesc),
412 (bool)GET_RX_DESC_PAGGR(rxdesc));
413 /* There is a phy status after this rx descriptor. */ 411 /* There is a phy status after this rx descriptor. */
414 if (GET_RX_DESC_PHY_STATUS(rxdesc)) { 412 if (GET_RX_DESC_PHY_STATUS(rxdesc)) {
415 p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE); 413 p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE);
@@ -545,7 +543,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
545 SET_TX_DESC_RTS_BW(txdesc, 0); 543 SET_TX_DESC_RTS_BW(txdesc, 0);
546 SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc); 544 SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);
547 SET_TX_DESC_RTS_SHORT(txdesc, 545 SET_TX_DESC_RTS_SHORT(txdesc,
548 ((tcb_desc->rts_rate <= DESC92_RATE54M) ? 546 ((tcb_desc->rts_rate <= DESC_RATE54M) ?
549 (tcb_desc->rts_use_shortpreamble ? 1 : 0) 547 (tcb_desc->rts_use_shortpreamble ? 1 : 0)
550 : (tcb_desc->rts_use_shortgi ? 1 : 0))); 548 : (tcb_desc->rts_use_shortgi ? 1 : 0)));
551 if (mac->bw_40) { 549 if (mac->bw_40) {
@@ -644,7 +642,7 @@ void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
644 } 642 }
645 SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */ 643 SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */
646 SET_TX_DESC_OWN(pDesc, 1); 644 SET_TX_DESC_OWN(pDesc, 1);
647 SET_TX_DESC_TX_RATE(pDesc, DESC92_RATE1M); 645 SET_TX_DESC_TX_RATE(pDesc, DESC_RATE1M);
648 _rtl_tx_desc_checksum(pDesc); 646 _rtl_tx_desc_checksum(pDesc);
649} 647}
650 648
@@ -660,7 +658,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
660 memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); 658 memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE);
661 if (firstseg) 659 if (firstseg)
662 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); 660 SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE);
663 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); 661 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
664 SET_TX_DESC_SEQ(pdesc, 0); 662 SET_TX_DESC_SEQ(pdesc, 0);
665 SET_TX_DESC_LINIP(pdesc, 0); 663 SET_TX_DESC_LINIP(pdesc, 0);
666 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); 664 SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue);
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/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
index 23177076b97f..62ef8209718f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
@@ -540,23 +540,6 @@ void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
540 return; 540 return;
541} 541}
542 542
543void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode)
544{
545 struct rtl_priv *rtlpriv = rtl_priv(hw);
546 u8 u1_h2c_set_pwrmode[3] = { 0 };
547 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
548
549 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode);
550 SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode);
551 SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1);
552 SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode,
553 ppsc->reg_max_lps_awakeintvl);
554 RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
555 "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode",
556 u1_h2c_set_pwrmode, 3);
557 rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode);
558}
559
560static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw, 543static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
561 struct sk_buff *skb) 544 struct sk_buff *skb)
562{ 545{
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
index a55a803a0b4d..1646e7c3d0f8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h
@@ -136,7 +136,6 @@ int rtl92d_download_fw(struct ieee80211_hw *hw);
136void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, 136void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id,
137 u32 cmd_len, u8 *p_cmdbuffer); 137 u32 cmd_len, u8 *p_cmdbuffer);
138void rtl92d_firmware_selfreset(struct ieee80211_hw *hw); 138void rtl92d_firmware_selfreset(struct ieee80211_hw *hw);
139void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
140void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); 139void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
141void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); 140void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
142 141
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/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index a0aba088259a..b19d0398215f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -337,21 +337,21 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
337 .maps[RTL_IMR_ROK] = IMR_ROK, 337 .maps[RTL_IMR_ROK] = IMR_ROK,
338 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 338 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
339 339
340 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, 340 .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
341 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, 341 .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
342 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, 342 .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
343 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, 343 .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
344 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, 344 .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
345 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, 345 .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
346 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, 346 .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
347 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, 347 .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
348 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, 348 .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
349 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, 349 .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
350 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, 350 .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
351 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, 351 .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
352 352
353 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, 353 .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
354 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 354 .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
355}; 355};
356 356
357static struct pci_device_id rtl92de_pci_ids[] = { 357static struct pci_device_id rtl92de_pci_ids[] = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
index 8efbcc7af250..1feaa629dd4f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c
@@ -235,8 +235,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw,
235 pstats->rx_pwdb_all = pwdb_all; 235 pstats->rx_pwdb_all = pwdb_all;
236 pstats->rxpower = rx_pwr_all; 236 pstats->rxpower = rx_pwr_all;
237 pstats->recvsignalpower = rx_pwr_all; 237 pstats->recvsignalpower = rx_pwr_all;
238 if (pdesc->rxht && pdesc->rxmcs >= DESC92_RATEMCS8 && 238 if (pdesc->rxht && pdesc->rxmcs >= DESC_RATEMCS8 &&
239 pdesc->rxmcs <= DESC92_RATEMCS15) 239 pdesc->rxmcs <= DESC_RATEMCS15)
240 max_spatial_stream = 2; 240 max_spatial_stream = 2;
241 else 241 else
242 max_spatial_stream = 1; 242 max_spatial_stream = 1;
@@ -499,6 +499,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
499 && (GET_RX_DESC_FAGGR(pdesc) == 1)); 499 && (GET_RX_DESC_FAGGR(pdesc) == 1));
500 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); 500 stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
501 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); 501 stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
502 stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
502 rx_status->freq = hw->conf.chandef.chan->center_freq; 503 rx_status->freq = hw->conf.chandef.chan->center_freq;
503 rx_status->band = hw->conf.chandef.chan->band; 504 rx_status->band = hw->conf.chandef.chan->band;
504 if (GET_RX_DESC_CRC32(pdesc)) 505 if (GET_RX_DESC_CRC32(pdesc))
@@ -512,10 +513,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
512 rx_status->flag |= RX_FLAG_MACTIME_START; 513 rx_status->flag |= RX_FLAG_MACTIME_START;
513 if (stats->decrypted) 514 if (stats->decrypted)
514 rx_status->flag |= RX_FLAG_DECRYPTED; 515 rx_status->flag |= RX_FLAG_DECRYPTED;
515 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 516 rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
516 (bool)GET_RX_DESC_RXHT(pdesc), 517 false, stats->rate);
517 (u8)GET_RX_DESC_RXMCS(pdesc),
518 (bool)GET_RX_DESC_PAGGR(pdesc));
519 rx_status->mactime = GET_RX_DESC_TSFL(pdesc); 518 rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
520 if (phystatus) { 519 if (phystatus) {
521 p_drvinfo = (struct rx_fwinfo_92d *)(skb->data + 520 p_drvinfo = (struct rx_fwinfo_92d *)(skb->data +
@@ -612,14 +611,14 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
612 } 611 }
613 /* 5G have no CCK rate */ 612 /* 5G have no CCK rate */
614 if (rtlhal->current_bandtype == BAND_ON_5G) 613 if (rtlhal->current_bandtype == BAND_ON_5G)
615 if (ptcb_desc->hw_rate < DESC92_RATE6M) 614 if (ptcb_desc->hw_rate < DESC_RATE6M)
616 ptcb_desc->hw_rate = DESC92_RATE6M; 615 ptcb_desc->hw_rate = DESC_RATE6M;
617 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate); 616 SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
618 if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble) 617 if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
619 SET_TX_DESC_DATA_SHORTGI(pdesc, 1); 618 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
620 619
621 if (rtlhal->macphymode == DUALMAC_DUALPHY && 620 if (rtlhal->macphymode == DUALMAC_DUALPHY &&
622 ptcb_desc->hw_rate == DESC92_RATEMCS7) 621 ptcb_desc->hw_rate == DESC_RATEMCS7)
623 SET_TX_DESC_DATA_SHORTGI(pdesc, 1); 622 SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
624 623
625 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 624 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
@@ -635,13 +634,13 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw,
635 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0)); 634 SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
636 /* 5G have no CCK rate */ 635 /* 5G have no CCK rate */
637 if (rtlhal->current_bandtype == BAND_ON_5G) 636 if (rtlhal->current_bandtype == BAND_ON_5G)
638 if (ptcb_desc->rts_rate < DESC92_RATE6M) 637 if (ptcb_desc->rts_rate < DESC_RATE6M)
639 ptcb_desc->rts_rate = DESC92_RATE6M; 638 ptcb_desc->rts_rate = DESC_RATE6M;
640 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); 639 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
641 SET_TX_DESC_RTS_BW(pdesc, 0); 640 SET_TX_DESC_RTS_BW(pdesc, 0);
642 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); 641 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
643 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= 642 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
644 DESC92_RATE54M) ? 643 DESC_RATE54M) ?
645 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : 644 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
646 (ptcb_desc->rts_use_shortgi ? 1 : 0))); 645 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
647 if (bw_40) { 646 if (bw_40) {
@@ -756,9 +755,9 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw,
756 * The braces are needed no matter what checkpatch says 755 * The braces are needed no matter what checkpatch says
757 */ 756 */
758 if (rtlhal->current_bandtype == BAND_ON_5G) { 757 if (rtlhal->current_bandtype == BAND_ON_5G) {
759 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE6M); 758 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE6M);
760 } else { 759 } else {
761 SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); 760 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
762 } 761 }
763 SET_TX_DESC_SEQ(pdesc, 0); 762 SET_TX_DESC_SEQ(pdesc, 0);
764 SET_TX_DESC_LINIP(pdesc, 0); 763 SET_TX_DESC_LINIP(pdesc, 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/rtl8192ee/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
index 45c128b91f7f..c5d4b8013cde 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/fw.c
@@ -666,7 +666,6 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
666 struct sk_buff *skb = NULL; 666 struct sk_buff *skb = NULL;
667 667
668 u32 totalpacketlen; 668 u32 totalpacketlen;
669 bool rtstatus;
670 u8 u1rsvdpageloc[5] = { 0 }; 669 u8 u1rsvdpageloc[5] = { 0 };
671 bool b_dlok = false; 670 bool b_dlok = false;
672 671
@@ -728,10 +727,7 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
728 memcpy((u8 *)skb_put(skb, totalpacketlen), 727 memcpy((u8 *)skb_put(skb, totalpacketlen),
729 &reserved_page_packet, totalpacketlen); 728 &reserved_page_packet, totalpacketlen);
730 729
731 rtstatus = rtl_cmd_send_packet(hw, skb); 730 b_dlok = true;
732
733 if (rtstatus)
734 b_dlok = true;
735 731
736 if (b_dlok) { 732 if (b_dlok) {
737 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , 733 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD ,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
index 1a87edca2c3f..b461b3128da5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
@@ -85,29 +85,6 @@ static void _rtl92ee_enable_bcn_sub_func(struct ieee80211_hw *hw)
85 _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(1)); 85 _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(1));
86} 86}
87 87
88static void _rtl92ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
89{
90 struct rtl_priv *rtlpriv = rtl_priv(hw);
91 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
92 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
93 unsigned long flags;
94
95 spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
96 while (skb_queue_len(&ring->queue)) {
97 struct rtl_tx_buffer_desc *entry =
98 &ring->buffer_desc[ring->idx];
99 struct sk_buff *skb = __skb_dequeue(&ring->queue);
100
101 pci_unmap_single(rtlpci->pdev,
102 rtlpriv->cfg->ops->get_desc(
103 (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
104 skb->len, PCI_DMA_TODEVICE);
105 kfree_skb(skb);
106 ring->idx = (ring->idx + 1) % ring->entries;
107 }
108 spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
109}
110
111static void _rtl92ee_disable_bcn_sub_func(struct ieee80211_hw *hw) 88static void _rtl92ee_disable_bcn_sub_func(struct ieee80211_hw *hw)
112{ 89{
113 _rtl92ee_set_bcn_ctrl_reg(hw, BIT(1), 0); 90 _rtl92ee_set_bcn_ctrl_reg(hw, BIT(1), 0);
@@ -403,9 +380,6 @@ static void _rtl92ee_download_rsvd_page(struct ieee80211_hw *hw)
403 rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, 380 rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2,
404 bcnvalid_reg | BIT(0)); 381 bcnvalid_reg | BIT(0));
405 382
406 /* Return Beacon TCB */
407 _rtl92ee_return_beacon_queue_skb(hw);
408
409 /* download rsvd page */ 383 /* download rsvd page */
410 rtl92ee_set_fw_rsvdpagepkt(hw, false); 384 rtl92ee_set_fw_rsvdpagepkt(hw, false);
411 385
@@ -1163,6 +1137,139 @@ void rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw)
1163 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 1137 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
1164} 1138}
1165 1139
1140static bool _rtl8192ee_check_pcie_dma_hang(struct rtl_priv *rtlpriv)
1141{
1142 u8 tmp;
1143
1144 /* write reg 0x350 Bit[26]=1. Enable debug port. */
1145 tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3);
1146 if (!(tmp & BIT(2))) {
1147 rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3,
1148 tmp | BIT(2));
1149 mdelay(100); /* Suggested by DD Justin_tsai. */
1150 }
1151
1152 /* read reg 0x350 Bit[25] if 1 : RX hang
1153 * read reg 0x350 Bit[24] if 1 : TX hang
1154 */
1155 tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3);
1156 if ((tmp & BIT(0)) || (tmp & BIT(1))) {
1157 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1158 "CheckPcieDMAHang8192EE(): true!!\n");
1159 return true;
1160 }
1161 return false;
1162}
1163
1164static void _rtl8192ee_reset_pcie_interface_dma(struct rtl_priv *rtlpriv,
1165 bool mac_power_on)
1166{
1167 u8 tmp;
1168 bool release_mac_rx_pause;
1169 u8 backup_pcie_dma_pause;
1170
1171 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1172 "ResetPcieInterfaceDMA8192EE()\n");
1173
1174 /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03"
1175 * released by SD1 Alan.
1176 */
1177
1178 /* 1. disable register write lock
1179 * write 0x1C bit[1:0] = 2'h0
1180 * write 0xCC bit[2] = 1'b1
1181 */
1182 tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL);
1183 tmp &= ~(BIT(1) | BIT(0));
1184 rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp);
1185 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1186 tmp |= BIT(2);
1187 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1188
1189 /* 2. Check and pause TRX DMA
1190 * write 0x284 bit[18] = 1'b1
1191 * write 0x301 = 0xFF
1192 */
1193 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1194 if (tmp & BIT(2)) {
1195 /* Already pause before the function for another reason. */
1196 release_mac_rx_pause = false;
1197 } else {
1198 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2)));
1199 release_mac_rx_pause = true;
1200 }
1201
1202 backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1);
1203 if (backup_pcie_dma_pause != 0xFF)
1204 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF);
1205
1206 if (mac_power_on) {
1207 /* 3. reset TRX function
1208 * write 0x100 = 0x00
1209 */
1210 rtl_write_byte(rtlpriv, REG_CR, 0);
1211 }
1212
1213 /* 4. Reset PCIe DMA
1214 * write 0x003 bit[0] = 0
1215 */
1216 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1217 tmp &= ~(BIT(0));
1218 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1219
1220 /* 5. Enable PCIe DMA
1221 * write 0x003 bit[0] = 1
1222 */
1223 tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
1224 tmp |= BIT(0);
1225 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp);
1226
1227 if (mac_power_on) {
1228 /* 6. enable TRX function
1229 * write 0x100 = 0xFF
1230 */
1231 rtl_write_byte(rtlpriv, REG_CR, 0xFF);
1232
1233 /* We should init LLT & RQPN and
1234 * prepare Tx/Rx descrptor address later
1235 * because MAC function is reset.
1236 */
1237 }
1238
1239 /* 7. Restore PCIe autoload down bit
1240 * write 0xF8 bit[17] = 1'b1
1241 */
1242 tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2);
1243 tmp |= BIT(1);
1244 rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp);
1245
1246 /* In MAC power on state, BB and RF maybe in ON state,
1247 * if we release TRx DMA here
1248 * it will cause packets to be started to Tx/Rx,
1249 * so we release Tx/Rx DMA later.
1250 */
1251 if (!mac_power_on) {
1252 /* 8. release TRX DMA
1253 * write 0x284 bit[18] = 1'b0
1254 * write 0x301 = 0x00
1255 */
1256 if (release_mac_rx_pause) {
1257 tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL);
1258 rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL,
1259 (tmp & (~BIT(2))));
1260 }
1261 rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1,
1262 backup_pcie_dma_pause);
1263 }
1264
1265 /* 9. lock system register
1266 * write 0xCC bit[2] = 1'b0
1267 */
1268 tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2);
1269 tmp &= ~(BIT(2));
1270 rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp);
1271}
1272
1166int rtl92ee_hw_init(struct ieee80211_hw *hw) 1273int rtl92ee_hw_init(struct ieee80211_hw *hw)
1167{ 1274{
1168 struct rtl_priv *rtlpriv = rtl_priv(hw); 1275 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1188,6 +1295,13 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw)
1188 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E; 1295 rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E;
1189 } 1296 }
1190 1297
1298 if (_rtl8192ee_check_pcie_dma_hang(rtlpriv)) {
1299 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "92ee dma hang!\n");
1300 _rtl8192ee_reset_pcie_interface_dma(rtlpriv,
1301 rtlhal->mac_func_enable);
1302 rtlhal->mac_func_enable = false;
1303 }
1304
1191 rtstatus = _rtl92ee_init_mac(hw); 1305 rtstatus = _rtl92ee_init_mac(hw);
1192 1306
1193 rtl_write_byte(rtlpriv, 0x577, 0x03); 1307 rtl_write_byte(rtlpriv, 0x577, 0x03);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h
index 3f2a9596e7cd..1eaa1fab550d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/reg.h
@@ -77,9 +77,11 @@
77#define REG_HIMRE 0x00B8 77#define REG_HIMRE 0x00B8
78#define REG_HISRE 0x00BC 78#define REG_HISRE 0x00BC
79 79
80#define REG_PMC_DBG_CTRL2 0x00CC
80#define REG_EFUSE_ACCESS 0x00CF 81#define REG_EFUSE_ACCESS 0x00CF
81#define REG_HPON_FSM 0x00EC 82#define REG_HPON_FSM 0x00EC
82#define REG_SYS_CFG1 0x00F0 83#define REG_SYS_CFG1 0x00F0
84#define REG_MAC_PHY_CTRL_NORMAL 0x00F8
83#define REG_SYS_CFG2 0x00FC 85#define REG_SYS_CFG2 0x00FC
84 86
85#define REG_CR 0x0100 87#define REG_CR 0x0100
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
index 9b5a7d5be121..c31c6bfb536d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/sw.c
@@ -113,8 +113,6 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw)
113 RCR_HTC_LOC_CTRL | 113 RCR_HTC_LOC_CTRL |
114 RCR_AMF | 114 RCR_AMF |
115 RCR_ACF | 115 RCR_ACF |
116 RCR_ADF |
117 RCR_AICV |
118 RCR_ACRC32 | 116 RCR_ACRC32 |
119 RCR_AB | 117 RCR_AB |
120 RCR_AM | 118 RCR_AM |
@@ -241,6 +239,7 @@ static struct rtl_hal_ops rtl8192ee_hal_ops = {
241 .set_desc = rtl92ee_set_desc, 239 .set_desc = rtl92ee_set_desc,
242 .get_desc = rtl92ee_get_desc, 240 .get_desc = rtl92ee_get_desc,
243 .is_tx_desc_closed = rtl92ee_is_tx_desc_closed, 241 .is_tx_desc_closed = rtl92ee_is_tx_desc_closed,
242 .get_available_desc = rtl92ee_get_available_desc,
244 .tx_polling = rtl92ee_tx_polling, 243 .tx_polling = rtl92ee_tx_polling,
245 .enable_hw_sec = rtl92ee_enable_hw_security_config, 244 .enable_hw_sec = rtl92ee_enable_hw_security_config,
246 .set_key = rtl92ee_set_key, 245 .set_key = rtl92ee_set_key,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
index 2fcbef1d029f..d39ee67f6113 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.c
@@ -47,164 +47,6 @@ static u8 _rtl92ee_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
47 return skb->priority; 47 return skb->priority;
48} 48}
49 49
50/* mac80211's rate_idx is like this:
51 *
52 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
53 *
54 * B/G rate:
55 * (rx_status->flag & RX_FLAG_HT) = 0,
56 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
57 *
58 * N rate:
59 * (rx_status->flag & RX_FLAG_HT) = 1,
60 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
61 *
62 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
63 * A rate:
64 * (rx_status->flag & RX_FLAG_HT) = 0,
65 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
66 *
67 * N rate:
68 * (rx_status->flag & RX_FLAG_HT) = 1,
69 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
70 */
71static int _rtl92ee_rate_mapping(struct ieee80211_hw *hw,
72 bool isht, u8 desc_rate)
73{
74 int rate_idx;
75
76 if (!isht) {
77 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
78 switch (desc_rate) {
79 case DESC92C_RATE1M:
80 rate_idx = 0;
81 break;
82 case DESC92C_RATE2M:
83 rate_idx = 1;
84 break;
85 case DESC92C_RATE5_5M:
86 rate_idx = 2;
87 break;
88 case DESC92C_RATE11M:
89 rate_idx = 3;
90 break;
91 case DESC92C_RATE6M:
92 rate_idx = 4;
93 break;
94 case DESC92C_RATE9M:
95 rate_idx = 5;
96 break;
97 case DESC92C_RATE12M:
98 rate_idx = 6;
99 break;
100 case DESC92C_RATE18M:
101 rate_idx = 7;
102 break;
103 case DESC92C_RATE24M:
104 rate_idx = 8;
105 break;
106 case DESC92C_RATE36M:
107 rate_idx = 9;
108 break;
109 case DESC92C_RATE48M:
110 rate_idx = 10;
111 break;
112 case DESC92C_RATE54M:
113 rate_idx = 11;
114 break;
115 default:
116 rate_idx = 0;
117 break;
118 }
119 } else {
120 switch (desc_rate) {
121 case DESC92C_RATE6M:
122 rate_idx = 0;
123 break;
124 case DESC92C_RATE9M:
125 rate_idx = 1;
126 break;
127 case DESC92C_RATE12M:
128 rate_idx = 2;
129 break;
130 case DESC92C_RATE18M:
131 rate_idx = 3;
132 break;
133 case DESC92C_RATE24M:
134 rate_idx = 4;
135 break;
136 case DESC92C_RATE36M:
137 rate_idx = 5;
138 break;
139 case DESC92C_RATE48M:
140 rate_idx = 6;
141 break;
142 case DESC92C_RATE54M:
143 rate_idx = 7;
144 break;
145 default:
146 rate_idx = 0;
147 break;
148 }
149 }
150 } else {
151 switch (desc_rate) {
152 case DESC92C_RATEMCS0:
153 rate_idx = 0;
154 break;
155 case DESC92C_RATEMCS1:
156 rate_idx = 1;
157 break;
158 case DESC92C_RATEMCS2:
159 rate_idx = 2;
160 break;
161 case DESC92C_RATEMCS3:
162 rate_idx = 3;
163 break;
164 case DESC92C_RATEMCS4:
165 rate_idx = 4;
166 break;
167 case DESC92C_RATEMCS5:
168 rate_idx = 5;
169 break;
170 case DESC92C_RATEMCS6:
171 rate_idx = 6;
172 break;
173 case DESC92C_RATEMCS7:
174 rate_idx = 7;
175 break;
176 case DESC92C_RATEMCS8:
177 rate_idx = 8;
178 break;
179 case DESC92C_RATEMCS9:
180 rate_idx = 9;
181 break;
182 case DESC92C_RATEMCS10:
183 rate_idx = 10;
184 break;
185 case DESC92C_RATEMCS11:
186 rate_idx = 11;
187 break;
188 case DESC92C_RATEMCS12:
189 rate_idx = 12;
190 break;
191 case DESC92C_RATEMCS13:
192 rate_idx = 13;
193 break;
194 case DESC92C_RATEMCS14:
195 rate_idx = 14;
196 break;
197 case DESC92C_RATEMCS15:
198 rate_idx = 15;
199 break;
200 default:
201 rate_idx = 0;
202 break;
203 }
204 }
205 return rate_idx;
206}
207
208static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw, 50static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw,
209 struct rtl_stats *pstatus, u8 *pdesc, 51 struct rtl_stats *pstatus, u8 *pdesc,
210 struct rx_fwinfo *p_drvinfo, 52 struct rx_fwinfo *p_drvinfo,
@@ -345,8 +187,8 @@ static void _rtl92ee_query_rxphystatus(struct ieee80211_hw *hw,
345 pstatus->recvsignalpower = rx_pwr_all; 187 pstatus->recvsignalpower = rx_pwr_all;
346 188
347 /* (3)EVM of HT rate */ 189 /* (3)EVM of HT rate */
348 if (pstatus->rate >= DESC92C_RATEMCS8 && 190 if (pstatus->rate >= DESC_RATEMCS8 &&
349 pstatus->rate <= DESC92C_RATEMCS15) 191 pstatus->rate <= DESC_RATEMCS15)
350 max_spatial_stream = 2; 192 max_spatial_stream = 2;
351 else 193 else
352 max_spatial_stream = 1; 194 max_spatial_stream = 1;
@@ -512,6 +354,10 @@ bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw,
512 struct ieee80211_hdr *hdr; 354 struct ieee80211_hdr *hdr;
513 u32 phystatus = GET_RX_DESC_PHYST(pdesc); 355 u32 phystatus = GET_RX_DESC_PHYST(pdesc);
514 356
357 if (GET_RX_STATUS_DESC_RPT_SEL(pdesc) == 0)
358 status->packet_report_type = NORMAL_RX;
359 else
360 status->packet_report_type = C2H_PACKET;
515 status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc); 361 status->length = (u16)GET_RX_DESC_PKT_LEN(pdesc);
516 status->rx_drvinfo_size = (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) * 362 status->rx_drvinfo_size = (u8)GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
517 RX_DRV_INFO_SIZE_UNIT; 363 RX_DRV_INFO_SIZE_UNIT;
@@ -576,9 +422,8 @@ bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw,
576 * are use (RX_FLAG_HT) 422 * are use (RX_FLAG_HT)
577 * Notice: this is diff with windows define 423 * Notice: this is diff with windows define
578 */ 424 */
579 rx_status->rate_idx = _rtl92ee_rate_mapping(hw, 425 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
580 status->is_ht, 426 false, status->rate);
581 status->rate);
582 427
583 rx_status->mactime = status->timestamp_low; 428 rx_status->mactime = status->timestamp_low;
584 if (phystatus) { 429 if (phystatus) {
@@ -654,14 +499,7 @@ u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, u8 queue_index)
654 if (!start_rx) 499 if (!start_rx)
655 return 0; 500 return 0;
656 501
657 if ((last_read_point > (RX_DESC_NUM_92E / 2)) && 502 remind_cnt = calc_fifo_space(read_point, write_point);
658 (read_point <= (RX_DESC_NUM_92E / 2))) {
659 remind_cnt = RX_DESC_NUM_92E - write_point;
660 } else {
661 remind_cnt = (read_point >= write_point) ?
662 (read_point - write_point) :
663 (RX_DESC_NUM_92E - write_point + read_point);
664 }
665 503
666 if (remind_cnt == 0) 504 if (remind_cnt == 0)
667 return 0; 505 return 0;
@@ -710,7 +548,7 @@ static u16 get_desc_addr_fr_q_idx(u16 queue_index)
710 return desc_address; 548 return desc_address;
711} 549}
712 550
713void rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx) 551u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx)
714{ 552{
715 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 553 struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
716 struct rtl_priv *rtlpriv = rtl_priv(hw); 554 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -723,12 +561,11 @@ void rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 q_idx)
723 current_tx_read_point = (u16)((tmp_4byte >> 16) & 0x0fff); 561 current_tx_read_point = (u16)((tmp_4byte >> 16) & 0x0fff);
724 current_tx_write_point = (u16)((tmp_4byte) & 0x0fff); 562 current_tx_write_point = (u16)((tmp_4byte) & 0x0fff);
725 563
726 point_diff = ((current_tx_read_point > current_tx_write_point) ? 564 point_diff = calc_fifo_space(current_tx_read_point,
727 (current_tx_read_point - current_tx_write_point) : 565 current_tx_write_point);
728 (TX_DESC_NUM_92E - current_tx_write_point +
729 current_tx_read_point));
730 566
731 rtlpci->tx_ring[q_idx].avl_desc = point_diff; 567 rtlpci->tx_ring[q_idx].avl_desc = point_diff;
568 return point_diff;
732} 569}
733 570
734void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, 571void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw,
@@ -901,13 +738,13 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw,
901 } else { 738 } else {
902 if (rtlpriv->ra.is_special_data) { 739 if (rtlpriv->ra.is_special_data) {
903 ptcb_desc->use_driver_rate = true; 740 ptcb_desc->use_driver_rate = true;
904 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE11M); 741 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE11M);
905 } else { 742 } else {
906 ptcb_desc->use_driver_rate = false; 743 ptcb_desc->use_driver_rate = false;
907 } 744 }
908 } 745 }
909 746
910 if (ptcb_desc->hw_rate > DESC92C_RATEMCS0) 747 if (ptcb_desc->hw_rate > DESC_RATEMCS0)
911 short_gi = (ptcb_desc->use_shortgi) ? 1 : 0; 748 short_gi = (ptcb_desc->use_shortgi) ? 1 : 0;
912 else 749 else
913 short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0; 750 short_gi = (ptcb_desc->use_shortpreamble) ? 1 : 0;
@@ -927,7 +764,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw,
927 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate); 764 SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
928 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc); 765 SET_TX_DESC_RTS_SC(pdesc, ptcb_desc->rts_sc);
929 SET_TX_DESC_RTS_SHORT(pdesc, 766 SET_TX_DESC_RTS_SHORT(pdesc,
930 ((ptcb_desc->rts_rate <= DESC92C_RATE54M) ? 767 ((ptcb_desc->rts_rate <= DESC_RATE54M) ?
931 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) : 768 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) :
932 (ptcb_desc->rts_use_shortgi ? 1 : 0))); 769 (ptcb_desc->rts_use_shortgi ? 1 : 0)));
933 770
@@ -1038,7 +875,7 @@ void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw,
1038 if (firstseg) 875 if (firstseg)
1039 SET_TX_DESC_OFFSET(pdesc, txdesc_len); 876 SET_TX_DESC_OFFSET(pdesc, txdesc_len);
1040 877
1041 SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); 878 SET_TX_DESC_TX_RATE(pdesc, DESC_RATE1M);
1042 879
1043 SET_TX_DESC_SEQ(pdesc, 0); 880 SET_TX_DESC_SEQ(pdesc, 0);
1044 881
@@ -1207,8 +1044,7 @@ bool rtl92ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index)
1207 static u8 stop_report_cnt; 1044 static u8 stop_report_cnt;
1208 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; 1045 struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
1209 1046
1210 /*checking Read/Write Point each interrupt wastes CPU */ 1047 {
1211 if (stop_report_cnt > 15 || !rtlpriv->link_info.busytraffic) {
1212 u16 point_diff = 0; 1048 u16 point_diff = 0;
1213 u16 cur_tx_rp, cur_tx_wp; 1049 u16 cur_tx_rp, cur_tx_wp;
1214 u32 tmpu32 = 0; 1050 u32 tmpu32 = 0;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
index 6f9be1c7515c..8f78ac9e6040 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/trx.h
@@ -542,6 +542,8 @@
542 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) 542 LE_BITS_TO_4BYTE(__pdesc+8, 12, 4)
543#define GET_RX_DESC_RX_IS_QOS(__pdesc) \ 543#define GET_RX_DESC_RX_IS_QOS(__pdesc) \
544 LE_BITS_TO_4BYTE(__pdesc+8, 16, 1) 544 LE_BITS_TO_4BYTE(__pdesc+8, 16, 1)
545#define GET_RX_STATUS_DESC_RPT_SEL(__pdesc) \
546 LE_BITS_TO_4BYTE(__pdesc+8, 28, 1)
545 547
546#define GET_RX_DESC_RXMCS(__pdesc) \ 548#define GET_RX_DESC_RXMCS(__pdesc) \
547 LE_BITS_TO_4BYTE(__pdesc+12, 0, 7) 549 LE_BITS_TO_4BYTE(__pdesc+12, 0, 7)
@@ -591,10 +593,10 @@ do { \
591} while (0) 593} while (0)
592 594
593#define RTL92EE_RX_HAL_IS_CCK_RATE(rxmcs)\ 595#define RTL92EE_RX_HAL_IS_CCK_RATE(rxmcs)\
594 (rxmcs == DESC92C_RATE1M ||\ 596 (rxmcs == DESC_RATE1M ||\
595 rxmcs == DESC92C_RATE2M ||\ 597 rxmcs == DESC_RATE2M ||\
596 rxmcs == DESC92C_RATE5_5M ||\ 598 rxmcs == DESC_RATE5_5M ||\
597 rxmcs == DESC92C_RATE11M) 599 rxmcs == DESC_RATE11M)
598 600
599#define IS_LITTLE_ENDIAN 1 601#define IS_LITTLE_ENDIAN 1
600 602
@@ -829,7 +831,7 @@ void rtl92ee_rx_check_dma_ok(struct ieee80211_hw *hw, u8 *header_desc,
829 u8 queue_index); 831 u8 queue_index);
830u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw, 832u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw,
831 u8 queue_index); 833 u8 queue_index);
832void rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index); 834u16 rtl92ee_get_available_desc(struct ieee80211_hw *hw, u8 queue_index);
833void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw, 835void rtl92ee_pre_fill_tx_bd_desc(struct ieee80211_hw *hw,
834 u8 *tx_bd_desc, u8 *desc, u8 queue_index, 836 u8 *tx_bd_desc, u8 *desc, u8 queue_index,
835 struct sk_buff *skb, dma_addr_t addr); 837 struct sk_buff *skb, dma_addr_t addr);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 6e7a70b43949..ef87c09b77d0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -450,10 +450,10 @@
450 SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32) 450 SHIFT_AND_MASK_LE(__pdesc + 24, 0, 32)
451 451
452#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\ 452#define SE_RX_HAL_IS_CCK_RATE(_pdesc)\
453 (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE1M || \ 453 (GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC_RATE1M || \
454 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE2M || \ 454 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC_RATE2M || \
455 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE5_5M ||\ 455 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC_RATE5_5M ||\
456 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92_RATE11M) 456 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC_RATE11M)
457 457
458enum rf_optype { 458enum rf_optype {
459 RF_OP_BY_SW_3WIRE = 0, 459 RF_OP_BY_SW_3WIRE = 0,
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/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index fb003868bdef..e1fd27c888bf 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -383,21 +383,21 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
383 .maps[RTL_IMR_ROK] = IMR_ROK, 383 .maps[RTL_IMR_ROK] = IMR_ROK,
384 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), 384 .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
385 385
386 .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, 386 .maps[RTL_RC_CCK_RATE1M] = DESC_RATE1M,
387 .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, 387 .maps[RTL_RC_CCK_RATE2M] = DESC_RATE2M,
388 .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, 388 .maps[RTL_RC_CCK_RATE5_5M] = DESC_RATE5_5M,
389 .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, 389 .maps[RTL_RC_CCK_RATE11M] = DESC_RATE11M,
390 .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, 390 .maps[RTL_RC_OFDM_RATE6M] = DESC_RATE6M,
391 .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, 391 .maps[RTL_RC_OFDM_RATE9M] = DESC_RATE9M,
392 .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, 392 .maps[RTL_RC_OFDM_RATE12M] = DESC_RATE12M,
393 .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, 393 .maps[RTL_RC_OFDM_RATE18M] = DESC_RATE18M,
394 .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, 394 .maps[RTL_RC_OFDM_RATE24M] = DESC_RATE24M,
395 .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, 395 .maps[RTL_RC_OFDM_RATE36M] = DESC_RATE36M,
396 .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, 396 .maps[RTL_RC_OFDM_RATE48M] = DESC_RATE48M,
397 .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, 397 .maps[RTL_RC_OFDM_RATE54M] = DESC_RATE54M,
398 398
399 .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, 399 .maps[RTL_RC_HT_RATEMCS7] = DESC_RATEMCS7,
400 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 400 .maps[RTL_RC_HT_RATEMCS15] = DESC_RATEMCS15,
401}; 401};
402 402
403static struct pci_device_id rtl92se_pci_ids[] = { 403static struct pci_device_id rtl92se_pci_ids[] = {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 672fd3b02835..125b29bd2f93 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -191,8 +191,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
191 pstats->rxpower = rx_pwr_all; 191 pstats->rxpower = rx_pwr_all;
192 pstats->recvsignalpower = rx_pwr_all; 192 pstats->recvsignalpower = rx_pwr_all;
193 193
194 if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 && 194 if (pstats->is_ht && pstats->rate >= DESC_RATEMCS8 &&
195 pstats->rate <= DESC92_RATEMCS15) 195 pstats->rate <= DESC_RATEMCS15)
196 max_spatial_stream = 2; 196 max_spatial_stream = 2;
197 else 197 else
198 max_spatial_stream = 1; 198 max_spatial_stream = 1;
@@ -264,7 +264,6 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
264 struct rx_fwinfo *p_drvinfo; 264 struct rx_fwinfo *p_drvinfo;
265 u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc); 265 u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
266 struct ieee80211_hdr *hdr; 266 struct ieee80211_hdr *hdr;
267 bool first_ampdu = false;
268 267
269 stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc); 268 stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
270 stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8; 269 stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
@@ -319,8 +318,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
319 rx_status->flag |= RX_FLAG_DECRYPTED; 318 rx_status->flag |= RX_FLAG_DECRYPTED;
320 } 319 }
321 320
322 rx_status->rate_idx = rtlwifi_rate_mapping(hw, 321 rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats->is_ht,
323 stats->is_ht, stats->rate, first_ampdu); 322 false, stats->rate);
324 323
325 rx_status->mactime = stats->timestamp_low; 324 rx_status->mactime = stats->timestamp_low;
326 if (phystatus) { 325 if (phystatus) {
@@ -394,14 +393,14 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
394 SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid); 393 SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
395 394
396 SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >= 395 SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
397 DESC92_RATEMCS0) ? 1 : 0)); 396 DESC_RATEMCS0) ? 1 : 0));
398 397
399 if (rtlhal->version == VERSION_8192S_ACUT) { 398 if (rtlhal->version == VERSION_8192S_ACUT) {
400 if (ptcb_desc->hw_rate == DESC92_RATE1M || 399 if (ptcb_desc->hw_rate == DESC_RATE1M ||
401 ptcb_desc->hw_rate == DESC92_RATE2M || 400 ptcb_desc->hw_rate == DESC_RATE2M ||
402 ptcb_desc->hw_rate == DESC92_RATE5_5M || 401 ptcb_desc->hw_rate == DESC_RATE5_5M ||
403 ptcb_desc->hw_rate == DESC92_RATE11M) { 402 ptcb_desc->hw_rate == DESC_RATE11M) {
404 ptcb_desc->hw_rate = DESC92_RATE12M; 403 ptcb_desc->hw_rate = DESC_RATE12M;
405 } 404 }
406 } 405 }
407 406
@@ -430,7 +429,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
430 SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0); 429 SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
431 SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc); 430 SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
432 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <= 431 SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
433 DESC92_RATE54M) ? 432 DESC_RATE54M) ?
434 (ptcb_desc->rts_use_shortpreamble ? 1 : 0) 433 (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
435 : (ptcb_desc->rts_use_shortgi ? 1 : 0))); 434 : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
436 435
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/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
index d372ccaf3465..2f7c144d7980 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c
@@ -45,164 +45,6 @@ static u8 _rtl8723e_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
45 return skb->priority; 45 return skb->priority;
46} 46}
47 47
48/* mac80211's rate_idx is like this:
49 *
50 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
51 *
52 * B/G rate:
53 * (rx_status->flag & RX_FLAG_HT) = 0,
54 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
55 *
56 * N rate:
57 * (rx_status->flag & RX_FLAG_HT) = 1,
58 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
59 *
60 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
61 * A rate:
62 * (rx_status->flag & RX_FLAG_HT) = 0,
63 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
64 *
65 * N rate:
66 * (rx_status->flag & RX_FLAG_HT) = 1,
67 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
68 */
69static int _rtl8723e_rate_mapping(struct ieee80211_hw *hw,
70 bool isht, u8 desc_rate)
71{
72 int rate_idx;
73
74 if (!isht) {
75 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
76 switch (desc_rate) {
77 case DESC92C_RATE1M:
78 rate_idx = 0;
79 break;
80 case DESC92C_RATE2M:
81 rate_idx = 1;
82 break;
83 case DESC92C_RATE5_5M:
84 rate_idx = 2;
85 break;
86 case DESC92C_RATE11M:
87 rate_idx = 3;
88 break;
89 case DESC92C_RATE6M:
90 rate_idx = 4;
91 break;
92 case DESC92C_RATE9M:
93 rate_idx = 5;
94 break;
95 case DESC92C_RATE12M:
96 rate_idx = 6;
97 break;
98 case DESC92C_RATE18M:
99 rate_idx = 7;
100 break;
101 case DESC92C_RATE24M:
102 rate_idx = 8;
103 break;
104 case DESC92C_RATE36M:
105 rate_idx = 9;
106 break;
107 case DESC92C_RATE48M:
108 rate_idx = 10;
109 break;
110 case DESC92C_RATE54M:
111 rate_idx = 11;
112 break;
113 default:
114 rate_idx = 0;
115 break;
116 }
117 } else {
118 switch (desc_rate) {
119 case DESC92C_RATE6M:
120 rate_idx = 0;
121 break;
122 case DESC92C_RATE9M:
123 rate_idx = 1;
124 break;
125 case DESC92C_RATE12M:
126 rate_idx = 2;
127 break;
128 case DESC92C_RATE18M:
129 rate_idx = 3;
130 break;
131 case DESC92C_RATE24M:
132 rate_idx = 4;
133 break;
134 case DESC92C_RATE36M:
135 rate_idx = 5;
136 break;
137 case DESC92C_RATE48M:
138 rate_idx = 6;
139 break;
140 case DESC92C_RATE54M:
141 rate_idx = 7;
142 break;
143 default:
144 rate_idx = 0;
145 break;
146 }
147 }
148 } else {
149 switch (desc_rate) {
150 case DESC92C_RATEMCS0:
151 rate_idx = 0;
152 break;
153 case DESC92C_RATEMCS1:
154 rate_idx = 1;
155 break;
156 case DESC92C_RATEMCS2:
157 rate_idx = 2;
158 break;
159 case DESC92C_RATEMCS3:
160 rate_idx = 3;
161 break;
162 case DESC92C_RATEMCS4:
163 rate_idx = 4;
164 break;
165 case DESC92C_RATEMCS5:
166 rate_idx = 5;
167 break;
168 case DESC92C_RATEMCS6:
169 rate_idx = 6;
170 break;
171 case DESC92C_RATEMCS7:
172 rate_idx = 7;
173 break;
174 case DESC92C_RATEMCS8:
175 rate_idx = 8;
176 break;
177 case DESC92C_RATEMCS9:
178 rate_idx = 9;
179 break;
180 case DESC92C_RATEMCS10:
181 rate_idx = 10;
182 break;
183 case DESC92C_RATEMCS11:
184 rate_idx = 11;
185 break;
186 case DESC92C_RATEMCS12:
187 rate_idx = 12;
188 break;
189 case DESC92C_RATEMCS13:
190 rate_idx = 13;
191 break;
192 case DESC92C_RATEMCS14:
193 rate_idx = 14;
194 break;
195 case DESC92C_RATEMCS15:
196 rate_idx = 15;
197 break;
198 default:
199 rate_idx = 0;
200 break;
201 }
202 }
203 return rate_idx;
204}
205
206static void _rtl8723e_query_rxphystatus(struct ieee80211_hw *hw, 48static void _rtl8723e_query_rxphystatus(struct ieee80211_hw *hw,
207 struct rtl_stats *pstatus, u8 *pdesc, 49 struct rtl_stats *pstatus, u8 *pdesc,
208 struct rx_fwinfo_8723e *p_drvinfo, 50 struct rx_fwinfo_8723e *p_drvinfo,
@@ -503,8 +345,8 @@ bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw,
503 * are use (RX_FLAG_HT) 345 * are use (RX_FLAG_HT)
504 * Notice: this is diff with windows define 346 * Notice: this is diff with windows define
505 */ 347 */
506 rx_status->rate_idx = _rtl8723e_rate_mapping(hw, 348 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
507 status->is_ht, status->rate); 349 false, status->rate);
508 350
509 rx_status->mactime = status->timestamp_low; 351 rx_status->mactime = status->timestamp_low;
510 if (phystatus == true) { 352 if (phystatus == true) {
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/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
index 20dcc25c506c..b7b73cbe346d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c
@@ -874,31 +874,6 @@ void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
874 ROFDM0_RXDETECTOR3, rtlphy->framesync); 874 ROFDM0_RXDETECTOR3, rtlphy->framesync);
875} 875}
876 876
877void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
878{
879 struct rtl_priv *rtlpriv = rtl_priv(hw);
880 struct rtl_phy *rtlphy = &rtlpriv->phy;
881 u8 txpwr_level;
882 long txpwr_dbm;
883
884 txpwr_level = rtlphy->cur_cck_txpwridx;
885 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
886 txpwr_level);
887 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
888 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
889 txpwr_dbm)
890 txpwr_dbm =
891 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
892 txpwr_level);
893 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
894 if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
895 txpwr_level) > txpwr_dbm)
896 txpwr_dbm =
897 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
898 txpwr_level);
899 *powerlevel = txpwr_dbm;
900}
901
902static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, 877static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
903 u8 rate) 878 u8 rate)
904{ 879{
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
index 6339738a0e33..9021d4745ab7 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.h
@@ -114,8 +114,6 @@ bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw);
114bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw); 114bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw);
115bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw); 115bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw);
116void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); 116void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
117void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw,
118 long *powerlevel);
119void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, 117void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw,
120 u8 channel); 118 u8 channel);
121void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, 119void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw,
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/rtl8723be/trx.c b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
index d6a1c70cb657..338ec9a9d09b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/trx.c
@@ -47,164 +47,6 @@ static u8 _rtl8723be_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
47 return skb->priority; 47 return skb->priority;
48} 48}
49 49
50/* mac80211's rate_idx is like this:
51 *
52 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
53 *
54 * B/G rate:
55 * (rx_status->flag & RX_FLAG_HT) = 0,
56 * DESC92C_RATE1M-->DESC92C_RATE54M ==> idx is 0-->11,
57 *
58 * N rate:
59 * (rx_status->flag & RX_FLAG_HT) = 1,
60 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
61 *
62 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
63 * A rate:
64 * (rx_status->flag & RX_FLAG_HT) = 0,
65 * DESC92C_RATE6M-->DESC92C_RATE54M ==> idx is 0-->7,
66 *
67 * N rate:
68 * (rx_status->flag & RX_FLAG_HT) = 1,
69 * DESC92C_RATEMCS0-->DESC92C_RATEMCS15 ==> idx is 0-->15
70 */
71static int _rtl8723be_rate_mapping(struct ieee80211_hw *hw,
72 bool isht, u8 desc_rate)
73{
74 int rate_idx;
75
76 if (!isht) {
77 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
78 switch (desc_rate) {
79 case DESC92C_RATE1M:
80 rate_idx = 0;
81 break;
82 case DESC92C_RATE2M:
83 rate_idx = 1;
84 break;
85 case DESC92C_RATE5_5M:
86 rate_idx = 2;
87 break;
88 case DESC92C_RATE11M:
89 rate_idx = 3;
90 break;
91 case DESC92C_RATE6M:
92 rate_idx = 4;
93 break;
94 case DESC92C_RATE9M:
95 rate_idx = 5;
96 break;
97 case DESC92C_RATE12M:
98 rate_idx = 6;
99 break;
100 case DESC92C_RATE18M:
101 rate_idx = 7;
102 break;
103 case DESC92C_RATE24M:
104 rate_idx = 8;
105 break;
106 case DESC92C_RATE36M:
107 rate_idx = 9;
108 break;
109 case DESC92C_RATE48M:
110 rate_idx = 10;
111 break;
112 case DESC92C_RATE54M:
113 rate_idx = 11;
114 break;
115 default:
116 rate_idx = 0;
117 break;
118 }
119 } else {
120 switch (desc_rate) {
121 case DESC92C_RATE6M:
122 rate_idx = 0;
123 break;
124 case DESC92C_RATE9M:
125 rate_idx = 1;
126 break;
127 case DESC92C_RATE12M:
128 rate_idx = 2;
129 break;
130 case DESC92C_RATE18M:
131 rate_idx = 3;
132 break;
133 case DESC92C_RATE24M:
134 rate_idx = 4;
135 break;
136 case DESC92C_RATE36M:
137 rate_idx = 5;
138 break;
139 case DESC92C_RATE48M:
140 rate_idx = 6;
141 break;
142 case DESC92C_RATE54M:
143 rate_idx = 7;
144 break;
145 default:
146 rate_idx = 0;
147 break;
148 }
149 }
150 } else {
151 switch (desc_rate) {
152 case DESC92C_RATEMCS0:
153 rate_idx = 0;
154 break;
155 case DESC92C_RATEMCS1:
156 rate_idx = 1;
157 break;
158 case DESC92C_RATEMCS2:
159 rate_idx = 2;
160 break;
161 case DESC92C_RATEMCS3:
162 rate_idx = 3;
163 break;
164 case DESC92C_RATEMCS4:
165 rate_idx = 4;
166 break;
167 case DESC92C_RATEMCS5:
168 rate_idx = 5;
169 break;
170 case DESC92C_RATEMCS6:
171 rate_idx = 6;
172 break;
173 case DESC92C_RATEMCS7:
174 rate_idx = 7;
175 break;
176 case DESC92C_RATEMCS8:
177 rate_idx = 8;
178 break;
179 case DESC92C_RATEMCS9:
180 rate_idx = 9;
181 break;
182 case DESC92C_RATEMCS10:
183 rate_idx = 10;
184 break;
185 case DESC92C_RATEMCS11:
186 rate_idx = 11;
187 break;
188 case DESC92C_RATEMCS12:
189 rate_idx = 12;
190 break;
191 case DESC92C_RATEMCS13:
192 rate_idx = 13;
193 break;
194 case DESC92C_RATEMCS14:
195 rate_idx = 14;
196 break;
197 case DESC92C_RATEMCS15:
198 rate_idx = 15;
199 break;
200 default:
201 rate_idx = 0;
202 break;
203 }
204 }
205 return rate_idx;
206}
207
208static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw, 50static void _rtl8723be_query_rxphystatus(struct ieee80211_hw *hw,
209 struct rtl_stats *pstatus, u8 *pdesc, 51 struct rtl_stats *pstatus, u8 *pdesc,
210 struct rx_fwinfo_8723be *p_drvinfo, 52 struct rx_fwinfo_8723be *p_drvinfo,
@@ -558,8 +400,8 @@ bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
558 * supported rates or MCS index if HT rates 400 * supported rates or MCS index if HT rates
559 * are use (RX_FLAG_HT) 401 * are use (RX_FLAG_HT)
560 */ 402 */
561 rx_status->rate_idx = _rtl8723be_rate_mapping(hw, status->is_ht, 403 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
562 status->rate); 404 false, status->rate);
563 405
564 rx_status->mactime = status->timestamp_low; 406 rx_status->mactime = status->timestamp_low;
565 if (phystatus) { 407 if (phystatus) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
index a730985ae81d..ee7c208bd070 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/def.h
@@ -373,60 +373,6 @@ enum rtl_desc_qsel {
373 QSLT_CMD = 0x13, 373 QSLT_CMD = 0x13,
374}; 374};
375 375
376enum rtl_desc8821ae_rate {
377 DESC_RATE1M = 0x00,
378 DESC_RATE2M = 0x01,
379 DESC_RATE5_5M = 0x02,
380 DESC_RATE11M = 0x03,
381
382 DESC_RATE6M = 0x04,
383 DESC_RATE9M = 0x05,
384 DESC_RATE12M = 0x06,
385 DESC_RATE18M = 0x07,
386 DESC_RATE24M = 0x08,
387 DESC_RATE36M = 0x09,
388 DESC_RATE48M = 0x0a,
389 DESC_RATE54M = 0x0b,
390
391 DESC_RATEMCS0 = 0x0c,
392 DESC_RATEMCS1 = 0x0d,
393 DESC_RATEMCS2 = 0x0e,
394 DESC_RATEMCS3 = 0x0f,
395 DESC_RATEMCS4 = 0x10,
396 DESC_RATEMCS5 = 0x11,
397 DESC_RATEMCS6 = 0x12,
398 DESC_RATEMCS7 = 0x13,
399 DESC_RATEMCS8 = 0x14,
400 DESC_RATEMCS9 = 0x15,
401 DESC_RATEMCS10 = 0x16,
402 DESC_RATEMCS11 = 0x17,
403 DESC_RATEMCS12 = 0x18,
404 DESC_RATEMCS13 = 0x19,
405 DESC_RATEMCS14 = 0x1a,
406 DESC_RATEMCS15 = 0x1b,
407
408 DESC_RATEVHT1SS_MCS0 = 0x2c,
409 DESC_RATEVHT1SS_MCS1 = 0x2d,
410 DESC_RATEVHT1SS_MCS2 = 0x2e,
411 DESC_RATEVHT1SS_MCS3 = 0x2f,
412 DESC_RATEVHT1SS_MCS4 = 0x30,
413 DESC_RATEVHT1SS_MCS5 = 0x31,
414 DESC_RATEVHT1SS_MCS6 = 0x32,
415 DESC_RATEVHT1SS_MCS7 = 0x33,
416 DESC_RATEVHT1SS_MCS8 = 0x34,
417 DESC_RATEVHT1SS_MCS9 = 0x35,
418 DESC_RATEVHT2SS_MCS0 = 0x36,
419 DESC_RATEVHT2SS_MCS1 = 0x37,
420 DESC_RATEVHT2SS_MCS2 = 0x38,
421 DESC_RATEVHT2SS_MCS3 = 0x39,
422 DESC_RATEVHT2SS_MCS4 = 0x3a,
423 DESC_RATEVHT2SS_MCS5 = 0x3b,
424 DESC_RATEVHT2SS_MCS6 = 0x3c,
425 DESC_RATEVHT2SS_MCS7 = 0x3d,
426 DESC_RATEVHT2SS_MCS8 = 0x3e,
427 DESC_RATEVHT2SS_MCS9 = 0x3f,
428};
429
430enum rx_packet_type { 376enum rx_packet_type {
431 NORMAL_RX, 377 NORMAL_RX,
432 TX_REPORT1, 378 TX_REPORT1,
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/rtl8821ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h
index bf0b0ce9519c..36b3e91d996e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/pwrseq.h
@@ -93,9 +93,9 @@
93 93
94#define RTL8812_TRANS_CARDEMU_TO_SUS \ 94#define RTL8812_TRANS_CARDEMU_TO_SUS \
95 {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\ 95 {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK,\
96 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xcc}, \ 96 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xc0}, \
97 {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\ 97 {0x0042, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK,\
98 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xEC}, \ 98 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xF0, 0xE0}, \
99 {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\ 99 {0x0043, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK,\
100 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07 \ 100 PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x07 \
101 /* gpio11 input mode, gpio10~8 output mode */}, \ 101 /* gpio11 input mode, gpio10~8 output mode */}, \
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
index fc92dd6a0d07..a4988121e1ab 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/sw.c
@@ -85,52 +85,6 @@ static void rtl8821ae_init_aspm_vars(struct ieee80211_hw *hw)
85 rtlpci->const_support_pciaspm = 1; 85 rtlpci->const_support_pciaspm = 1;
86} 86}
87 87
88static void load_wowlan_fw(struct rtl_priv *rtlpriv)
89{
90 /* callback routine to load wowlan firmware after main fw has
91 * been loaded
92 */
93 const struct firmware *wowlan_firmware;
94 char *fw_name = NULL;
95 int err;
96
97 /* for wowlan firmware buf */
98 rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000);
99 if (!rtlpriv->rtlhal.wowlan_firmware) {
100 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
101 "Can't alloc buffer for wowlan fw.\n");
102 return;
103 }
104
105 if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8821AE)
106 fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
107 else
108 fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
109 err = request_firmware(&wowlan_firmware, fw_name, rtlpriv->io.dev);
110 if (err) {
111 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
112 "Failed to request wowlan firmware!\n");
113 goto error;
114 }
115
116 if (wowlan_firmware->size > 0x8000) {
117 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
118 "Wowlan Firmware is too big!\n");
119 goto error;
120 }
121
122 memcpy(rtlpriv->rtlhal.wowlan_firmware, wowlan_firmware->data,
123 wowlan_firmware->size);
124 rtlpriv->rtlhal.wowlan_fwsize = wowlan_firmware->size;
125 release_firmware(wowlan_firmware);
126
127 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "WOWLAN FirmwareDownload OK\n");
128 return;
129error:
130 release_firmware(wowlan_firmware);
131 vfree(rtlpriv->rtlhal.wowlan_firmware);
132}
133
134/*InitializeVariables8812E*/ 88/*InitializeVariables8812E*/
135int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) 89int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
136{ 90{
@@ -231,7 +185,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
231 else if (rtlpriv->psc.reg_fwctrl_lps == 3) 185 else if (rtlpriv->psc.reg_fwctrl_lps == 3)
232 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; 186 rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
233 187
234 rtlpriv->rtl_fw_second_cb = load_wowlan_fw;
235 /* for firmware buf */ 188 /* for firmware buf */
236 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); 189 rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
237 if (!rtlpriv->rtlhal.pfirmware) { 190 if (!rtlpriv->rtlhal.pfirmware) {
@@ -239,20 +192,41 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw)
239 "Can't alloc buffer for fw.\n"); 192 "Can't alloc buffer for fw.\n");
240 return 1; 193 return 1;
241 } 194 }
195 rtlpriv->rtlhal.wowlan_firmware = vzalloc(0x8000);
196 if (!rtlpriv->rtlhal.wowlan_firmware) {
197 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
198 "Can't alloc buffer for wowlan fw.\n");
199 return 1;
200 }
242 201
243 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 202 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
244 rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin"; 203 rtlpriv->cfg->fw_name = "rtlwifi/rtl8812aefw.bin";
245 else 204 rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8812aefw_wowlan.bin";
205 } else {
246 rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin"; 206 rtlpriv->cfg->fw_name = "rtlwifi/rtl8821aefw.bin";
207 rtlpriv->cfg->wowlan_fw_name = "rtlwifi/rtl8821aefw_wowlan.bin";
208 }
247 209
248 rtlpriv->max_fw_size = 0x8000; 210 rtlpriv->max_fw_size = 0x8000;
211 /*load normal firmware*/
249 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); 212 pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
250 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, 213 err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
251 rtlpriv->io.dev, GFP_KERNEL, hw, 214 rtlpriv->io.dev, GFP_KERNEL, hw,
252 rtl_fw_cb); 215 rtl_fw_cb);
253 if (err) { 216 if (err) {
254 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 217 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
255 "Failed to request firmware!\n"); 218 "Failed to request normal firmware!\n");
219 return 1;
220 }
221 /*load wowlan firmware*/
222 pr_info("Using firmware %s\n", rtlpriv->cfg->wowlan_fw_name);
223 err = request_firmware_nowait(THIS_MODULE, 1,
224 rtlpriv->cfg->wowlan_fw_name,
225 rtlpriv->io.dev, GFP_KERNEL, hw,
226 rtl_wowlan_fw_cb);
227 if (err) {
228 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
229 "Failed to request wowlan firmware!\n");
256 return 1; 230 return 1;
257 } 231 }
258 return 0; 232 return 0;
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
index 383b86b05cba..72af4b9ee32b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
@@ -48,232 +48,6 @@ static u8 _rtl8821ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
48 return skb->priority; 48 return skb->priority;
49} 49}
50 50
51/* mac80211's rate_idx is like this:
52 *
53 * 2.4G band:rx_status->band == IEEE80211_BAND_2GHZ
54 *
55 * B/G rate:
56 * (rx_status->flag & RX_FLAG_HT) = 0,
57 * DESC_RATE1M-->DESC_RATE54M ==> idx is 0-->11,
58 *
59 * N rate:
60 * (rx_status->flag & RX_FLAG_HT) = 1,
61 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
62 *
63 * 5G band:rx_status->band == IEEE80211_BAND_5GHZ
64 * A rate:
65 * (rx_status->flag & RX_FLAG_HT) = 0,
66 * DESC_RATE6M-->DESC_RATE54M ==> idx is 0-->7,
67 *
68 * N rate:
69 * (rx_status->flag & RX_FLAG_HT) = 1,
70 * DESC_RATEMCS0-->DESC_RATEMCS15 ==> idx is 0-->15
71 */
72static int _rtl8821ae_rate_mapping(struct ieee80211_hw *hw,
73 bool isht, bool isvht, u8 desc_rate)
74{
75 int rate_idx;
76
77 if (!isht) {
78 if (IEEE80211_BAND_2GHZ == hw->conf.chandef.chan->band) {
79 switch (desc_rate) {
80 case DESC_RATE1M:
81 rate_idx = 0;
82 break;
83 case DESC_RATE2M:
84 rate_idx = 1;
85 break;
86 case DESC_RATE5_5M:
87 rate_idx = 2;
88 break;
89 case DESC_RATE11M:
90 rate_idx = 3;
91 break;
92 case DESC_RATE6M:
93 rate_idx = 4;
94 break;
95 case DESC_RATE9M:
96 rate_idx = 5;
97 break;
98 case DESC_RATE12M:
99 rate_idx = 6;
100 break;
101 case DESC_RATE18M:
102 rate_idx = 7;
103 break;
104 case DESC_RATE24M:
105 rate_idx = 8;
106 break;
107 case DESC_RATE36M:
108 rate_idx = 9;
109 break;
110 case DESC_RATE48M:
111 rate_idx = 10;
112 break;
113 case DESC_RATE54M:
114 rate_idx = 11;
115 break;
116 default:
117 rate_idx = 0;
118 break;
119 }
120 } else {
121 switch (desc_rate) {
122 case DESC_RATE6M:
123 rate_idx = 0;
124 break;
125 case DESC_RATE9M:
126 rate_idx = 1;
127 break;
128 case DESC_RATE12M:
129 rate_idx = 2;
130 break;
131 case DESC_RATE18M:
132 rate_idx = 3;
133 break;
134 case DESC_RATE24M:
135 rate_idx = 4;
136 break;
137 case DESC_RATE36M:
138 rate_idx = 5;
139 break;
140 case DESC_RATE48M:
141 rate_idx = 6;
142 break;
143 case DESC_RATE54M:
144 rate_idx = 7;
145 break;
146 default:
147 rate_idx = 0;
148 break;
149 }
150 }
151 } else {
152 switch (desc_rate) {
153 case DESC_RATEMCS0:
154 rate_idx = 0;
155 break;
156 case DESC_RATEMCS1:
157 rate_idx = 1;
158 break;
159 case DESC_RATEMCS2:
160 rate_idx = 2;
161 break;
162 case DESC_RATEMCS3:
163 rate_idx = 3;
164 break;
165 case DESC_RATEMCS4:
166 rate_idx = 4;
167 break;
168 case DESC_RATEMCS5:
169 rate_idx = 5;
170 break;
171 case DESC_RATEMCS6:
172 rate_idx = 6;
173 break;
174 case DESC_RATEMCS7:
175 rate_idx = 7;
176 break;
177 case DESC_RATEMCS8:
178 rate_idx = 8;
179 break;
180 case DESC_RATEMCS9:
181 rate_idx = 9;
182 break;
183 case DESC_RATEMCS10:
184 rate_idx = 10;
185 break;
186 case DESC_RATEMCS11:
187 rate_idx = 11;
188 break;
189 case DESC_RATEMCS12:
190 rate_idx = 12;
191 break;
192 case DESC_RATEMCS13:
193 rate_idx = 13;
194 break;
195 case DESC_RATEMCS14:
196 rate_idx = 14;
197 break;
198 case DESC_RATEMCS15:
199 rate_idx = 15;
200 break;
201 default:
202 rate_idx = 0;
203 break;
204 }
205 }
206
207 if (isvht) {
208 switch (desc_rate) {
209 case DESC_RATEVHT1SS_MCS0:
210 rate_idx = 0;
211 break;
212 case DESC_RATEVHT1SS_MCS1:
213 rate_idx = 1;
214 break;
215 case DESC_RATEVHT1SS_MCS2:
216 rate_idx = 2;
217 break;
218 case DESC_RATEVHT1SS_MCS3:
219 rate_idx = 3;
220 break;
221 case DESC_RATEVHT1SS_MCS4:
222 rate_idx = 4;
223 break;
224 case DESC_RATEVHT1SS_MCS5:
225 rate_idx = 5;
226 break;
227 case DESC_RATEVHT1SS_MCS6:
228 rate_idx = 6;
229 break;
230 case DESC_RATEVHT1SS_MCS7:
231 rate_idx = 7;
232 break;
233 case DESC_RATEVHT1SS_MCS8:
234 rate_idx = 8;
235 break;
236 case DESC_RATEVHT1SS_MCS9:
237 rate_idx = 9;
238 break;
239 case DESC_RATEVHT2SS_MCS0:
240 rate_idx = 0;
241 break;
242 case DESC_RATEVHT2SS_MCS1:
243 rate_idx = 1;
244 break;
245 case DESC_RATEVHT2SS_MCS2:
246 rate_idx = 2;
247 break;
248 case DESC_RATEVHT2SS_MCS3:
249 rate_idx = 3;
250 break;
251 case DESC_RATEVHT2SS_MCS4:
252 rate_idx = 4;
253 break;
254 case DESC_RATEVHT2SS_MCS5:
255 rate_idx = 5;
256 break;
257 case DESC_RATEVHT2SS_MCS6:
258 rate_idx = 6;
259 break;
260 case DESC_RATEVHT2SS_MCS7:
261 rate_idx = 7;
262 break;
263 case DESC_RATEVHT2SS_MCS8:
264 rate_idx = 8;
265 break;
266 case DESC_RATEVHT2SS_MCS9:
267 rate_idx = 9;
268 break;
269 default:
270 rate_idx = 0;
271 break;
272 }
273 }
274 return rate_idx;
275}
276
277static u16 odm_cfo(char value) 51static u16 odm_cfo(char value)
278{ 52{
279 int ret_val; 53 int ret_val;
@@ -766,9 +540,9 @@ bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
766 * supported rates or MCS index if HT rates 540 * supported rates or MCS index if HT rates
767 * are use (RX_FLAG_HT) 541 * are use (RX_FLAG_HT)
768 */ 542 */
769 rx_status->rate_idx = 543 rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht,
770 _rtl8821ae_rate_mapping(hw, status->is_ht, 544 status->is_vht,
771 status->is_vht, status->rate); 545 status->rate);
772 546
773 rx_status->mactime = status->timestamp_low; 547 rx_status->mactime = status->timestamp_low;
774 if (phystatus) { 548 if (phystatus) {
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 6866dcf24340..51572912c53d 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -331,10 +331,10 @@ enum hardware_type {
331(IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) 331(IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal))
332 332
333#define RX_HAL_IS_CCK_RATE(rxmcs) \ 333#define RX_HAL_IS_CCK_RATE(rxmcs) \
334 ((rxmcs) == DESC92_RATE1M || \ 334 ((rxmcs) == DESC_RATE1M || \
335 (rxmcs) == DESC92_RATE2M || \ 335 (rxmcs) == DESC_RATE2M || \
336 (rxmcs) == DESC92_RATE5_5M || \ 336 (rxmcs) == DESC_RATE5_5M || \
337 (rxmcs) == DESC92_RATE11M) 337 (rxmcs) == DESC_RATE11M)
338 338
339enum scan_operation_backup_opt { 339enum scan_operation_backup_opt {
340 SCAN_OPT_BACKUP = 0, 340 SCAN_OPT_BACKUP = 0,
@@ -579,38 +579,59 @@ enum rtl_hal_state {
579}; 579};
580 580
581enum rtl_desc92_rate { 581enum rtl_desc92_rate {
582 DESC92_RATE1M = 0x00, 582 DESC_RATE1M = 0x00,
583 DESC92_RATE2M = 0x01, 583 DESC_RATE2M = 0x01,
584 DESC92_RATE5_5M = 0x02, 584 DESC_RATE5_5M = 0x02,
585 DESC92_RATE11M = 0x03, 585 DESC_RATE11M = 0x03,
586 586
587 DESC92_RATE6M = 0x04, 587 DESC_RATE6M = 0x04,
588 DESC92_RATE9M = 0x05, 588 DESC_RATE9M = 0x05,
589 DESC92_RATE12M = 0x06, 589 DESC_RATE12M = 0x06,
590 DESC92_RATE18M = 0x07, 590 DESC_RATE18M = 0x07,
591 DESC92_RATE24M = 0x08, 591 DESC_RATE24M = 0x08,
592 DESC92_RATE36M = 0x09, 592 DESC_RATE36M = 0x09,
593 DESC92_RATE48M = 0x0a, 593 DESC_RATE48M = 0x0a,
594 DESC92_RATE54M = 0x0b, 594 DESC_RATE54M = 0x0b,
595 595
596 DESC92_RATEMCS0 = 0x0c, 596 DESC_RATEMCS0 = 0x0c,
597 DESC92_RATEMCS1 = 0x0d, 597 DESC_RATEMCS1 = 0x0d,
598 DESC92_RATEMCS2 = 0x0e, 598 DESC_RATEMCS2 = 0x0e,
599 DESC92_RATEMCS3 = 0x0f, 599 DESC_RATEMCS3 = 0x0f,
600 DESC92_RATEMCS4 = 0x10, 600 DESC_RATEMCS4 = 0x10,
601 DESC92_RATEMCS5 = 0x11, 601 DESC_RATEMCS5 = 0x11,
602 DESC92_RATEMCS6 = 0x12, 602 DESC_RATEMCS6 = 0x12,
603 DESC92_RATEMCS7 = 0x13, 603 DESC_RATEMCS7 = 0x13,
604 DESC92_RATEMCS8 = 0x14, 604 DESC_RATEMCS8 = 0x14,
605 DESC92_RATEMCS9 = 0x15, 605 DESC_RATEMCS9 = 0x15,
606 DESC92_RATEMCS10 = 0x16, 606 DESC_RATEMCS10 = 0x16,
607 DESC92_RATEMCS11 = 0x17, 607 DESC_RATEMCS11 = 0x17,
608 DESC92_RATEMCS12 = 0x18, 608 DESC_RATEMCS12 = 0x18,
609 DESC92_RATEMCS13 = 0x19, 609 DESC_RATEMCS13 = 0x19,
610 DESC92_RATEMCS14 = 0x1a, 610 DESC_RATEMCS14 = 0x1a,
611 DESC92_RATEMCS15 = 0x1b, 611 DESC_RATEMCS15 = 0x1b,
612 DESC92_RATEMCS15_SG = 0x1c, 612 DESC_RATEMCS15_SG = 0x1c,
613 DESC92_RATEMCS32 = 0x20, 613 DESC_RATEMCS32 = 0x20,
614
615 DESC_RATEVHT1SS_MCS0 = 0x2c,
616 DESC_RATEVHT1SS_MCS1 = 0x2d,
617 DESC_RATEVHT1SS_MCS2 = 0x2e,
618 DESC_RATEVHT1SS_MCS3 = 0x2f,
619 DESC_RATEVHT1SS_MCS4 = 0x30,
620 DESC_RATEVHT1SS_MCS5 = 0x31,
621 DESC_RATEVHT1SS_MCS6 = 0x32,
622 DESC_RATEVHT1SS_MCS7 = 0x33,
623 DESC_RATEVHT1SS_MCS8 = 0x34,
624 DESC_RATEVHT1SS_MCS9 = 0x35,
625 DESC_RATEVHT2SS_MCS0 = 0x36,
626 DESC_RATEVHT2SS_MCS1 = 0x37,
627 DESC_RATEVHT2SS_MCS2 = 0x38,
628 DESC_RATEVHT2SS_MCS3 = 0x39,
629 DESC_RATEVHT2SS_MCS4 = 0x3a,
630 DESC_RATEVHT2SS_MCS5 = 0x3b,
631 DESC_RATEVHT2SS_MCS6 = 0x3c,
632 DESC_RATEVHT2SS_MCS7 = 0x3d,
633 DESC_RATEVHT2SS_MCS8 = 0x3e,
634 DESC_RATEVHT2SS_MCS9 = 0x3f,
614}; 635};
615 636
616enum rtl_var_map { 637enum rtl_var_map {
@@ -2161,6 +2182,7 @@ struct rtl_hal_ops {
2161 void (*add_wowlan_pattern)(struct ieee80211_hw *hw, 2182 void (*add_wowlan_pattern)(struct ieee80211_hw *hw,
2162 struct rtl_wow_pattern *rtl_pattern, 2183 struct rtl_wow_pattern *rtl_pattern,
2163 u8 index); 2184 u8 index);
2185 u16 (*get_available_desc)(struct ieee80211_hw *hw, u8 q_idx);
2164}; 2186};
2165 2187
2166struct rtl_intf_ops { 2188struct rtl_intf_ops {
@@ -2242,6 +2264,7 @@ struct rtl_hal_cfg {
2242 char *name; 2264 char *name;
2243 char *fw_name; 2265 char *fw_name;
2244 char *alt_fw_name; 2266 char *alt_fw_name;
2267 char *wowlan_fw_name;
2245 struct rtl_hal_ops *ops; 2268 struct rtl_hal_ops *ops;
2246 struct rtl_mod_params *mod_params; 2269 struct rtl_mod_params *mod_params;
2247 struct rtl_hal_usbint_cfg *usb_interface_cfg; 2270 struct rtl_hal_usbint_cfg *usb_interface_cfg;
@@ -2390,8 +2413,6 @@ struct dig_t {
2390 u8 pre_ccastate; 2413 u8 pre_ccastate;
2391 u8 cur_ccasate; 2414 u8 cur_ccasate;
2392 u8 large_fa_hit; 2415 u8 large_fa_hit;
2393 u8 dig_dynamic_min;
2394 u8 dig_dynamic_min_1;
2395 u8 forbidden_igi; 2416 u8 forbidden_igi;
2396 u8 dig_state; 2417 u8 dig_state;
2397 u8 dig_highpwrstate; 2418 u8 dig_highpwrstate;
@@ -2518,8 +2539,6 @@ struct proxim {
2518 2539
2519struct rtl_priv { 2540struct rtl_priv {
2520 struct ieee80211_hw *hw; 2541 struct ieee80211_hw *hw;
2521 /* Used to load a second firmware */
2522 void (*rtl_fw_second_cb)(struct rtl_priv *rtlpriv);
2523 struct completion firmware_loading_complete; 2542 struct completion firmware_loading_complete;
2524 struct list_head list; 2543 struct list_head list;
2525 struct rtl_priv *buddy_priv; 2544 struct rtl_priv *buddy_priv;
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 0b30a7b4d663..d4ba009ac9aa 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -500,6 +500,7 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
500 int ret = 0; 500 int ret = 0;
501 501
502 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 502 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
503 IEEE80211_VIF_SUPPORTS_UAPSD |
503 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 504 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
504 505
505 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 506 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
@@ -1480,9 +1481,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1480 /* unit us */ 1481 /* unit us */
1481 /* FIXME: find a proper value */ 1482 /* FIXME: find a proper value */
1482 1483
1483 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1484 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS;
1484 IEEE80211_HW_SUPPORTS_PS |
1485 IEEE80211_HW_SUPPORTS_UAPSD;
1486 1485
1487 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1486 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1488 BIT(NL80211_IFTYPE_ADHOC); 1487 BIT(NL80211_IFTYPE_ADHOC);
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 6ad3fcedab9b..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,
@@ -2508,6 +2554,7 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
2508 } 2554 }
2509 2555
2510 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | 2556 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
2557 IEEE80211_VIF_SUPPORTS_UAPSD |
2511 IEEE80211_VIF_SUPPORTS_CQM_RSSI; 2558 IEEE80211_VIF_SUPPORTS_CQM_RSSI;
2512 2559
2513 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 2560 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
@@ -2723,6 +2770,7 @@ unlock:
2723 del_timer_sync(&wlvif->rx_streaming_timer); 2770 del_timer_sync(&wlvif->rx_streaming_timer);
2724 cancel_work_sync(&wlvif->rx_streaming_enable_work); 2771 cancel_work_sync(&wlvif->rx_streaming_enable_work);
2725 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);
2726 cancel_delayed_work_sync(&wlvif->connection_loss_work); 2774 cancel_delayed_work_sync(&wlvif->connection_loss_work);
2727 cancel_delayed_work_sync(&wlvif->channel_switch_work); 2775 cancel_delayed_work_sync(&wlvif->channel_switch_work);
2728 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work); 2776 cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
@@ -4072,8 +4120,14 @@ static int wl1271_bss_beacon_info_changed(struct wl1271 *wl,
4072 ret = wlcore_set_beacon_template(wl, vif, is_ap); 4120 ret = wlcore_set_beacon_template(wl, vif, is_ap);
4073 if (ret < 0) 4121 if (ret < 0)
4074 goto out; 4122 goto out;
4075 }
4076 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 }
4077out: 4131out:
4078 if (ret != 0) 4132 if (ret != 0)
4079 wl1271_error("beacon info change failed: %d", ret); 4133 wl1271_error("beacon info change failed: %d", ret);
@@ -4574,10 +4628,46 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw,
4574 struct ieee80211_chanctx_conf *ctx, 4628 struct ieee80211_chanctx_conf *ctx,
4575 u32 changed) 4629 u32 changed)
4576{ 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
4577 wl1271_debug(DEBUG_MAC80211, 4637 wl1271_debug(DEBUG_MAC80211,
4578 "mac80211 change chanctx %d (type %d) changed 0x%x", 4638 "mac80211 change chanctx %d (type %d) changed 0x%x",
4579 ieee80211_frequency_to_channel(ctx->def.chan->center_freq), 4639 channel, cfg80211_get_chandef_type(&ctx->def), changed);
4580 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);
4581} 4671}
4582 4672
4583static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, 4673static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -4588,13 +4678,26 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4588 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4678 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4589 int channel = ieee80211_frequency_to_channel( 4679 int channel = ieee80211_frequency_to_channel(
4590 ctx->def.chan->center_freq); 4680 ctx->def.chan->center_freq);
4681 int ret = -EINVAL;
4591 4682
4592 wl1271_debug(DEBUG_MAC80211, 4683 wl1271_debug(DEBUG_MAC80211,
4593 "mac80211 assign chanctx (role %d) %d (type %d)", 4684 "mac80211 assign chanctx (role %d) %d (type %d) (radar %d dfs_state %d)",
4594 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);
4595 4688
4596 mutex_lock(&wl->mutex); 4689 mutex_lock(&wl->mutex);
4597 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
4598 wlvif->band = ctx->def.chan->band; 4701 wlvif->band = ctx->def.chan->band;
4599 wlvif->channel = channel; 4702 wlvif->channel = channel;
4600 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def); 4703 wlvif->channel_type = cfg80211_get_chandef_type(&ctx->def);
@@ -4602,6 +4705,15 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw,
4602 /* update default rates according to the band */ 4705 /* update default rates according to the band */
4603 wl1271_set_band_rate(wl, wlvif); 4706 wl1271_set_band_rate(wl, wlvif);
4604 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:
4605 mutex_unlock(&wl->mutex); 4717 mutex_unlock(&wl->mutex);
4606 4718
4607 return 0; 4719 return 0;
@@ -4613,6 +4725,7 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4613{ 4725{
4614 struct wl1271 *wl = hw->priv; 4726 struct wl1271 *wl = hw->priv;
4615 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 4727 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
4728 int ret;
4616 4729
4617 wl1271_debug(DEBUG_MAC80211, 4730 wl1271_debug(DEBUG_MAC80211,
4618 "mac80211 unassign chanctx (role %d) %d (type %d)", 4731 "mac80211 unassign chanctx (role %d) %d (type %d)",
@@ -4621,6 +4734,99 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw,
4621 cfg80211_get_chandef_type(&ctx->def)); 4734 cfg80211_get_chandef_type(&ctx->def));
4622 4735
4623 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;
4624} 4830}
4625 4831
4626static int wl1271_op_conf_tx(struct ieee80211_hw *hw, 4832static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
@@ -5228,6 +5434,83 @@ out:
5228 mutex_unlock(&wl->mutex); 5434 mutex_unlock(&wl->mutex);
5229} 5435}
5230 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
5231static 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,
5232 u32 queues, bool drop) 5515 u32 queues, bool drop)
5233{ 5516{
@@ -5370,19 +5653,26 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw,
5370 u32 changed) 5653 u32 changed)
5371{ 5654{
5372 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5655 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5373 struct wl1271 *wl = hw->priv;
5374 5656
5375 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);
5376} 5665}
5377 5666
5378static int wlcore_op_get_rssi(struct ieee80211_hw *hw, 5667static void wlcore_op_sta_statistics(struct ieee80211_hw *hw,
5379 struct ieee80211_vif *vif, 5668 struct ieee80211_vif *vif,
5380 struct ieee80211_sta *sta, 5669 struct ieee80211_sta *sta,
5381 s8 *rssi_dbm) 5670 struct station_info *sinfo)
5382{ 5671{
5383 struct wl1271 *wl = hw->priv; 5672 struct wl1271 *wl = hw->priv;
5384 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 5673 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
5385 int ret = 0; 5674 s8 rssi_dbm;
5675 int ret;
5386 5676
5387 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi"); 5677 wl1271_debug(DEBUG_MAC80211, "mac80211 get_rssi");
5388 5678
@@ -5395,17 +5685,18 @@ static int wlcore_op_get_rssi(struct ieee80211_hw *hw,
5395 if (ret < 0) 5685 if (ret < 0)
5396 goto out_sleep; 5686 goto out_sleep;
5397 5687
5398 ret = wlcore_acx_average_rssi(wl, wlvif, rssi_dbm); 5688 ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm);
5399 if (ret < 0) 5689 if (ret < 0)
5400 goto out_sleep; 5690 goto out_sleep;
5401 5691
5692 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
5693 sinfo->signal = rssi_dbm;
5694
5402out_sleep: 5695out_sleep:
5403 wl1271_ps_elp_sleep(wl); 5696 wl1271_ps_elp_sleep(wl);
5404 5697
5405out: 5698out:
5406 mutex_unlock(&wl->mutex); 5699 mutex_unlock(&wl->mutex);
5407
5408 return ret;
5409} 5700}
5410 5701
5411static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw) 5702static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
@@ -5596,6 +5887,7 @@ static const struct ieee80211_ops wl1271_ops = {
5596 .set_bitrate_mask = wl12xx_set_bitrate_mask, 5887 .set_bitrate_mask = wl12xx_set_bitrate_mask,
5597 .set_default_unicast_key = wl1271_op_set_default_key_idx, 5888 .set_default_unicast_key = wl1271_op_set_default_key_idx,
5598 .channel_switch = wl12xx_op_channel_switch, 5889 .channel_switch = wl12xx_op_channel_switch,
5890 .channel_switch_beacon = wlcore_op_channel_switch_beacon,
5599 .flush = wlcore_op_flush, 5891 .flush = wlcore_op_flush,
5600 .remain_on_channel = wlcore_op_remain_on_channel, 5892 .remain_on_channel = wlcore_op_remain_on_channel,
5601 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel, 5893 .cancel_remain_on_channel = wlcore_op_cancel_remain_on_channel,
@@ -5604,8 +5896,9 @@ static const struct ieee80211_ops wl1271_ops = {
5604 .change_chanctx = wlcore_op_change_chanctx, 5896 .change_chanctx = wlcore_op_change_chanctx,
5605 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, 5897 .assign_vif_chanctx = wlcore_op_assign_vif_chanctx,
5606 .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,
5607 .sta_rc_update = wlcore_op_sta_rc_update, 5900 .sta_rc_update = wlcore_op_sta_rc_update,
5608 .get_rssi = wlcore_op_get_rssi, 5901 .sta_statistics = wlcore_op_sta_statistics,
5609 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 5902 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
5610}; 5903};
5611 5904
@@ -5776,7 +6069,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5776 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 6069 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
5777 IEEE80211_HW_SUPPORTS_PS | 6070 IEEE80211_HW_SUPPORTS_PS |
5778 IEEE80211_HW_SUPPORTS_DYNAMIC_PS | 6071 IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
5779 IEEE80211_HW_SUPPORTS_UAPSD |
5780 IEEE80211_HW_HAS_RATE_CONTROL | 6072 IEEE80211_HW_HAS_RATE_CONTROL |
5781 IEEE80211_HW_CONNECTION_MONITOR | 6073 IEEE80211_HW_CONNECTION_MONITOR |
5782 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 6074 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
@@ -5811,7 +6103,8 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
5811 6103
5812 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD | 6104 wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
5813 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 6105 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5814 WIPHY_FLAG_SUPPORTS_SCHED_SCAN; 6106 WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
6107 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
5815 6108
5816 /* make sure all our channels fit in the scanned_ch bitmask */ 6109 /* make sure all our channels fit in the scanned_ch bitmask */
5817 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.