aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
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.