aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-08 17:20:31 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-08 17:20:31 -0400
commit72948cdcbbcb5cd6b85c0a724a228b735d198212 (patch)
tree96b61b260afc51eb12768566228bf29756b264ad
parent9f12fbe603f7ae346b2b46008e325f0c9a68e55d (diff)
parentf473832fece16611520bf54ad52b16c3f6db0a94 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== pull request: wireless-next 2014-07-03 Please pull this first batch of wireless updates intended for the 3.17 stream... For the mac80211 bits, Johannes says: "The biggest thing here is probably Arik's TDLS rework, beyond that we have smaller improvements and features like David's scanning IE thing, Luca's queue work, some CSA work, etc. Also your PID rate control removal, of course." For the iwlwifi bits, Emmanuel says: "I have here a whole bunch of various things. Andy contributes better debug prints for dvm specific flows and a module parameter to completely disable power save for dvm. Andrei is sharing the premises of his work on CSA - more to come. Eran and Liad keep on working on the new devices. I have the regular amount of BT Coex stuff and I continue to work on the firmware error report system adding more debug capabilities. More to come on that subject too." On top of that, there are some cleanups to the new rsi driver, some continuing improvements to the rtl818x drivers, and the usual bundles of updates to ath9k, b43, mwifiex, wil6210, and a few other bits here and there. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--MAINTAINERS10
-rw-r--r--drivers/bcma/Makefile1
-rw-r--r--drivers/bcma/driver_gpio.c1
-rw-r--r--drivers/bcma/driver_pcie2.c175
-rw-r--r--drivers/bcma/main.c8
-rw-r--r--drivers/net/wireless/at76c50x-usb.c3
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c31
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h201
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h159
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c97
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c685
-rw-r--r--drivers/net/wireless/ath/ath9k/common-beacon.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c892
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c114
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c68
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c305
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c22
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c31
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c1
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c33
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h10
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c40
-rw-r--r--drivers/net/wireless/b43/Kconfig9
-rw-r--r--drivers/net/wireless/b43/Makefile6
-rw-r--r--drivers/net/wireless/b43/main.c311
-rw-r--r--drivers/net/wireless/b43/phy_a.c2
-rw-r--r--drivers/net/wireless/b43/phy_a.h4
-rw-r--r--drivers/net/wireless/b43/phy_common.c26
-rw-r--r--drivers/net/wireless/b43/phy_common.h12
-rw-r--r--drivers/net/wireless/b43/phy_ht.c2
-rw-r--r--drivers/net/wireless/b43/phy_n.c360
-rw-r--r--drivers/net/wireless/b43/radio_2057.c122
-rw-r--r--drivers/net/wireless/b43/radio_2057.h66
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c470
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/btcoex.c38
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c214
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.c115
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/vendor.h64
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c81
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c6
-rw-r--r--drivers/net/wireless/cw1200/scan.c3
-rw-r--r--drivers/net/wireless/cw1200/scan.h2
-rw-r--r--drivers/net/wireless/cw1200/sta.c3
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/power.c9
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h50
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c99
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c350
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c1332
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c232
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h220
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h256
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c116
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c515
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h98
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c31
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c114
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c39
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c38
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c96
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rx.c17
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c599
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c74
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.h12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c73
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h29
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c25
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c65
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h7
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c145
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c1
-rw-r--r--drivers/net/wireless/libertas/Kconfig2
-rw-r--r--drivers/net/wireless/libertas/cmd.c1
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c69
-rw-r--r--drivers/net/wireless/mwifiex/11ac.c2
-rw-r--r--drivers/net/wireless/mwifiex/11ac.h2
-rw-r--r--drivers/net/wireless/mwifiex/11h.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.h2
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.h2
-rw-r--r--drivers/net/wireless/mwifiex/Makefile2
-rw-r--r--drivers/net/wireless/mwifiex/README32
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c55
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h2
-rw-r--r--drivers/net/wireless/mwifiex/cfp.c2
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c30
-rw-r--r--drivers/net/wireless/mwifiex/debugfs.c95
-rw-r--r--drivers/net/wireless/mwifiex/decl.h2
-rw-r--r--drivers/net/wireless/mwifiex/ethtool.c85
-rw-r--r--drivers/net/wireless/mwifiex/fw.h2
-rw-r--r--drivers/net/wireless/mwifiex/ie.c2
-rw-r--r--drivers/net/wireless/mwifiex/init.c15
-rw-r--r--drivers/net/wireless/mwifiex/ioctl.h2
-rw-r--r--drivers/net/wireless/mwifiex/join.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.c8
-rw-r--r--drivers/net/wireless/mwifiex/main.h34
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c195
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h12
-rw-r--r--drivers/net/wireless/mwifiex/scan.c2
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c240
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h14
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c8
-rw-r--r--drivers/net/wireless/mwifiex/sta_rx.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_tx.c2
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c8
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_event.c2
-rw-r--r--drivers/net/wireless/mwifiex/uap_txrx.c6
-rw-r--r--drivers/net/wireless/mwifiex/usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/usb.h2
-rw-r--r--drivers/net/wireless/mwifiex/util.c2
-rw-r--r--drivers/net/wireless/mwifiex/util.h2
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c11
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
-rw-r--r--drivers/net/wireless/orinoco/Kconfig4
-rw-r--r--drivers/net/wireless/p54/p54spi.c2
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_core.c85
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_debugfs.c10
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c143
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c239
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_pkt.c17
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio.c6
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_sdio_ops.c8
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_usb.c88
-rw-r--r--drivers/net/wireless/rsi/rsi_main.h12
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h25
-rw-r--r--drivers/net/wireless/rsi/rsi_sdio.h8
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c69
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c20
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mmio.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c21
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c78
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8180.h1
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/reg.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/reg.h1
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c3
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c20
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.c16
-rw-r--r--drivers/net/wireless/ti/wl18xx/scan.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c11
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.h3
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c5
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.h2
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h2
-rw-r--r--include/linux/bcma/bcma.h2
-rw-r--r--include/linux/bcma/bcma_driver_pcie2.h158
-rw-r--r--include/linux/ieee80211.h3
-rw-r--r--include/net/cfg80211.h38
-rw-r--r--include/net/mac80211.h71
-rw-r--r--include/uapi/linux/nl80211.h5
-rw-r--r--net/mac80211/Kconfig17
-rw-r--r--net/mac80211/Makefile6
-rw-r--r--net/mac80211/agg-tx.c8
-rw-r--r--net/mac80211/cfg.c555
-rw-r--r--net/mac80211/chan.c861
-rw-r--r--net/mac80211/debugfs_sta.c3
-rw-r--r--net/mac80211/driver-ops.h20
-rw-r--r--net/mac80211/ethtool.c244
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h88
-rw-r--r--net/mac80211/iface.c13
-rw-r--r--net/mac80211/main.c10
-rw-r--r--net/mac80211/mesh.c4
-rw-r--r--net/mac80211/mesh_plink.c30
-rw-r--r--net/mac80211/mlme.c134
-rw-r--r--net/mac80211/offchannel.c6
-rw-r--r--net/mac80211/pm.c6
-rw-r--r--net/mac80211/rate.h13
-rw-r--r--net/mac80211/rc80211_pid.h278
-rw-r--r--net/mac80211/rc80211_pid_algo.c478
-rw-r--r--net/mac80211/rc80211_pid_debugfs.c228
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c118
-rw-r--r--net/mac80211/sta_info.c201
-rw-r--r--net/mac80211/sta_info.h13
-rw-r--r--net/mac80211/status.c7
-rw-r--r--net/mac80211/tdls.c293
-rw-r--r--net/mac80211/trace.h7
-rw-r--r--net/mac80211/tx.c170
-rw-r--r--net/mac80211/util.c270
-rw-r--r--net/mac80211/wep.c20
-rw-r--r--net/wireless/core.c3
-rw-r--r--net/wireless/ethtool.c86
-rw-r--r--net/wireless/ethtool.h6
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/rdev-ops.h54
-rw-r--r--net/wireless/trace.h59
256 files changed, 11859 insertions, 4509 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index f492681ea99e..5eede718b13e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5622,16 +5622,6 @@ F: Documentation/networking/mac80211-injection.txt
5622F: include/net/mac80211.h 5622F: include/net/mac80211.h
5623F: net/mac80211/ 5623F: net/mac80211/
5624 5624
5625MAC80211 PID RATE CONTROL
5626M: Stefano Brivio <stefano.brivio@polimi.it>
5627M: Mattias Nissler <mattias.nissler@gmx.de>
5628L: linux-wireless@vger.kernel.org
5629W: http://wireless.kernel.org/en/developers/Documentation/mac80211/RateControl/PID
5630T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
5631T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
5632S: Maintained
5633F: net/mac80211/rc80211_pid*
5634
5635MACVLAN DRIVER 5625MACVLAN DRIVER
5636M: Patrick McHardy <kaber@trash.net> 5626M: Patrick McHardy <kaber@trash.net>
5637L: netdev@vger.kernel.org 5627L: netdev@vger.kernel.org
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index 734b32f09c0a..91290f7f61b8 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -3,6 +3,7 @@ bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
3bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o 3bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o
4bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o 4bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o
5bcma-y += driver_pci.o 5bcma-y += driver_pci.o
6bcma-y += driver_pcie2.o
6bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o 7bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
7bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o 8bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
8bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o 9bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o
diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c
index d7f81ad56b8a..aec9f850b4a8 100644
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -220,6 +220,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
220#endif 220#endif
221 switch (cc->core->bus->chipinfo.id) { 221 switch (cc->core->bus->chipinfo.id) {
222 case BCMA_CHIP_ID_BCM5357: 222 case BCMA_CHIP_ID_BCM5357:
223 case BCMA_CHIP_ID_BCM53572:
223 chip->ngpio = 32; 224 chip->ngpio = 32;
224 break; 225 break;
225 default: 226 default:
diff --git a/drivers/bcma/driver_pcie2.c b/drivers/bcma/driver_pcie2.c
new file mode 100644
index 000000000000..e4be537b0c66
--- /dev/null
+++ b/drivers/bcma/driver_pcie2.c
@@ -0,0 +1,175 @@
1/*
2 * Broadcom specific AMBA
3 * PCIe Gen 2 Core
4 *
5 * Copyright 2014, Broadcom Corporation
6 * Copyright 2014, Rafał Miłecki <zajec5@gmail.com>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "bcma_private.h"
12#include <linux/bcma/bcma.h>
13
14/**************************************************
15 * R/W ops.
16 **************************************************/
17
18#if 0
19static u32 bcma_core_pcie2_cfg_read(struct bcma_drv_pcie2 *pcie2, u32 addr)
20{
21 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
22 pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR);
23 return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
24}
25#endif
26
27static void bcma_core_pcie2_cfg_write(struct bcma_drv_pcie2 *pcie2, u32 addr,
28 u32 val)
29{
30 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, addr);
31 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, val);
32}
33
34/**************************************************
35 * Init.
36 **************************************************/
37
38static u32 bcma_core_pcie2_war_delay_perst_enab(struct bcma_drv_pcie2 *pcie2,
39 bool enable)
40{
41 u32 val;
42
43 /* restore back to default */
44 val = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
45 val |= PCIE2_CLKC_DLYPERST;
46 val &= ~PCIE2_CLKC_DISSPROMLD;
47 if (enable) {
48 val &= ~PCIE2_CLKC_DLYPERST;
49 val |= PCIE2_CLKC_DISSPROMLD;
50 }
51 pcie2_write32(pcie2, (BCMA_CORE_PCIE2_CLK_CONTROL), val);
52 /* flush */
53 return pcie2_read32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL);
54}
55
56static void bcma_core_pcie2_set_ltr_vals(struct bcma_drv_pcie2 *pcie2)
57{
58 /* LTR0 */
59 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x844);
60 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x883c883c);
61 /* LTR1 */
62 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x848);
63 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x88648864);
64 /* LTR2 */
65 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, 0x84C);
66 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x90039003);
67}
68
69static void bcma_core_pcie2_hw_ltr_war(struct bcma_drv_pcie2 *pcie2)
70{
71 u8 core_rev = pcie2->core->id.rev;
72 u32 devstsctr2;
73
74 if (core_rev < 2 || core_rev == 10 || core_rev > 13)
75 return;
76
77 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
78 PCIE2_CAP_DEVSTSCTRL2_OFFSET);
79 devstsctr2 = pcie2_read32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA);
80 if (devstsctr2 & PCIE2_CAP_DEVSTSCTRL2_LTRENAB) {
81 /* force the right LTR values */
82 bcma_core_pcie2_set_ltr_vals(pcie2);
83
84 /* TODO:
85 si_core_wrapperreg(pcie2, 3, 0x60, 0x8080, 0); */
86
87 /* enable the LTR */
88 devstsctr2 |= PCIE2_CAP_DEVSTSCTRL2_LTRENAB;
89 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
90 PCIE2_CAP_DEVSTSCTRL2_OFFSET);
91 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, devstsctr2);
92
93 /* set the LTR state to be active */
94 pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
95 PCIE2_LTR_ACTIVE);
96 usleep_range(1000, 2000);
97
98 /* set the LTR state to be sleep */
99 pcie2_write32(pcie2, BCMA_CORE_PCIE2_LTR_STATE,
100 PCIE2_LTR_SLEEP);
101 usleep_range(1000, 2000);
102 }
103}
104
105static void pciedev_crwlpciegen2(struct bcma_drv_pcie2 *pcie2)
106{
107 u8 core_rev = pcie2->core->id.rev;
108 bool pciewar160, pciewar162;
109
110 pciewar160 = core_rev == 7 || core_rev == 9 || core_rev == 11;
111 pciewar162 = core_rev == 5 || core_rev == 7 || core_rev == 8 ||
112 core_rev == 9 || core_rev == 11;
113
114 if (!pciewar160 && !pciewar162)
115 return;
116
117/* TODO */
118#if 0
119 pcie2_set32(pcie2, BCMA_CORE_PCIE2_CLK_CONTROL,
120 PCIE_DISABLE_L1CLK_GATING);
121#if 0
122 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
123 PCIEGEN2_COE_PVT_TL_CTRL_0);
124 pcie2_mask32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA,
125 ~(1 << COE_PVT_TL_CTRL_0_PM_DIS_L1_REENTRY_BIT));
126#endif
127#endif
128}
129
130static void pciedev_crwlpciegen2_180(struct bcma_drv_pcie2 *pcie2)
131{
132 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_PMCR_REFUP);
133 pcie2_set32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 0x1f);
134}
135
136static void pciedev_crwlpciegen2_182(struct bcma_drv_pcie2 *pcie2)
137{
138 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR, PCIE2_SBMBX);
139 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, 1 << 0);
140}
141
142static void pciedev_reg_pm_clk_period(struct bcma_drv_pcie2 *pcie2)
143{
144 struct bcma_drv_cc *drv_cc = &pcie2->core->bus->drv_cc;
145 u8 core_rev = pcie2->core->id.rev;
146 u32 alp_khz, pm_value;
147
148 if (core_rev <= 13) {
149 alp_khz = bcma_pmu_get_alp_clock(drv_cc) / 1000;
150 pm_value = (1000000 * 2) / alp_khz;
151 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDADDR,
152 PCIE2_PVT_REG_PM_CLK_PERIOD);
153 pcie2_write32(pcie2, BCMA_CORE_PCIE2_CONFIGINDDATA, pm_value);
154 }
155}
156
157void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
158{
159 struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
160 u32 tmp;
161
162 tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
163 if ((tmp & 0xe) >> 1 == 2)
164 bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
165
166 /* TODO: Do we need pcie_reqsize? */
167
168 if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
169 bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
170 bcma_core_pcie2_hw_ltr_war(pcie2);
171 pciedev_crwlpciegen2(pcie2);
172 pciedev_reg_pm_clk_period(pcie2);
173 pciedev_crwlpciegen2_180(pcie2);
174 pciedev_crwlpciegen2_182(pcie2);
175}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 34ea4c588d36..0ff8d58831ef 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -132,6 +132,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
132 case BCMA_CORE_CHIPCOMMON: 132 case BCMA_CORE_CHIPCOMMON:
133 case BCMA_CORE_PCI: 133 case BCMA_CORE_PCI:
134 case BCMA_CORE_PCIE: 134 case BCMA_CORE_PCIE:
135 case BCMA_CORE_PCIE2:
135 case BCMA_CORE_MIPS_74K: 136 case BCMA_CORE_MIPS_74K:
136 case BCMA_CORE_4706_MAC_GBIT_COMMON: 137 case BCMA_CORE_4706_MAC_GBIT_COMMON:
137 continue; 138 continue;
@@ -281,6 +282,13 @@ int bcma_bus_register(struct bcma_bus *bus)
281 bcma_core_pci_init(&bus->drv_pci[1]); 282 bcma_core_pci_init(&bus->drv_pci[1]);
282 } 283 }
283 284
285 /* Init PCIe Gen 2 core */
286 core = bcma_find_core_unit(bus, BCMA_CORE_PCIE2, 0);
287 if (core) {
288 bus->drv_pcie2.core = core;
289 bcma_core_pcie2_init(&bus->drv_pcie2);
290 }
291
284 /* Init GBIT MAC COMMON core */ 292 /* Init GBIT MAC COMMON core */
285 core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); 293 core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
286 if (core) { 294 if (core) {
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index d48776e4f343..334c2ece855a 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1955,8 +1955,9 @@ static void at76_dwork_hw_scan(struct work_struct *work)
1955 1955
1956static int at76_hw_scan(struct ieee80211_hw *hw, 1956static int at76_hw_scan(struct ieee80211_hw *hw,
1957 struct ieee80211_vif *vif, 1957 struct ieee80211_vif *vif,
1958 struct cfg80211_scan_request *req) 1958 struct ieee80211_scan_request *hw_req)
1959{ 1959{
1960 struct cfg80211_scan_request *req = &hw_req->req;
1960 struct at76_priv *priv = hw->priv; 1961 struct at76_priv *priv = hw->priv;
1961 struct at76_req_scan scan; 1962 struct at76_req_scan scan;
1962 u8 *ssid = NULL; 1963 u8 *ssid = NULL;
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index a889fd66fc63..fd9e5305e77f 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -63,6 +63,7 @@ enum ath_op_flags {
63 ATH_OP_PRIM_STA_VIF, 63 ATH_OP_PRIM_STA_VIF,
64 ATH_OP_HW_RESET, 64 ATH_OP_HW_RESET,
65 ATH_OP_SCANNING, 65 ATH_OP_SCANNING,
66 ATH_OP_MULTI_CHANNEL,
66}; 67};
67 68
68enum ath_bus_type { 69enum ath_bus_type {
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index a21080028c54..b8314a534972 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3137,10 +3137,11 @@ exit:
3137 3137
3138static int ath10k_hw_scan(struct ieee80211_hw *hw, 3138static int ath10k_hw_scan(struct ieee80211_hw *hw,
3139 struct ieee80211_vif *vif, 3139 struct ieee80211_vif *vif,
3140 struct cfg80211_scan_request *req) 3140 struct ieee80211_scan_request *hw_req)
3141{ 3141{
3142 struct ath10k *ar = hw->priv; 3142 struct ath10k *ar = hw->priv;
3143 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); 3143 struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
3144 struct cfg80211_scan_request *req = &hw_req->req;
3144 struct wmi_start_scan_arg arg; 3145 struct wmi_start_scan_arg arg;
3145 int ret = 0; 3146 int ret = 0;
3146 int i; 3147 int i;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 74bd54d6aceb..85316bb3f8c6 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1285,6 +1285,7 @@ struct ath5k_hw {
1285#define ATH_STAT_STARTED 3 /* opened & irqs enabled */ 1285#define ATH_STAT_STARTED 3 /* opened & irqs enabled */
1286 1286
1287 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ 1287 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
1288 unsigned int fif_filter_flags; /* Current FIF_* filter flags */
1288 struct ieee80211_channel *curchan; /* current h/w channel */ 1289 struct ieee80211_channel *curchan; /* current h/w channel */
1289 1290
1290 u16 nvifs; 1291 u16 nvifs;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 4b18434ba697..8ad2550bce7f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1382,6 +1382,9 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
1382 rxs->flag = 0; 1382 rxs->flag = 0;
1383 if (unlikely(rs->rs_status & AR5K_RXERR_MIC)) 1383 if (unlikely(rs->rs_status & AR5K_RXERR_MIC))
1384 rxs->flag |= RX_FLAG_MMIC_ERROR; 1384 rxs->flag |= RX_FLAG_MMIC_ERROR;
1385 if (unlikely(rs->rs_status & AR5K_RXERR_CRC))
1386 rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
1387
1385 1388
1386 /* 1389 /*
1387 * always extend the mac timestamp, since this information is 1390 * always extend the mac timestamp, since this information is
@@ -1449,6 +1452,8 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
1449 ah->stats.rx_bytes_count += rs->rs_datalen; 1452 ah->stats.rx_bytes_count += rs->rs_datalen;
1450 1453
1451 if (unlikely(rs->rs_status)) { 1454 if (unlikely(rs->rs_status)) {
1455 unsigned int filters;
1456
1452 if (rs->rs_status & AR5K_RXERR_CRC) 1457 if (rs->rs_status & AR5K_RXERR_CRC)
1453 ah->stats.rxerr_crc++; 1458 ah->stats.rxerr_crc++;
1454 if (rs->rs_status & AR5K_RXERR_FIFO) 1459 if (rs->rs_status & AR5K_RXERR_FIFO)
@@ -1457,7 +1462,20 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
1457 ah->stats.rxerr_phy++; 1462 ah->stats.rxerr_phy++;
1458 if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32) 1463 if (rs->rs_phyerr > 0 && rs->rs_phyerr < 32)
1459 ah->stats.rxerr_phy_code[rs->rs_phyerr]++; 1464 ah->stats.rxerr_phy_code[rs->rs_phyerr]++;
1460 return false; 1465
1466 /*
1467 * Treat packets that underwent a CCK or OFDM reset as having a bad CRC.
1468 * These restarts happen when the radio resynchronizes to a stronger frame
1469 * while receiving a weaker frame. Here we receive the prefix of the weak
1470 * frame. Since these are incomplete packets, mark their CRC as invalid.
1471 */
1472 if (rs->rs_phyerr == AR5K_RX_PHY_ERROR_OFDM_RESTART ||
1473 rs->rs_phyerr == AR5K_RX_PHY_ERROR_CCK_RESTART) {
1474 rs->rs_status |= AR5K_RXERR_CRC;
1475 rs->rs_status &= ~AR5K_RXERR_PHY;
1476 } else {
1477 return false;
1478 }
1461 } 1479 }
1462 if (rs->rs_status & AR5K_RXERR_DECRYPT) { 1480 if (rs->rs_status & AR5K_RXERR_DECRYPT) {
1463 /* 1481 /*
@@ -1480,8 +1498,15 @@ ath5k_receive_frame_ok(struct ath5k_hw *ah, struct ath5k_rx_status *rs)
1480 return true; 1498 return true;
1481 } 1499 }
1482 1500
1483 /* reject any frames with non-crypto errors */ 1501 /*
1484 if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) 1502 * Reject any frames with non-crypto errors, and take into account the
1503 * current FIF_* filters.
1504 */
1505 filters = AR5K_RXERR_DECRYPT;
1506 if (ah->fif_filter_flags & FIF_FCSFAIL)
1507 filters |= AR5K_RXERR_CRC;
1508
1509 if (rs->rs_status & ~filters)
1485 return false; 1510 return false;
1486 } 1511 }
1487 1512
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index afb23b3cc7be..b65c38fdaa4b 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -473,6 +473,8 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
473 /* Set the cached hw filter flags, this will later actually 473 /* Set the cached hw filter flags, this will later actually
474 * be set in HW */ 474 * be set in HW */
475 ah->filter_flags = rfilt; 475 ah->filter_flags = rfilt;
476 /* Store current FIF filter flags */
477 ah->fif_filter_flags = *new_flags;
476 478
477 mutex_unlock(&ah->lock); 479 mutex_unlock(&ah->lock);
478} 480}
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 8fcd586d1c39..6b4020a57984 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -5,7 +5,8 @@ ath9k-y += beacon.o \
5 recv.o \ 5 recv.o \
6 xmit.o \ 6 xmit.o \
7 link.o \ 7 link.o \
8 antenna.o 8 antenna.o \
9 channel.o
9 10
10ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o 11ath9k-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += mci.o
11ath9k-$(CONFIG_ATH9K_PCI) += pci.o 12ath9k-$(CONFIG_ATH9K_PCI) += pci.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 235053ba7737..80c6eacbda53 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3535,7 +3535,8 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
3535{ 3535{
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 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);
3540 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))
3541 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);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index ec1da0cc25f5..ddef9eedbac6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -314,10 +314,17 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
314 qca953x_1p0_mac_core); 314 qca953x_1p0_mac_core);
315 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], 315 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
316 qca953x_1p0_mac_postamble); 316 qca953x_1p0_mac_postamble);
317 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], 317 if (AR_SREV_9531_20(ah)) {
318 qca953x_1p0_baseband_core); 318 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
319 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], 319 qca953x_2p0_baseband_core);
320 qca953x_1p0_baseband_postamble); 320 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
321 qca953x_2p0_baseband_postamble);
322 } else {
323 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
324 qca953x_1p0_baseband_core);
325 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
326 qca953x_1p0_baseband_postamble);
327 }
321 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], 328 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
322 qca953x_1p0_radio_core); 329 qca953x_1p0_radio_core);
323 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], 330 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 8927fc34d84c..542a8d51d3b0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1552,13 +1552,15 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1552 u8 *ini_reloaded) 1552 u8 *ini_reloaded)
1553{ 1553{
1554 unsigned int regWrites = 0; 1554 unsigned int regWrites = 0;
1555 u32 modesIndex; 1555 u32 modesIndex, txgain_index;
1556 1556
1557 if (IS_CHAN_5GHZ(chan)) 1557 if (IS_CHAN_5GHZ(chan))
1558 modesIndex = IS_CHAN_HT40(chan) ? 2 : 1; 1558 modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;
1559 else 1559 else
1560 modesIndex = IS_CHAN_HT40(chan) ? 3 : 4; 1560 modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;
1561 1561
1562 txgain_index = AR_SREV_9531(ah) ? 1 : modesIndex;
1563
1562 if (modesIndex == ah->modes_index) { 1564 if (modesIndex == ah->modes_index) {
1563 *ini_reloaded = false; 1565 *ini_reloaded = false;
1564 goto set_rfmode; 1566 goto set_rfmode;
@@ -1573,7 +1575,7 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1573 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, 1575 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
1574 modesIndex); 1576 modesIndex);
1575 1577
1576 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1578 REG_WRITE_ARRAY(&ah->iniModesTxGain, txgain_index, regWrites);
1577 1579
1578 if (AR_SREV_9462_20_OR_LATER(ah)) { 1580 if (AR_SREV_9462_20_OR_LATER(ah)) {
1579 /* 1581 /*
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
index 8e5c3b9786e3..812a9d787bf3 100644
--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -219,7 +219,7 @@ static const u32 qca953x_1p0_baseband_core[][2] = {
219 {0x00009d04, 0x40206c10}, 219 {0x00009d04, 0x40206c10},
220 {0x00009d08, 0x009c4060}, 220 {0x00009d08, 0x009c4060},
221 {0x00009d0c, 0x9883800a}, 221 {0x00009d0c, 0x9883800a},
222 {0x00009d10, 0x01884061}, 222 {0x00009d10, 0x018848c6},
223 {0x00009d14, 0x00c0040b}, 223 {0x00009d14, 0x00c0040b},
224 {0x00009d18, 0x00000000}, 224 {0x00009d18, 0x00000000},
225 {0x00009e08, 0x0038230c}, 225 {0x00009e08, 0x0038230c},
@@ -715,4 +715,203 @@ static const u32 qca953x_1p1_modes_no_xpa_tx_gain_table[][2] = {
715 {0x00016448, 0x6c927a70}, 715 {0x00016448, 0x6c927a70},
716}; 716};
717 717
718static const u32 qca953x_2p0_baseband_core[][2] = {
719 /* Addr allmodes */
720 {0x00009800, 0xafe68e30},
721 {0x00009804, 0xfd14e000},
722 {0x00009808, 0x9c0a9f6b},
723 {0x0000980c, 0x04900000},
724 {0x00009814, 0x0280c00a},
725 {0x00009818, 0x00000000},
726 {0x0000981c, 0x00020028},
727 {0x00009834, 0x6400a190},
728 {0x00009838, 0x0108ecff},
729 {0x0000983c, 0x14000600},
730 {0x00009880, 0x201fff00},
731 {0x00009884, 0x00001042},
732 {0x000098a4, 0x00200400},
733 {0x000098b0, 0x32840bbe},
734 {0x000098bc, 0x00000002},
735 {0x000098d0, 0x004b6a8e},
736 {0x000098d4, 0x00000820},
737 {0x000098dc, 0x00000000},
738 {0x000098f0, 0x00000000},
739 {0x000098f4, 0x00000000},
740 {0x00009c04, 0xff55ff55},
741 {0x00009c08, 0x0320ff55},
742 {0x00009c0c, 0x00000000},
743 {0x00009c10, 0x00000000},
744 {0x00009c14, 0x00046384},
745 {0x00009c18, 0x05b6b440},
746 {0x00009c1c, 0x00b6b440},
747 {0x00009d00, 0xc080a333},
748 {0x00009d04, 0x40206c10},
749 {0x00009d08, 0x009c4060},
750 {0x00009d0c, 0x9883800a},
751 {0x00009d10, 0x018848c6},
752 {0x00009d14, 0x00c0040b},
753 {0x00009d18, 0x00000000},
754 {0x00009e08, 0x0038230c},
755 {0x00009e24, 0x990bb515},
756 {0x00009e28, 0x0c6f0000},
757 {0x00009e30, 0x06336f77},
758 {0x00009e34, 0x6af6532f},
759 {0x00009e38, 0x0cc80c00},
760 {0x00009e40, 0x0d261820},
761 {0x00009e4c, 0x00001004},
762 {0x00009e50, 0x00ff03f1},
763 {0x00009fc0, 0x813e4788},
764 {0x00009fc4, 0x0001efb5},
765 {0x00009fcc, 0x40000014},
766 {0x00009fd0, 0x02993b93},
767 {0x0000a20c, 0x00000000},
768 {0x0000a220, 0x00000000},
769 {0x0000a224, 0x00000000},
770 {0x0000a228, 0x10002310},
771 {0x0000a23c, 0x00000000},
772 {0x0000a244, 0x0c000000},
773 {0x0000a248, 0x00000140},
774 {0x0000a2a0, 0x00000007},
775 {0x0000a2c0, 0x00000007},
776 {0x0000a2c8, 0x00000000},
777 {0x0000a2d4, 0x00000000},
778 {0x0000a2ec, 0x00000000},
779 {0x0000a2f0, 0x00000000},
780 {0x0000a2f4, 0x00000000},
781 {0x0000a2f8, 0x00000000},
782 {0x0000a344, 0x00000000},
783 {0x0000a34c, 0x00000000},
784 {0x0000a350, 0x0000a000},
785 {0x0000a364, 0x00000000},
786 {0x0000a370, 0x00000000},
787 {0x0000a390, 0x00000001},
788 {0x0000a394, 0x00000444},
789 {0x0000a398, 0x001f0e0f},
790 {0x0000a39c, 0x0075393f},
791 {0x0000a3a0, 0xb79f6427},
792 {0x0000a3a4, 0x000400ff},
793 {0x0000a3a8, 0x6a6a6a6a},
794 {0x0000a3ac, 0x6a6a6a6a},
795 {0x0000a3b0, 0x00c8641a},
796 {0x0000a3b4, 0x0000001a},
797 {0x0000a3b8, 0x0088642a},
798 {0x0000a3bc, 0x000001fa},
799 {0x0000a3c0, 0x20202020},
800 {0x0000a3c4, 0x22222220},
801 {0x0000a3c8, 0x20200020},
802 {0x0000a3cc, 0x20202020},
803 {0x0000a3d0, 0x20202020},
804 {0x0000a3d4, 0x20202020},
805 {0x0000a3d8, 0x20202020},
806 {0x0000a3dc, 0x20202020},
807 {0x0000a3e0, 0x20202020},
808 {0x0000a3e4, 0x20202020},
809 {0x0000a3e8, 0x20202020},
810 {0x0000a3ec, 0x20202020},
811 {0x0000a3f0, 0x00000000},
812 {0x0000a3f4, 0x00000000},
813 {0x0000a3f8, 0x0c9bd380},
814 {0x0000a3fc, 0x000f0f01},
815 {0x0000a400, 0x8fa91f01},
816 {0x0000a404, 0x00000000},
817 {0x0000a408, 0x0e79e5c6},
818 {0x0000a40c, 0x00820820},
819 {0x0000a414, 0x1ce42108},
820 {0x0000a418, 0x2d001dce},
821 {0x0000a41c, 0x1ce73908},
822 {0x0000a420, 0x000001ce},
823 {0x0000a424, 0x1ce738e7},
824 {0x0000a428, 0x000001ce},
825 {0x0000a42c, 0x1ce739ce},
826 {0x0000a430, 0x1ce739ce},
827 {0x0000a434, 0x00000000},
828 {0x0000a438, 0x00001801},
829 {0x0000a43c, 0x00100000},
830 {0x0000a444, 0x00000000},
831 {0x0000a448, 0x05000080},
832 {0x0000a44c, 0x00000001},
833 {0x0000a450, 0x00010000},
834 {0x0000a458, 0x00000000},
835 {0x0000a644, 0xbfad9d74},
836 {0x0000a648, 0x0048060a},
837 {0x0000a64c, 0x00003c37},
838 {0x0000a670, 0x03020100},
839 {0x0000a674, 0x09080504},
840 {0x0000a678, 0x0d0c0b0a},
841 {0x0000a67c, 0x13121110},
842 {0x0000a680, 0x31301514},
843 {0x0000a684, 0x35343332},
844 {0x0000a688, 0x00000036},
845 {0x0000a690, 0x08000838},
846 {0x0000a7cc, 0x00000000},
847 {0x0000a7d0, 0x00000000},
848 {0x0000a7d4, 0x00000004},
849 {0x0000a7dc, 0x00000000},
850 {0x0000a8d0, 0x004b6a8e},
851 {0x0000a8d4, 0x00000820},
852 {0x0000a8dc, 0x00000000},
853 {0x0000a8f0, 0x00000000},
854 {0x0000a8f4, 0x00000000},
855 {0x0000b2d0, 0x00000080},
856 {0x0000b2d4, 0x00000000},
857 {0x0000b2ec, 0x00000000},
858 {0x0000b2f0, 0x00000000},
859 {0x0000b2f4, 0x00000000},
860 {0x0000b2f8, 0x00000000},
861 {0x0000b408, 0x0e79e5c0},
862 {0x0000b40c, 0x00820820},
863 {0x0000b420, 0x00000000},
864};
865
866static const u32 qca953x_2p0_baseband_postamble[][5] = {
867 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
868 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
869 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
870 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
871 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
872 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
873 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
874 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
875 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0},
876 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
877 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
878 {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e},
879 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e},
880 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
881 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
882 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
883 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
884 {0x00009e3c, 0xcfa10820, 0xcfa10820, 0xcf946222, 0xcf946222},
885 {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27},
886 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
887 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
888 {0x0000a204, 0x005c0ec0, 0x005c0ec4, 0x005c0ec4, 0x005c0ec0},
889 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
890 {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f},
891 {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
892 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
893 {0x0000a238, 0xffb01018, 0xffb01018, 0xffb01018, 0xffb01018},
894 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
895 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
896 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
897 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01010e0e, 0x01010e0e},
898 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
899 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x01000e0e, 0x01000e0e},
900 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
901 {0x0000a284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
902 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
903 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
904 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
905 {0x0000a2cc, 0x18c50033, 0x18c43433, 0x18c41033, 0x18c44c33},
906 {0x0000a2d0, 0x00041982, 0x00041982, 0x00041982, 0x00041982},
907 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
908 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
909 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
910 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000},
911 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
912 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
913 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
914 {0x0000b284, 0x00000000, 0x00000000, 0x00000010, 0x00000010},
915};
916
718#endif /* INITVALS_953X_H */ 917#endif /* INITVALS_953X_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2ca8f7e06174..11b5e4dd6294 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -22,6 +22,7 @@
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/leds.h> 23#include <linux/leds.h>
24#include <linux/completion.h> 24#include <linux/completion.h>
25#include <linux/time.h>
25 26
26#include "common.h" 27#include "common.h"
27#include "debug.h" 28#include "debug.h"
@@ -35,10 +36,7 @@ extern struct ieee80211_ops ath9k_ops;
35extern int ath9k_modparam_nohwcrypt; 36extern int ath9k_modparam_nohwcrypt;
36extern int led_blink; 37extern int led_blink;
37extern bool is_ath9k_unloaded; 38extern bool is_ath9k_unloaded;
38 39extern int ath9k_use_chanctx;
39struct ath_config {
40 u16 txpowlimit;
41};
42 40
43/*************************/ 41/*************************/
44/* Descriptor Management */ 42/* Descriptor Management */
@@ -167,7 +165,6 @@ struct ath_txq {
167 u32 axq_ampdu_depth; 165 u32 axq_ampdu_depth;
168 bool stopped; 166 bool stopped;
169 bool axq_tx_inprogress; 167 bool axq_tx_inprogress;
170 struct list_head axq_acq;
171 struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; 168 struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
172 u8 txq_headidx; 169 u8 txq_headidx;
173 u8 txq_tailidx; 170 u8 txq_tailidx;
@@ -280,8 +277,9 @@ struct ath_node {
280struct ath_tx_control { 277struct ath_tx_control {
281 struct ath_txq *txq; 278 struct ath_txq *txq;
282 struct ath_node *an; 279 struct ath_node *an;
283 u8 paprd;
284 struct ieee80211_sta *sta; 280 struct ieee80211_sta *sta;
281 u8 paprd;
282 bool force_channel;
285}; 283};
286 284
287 285
@@ -325,6 +323,116 @@ struct ath_rx {
325 u32 ampdu_ref; 323 u32 ampdu_ref;
326}; 324};
327 325
326struct ath_chanctx {
327 struct cfg80211_chan_def chandef;
328 struct list_head vifs;
329 struct list_head acq[IEEE80211_NUM_ACS];
330 int hw_queue_base;
331
332 /* do not dereference, use for comparison only */
333 struct ieee80211_vif *primary_sta;
334
335 struct ath_beacon_config beacon;
336 struct ath9k_hw_cal_data caldata;
337 struct timespec tsf_ts;
338 u64 tsf_val;
339 u32 last_beacon;
340
341 u16 txpower;
342 bool offchannel;
343 bool stopped;
344 bool active;
345 bool assigned;
346 bool switch_after_beacon;
347};
348
349enum ath_chanctx_event {
350 ATH_CHANCTX_EVENT_BEACON_PREPARE,
351 ATH_CHANCTX_EVENT_BEACON_SENT,
352 ATH_CHANCTX_EVENT_TSF_TIMER,
353 ATH_CHANCTX_EVENT_BEACON_RECEIVED,
354 ATH_CHANCTX_EVENT_ASSOC,
355 ATH_CHANCTX_EVENT_SWITCH,
356 ATH_CHANCTX_EVENT_UNASSIGN,
357 ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL,
358};
359
360enum ath_chanctx_state {
361 ATH_CHANCTX_STATE_IDLE,
362 ATH_CHANCTX_STATE_WAIT_FOR_BEACON,
363 ATH_CHANCTX_STATE_WAIT_FOR_TIMER,
364 ATH_CHANCTX_STATE_SWITCH,
365 ATH_CHANCTX_STATE_FORCE_ACTIVE,
366};
367
368struct ath_chanctx_sched {
369 bool beacon_pending;
370 bool offchannel_pending;
371 enum ath_chanctx_state state;
372 u8 beacon_miss;
373
374 u32 next_tbtt;
375 u32 switch_start_time;
376 unsigned int offchannel_duration;
377 unsigned int channel_switch_time;
378
379 /* backup, in case the hardware timer fails */
380 struct timer_list timer;
381};
382
383enum ath_offchannel_state {
384 ATH_OFFCHANNEL_IDLE,
385 ATH_OFFCHANNEL_PROBE_SEND,
386 ATH_OFFCHANNEL_PROBE_WAIT,
387 ATH_OFFCHANNEL_SUSPEND,
388 ATH_OFFCHANNEL_ROC_START,
389 ATH_OFFCHANNEL_ROC_WAIT,
390 ATH_OFFCHANNEL_ROC_DONE,
391};
392
393struct ath_offchannel {
394 struct ath_chanctx chan;
395 struct timer_list timer;
396 struct cfg80211_scan_request *scan_req;
397 struct ieee80211_vif *scan_vif;
398 int scan_idx;
399 enum ath_offchannel_state state;
400 struct ieee80211_channel *roc_chan;
401 struct ieee80211_vif *roc_vif;
402 int roc_duration;
403 int duration;
404};
405#define ath_for_each_chanctx(_sc, _ctx) \
406 for (ctx = &sc->chanctx[0]; \
407 ctx <= &sc->chanctx[ARRAY_SIZE(sc->chanctx) - 1]; \
408 ctx++)
409
410void ath9k_fill_chanctx_ops(void);
411void ath9k_chanctx_force_active(struct ieee80211_hw *hw,
412 struct ieee80211_vif *vif);
413static inline struct ath_chanctx *
414ath_chanctx_get(struct ieee80211_chanctx_conf *ctx)
415{
416 struct ath_chanctx **ptr = (void *) ctx->drv_priv;
417 return *ptr;
418}
419void ath_chanctx_init(struct ath_softc *sc);
420void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
421 struct cfg80211_chan_def *chandef);
422void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
423 struct cfg80211_chan_def *chandef);
424void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx);
425void ath_offchannel_timer(unsigned long data);
426void ath_offchannel_channel_change(struct ath_softc *sc);
427void ath_chanctx_offchan_switch(struct ath_softc *sc,
428 struct ieee80211_channel *chan);
429struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc,
430 bool active);
431void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
432 enum ath_chanctx_event ev);
433void ath_chanctx_timer(unsigned long data);
434
435int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
328int ath_startrecv(struct ath_softc *sc); 436int ath_startrecv(struct ath_softc *sc);
329bool ath_stoprecv(struct ath_softc *sc); 437bool ath_stoprecv(struct ath_softc *sc);
330u32 ath_calcrxfilter(struct ath_softc *sc); 438u32 ath_calcrxfilter(struct ath_softc *sc);
@@ -341,6 +449,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq);
341void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); 449void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
342void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); 450void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
343void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq); 451void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
452void ath_txq_schedule_all(struct ath_softc *sc);
344int ath_tx_init(struct ath_softc *sc, int nbufs); 453int ath_tx_init(struct ath_softc *sc, int nbufs);
345int ath_txq_update(struct ath_softc *sc, int qnum, 454int ath_txq_update(struct ath_softc *sc, int qnum,
346 struct ath9k_tx_queue_info *q); 455 struct ath9k_tx_queue_info *q);
@@ -370,32 +479,47 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
370/********/ 479/********/
371 480
372struct ath_vif { 481struct ath_vif {
482 struct list_head list;
483
373 struct ieee80211_vif *vif; 484 struct ieee80211_vif *vif;
374 struct ath_node mcast_node; 485 struct ath_node mcast_node;
375 int av_bslot; 486 int av_bslot;
376 bool primary_sta_vif;
377 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ 487 __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
378 struct ath_buf *av_bcbuf; 488 struct ath_buf *av_bcbuf;
489 struct ath_chanctx *chanctx;
379 490
380 /* P2P Client */ 491 /* P2P Client */
381 struct ieee80211_noa_data noa; 492 struct ieee80211_noa_data noa;
493
494 /* P2P GO */
495 u8 noa_index;
496 u32 offchannel_start;
497 u32 offchannel_duration;
498
499 u32 periodic_noa_start;
500 u32 periodic_noa_duration;
382}; 501};
383 502
384struct ath9k_vif_iter_data { 503struct ath9k_vif_iter_data {
385 u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */ 504 u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
386 u8 mask[ETH_ALEN]; /* bssid mask */ 505 u8 mask[ETH_ALEN]; /* bssid mask */
387 bool has_hw_macaddr; 506 bool has_hw_macaddr;
507 u8 slottime;
508 bool beacons;
388 509
389 int naps; /* number of AP vifs */ 510 int naps; /* number of AP vifs */
390 int nmeshes; /* number of mesh vifs */ 511 int nmeshes; /* number of mesh vifs */
391 int nstations; /* number of station vifs */ 512 int nstations; /* number of station vifs */
392 int nwds; /* number of WDS vifs */ 513 int nwds; /* number of WDS vifs */
393 int nadhocs; /* number of adhoc vifs */ 514 int nadhocs; /* number of adhoc vifs */
515 struct ieee80211_vif *primary_sta;
394}; 516};
395 517
396void ath9k_calculate_iter_data(struct ieee80211_hw *hw, 518void ath9k_calculate_iter_data(struct ath_softc *sc,
397 struct ieee80211_vif *vif, 519 struct ath_chanctx *ctx,
398 struct ath9k_vif_iter_data *iter_data); 520 struct ath9k_vif_iter_data *iter_data);
521void ath9k_calculate_summary_state(struct ath_softc *sc,
522 struct ath_chanctx *ctx);
399 523
400/*******************/ 524/*******************/
401/* Beacon Handling */ 525/* Beacon Handling */
@@ -458,6 +582,7 @@ void ath9k_csa_update(struct ath_softc *sc);
458#define ATH_PAPRD_TIMEOUT 100 /* msecs */ 582#define ATH_PAPRD_TIMEOUT 100 /* msecs */
459#define ATH_PLL_WORK_INTERVAL 100 583#define ATH_PLL_WORK_INTERVAL 100
460 584
585void ath_chanctx_work(struct work_struct *work);
461void ath_tx_complete_poll_work(struct work_struct *work); 586void ath_tx_complete_poll_work(struct work_struct *work);
462void ath_reset_work(struct work_struct *work); 587void ath_reset_work(struct work_struct *work);
463bool ath_hw_check(struct ath_softc *sc); 588bool ath_hw_check(struct ath_softc *sc);
@@ -473,6 +598,7 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
473void ath_ps_full_sleep(unsigned long data); 598void ath_ps_full_sleep(unsigned long data);
474void ath9k_p2p_ps_timer(void *priv); 599void ath9k_p2p_ps_timer(void *priv);
475void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif); 600void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif);
601void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop);
476 602
477/**********/ 603/**********/
478/* BTCOEX */ 604/* BTCOEX */
@@ -702,6 +828,8 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
702#define PS_BEACON_SYNC BIT(4) 828#define PS_BEACON_SYNC BIT(4)
703#define PS_WAIT_FOR_ANI BIT(5) 829#define PS_WAIT_FOR_ANI BIT(5)
704 830
831#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
832
705struct ath_softc { 833struct ath_softc {
706 struct ieee80211_hw *hw; 834 struct ieee80211_hw *hw;
707 struct device *dev; 835 struct device *dev;
@@ -720,6 +848,7 @@ struct ath_softc {
720 struct mutex mutex; 848 struct mutex mutex;
721 struct work_struct paprd_work; 849 struct work_struct paprd_work;
722 struct work_struct hw_reset_work; 850 struct work_struct hw_reset_work;
851 struct work_struct chanctx_work;
723 struct completion paprd_complete; 852 struct completion paprd_complete;
724 wait_queue_head_t tx_wait; 853 wait_queue_head_t tx_wait;
725 854
@@ -738,23 +867,27 @@ struct ath_softc {
738 short nvifs; 867 short nvifs;
739 unsigned long ps_usecount; 868 unsigned long ps_usecount;
740 869
741 struct ath_config config;
742 struct ath_rx rx; 870 struct ath_rx rx;
743 struct ath_tx tx; 871 struct ath_tx tx;
744 struct ath_beacon beacon; 872 struct ath_beacon beacon;
745 873
874 struct cfg80211_chan_def cur_chandef;
875 struct ath_chanctx chanctx[ATH9K_NUM_CHANCTX];
876 struct ath_chanctx *cur_chan;
877 struct ath_chanctx *next_chan;
878 spinlock_t chan_lock;
879 struct ath_offchannel offchannel;
880 struct ath_chanctx_sched sched;
881
746#ifdef CONFIG_MAC80211_LEDS 882#ifdef CONFIG_MAC80211_LEDS
747 bool led_registered; 883 bool led_registered;
748 char led_name[32]; 884 char led_name[32];
749 struct led_classdev led_cdev; 885 struct led_classdev led_cdev;
750#endif 886#endif
751 887
752 struct ath9k_hw_cal_data caldata;
753
754#ifdef CONFIG_ATH9K_DEBUGFS 888#ifdef CONFIG_ATH9K_DEBUGFS
755 struct ath9k_debug debug; 889 struct ath9k_debug debug;
756#endif 890#endif
757 struct ath_beacon_config cur_beacon_conf;
758 struct delayed_work tx_complete_work; 891 struct delayed_work tx_complete_work;
759 struct delayed_work hw_pll_work; 892 struct delayed_work hw_pll_work;
760 struct timer_list sleep_timer; 893 struct timer_list sleep_timer;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index e387f0b2954a..eaf8f058c151 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -80,7 +80,7 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
80 u8 chainmask = ah->txchainmask; 80 u8 chainmask = ah->txchainmask;
81 u8 rate = 0; 81 u8 rate = 0;
82 82
83 sband = &common->sbands[common->hw->conf.chandef.chan->band]; 83 sband = &common->sbands[sc->cur_chandef.chan->band];
84 rate = sband->bitrates[rateidx].hw_value; 84 rate = sband->bitrates[rateidx].hw_value;
85 if (vif->bss_conf.use_short_preamble) 85 if (vif->bss_conf.use_short_preamble)
86 rate |= sband->bitrates[rateidx].hw_value_short; 86 rate |= sband->bitrates[rateidx].hw_value_short;
@@ -108,6 +108,55 @@ static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif,
108 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); 108 ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
109} 109}
110 110
111static void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
112 struct sk_buff *skb)
113{
114 static const u8 noa_ie_hdr[] = {
115 WLAN_EID_VENDOR_SPECIFIC, /* type */
116 0, /* length */
117 0x50, 0x6f, 0x9a, /* WFA OUI */
118 0x09, /* P2P subtype */
119 0x0c, /* Notice of Absence */
120 0x00, /* LSB of little-endian len */
121 0x00, /* MSB of little-endian len */
122 };
123
124 struct ieee80211_p2p_noa_attr *noa;
125 int noa_len, noa_desc, i = 0;
126 u8 *hdr;
127
128 if (!avp->offchannel_duration && !avp->periodic_noa_duration)
129 return;
130
131 noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration;
132 noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc;
133
134 hdr = skb_put(skb, sizeof(noa_ie_hdr));
135 memcpy(hdr, noa_ie_hdr, sizeof(noa_ie_hdr));
136 hdr[1] = sizeof(noa_ie_hdr) + noa_len - 2;
137 hdr[7] = noa_len;
138
139 noa = (void *) skb_put(skb, noa_len);
140 memset(noa, 0, noa_len);
141
142 noa->index = avp->noa_index;
143 if (avp->periodic_noa_duration) {
144 u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
145
146 noa->desc[i].count = 255;
147 noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start);
148 noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration);
149 noa->desc[i].interval = cpu_to_le32(interval);
150 i++;
151 }
152
153 if (avp->offchannel_duration) {
154 noa->desc[i].count = 1;
155 noa->desc[i].start_time = cpu_to_le32(avp->offchannel_start);
156 noa->desc[i].duration = cpu_to_le32(avp->offchannel_duration);
157 }
158}
159
111static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, 160static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
112 struct ieee80211_vif *vif) 161 struct ieee80211_vif *vif)
113{ 162{
@@ -155,6 +204,9 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
155 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); 204 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
156 } 205 }
157 206
207 if (vif->p2p)
208 ath9k_beacon_add_noa(sc, avp, skb);
209
158 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, 210 bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
159 skb->len, DMA_TO_DEVICE); 211 skb->len, DMA_TO_DEVICE);
160 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { 212 if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
@@ -249,7 +301,7 @@ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif)
249static int ath9k_beacon_choose_slot(struct ath_softc *sc) 301static int ath9k_beacon_choose_slot(struct ath_softc *sc)
250{ 302{
251 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 303 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
252 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 304 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
253 u16 intval; 305 u16 intval;
254 u32 tsftu; 306 u32 tsftu;
255 u64 tsf; 307 u64 tsf;
@@ -277,8 +329,8 @@ static int ath9k_beacon_choose_slot(struct ath_softc *sc)
277static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) 329static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif)
278{ 330{
279 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 331 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
280 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
281 struct ath_vif *avp = (void *)vif->drv_priv; 332 struct ath_vif *avp = (void *)vif->drv_priv;
333 struct ath_beacon_config *cur_conf = &avp->chanctx->beacon;
282 u32 tsfadjust; 334 u32 tsfadjust;
283 335
284 if (avp->av_bslot == 0) 336 if (avp->av_bslot == 0)
@@ -374,12 +426,19 @@ void ath9k_beacon_tasklet(unsigned long data)
374 vif = sc->beacon.bslot[slot]; 426 vif = sc->beacon.bslot[slot];
375 427
376 /* EDMA devices check that in the tx completion function. */ 428 /* EDMA devices check that in the tx completion function. */
377 if (!edma && ath9k_csa_is_finished(sc, vif)) 429 if (!edma) {
378 return; 430 if (sc->sched.beacon_pending)
431 ath_chanctx_event(sc, NULL,
432 ATH_CHANCTX_EVENT_BEACON_SENT);
433
434 if (ath9k_csa_is_finished(sc, vif))
435 return;
436 }
379 437
380 if (!vif || !vif->bss_conf.enable_beacon) 438 if (!vif || !vif->bss_conf.enable_beacon)
381 return; 439 return;
382 440
441 ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_BEACON_PREPARE);
383 bf = ath9k_beacon_generate(sc->hw, vif); 442 bf = ath9k_beacon_generate(sc->hw, vif);
384 443
385 if (sc->beacon.bmisscnt != 0) { 444 if (sc->beacon.bmisscnt != 0) {
@@ -500,7 +559,6 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
500 struct ieee80211_vif *vif) 559 struct ieee80211_vif *vif)
501{ 560{
502 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 561 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
503 struct ath_vif *avp = (void *)vif->drv_priv;
504 562
505 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 563 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
506 if ((vif->type != NL80211_IFTYPE_AP) || 564 if ((vif->type != NL80211_IFTYPE_AP) ||
@@ -514,7 +572,7 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
514 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { 572 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) {
515 if ((vif->type == NL80211_IFTYPE_STATION) && 573 if ((vif->type == NL80211_IFTYPE_STATION) &&
516 test_bit(ATH_OP_BEACONS, &common->op_flags) && 574 test_bit(ATH_OP_BEACONS, &common->op_flags) &&
517 !avp->primary_sta_vif) { 575 vif != sc->cur_chan->primary_sta) {
518 ath_dbg(common, CONFIG, 576 ath_dbg(common, CONFIG,
519 "Beacon already configured for a station interface\n"); 577 "Beacon already configured for a station interface\n");
520 return false; 578 return false;
@@ -525,10 +583,11 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
525} 583}
526 584
527static void ath9k_cache_beacon_config(struct ath_softc *sc, 585static void ath9k_cache_beacon_config(struct ath_softc *sc,
586 struct ath_chanctx *ctx,
528 struct ieee80211_bss_conf *bss_conf) 587 struct ieee80211_bss_conf *bss_conf)
529{ 588{
530 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 589 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
531 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 590 struct ath_beacon_config *cur_conf = &ctx->beacon;
532 591
533 ath_dbg(common, BEACON, 592 ath_dbg(common, BEACON,
534 "Caching beacon data for BSS: %pM\n", bss_conf->bssid); 593 "Caching beacon data for BSS: %pM\n", bss_conf->bssid);
@@ -564,20 +623,29 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
564 u32 changed) 623 u32 changed)
565{ 624{
566 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 625 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
567 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
568 struct ath_hw *ah = sc->sc_ah; 626 struct ath_hw *ah = sc->sc_ah;
569 struct ath_common *common = ath9k_hw_common(ah); 627 struct ath_common *common = ath9k_hw_common(ah);
628 struct ath_vif *avp = (void *)vif->drv_priv;
629 struct ath_chanctx *ctx = avp->chanctx;
630 struct ath_beacon_config *cur_conf;
570 unsigned long flags; 631 unsigned long flags;
571 bool skip_beacon = false; 632 bool skip_beacon = false;
572 633
634 if (!ctx)
635 return;
636
637 cur_conf = &avp->chanctx->beacon;
573 if (vif->type == NL80211_IFTYPE_AP) 638 if (vif->type == NL80211_IFTYPE_AP)
574 ath9k_set_tsfadjust(sc, vif); 639 ath9k_set_tsfadjust(sc, vif);
575 640
576 if (!ath9k_allow_beacon_config(sc, vif)) 641 if (!ath9k_allow_beacon_config(sc, vif))
577 return; 642 return;
578 643
579 if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { 644 if (vif->type == NL80211_IFTYPE_STATION) {
580 ath9k_cache_beacon_config(sc, bss_conf); 645 ath9k_cache_beacon_config(sc, ctx, bss_conf);
646 if (ctx != sc->cur_chan)
647 return;
648
581 ath9k_set_beacon(sc); 649 ath9k_set_beacon(sc);
582 set_bit(ATH_OP_BEACONS, &common->op_flags); 650 set_bit(ATH_OP_BEACONS, &common->op_flags);
583 return; 651 return;
@@ -593,10 +661,13 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
593 cur_conf->enable_beacon = false; 661 cur_conf->enable_beacon = false;
594 } else if (bss_conf->enable_beacon) { 662 } else if (bss_conf->enable_beacon) {
595 cur_conf->enable_beacon = true; 663 cur_conf->enable_beacon = true;
596 ath9k_cache_beacon_config(sc, bss_conf); 664 ath9k_cache_beacon_config(sc, ctx, bss_conf);
597 } 665 }
598 } 666 }
599 667
668 if (ctx != sc->cur_chan)
669 return;
670
600 /* 671 /*
601 * Configure the HW beacon registers only when we have a valid 672 * Configure the HW beacon registers only when we have a valid
602 * beacon interval. 673 * beacon interval.
@@ -631,7 +702,7 @@ void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif,
631void ath9k_set_beacon(struct ath_softc *sc) 702void ath9k_set_beacon(struct ath_softc *sc)
632{ 703{
633 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 704 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
634 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 705 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
635 706
636 switch (sc->sc_ah->opmode) { 707 switch (sc->sc_ah->opmode) {
637 case NL80211_IFTYPE_AP: 708 case NL80211_IFTYPE_AP:
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
new file mode 100644
index 000000000000..ba214ebdcd16
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -0,0 +1,685 @@
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 "ath9k.h"
18
19/* Set/change channels. If the channel is really being changed, it's done
20 * by reseting the chip. To accomplish this we must first cleanup any pending
21 * DMA, then restart stuff.
22 */
23static int ath_set_channel(struct ath_softc *sc)
24{
25 struct ath_hw *ah = sc->sc_ah;
26 struct ath_common *common = ath9k_hw_common(ah);
27 struct ieee80211_hw *hw = sc->hw;
28 struct ath9k_channel *hchan;
29 struct cfg80211_chan_def *chandef = &sc->cur_chan->chandef;
30 struct ieee80211_channel *chan = chandef->chan;
31 int pos = chan->hw_value;
32 int old_pos = -1;
33 int r;
34
35 if (test_bit(ATH_OP_INVALID, &common->op_flags))
36 return -EIO;
37
38 if (ah->curchan)
39 old_pos = ah->curchan - &ah->channels[0];
40
41 ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
42 chan->center_freq, chandef->width);
43
44 /* update survey stats for the old channel before switching */
45 spin_lock_bh(&common->cc_lock);
46 ath_update_survey_stats(sc);
47 spin_unlock_bh(&common->cc_lock);
48
49 ath9k_cmn_get_channel(hw, ah, chandef);
50
51 /* If the operating channel changes, change the survey in-use flags
52 * along with it.
53 * Reset the survey data for the new channel, unless we're switching
54 * back to the operating channel from an off-channel operation.
55 */
56 if (!sc->cur_chan->offchannel && sc->cur_survey != &sc->survey[pos]) {
57 if (sc->cur_survey)
58 sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
59
60 sc->cur_survey = &sc->survey[pos];
61
62 memset(sc->cur_survey, 0, sizeof(struct survey_info));
63 sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
64 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
65 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
66 }
67
68 hchan = &sc->sc_ah->channels[pos];
69 r = ath_reset_internal(sc, hchan);
70 if (r)
71 return r;
72
73 /* The most recent snapshot of channel->noisefloor for the old
74 * channel is only available after the hardware reset. Copy it to
75 * the survey stats now.
76 */
77 if (old_pos >= 0)
78 ath_update_survey_nf(sc, old_pos);
79
80 /* Enable radar pulse detection if on a DFS channel. Spectral
81 * scanning and radar detection can not be used concurrently.
82 */
83 if (hw->conf.radar_enabled) {
84 u32 rxfilter;
85
86 /* set HW specific DFS configuration */
87 ath9k_hw_set_radar_params(ah);
88 rxfilter = ath9k_hw_getrxfilter(ah);
89 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
90 ATH9K_RX_FILTER_PHYERR;
91 ath9k_hw_setrxfilter(ah, rxfilter);
92 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
93 chan->center_freq);
94 } else {
95 /* perform spectral scan if requested. */
96 if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
97 sc->spectral_mode == SPECTRAL_CHANSCAN)
98 ath9k_spectral_scan_trigger(hw);
99 }
100
101 return 0;
102}
103
104static bool
105ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
106 bool powersave)
107{
108 struct ieee80211_vif *vif = avp->vif;
109 struct ieee80211_sta *sta = NULL;
110 struct ieee80211_hdr_3addr *nullfunc;
111 struct ath_tx_control txctl;
112 struct sk_buff *skb;
113 int band = sc->cur_chan->chandef.chan->band;
114
115 switch (vif->type) {
116 case NL80211_IFTYPE_STATION:
117 if (!vif->bss_conf.assoc)
118 return false;
119
120 skb = ieee80211_nullfunc_get(sc->hw, vif);
121 if (!skb)
122 return false;
123
124 nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
125 if (powersave)
126 nullfunc->frame_control |=
127 cpu_to_le16(IEEE80211_FCTL_PM);
128
129 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
130 if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
131 dev_kfree_skb_any(skb);
132 return false;
133 }
134 break;
135 default:
136 return false;
137 }
138
139 memset(&txctl, 0, sizeof(txctl));
140 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
141 txctl.sta = sta;
142 txctl.force_channel = true;
143 if (ath_tx_start(sc->hw, skb, &txctl)) {
144 ieee80211_free_txskb(sc->hw, skb);
145 return false;
146 }
147
148 return true;
149}
150
151void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx)
152{
153 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
154 struct ath_vif *avp;
155 bool active = false;
156 u8 n_active = 0;
157
158 if (!ctx)
159 return;
160
161 list_for_each_entry(avp, &ctx->vifs, list) {
162 struct ieee80211_vif *vif = avp->vif;
163
164 switch (vif->type) {
165 case NL80211_IFTYPE_P2P_CLIENT:
166 case NL80211_IFTYPE_STATION:
167 if (vif->bss_conf.assoc)
168 active = true;
169 break;
170 default:
171 active = true;
172 break;
173 }
174 }
175 ctx->active = active;
176
177 ath_for_each_chanctx(sc, ctx) {
178 if (!ctx->assigned || list_empty(&ctx->vifs))
179 continue;
180 n_active++;
181 }
182
183 if (n_active <= 1) {
184 clear_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags);
185 return;
186 }
187 if (test_and_set_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
188 return;
189 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL);
190}
191
192static bool
193ath_chanctx_send_ps_frame(struct ath_softc *sc, bool powersave)
194{
195 struct ath_vif *avp;
196 bool sent = false;
197
198 rcu_read_lock();
199 list_for_each_entry(avp, &sc->cur_chan->vifs, list) {
200 if (ath_chanctx_send_vif_ps_frame(sc, avp, powersave))
201 sent = true;
202 }
203 rcu_read_unlock();
204
205 return sent;
206}
207
208static bool ath_chanctx_defer_switch(struct ath_softc *sc)
209{
210 if (sc->cur_chan == &sc->offchannel.chan)
211 return false;
212
213 switch (sc->sched.state) {
214 case ATH_CHANCTX_STATE_SWITCH:
215 return false;
216 case ATH_CHANCTX_STATE_IDLE:
217 if (!sc->cur_chan->switch_after_beacon)
218 return false;
219
220 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
221 break;
222 default:
223 break;
224 }
225
226 return true;
227}
228
229static void ath_chanctx_set_next(struct ath_softc *sc, bool force)
230{
231 struct timespec ts;
232 bool measure_time = false;
233 bool send_ps = false;
234
235 spin_lock_bh(&sc->chan_lock);
236 if (!sc->next_chan) {
237 spin_unlock_bh(&sc->chan_lock);
238 return;
239 }
240
241 if (!force && ath_chanctx_defer_switch(sc)) {
242 spin_unlock_bh(&sc->chan_lock);
243 return;
244 }
245
246 if (sc->cur_chan != sc->next_chan) {
247 sc->cur_chan->stopped = true;
248 spin_unlock_bh(&sc->chan_lock);
249
250 if (sc->next_chan == &sc->offchannel.chan) {
251 getrawmonotonic(&ts);
252 measure_time = true;
253 }
254 __ath9k_flush(sc->hw, ~0, true);
255
256 if (ath_chanctx_send_ps_frame(sc, true))
257 __ath9k_flush(sc->hw, BIT(IEEE80211_AC_VO), false);
258
259 send_ps = true;
260 spin_lock_bh(&sc->chan_lock);
261
262 if (sc->cur_chan != &sc->offchannel.chan) {
263 getrawmonotonic(&sc->cur_chan->tsf_ts);
264 sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah);
265 }
266 }
267 sc->cur_chan = sc->next_chan;
268 sc->cur_chan->stopped = false;
269 sc->next_chan = NULL;
270 sc->sched.offchannel_duration = 0;
271 if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE)
272 sc->sched.state = ATH_CHANCTX_STATE_IDLE;
273
274 spin_unlock_bh(&sc->chan_lock);
275
276 if (sc->sc_ah->chip_fullsleep ||
277 memcmp(&sc->cur_chandef, &sc->cur_chan->chandef,
278 sizeof(sc->cur_chandef))) {
279 ath_set_channel(sc);
280 if (measure_time)
281 sc->sched.channel_switch_time =
282 ath9k_hw_get_tsf_offset(&ts, NULL);
283 }
284 if (send_ps)
285 ath_chanctx_send_ps_frame(sc, false);
286
287 ath_offchannel_channel_change(sc);
288 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_SWITCH);
289}
290
291void ath_chanctx_work(struct work_struct *work)
292{
293 struct ath_softc *sc = container_of(work, struct ath_softc,
294 chanctx_work);
295 mutex_lock(&sc->mutex);
296 ath_chanctx_set_next(sc, false);
297 mutex_unlock(&sc->mutex);
298}
299
300void ath_chanctx_init(struct ath_softc *sc)
301{
302 struct ath_chanctx *ctx;
303 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
304 struct ieee80211_supported_band *sband;
305 struct ieee80211_channel *chan;
306 int i, j;
307
308 sband = &common->sbands[IEEE80211_BAND_2GHZ];
309 if (!sband->n_channels)
310 sband = &common->sbands[IEEE80211_BAND_5GHZ];
311
312 chan = &sband->channels[0];
313 for (i = 0; i < ATH9K_NUM_CHANCTX; i++) {
314 ctx = &sc->chanctx[i];
315 cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
316 INIT_LIST_HEAD(&ctx->vifs);
317 ctx->txpower = ATH_TXPOWER_MAX;
318 for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
319 INIT_LIST_HEAD(&ctx->acq[j]);
320 }
321 ctx = &sc->offchannel.chan;
322 cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
323 INIT_LIST_HEAD(&ctx->vifs);
324 ctx->txpower = ATH_TXPOWER_MAX;
325 for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
326 INIT_LIST_HEAD(&ctx->acq[j]);
327 sc->offchannel.chan.offchannel = true;
328
329}
330
331void ath9k_chanctx_force_active(struct ieee80211_hw *hw,
332 struct ieee80211_vif *vif)
333{
334 struct ath_softc *sc = hw->priv;
335 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
336 struct ath_vif *avp = (struct ath_vif *) vif->drv_priv;
337 bool changed = false;
338
339 if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
340 return;
341
342 if (!avp->chanctx)
343 return;
344
345 mutex_lock(&sc->mutex);
346
347 spin_lock_bh(&sc->chan_lock);
348 if (sc->next_chan || (sc->cur_chan != avp->chanctx)) {
349 sc->next_chan = avp->chanctx;
350 changed = true;
351 }
352 sc->sched.state = ATH_CHANCTX_STATE_FORCE_ACTIVE;
353 spin_unlock_bh(&sc->chan_lock);
354
355 if (changed)
356 ath_chanctx_set_next(sc, true);
357
358 mutex_unlock(&sc->mutex);
359}
360
361void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
362 struct cfg80211_chan_def *chandef)
363{
364 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
365
366 spin_lock_bh(&sc->chan_lock);
367
368 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&
369 (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {
370 sc->sched.offchannel_pending = true;
371 spin_unlock_bh(&sc->chan_lock);
372 return;
373 }
374
375 sc->next_chan = ctx;
376 if (chandef)
377 ctx->chandef = *chandef;
378
379 if (sc->next_chan == &sc->offchannel.chan) {
380 sc->sched.offchannel_duration =
381 TU_TO_USEC(sc->offchannel.duration) +
382 sc->sched.channel_switch_time;
383 }
384 spin_unlock_bh(&sc->chan_lock);
385 ieee80211_queue_work(sc->hw, &sc->chanctx_work);
386}
387
388void ath_chanctx_set_channel(struct ath_softc *sc, struct ath_chanctx *ctx,
389 struct cfg80211_chan_def *chandef)
390{
391 bool cur_chan;
392
393 spin_lock_bh(&sc->chan_lock);
394 if (chandef)
395 memcpy(&ctx->chandef, chandef, sizeof(*chandef));
396 cur_chan = sc->cur_chan == ctx;
397 spin_unlock_bh(&sc->chan_lock);
398
399 if (!cur_chan)
400 return;
401
402 ath_set_channel(sc);
403}
404
405struct ath_chanctx *ath_chanctx_get_oper_chan(struct ath_softc *sc, bool active)
406{
407 struct ath_chanctx *ctx;
408
409 ath_for_each_chanctx(sc, ctx) {
410 if (!ctx->assigned || list_empty(&ctx->vifs))
411 continue;
412 if (active && !ctx->active)
413 continue;
414
415 if (ctx->switch_after_beacon)
416 return ctx;
417 }
418
419 return &sc->chanctx[0];
420}
421
422void ath_chanctx_offchan_switch(struct ath_softc *sc,
423 struct ieee80211_channel *chan)
424{
425 struct cfg80211_chan_def chandef;
426
427 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_NO_HT);
428
429 ath_chanctx_switch(sc, &sc->offchannel.chan, &chandef);
430}
431
432static struct ath_chanctx *
433ath_chanctx_get_next(struct ath_softc *sc, struct ath_chanctx *ctx)
434{
435 int idx = ctx - &sc->chanctx[0];
436
437 return &sc->chanctx[!idx];
438}
439
440static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc)
441{
442 struct ath_chanctx *prev, *cur;
443 struct timespec ts;
444 u32 cur_tsf, prev_tsf, beacon_int;
445 s32 offset;
446
447 beacon_int = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
448
449 cur = sc->cur_chan;
450 prev = ath_chanctx_get_next(sc, cur);
451
452 getrawmonotonic(&ts);
453 cur_tsf = (u32) cur->tsf_val +
454 ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts);
455
456 prev_tsf = prev->last_beacon - (u32) prev->tsf_val + cur_tsf;
457 prev_tsf -= ath9k_hw_get_tsf_offset(&prev->tsf_ts, &ts);
458
459 /* Adjust the TSF time of the AP chanctx to keep its beacons
460 * at half beacon interval offset relative to the STA chanctx.
461 */
462 offset = cur_tsf - prev_tsf;
463
464 /* Ignore stale data or spurious timestamps */
465 if (offset < 0 || offset > 3 * beacon_int)
466 return;
467
468 offset = beacon_int / 2 - (offset % beacon_int);
469 prev->tsf_val += offset;
470}
471
472void ath_chanctx_timer(unsigned long data)
473{
474 struct ath_softc *sc = (struct ath_softc *) data;
475
476 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
477}
478
479/* Configure the TSF based hardware timer for a channel switch.
480 * Also set up backup software timer, in case the gen timer fails.
481 * This could be caused by a hardware reset.
482 */
483static void ath_chanctx_setup_timer(struct ath_softc *sc, u32 tsf_time)
484{
485 struct ath_hw *ah = sc->sc_ah;
486
487 ath9k_hw_gen_timer_start(ah, sc->p2p_ps_timer, tsf_time, 1000000);
488 tsf_time -= ath9k_hw_gettsf32(ah);
489 tsf_time = msecs_to_jiffies(tsf_time / 1000) + 1;
490 mod_timer(&sc->sched.timer, tsf_time);
491}
492
493void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
494 enum ath_chanctx_event ev)
495{
496 struct ath_hw *ah = sc->sc_ah;
497 struct ath_common *common = ath9k_hw_common(ah);
498 struct ath_beacon_config *cur_conf;
499 struct ath_vif *avp = NULL;
500 struct ath_chanctx *ctx;
501 u32 tsf_time;
502 u32 beacon_int;
503 bool noa_changed = false;
504
505 if (vif)
506 avp = (struct ath_vif *) vif->drv_priv;
507
508 spin_lock_bh(&sc->chan_lock);
509
510 switch (ev) {
511 case ATH_CHANCTX_EVENT_BEACON_PREPARE:
512 if (avp->offchannel_duration)
513 avp->offchannel_duration = 0;
514
515 if (avp->chanctx != sc->cur_chan)
516 break;
517
518 if (sc->sched.offchannel_pending) {
519 sc->sched.offchannel_pending = false;
520 sc->next_chan = &sc->offchannel.chan;
521 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
522 }
523
524 ctx = ath_chanctx_get_next(sc, sc->cur_chan);
525 if (ctx->active && sc->sched.state == ATH_CHANCTX_STATE_IDLE) {
526 sc->next_chan = ctx;
527 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
528 }
529
530 /* if the timer missed its window, use the next interval */
531 if (sc->sched.state == ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
532 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
533
534 if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
535 break;
536
537 sc->sched.beacon_pending = true;
538 sc->sched.next_tbtt = REG_READ(ah, AR_NEXT_TBTT_TIMER);
539
540 cur_conf = &sc->cur_chan->beacon;
541 beacon_int = TU_TO_USEC(cur_conf->beacon_interval);
542
543 /* defer channel switch by a quarter beacon interval */
544 tsf_time = sc->sched.next_tbtt + beacon_int / 4;
545 sc->sched.switch_start_time = tsf_time;
546 sc->cur_chan->last_beacon = sc->sched.next_tbtt;
547
548 /* Prevent wrap-around issues */
549 if (avp->periodic_noa_duration &&
550 tsf_time - avp->periodic_noa_start > BIT(30))
551 avp->periodic_noa_duration = 0;
552
553 if (ctx->active && !avp->periodic_noa_duration) {
554 avp->periodic_noa_start = tsf_time;
555 avp->periodic_noa_duration =
556 TU_TO_USEC(cur_conf->beacon_interval) / 2 -
557 sc->sched.channel_switch_time;
558 noa_changed = true;
559 } else if (!ctx->active && avp->periodic_noa_duration) {
560 avp->periodic_noa_duration = 0;
561 noa_changed = true;
562 }
563
564 /* If at least two consecutive beacons were missed on the STA
565 * chanctx, stay on the STA channel for one extra beacon period,
566 * to resync the timer properly.
567 */
568 if (ctx->active && sc->sched.beacon_miss >= 2)
569 sc->sched.offchannel_duration = 3 * beacon_int / 2;
570
571 if (sc->sched.offchannel_duration) {
572 noa_changed = true;
573 avp->offchannel_start = tsf_time;
574 avp->offchannel_duration =
575 sc->sched.offchannel_duration;
576 }
577
578 if (noa_changed)
579 avp->noa_index++;
580 break;
581 case ATH_CHANCTX_EVENT_BEACON_SENT:
582 if (!sc->sched.beacon_pending)
583 break;
584
585 sc->sched.beacon_pending = false;
586 if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_BEACON)
587 break;
588
589 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
590 ath_chanctx_setup_timer(sc, sc->sched.switch_start_time);
591 break;
592 case ATH_CHANCTX_EVENT_TSF_TIMER:
593 if (sc->sched.state != ATH_CHANCTX_STATE_WAIT_FOR_TIMER)
594 break;
595
596 if (!sc->cur_chan->switch_after_beacon &&
597 sc->sched.beacon_pending)
598 sc->sched.beacon_miss++;
599
600 sc->sched.state = ATH_CHANCTX_STATE_SWITCH;
601 ieee80211_queue_work(sc->hw, &sc->chanctx_work);
602 break;
603 case ATH_CHANCTX_EVENT_BEACON_RECEIVED:
604 if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
605 sc->cur_chan == &sc->offchannel.chan)
606 break;
607
608 ath_chanctx_adjust_tbtt_delta(sc);
609 sc->sched.beacon_pending = false;
610 sc->sched.beacon_miss = 0;
611
612 /* TSF time might have been updated by the incoming beacon,
613 * need update the channel switch timer to reflect the change.
614 */
615 tsf_time = sc->sched.switch_start_time;
616 tsf_time -= (u32) sc->cur_chan->tsf_val +
617 ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL);
618 tsf_time += ath9k_hw_gettsf32(ah);
619
620
621 ath_chanctx_setup_timer(sc, tsf_time);
622 break;
623 case ATH_CHANCTX_EVENT_ASSOC:
624 if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE ||
625 avp->chanctx != sc->cur_chan)
626 break;
627
628 sc->sched.state = ATH_CHANCTX_STATE_IDLE;
629 /* fall through */
630 case ATH_CHANCTX_EVENT_SWITCH:
631 if (!test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) ||
632 sc->sched.state == ATH_CHANCTX_STATE_FORCE_ACTIVE ||
633 sc->cur_chan->switch_after_beacon ||
634 sc->cur_chan == &sc->offchannel.chan)
635 break;
636
637 /* If this is a station chanctx, stay active for a half
638 * beacon period (minus channel switch time)
639 */
640 sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
641 cur_conf = &sc->cur_chan->beacon;
642
643 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
644
645 tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;
646 if (sc->sched.beacon_miss >= 2) {
647 sc->sched.beacon_miss = 0;
648 tsf_time *= 3;
649 }
650
651 tsf_time -= sc->sched.channel_switch_time;
652 tsf_time += ath9k_hw_gettsf32(sc->sc_ah);
653 sc->sched.switch_start_time = tsf_time;
654
655 ath_chanctx_setup_timer(sc, tsf_time);
656 sc->sched.beacon_pending = true;
657 break;
658 case ATH_CHANCTX_EVENT_ENABLE_MULTICHANNEL:
659 if (sc->cur_chan == &sc->offchannel.chan ||
660 sc->cur_chan->switch_after_beacon)
661 break;
662
663 sc->next_chan = ath_chanctx_get_next(sc, sc->cur_chan);
664 ieee80211_queue_work(sc->hw, &sc->chanctx_work);
665 break;
666 case ATH_CHANCTX_EVENT_UNASSIGN:
667 if (sc->cur_chan->assigned) {
668 if (sc->next_chan && !sc->next_chan->assigned &&
669 sc->next_chan != &sc->offchannel.chan)
670 sc->sched.state = ATH_CHANCTX_STATE_IDLE;
671 break;
672 }
673
674 ctx = ath_chanctx_get_next(sc, sc->cur_chan);
675 sc->sched.state = ATH_CHANCTX_STATE_IDLE;
676 if (!ctx->assigned)
677 break;
678
679 sc->next_chan = ctx;
680 ieee80211_queue_work(sc->hw, &sc->chanctx_work);
681 break;
682 }
683
684 spin_unlock_bh(&sc->chan_lock);
685}
diff --git a/drivers/net/wireless/ath/ath9k/common-beacon.c b/drivers/net/wireless/ath/ath9k/common-beacon.c
index 775d1d20ce0b..733be5178481 100644
--- a/drivers/net/wireless/ath/ath9k/common-beacon.c
+++ b/drivers/net/wireless/ath/ath9k/common-beacon.c
@@ -57,7 +57,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
57 struct ath9k_beacon_state *bs) 57 struct ath9k_beacon_state *bs)
58{ 58{
59 struct ath_common *common = ath9k_hw_common(ah); 59 struct ath_common *common = ath9k_hw_common(ah);
60 int dtim_intval; 60 int dtim_intval, sleepduration;
61 u64 tsf; 61 u64 tsf;
62 62
63 /* No need to configure beacon if we are not associated */ 63 /* No need to configure beacon if we are not associated */
@@ -75,6 +75,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
75 * last beacon we received (which may be none). 75 * last beacon we received (which may be none).
76 */ 76 */
77 dtim_intval = conf->intval * conf->dtim_period; 77 dtim_intval = conf->intval * conf->dtim_period;
78 sleepduration = ah->hw->conf.listen_interval * conf->intval;
78 79
79 /* 80 /*
80 * Pull nexttbtt forward to reflect the current 81 * Pull nexttbtt forward to reflect the current
@@ -112,7 +113,7 @@ int ath9k_cmn_beacon_config_sta(struct ath_hw *ah,
112 */ 113 */
113 114
114 bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100), 115 bs->bs_sleepduration = TU_TO_USEC(roundup(IEEE80211_MS_TO_TU(100),
115 conf->intval)); 116 sleepduration));
116 if (bs->bs_sleepduration > bs->bs_dtimperiod) 117 if (bs->bs_sleepduration > bs->bs_dtimperiod)
117 bs->bs_sleepduration = bs->bs_dtimperiod; 118 bs->bs_sleepduration = bs->bs_dtimperiod;
118 119
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 6cc42be48d4e..ce073e995dfe 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -750,13 +750,13 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
750{ 750{
751 struct ath_softc *sc = file->private_data; 751 struct ath_softc *sc = file->private_data;
752 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 752 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
753 struct ieee80211_hw *hw = sc->hw;
754 struct ath9k_vif_iter_data iter_data; 753 struct ath9k_vif_iter_data iter_data;
754 struct ath_chanctx *ctx;
755 char buf[512]; 755 char buf[512];
756 unsigned int len = 0; 756 unsigned int len = 0;
757 ssize_t retval = 0; 757 ssize_t retval = 0;
758 unsigned int reg; 758 unsigned int reg;
759 u32 rxfilter; 759 u32 rxfilter, i;
760 760
761 len += scnprintf(buf + len, sizeof(buf) - len, 761 len += scnprintf(buf + len, sizeof(buf) - len,
762 "BSSID: %pM\n", common->curbssid); 762 "BSSID: %pM\n", common->curbssid);
@@ -826,14 +826,20 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
826 826
827 len += scnprintf(buf + len, sizeof(buf) - len, "\n"); 827 len += scnprintf(buf + len, sizeof(buf) - len, "\n");
828 828
829 ath9k_calculate_iter_data(hw, NULL, &iter_data); 829 i = 0;
830 830 ath_for_each_chanctx(sc, ctx) {
831 len += scnprintf(buf + len, sizeof(buf) - len, 831 if (!ctx->assigned || list_empty(&ctx->vifs))
832 "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" 832 continue;
833 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", 833 ath9k_calculate_iter_data(sc, ctx, &iter_data);
834 iter_data.naps, iter_data.nstations, iter_data.nmeshes, 834
835 iter_data.nwds, iter_data.nadhocs, 835 len += scnprintf(buf + len, sizeof(buf) - len,
836 sc->nvifs, sc->nbcnvifs); 836 "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i",
837 i++, iter_data.naps, iter_data.nstations,
838 iter_data.nmeshes, iter_data.nwds);
839 len += scnprintf(buf + len, sizeof(buf) - len,
840 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
841 iter_data.nadhocs, sc->nvifs, sc->nbcnvifs);
842 }
837 843
838 if (len > sizeof(buf)) 844 if (len > sizeof(buf))
839 len = sizeof(buf); 845 len = sizeof(buf);
@@ -1080,7 +1086,7 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf,
1080{ 1086{
1081 struct ath_softc *sc = file->private_data; 1087 struct ath_softc *sc = file->private_data;
1082 struct ath_hw *ah = sc->sc_ah; 1088 struct ath_hw *ah = sc->sc_ah;
1083 struct ath9k_nfcal_hist *h = sc->caldata.nfCalHist; 1089 struct ath9k_nfcal_hist *h = sc->cur_chan->caldata.nfCalHist;
1084 struct ath_common *common = ath9k_hw_common(ah); 1090 struct ath_common *common = ath9k_hw_common(ah);
1085 struct ieee80211_conf *conf = &common->hw->conf; 1091 struct ieee80211_conf *conf = &common->hw->conf;
1086 u32 len = 0, size = 1500; 1092 u32 len = 0, size = 1500;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 2a8ed8375ec0..fd0158fdf144 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -791,7 +791,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
791 refdiv = 5; 791 refdiv = 5;
792 } else { 792 } else {
793 pll2_divint = 0x11; 793 pll2_divint = 0x11;
794 pll2_divfrac = 0x26666; 794 pll2_divfrac =
795 AR_SREV_9531(ah) ? 0x26665 : 0x26666;
795 refdiv = 1; 796 refdiv = 1;
796 } 797 }
797 } 798 }
@@ -1730,6 +1731,23 @@ fail:
1730 return -EINVAL; 1731 return -EINVAL;
1731} 1732}
1732 1733
1734u32 ath9k_hw_get_tsf_offset(struct timespec *last, struct timespec *cur)
1735{
1736 struct timespec ts;
1737 s64 usec;
1738
1739 if (!cur) {
1740 getrawmonotonic(&ts);
1741 cur = &ts;
1742 }
1743
1744 usec = cur->tv_sec * 1000000ULL + cur->tv_nsec / 1000;
1745 usec -= last->tv_sec * 1000000ULL + last->tv_nsec / 1000;
1746
1747 return (u32) usec;
1748}
1749EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
1750
1733int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 1751int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1734 struct ath9k_hw_cal_data *caldata, bool fastcc) 1752 struct ath9k_hw_cal_data *caldata, bool fastcc)
1735{ 1753{
@@ -1739,7 +1757,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1739 u32 saveDefAntenna; 1757 u32 saveDefAntenna;
1740 u32 macStaId1; 1758 u32 macStaId1;
1741 u64 tsf = 0; 1759 u64 tsf = 0;
1742 s64 usec = 0;
1743 int r; 1760 int r;
1744 bool start_mci_reset = false; 1761 bool start_mci_reset = false;
1745 bool save_fullsleep = ah->chip_fullsleep; 1762 bool save_fullsleep = ah->chip_fullsleep;
@@ -1785,7 +1802,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1785 /* Save TSF before chip reset, a cold reset clears it */ 1802 /* Save TSF before chip reset, a cold reset clears it */
1786 tsf = ath9k_hw_gettsf64(ah); 1803 tsf = ath9k_hw_gettsf64(ah);
1787 getrawmonotonic(&ts); 1804 getrawmonotonic(&ts);
1788 usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000;
1789 1805
1790 saveLedState = REG_READ(ah, AR_CFG_LED) & 1806 saveLedState = REG_READ(ah, AR_CFG_LED) &
1791 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 1807 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1818,9 +1834,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1818 } 1834 }
1819 1835
1820 /* Restore TSF */ 1836 /* Restore TSF */
1821 getrawmonotonic(&ts); 1837 ath9k_hw_settsf64(ah, tsf + ath9k_hw_get_tsf_offset(&ts, NULL));
1822 usec = ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000 - usec;
1823 ath9k_hw_settsf64(ah, tsf + usec);
1824 1838
1825 if (AR_SREV_9280_20_OR_LATER(ah)) 1839 if (AR_SREV_9280_20_OR_LATER(ah))
1826 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1840 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 0acd4b5a4892..51b4ebe04c04 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1000,6 +1000,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
1000u64 ath9k_hw_gettsf64(struct ath_hw *ah); 1000u64 ath9k_hw_gettsf64(struct ath_hw *ah);
1001void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); 1001void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
1002void ath9k_hw_reset_tsf(struct ath_hw *ah); 1002void ath9k_hw_reset_tsf(struct ath_hw *ah);
1003u32 ath9k_hw_get_tsf_offset(struct timespec *last, struct timespec *cur);
1003void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set); 1004void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set);
1004void ath9k_hw_init_global_settings(struct ath_hw *ah); 1005void ath9k_hw_init_global_settings(struct ath_hw *ah);
1005u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); 1006u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 0246b990fe87..39419ea845cc 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -61,7 +61,7 @@ static int ath9k_ps_enable;
61module_param_named(ps_enable, ath9k_ps_enable, int, 0444); 61module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
62MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); 62MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
63 63
64static int ath9k_use_chanctx; 64int ath9k_use_chanctx;
65module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444); 65module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444);
66MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency"); 66MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency");
67 67
@@ -169,9 +169,9 @@ static void ath9k_reg_notifier(struct wiphy *wiphy,
169 169
170 /* Set tx power */ 170 /* Set tx power */
171 if (ah->curchan) { 171 if (ah->curchan) {
172 sc->config.txpowlimit = 2 * ah->curchan->chan->max_power; 172 sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
173 ath9k_ps_wakeup(sc); 173 ath9k_ps_wakeup(sc);
174 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); 174 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
175 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit; 175 sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
176 /* synchronize DFS detector if regulatory domain changed */ 176 /* synchronize DFS detector if regulatory domain changed */
177 if (sc->dfs_detector != NULL) 177 if (sc->dfs_detector != NULL)
@@ -335,7 +335,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
335 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); 335 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
336 336
337 common->last_rssi = ATH_RSSI_DUMMY_MARKER; 337 common->last_rssi = ATH_RSSI_DUMMY_MARKER;
338 sc->config.txpowlimit = ATH_TXPOWER_MAX;
339 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); 338 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
340 sc->beacon.slottime = ATH9K_SLOT_TIME_9; 339 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
341 340
@@ -511,6 +510,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
511 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); 510 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
512 sc->tx99_power = MAX_RATE_POWER + 1; 511 sc->tx99_power = MAX_RATE_POWER + 1;
513 init_waitqueue_head(&sc->tx_wait); 512 init_waitqueue_head(&sc->tx_wait);
513 sc->cur_chan = &sc->chanctx[0];
514 if (!ath9k_use_chanctx)
515 sc->cur_chan->hw_queue_base = 0;
514 516
515 if (!pdata || pdata->use_eeprom) { 517 if (!pdata || pdata->use_eeprom) {
516 ah->ah_flags |= AH_USE_EEPROM; 518 ah->ah_flags |= AH_USE_EEPROM;
@@ -556,6 +558,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
556 spin_lock_init(&common->cc_lock); 558 spin_lock_init(&common->cc_lock);
557 spin_lock_init(&sc->sc_serial_rw); 559 spin_lock_init(&sc->sc_serial_rw);
558 spin_lock_init(&sc->sc_pm_lock); 560 spin_lock_init(&sc->sc_pm_lock);
561 spin_lock_init(&sc->chan_lock);
559 mutex_init(&sc->mutex); 562 mutex_init(&sc->mutex);
560 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 563 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
561 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 564 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
@@ -564,7 +567,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
564 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); 567 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
565 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 568 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
566 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); 569 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
570 INIT_WORK(&sc->chanctx_work, ath_chanctx_work);
567 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); 571 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
572 setup_timer(&sc->offchannel.timer, ath_offchannel_timer,
573 (unsigned long)sc);
574 setup_timer(&sc->sched.timer, ath_chanctx_timer, (unsigned long)sc);
568 575
569 /* 576 /*
570 * Cache line size is used to size and align various 577 * Cache line size is used to size and align various
@@ -599,6 +606,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
599 ath9k_cmn_init_crypto(sc->sc_ah); 606 ath9k_cmn_init_crypto(sc->sc_ah);
600 ath9k_init_misc(sc); 607 ath9k_init_misc(sc);
601 ath_fill_led_pin(sc); 608 ath_fill_led_pin(sc);
609 ath_chanctx_init(sc);
602 610
603 if (common->bus_ops->aspm_init) 611 if (common->bus_ops->aspm_init)
604 common->bus_ops->aspm_init(common); 612 common->bus_ops->aspm_init(common);
@@ -664,6 +672,12 @@ static const struct ieee80211_iface_limit wds_limits[] = {
664 { .max = 2048, .types = BIT(NL80211_IFTYPE_WDS) }, 672 { .max = 2048, .types = BIT(NL80211_IFTYPE_WDS) },
665}; 673};
666 674
675static const struct ieee80211_iface_limit if_limits_multi[] = {
676 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) },
677 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
678 BIT(NL80211_IFTYPE_P2P_GO) },
679};
680
667static const struct ieee80211_iface_limit if_dfs_limits[] = { 681static const struct ieee80211_iface_limit if_dfs_limits[] = {
668 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | 682 { .max = 1, .types = BIT(NL80211_IFTYPE_AP) |
669#ifdef CONFIG_MAC80211_MESH 683#ifdef CONFIG_MAC80211_MESH
@@ -672,6 +686,16 @@ static const struct ieee80211_iface_limit if_dfs_limits[] = {
672 BIT(NL80211_IFTYPE_ADHOC) }, 686 BIT(NL80211_IFTYPE_ADHOC) },
673}; 687};
674 688
689static const struct ieee80211_iface_combination if_comb_multi[] = {
690 {
691 .limits = if_limits_multi,
692 .n_limits = ARRAY_SIZE(if_limits_multi),
693 .max_interfaces = 2,
694 .num_different_channels = 2,
695 .beacon_int_infra_match = true,
696 },
697};
698
675static const struct ieee80211_iface_combination if_comb[] = { 699static const struct ieee80211_iface_combination if_comb[] = {
676 { 700 {
677 .limits = if_limits, 701 .limits = if_limits,
@@ -712,6 +736,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
712 IEEE80211_HW_SPECTRUM_MGMT | 736 IEEE80211_HW_SPECTRUM_MGMT |
713 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 737 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
714 IEEE80211_HW_SUPPORTS_RC_TABLE | 738 IEEE80211_HW_SUPPORTS_RC_TABLE |
739 IEEE80211_HW_QUEUE_CONTROL |
715 IEEE80211_HW_SUPPORTS_HT_CCK_RATES; 740 IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
716 741
717 if (ath9k_ps_enable) 742 if (ath9k_ps_enable)
@@ -739,12 +764,21 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
739 BIT(NL80211_IFTYPE_STATION) | 764 BIT(NL80211_IFTYPE_STATION) |
740 BIT(NL80211_IFTYPE_ADHOC) | 765 BIT(NL80211_IFTYPE_ADHOC) |
741 BIT(NL80211_IFTYPE_MESH_POINT); 766 BIT(NL80211_IFTYPE_MESH_POINT);
742 hw->wiphy->iface_combinations = if_comb;
743 if (!ath9k_use_chanctx) { 767 if (!ath9k_use_chanctx) {
768 hw->wiphy->iface_combinations = if_comb;
744 hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); 769 hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
745 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_WDS); 770 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_WDS);
746 } else 771 } else {
747 hw->wiphy->n_iface_combinations = 1; 772 hw->wiphy->iface_combinations = if_comb_multi;
773 hw->wiphy->n_iface_combinations =
774 ARRAY_SIZE(if_comb_multi);
775 hw->wiphy->max_scan_ssids = 255;
776 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
777 hw->wiphy->max_remain_on_channel_duration = 10000;
778 hw->chanctx_data_size = sizeof(void *);
779 hw->extra_beacon_tailroom =
780 sizeof(struct ieee80211_p2p_noa_attr) + 9;
781 }
748 } 782 }
749 783
750 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 784 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -756,9 +790,14 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
756 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 790 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
757 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 791 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
758 792
759 hw->queues = 4; 793 /* allow 4 queues per channel context +
794 * 1 cab queue + 1 offchannel tx queue
795 */
796 hw->queues = 10;
797 /* last queue for offchannel */
798 hw->offchannel_tx_hw_queue = hw->queues - 1;
760 hw->max_rates = 4; 799 hw->max_rates = 4;
761 hw->max_listen_interval = 1; 800 hw->max_listen_interval = 10;
762 hw->max_rate_tries = 10; 801 hw->max_rate_tries = 10;
763 hw->sta_data_size = sizeof(struct ath_node); 802 hw->sta_data_size = sizeof(struct ath_node);
764 hw->vif_data_size = sizeof(struct ath_vif); 803 hw->vif_data_size = sizeof(struct ath_vif);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 72a715fe8f24..2343f56e6498 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -178,7 +178,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int
178 txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; 178 txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE];
179 179
180 memset(tx_info, 0, sizeof(*tx_info)); 180 memset(tx_info, 0, sizeof(*tx_info));
181 tx_info->band = hw->conf.chandef.chan->band; 181 tx_info->band = sc->cur_chandef.chan->band;
182 tx_info->flags |= IEEE80211_TX_CTL_NO_ACK; 182 tx_info->flags |= IEEE80211_TX_CTL_NO_ACK;
183 tx_info->control.rates[0].idx = 0; 183 tx_info->control.rates[0].idx = 0;
184 tx_info->control.rates[0].count = 1; 184 tx_info->control.rates[0].count = 1;
@@ -416,7 +416,7 @@ void ath_start_ani(struct ath_softc *sc)
416 416
417 if (common->disable_ani || 417 if (common->disable_ani ||
418 !test_bit(ATH_OP_ANI_RUN, &common->op_flags) || 418 !test_bit(ATH_OP_ANI_RUN, &common->op_flags) ||
419 (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 419 sc->cur_chan->offchannel)
420 return; 420 return;
421 421
422 common->ani.longcal_timer = timestamp; 422 common->ani.longcal_timer = timestamp;
@@ -440,7 +440,7 @@ void ath_check_ani(struct ath_softc *sc)
440{ 440{
441 struct ath_hw *ah = sc->sc_ah; 441 struct ath_hw *ah = sc->sc_ah;
442 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 442 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
443 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 443 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
444 444
445 /* 445 /*
446 * Check for the various conditions in which ANI has to 446 * Check for the various conditions in which ANI has to
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 62ac95d6bb9d..e6ac8d2e610c 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -19,9 +19,6 @@
19#include "ath9k.h" 19#include "ath9k.h"
20#include "btcoex.h" 20#include "btcoex.h"
21 21
22static void ath9k_set_assoc_state(struct ath_softc *sc,
23 struct ieee80211_vif *vif);
24
25u8 ath9k_parse_mpdudensity(u8 mpdudensity) 22u8 ath9k_parse_mpdudensity(u8 mpdudensity)
26{ 23{
27 /* 24 /*
@@ -63,9 +60,16 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq)
63 60
64 spin_lock_bh(&txq->axq_lock); 61 spin_lock_bh(&txq->axq_lock);
65 62
66 if (txq->axq_depth || !list_empty(&txq->axq_acq)) 63 if (txq->axq_depth)
67 pending = true; 64 pending = true;
68 65
66 if (txq->mac80211_qnum >= 0) {
67 struct list_head *list;
68
69 list = &sc->cur_chan->acq[txq->mac80211_qnum];
70 if (!list_empty(list))
71 pending = true;
72 }
69 spin_unlock_bh(&txq->axq_lock); 73 spin_unlock_bh(&txq->axq_lock);
70 return pending; 74 return pending;
71} 75}
@@ -227,13 +231,22 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
227 } 231 }
228 232
229 ath9k_cmn_update_txpow(ah, sc->curtxpow, 233 ath9k_cmn_update_txpow(ah, sc->curtxpow,
230 sc->config.txpowlimit, &sc->curtxpow); 234 sc->cur_chan->txpower, &sc->curtxpow);
231 235
232 clear_bit(ATH_OP_HW_RESET, &common->op_flags); 236 clear_bit(ATH_OP_HW_RESET, &common->op_flags);
233 ath9k_hw_set_interrupts(ah); 237 ath9k_calculate_summary_state(sc, sc->cur_chan);
234 ath9k_hw_enable_interrupts(ah); 238
239 if (!sc->cur_chan->offchannel && start) {
240 /* restore per chanctx TSF timer */
241 if (sc->cur_chan->tsf_val) {
242 u32 offset;
243
244 offset = ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts,
245 NULL);
246 ath9k_hw_settsf64(ah, sc->cur_chan->tsf_val + offset);
247 }
248
235 249
236 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && start) {
237 if (!test_bit(ATH_OP_BEACONS, &common->op_flags)) 250 if (!test_bit(ATH_OP_BEACONS, &common->op_flags))
238 goto work; 251 goto work;
239 252
@@ -247,26 +260,35 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
247 } 260 }
248 work: 261 work:
249 ath_restart_work(sc); 262 ath_restart_work(sc);
263 ath_txq_schedule_all(sc);
264 }
250 265
251 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 266 sc->gtt_cnt = 0;
252 if (!ATH_TXQ_SETUP(sc, i))
253 continue;
254 267
255 spin_lock_bh(&sc->tx.txq[i].axq_lock); 268 ath9k_hw_set_interrupts(ah);
256 ath_txq_schedule(sc, &sc->tx.txq[i]); 269 ath9k_hw_enable_interrupts(ah);
257 spin_unlock_bh(&sc->tx.txq[i].axq_lock); 270
271 if (!ath9k_use_chanctx)
272 ieee80211_wake_queues(sc->hw);
273 else {
274 if (sc->cur_chan == &sc->offchannel.chan)
275 ieee80211_wake_queue(sc->hw,
276 sc->hw->offchannel_tx_hw_queue);
277 else {
278 for (i = 0; i < IEEE80211_NUM_ACS; i++)
279 ieee80211_wake_queue(sc->hw,
280 sc->cur_chan->hw_queue_base + i);
258 } 281 }
282 if (ah->opmode == NL80211_IFTYPE_AP)
283 ieee80211_wake_queue(sc->hw, sc->hw->queues - 2);
259 } 284 }
260 285
261 sc->gtt_cnt = 0;
262 ieee80211_wake_queues(sc->hw);
263
264 ath9k_p2p_ps_timer(sc); 286 ath9k_p2p_ps_timer(sc);
265 287
266 return true; 288 return true;
267} 289}
268 290
269static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan) 291int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
270{ 292{
271 struct ath_hw *ah = sc->sc_ah; 293 struct ath_hw *ah = sc->sc_ah;
272 struct ath_common *common = ath9k_hw_common(ah); 294 struct ath_common *common = ath9k_hw_common(ah);
@@ -279,9 +301,9 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
279 tasklet_disable(&sc->intr_tq); 301 tasklet_disable(&sc->intr_tq);
280 spin_lock_bh(&sc->sc_pcu_lock); 302 spin_lock_bh(&sc->sc_pcu_lock);
281 303
282 if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) { 304 if (!sc->cur_chan->offchannel) {
283 fastcc = false; 305 fastcc = false;
284 caldata = &sc->caldata; 306 caldata = &sc->cur_chan->caldata;
285 } 307 }
286 308
287 if (!hchan) { 309 if (!hchan) {
@@ -292,6 +314,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
292 if (!ath_prepare_reset(sc)) 314 if (!ath_prepare_reset(sc))
293 fastcc = false; 315 fastcc = false;
294 316
317 spin_lock_bh(&sc->chan_lock);
318 sc->cur_chandef = sc->cur_chan->chandef;
319 spin_unlock_bh(&sc->chan_lock);
320
295 ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", 321 ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
296 hchan->channel, IS_CHAN_HT40(hchan), fastcc); 322 hchan->channel, IS_CHAN_HT40(hchan), fastcc);
297 323
@@ -307,7 +333,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
307 } 333 }
308 334
309 if (ath9k_hw_mci_is_enabled(sc->sc_ah) && 335 if (ath9k_hw_mci_is_enabled(sc->sc_ah) &&
310 (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) 336 sc->cur_chan->offchannel)
311 ath9k_mci_set_txpower(sc, true, false); 337 ath9k_mci_set_txpower(sc, true, false);
312 338
313 if (!ath_complete_reset(sc, true)) 339 if (!ath_complete_reset(sc, true))
@@ -320,98 +346,6 @@ out:
320 return r; 346 return r;
321} 347}
322 348
323
324/*
325 * Set/change channels. If the channel is really being changed, it's done
326 * by reseting the chip. To accomplish this we must first cleanup any pending
327 * DMA, then restart stuff.
328*/
329static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef)
330{
331 struct ath_hw *ah = sc->sc_ah;
332 struct ath_common *common = ath9k_hw_common(ah);
333 struct ieee80211_hw *hw = sc->hw;
334 struct ath9k_channel *hchan;
335 struct ieee80211_channel *chan = chandef->chan;
336 bool offchannel;
337 int pos = chan->hw_value;
338 int old_pos = -1;
339 int r;
340
341 if (test_bit(ATH_OP_INVALID, &common->op_flags))
342 return -EIO;
343
344 offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
345
346 if (ah->curchan)
347 old_pos = ah->curchan - &ah->channels[0];
348
349 ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
350 chan->center_freq, chandef->width);
351
352 /* update survey stats for the old channel before switching */
353 spin_lock_bh(&common->cc_lock);
354 ath_update_survey_stats(sc);
355 spin_unlock_bh(&common->cc_lock);
356
357 ath9k_cmn_get_channel(hw, ah, chandef);
358
359 /*
360 * If the operating channel changes, change the survey in-use flags
361 * along with it.
362 * Reset the survey data for the new channel, unless we're switching
363 * back to the operating channel from an off-channel operation.
364 */
365 if (!offchannel && sc->cur_survey != &sc->survey[pos]) {
366 if (sc->cur_survey)
367 sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
368
369 sc->cur_survey = &sc->survey[pos];
370
371 memset(sc->cur_survey, 0, sizeof(struct survey_info));
372 sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
373 } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
374 memset(&sc->survey[pos], 0, sizeof(struct survey_info));
375 }
376
377 hchan = &sc->sc_ah->channels[pos];
378 r = ath_reset_internal(sc, hchan);
379 if (r)
380 return r;
381
382 /*
383 * The most recent snapshot of channel->noisefloor for the old
384 * channel is only available after the hardware reset. Copy it to
385 * the survey stats now.
386 */
387 if (old_pos >= 0)
388 ath_update_survey_nf(sc, old_pos);
389
390 /*
391 * Enable radar pulse detection if on a DFS channel. Spectral
392 * scanning and radar detection can not be used concurrently.
393 */
394 if (hw->conf.radar_enabled) {
395 u32 rxfilter;
396
397 /* set HW specific DFS configuration */
398 ath9k_hw_set_radar_params(ah);
399 rxfilter = ath9k_hw_getrxfilter(ah);
400 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
401 ATH9K_RX_FILTER_PHYERR;
402 ath9k_hw_setrxfilter(ah, rxfilter);
403 ath_dbg(common, DFS, "DFS enabled at freq %d\n",
404 chan->center_freq);
405 } else {
406 /* perform spectral scan if requested. */
407 if (test_bit(ATH_OP_SCANNING, &common->op_flags) &&
408 sc->spectral_mode == SPECTRAL_CHANSCAN)
409 ath9k_spectral_scan_trigger(hw);
410 }
411
412 return 0;
413}
414
415static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, 349static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
416 struct ieee80211_vif *vif) 350 struct ieee80211_vif *vif)
417{ 351{
@@ -712,7 +646,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
712 struct ath_softc *sc = hw->priv; 646 struct ath_softc *sc = hw->priv;
713 struct ath_hw *ah = sc->sc_ah; 647 struct ath_hw *ah = sc->sc_ah;
714 struct ath_common *common = ath9k_hw_common(ah); 648 struct ath_common *common = ath9k_hw_common(ah);
715 struct ieee80211_channel *curchan = hw->conf.chandef.chan; 649 struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
650 struct ath_chanctx *ctx = sc->cur_chan;
716 struct ath9k_channel *init_channel; 651 struct ath9k_channel *init_channel;
717 int r; 652 int r;
718 653
@@ -723,7 +658,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
723 ath9k_ps_wakeup(sc); 658 ath9k_ps_wakeup(sc);
724 mutex_lock(&sc->mutex); 659 mutex_lock(&sc->mutex);
725 660
726 init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); 661 init_channel = ath9k_cmn_get_channel(hw, ah, &ctx->chandef);
662 sc->cur_chandef = hw->conf.chandef;
727 663
728 /* Reset SERDES registers */ 664 /* Reset SERDES registers */
729 ath9k_hw_configpcipowersave(ah, false); 665 ath9k_hw_configpcipowersave(ah, false);
@@ -886,6 +822,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
886 struct ath_common *common = ath9k_hw_common(ah); 822 struct ath_common *common = ath9k_hw_common(ah);
887 bool prev_idle; 823 bool prev_idle;
888 824
825 cancel_work_sync(&sc->chanctx_work);
889 mutex_lock(&sc->mutex); 826 mutex_lock(&sc->mutex);
890 827
891 ath_cancel_work(sc); 828 ath_cancel_work(sc);
@@ -934,7 +871,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
934 } 871 }
935 872
936 if (!ah->curchan) 873 if (!ah->curchan)
937 ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); 874 ah->curchan = ath9k_cmn_get_channel(hw, ah,
875 &sc->cur_chan->chandef);
938 876
939 ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 877 ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
940 ath9k_hw_phy_disable(ah); 878 ath9k_hw_phy_disable(ah);
@@ -979,18 +917,29 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
979 iter_data->has_hw_macaddr = true; 917 iter_data->has_hw_macaddr = true;
980 } 918 }
981 919
920 if (!vif->bss_conf.use_short_slot)
921 iter_data->slottime = ATH9K_SLOT_TIME_20;
922
982 switch (vif->type) { 923 switch (vif->type) {
983 case NL80211_IFTYPE_AP: 924 case NL80211_IFTYPE_AP:
984 iter_data->naps++; 925 iter_data->naps++;
926 if (vif->bss_conf.enable_beacon)
927 iter_data->beacons = true;
985 break; 928 break;
986 case NL80211_IFTYPE_STATION: 929 case NL80211_IFTYPE_STATION:
987 iter_data->nstations++; 930 iter_data->nstations++;
931 if (vif->bss_conf.assoc && !iter_data->primary_sta)
932 iter_data->primary_sta = vif;
988 break; 933 break;
989 case NL80211_IFTYPE_ADHOC: 934 case NL80211_IFTYPE_ADHOC:
990 iter_data->nadhocs++; 935 iter_data->nadhocs++;
936 if (vif->bss_conf.enable_beacon)
937 iter_data->beacons = true;
991 break; 938 break;
992 case NL80211_IFTYPE_MESH_POINT: 939 case NL80211_IFTYPE_MESH_POINT:
993 iter_data->nmeshes++; 940 iter_data->nmeshes++;
941 if (vif->bss_conf.enable_beacon)
942 iter_data->beacons = true;
994 break; 943 break;
995 case NL80211_IFTYPE_WDS: 944 case NL80211_IFTYPE_WDS:
996 iter_data->nwds++; 945 iter_data->nwds++;
@@ -1000,26 +949,12 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1000 } 949 }
1001} 950}
1002 951
1003static void ath9k_sta_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1004{
1005 struct ath_softc *sc = data;
1006 struct ath_vif *avp = (void *)vif->drv_priv;
1007
1008 if (vif->type != NL80211_IFTYPE_STATION)
1009 return;
1010
1011 if (avp->primary_sta_vif)
1012 ath9k_set_assoc_state(sc, vif);
1013}
1014
1015/* Called with sc->mutex held. */ 952/* Called with sc->mutex held. */
1016void ath9k_calculate_iter_data(struct ieee80211_hw *hw, 953void ath9k_calculate_iter_data(struct ath_softc *sc,
1017 struct ieee80211_vif *vif, 954 struct ath_chanctx *ctx,
1018 struct ath9k_vif_iter_data *iter_data) 955 struct ath9k_vif_iter_data *iter_data)
1019{ 956{
1020 struct ath_softc *sc = hw->priv; 957 struct ath_vif *avp;
1021 struct ath_hw *ah = sc->sc_ah;
1022 struct ath_common *common = ath9k_hw_common(ah);
1023 958
1024 /* 959 /*
1025 * Pick the MAC address of the first interface as the new hardware 960 * Pick the MAC address of the first interface as the new hardware
@@ -1028,29 +963,80 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
1028 */ 963 */
1029 memset(iter_data, 0, sizeof(*iter_data)); 964 memset(iter_data, 0, sizeof(*iter_data));
1030 memset(&iter_data->mask, 0xff, ETH_ALEN); 965 memset(&iter_data->mask, 0xff, ETH_ALEN);
966 iter_data->slottime = ATH9K_SLOT_TIME_9;
967
968 list_for_each_entry(avp, &ctx->vifs, list)
969 ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
970
971 if (ctx == &sc->offchannel.chan) {
972 struct ieee80211_vif *vif;
973
974 if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
975 vif = sc->offchannel.scan_vif;
976 else
977 vif = sc->offchannel.roc_vif;
978
979 if (vif)
980 ath9k_vif_iter(iter_data, vif->addr, vif);
981 iter_data->beacons = false;
982 }
983}
984
985static void ath9k_set_assoc_state(struct ath_softc *sc,
986 struct ieee80211_vif *vif, bool changed)
987{
988 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
989 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
990 unsigned long flags;
1031 991
1032 if (vif) 992 set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1033 ath9k_vif_iter(iter_data, vif->addr, vif); 993 /* Set the AID, BSSID and do beacon-sync only when
994 * the HW opmode is STATION.
995 *
996 * But the primary bit is set above in any case.
997 */
998 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
999 return;
1000
1001 ether_addr_copy(common->curbssid, bss_conf->bssid);
1002 common->curaid = bss_conf->aid;
1003 ath9k_hw_write_associd(sc->sc_ah);
1034 1004
1035 /* Get list of all active MAC addresses */ 1005 if (changed) {
1036 ieee80211_iterate_active_interfaces_atomic( 1006 common->last_rssi = ATH_RSSI_DUMMY_MARKER;
1037 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, 1007 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1038 ath9k_vif_iter, iter_data);
1039 1008
1040 memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN); 1009 spin_lock_irqsave(&sc->sc_pm_lock, flags);
1010 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
1011 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1012 }
1013
1014 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1015 ath9k_mci_update_wlan_channels(sc, false);
1016
1017 ath_dbg(common, CONFIG,
1018 "Primary Station interface: %pM, BSSID: %pM\n",
1019 vif->addr, common->curbssid);
1041} 1020}
1042 1021
1043/* Called with sc->mutex held. */ 1022/* Called with sc->mutex held. */
1044static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, 1023void ath9k_calculate_summary_state(struct ath_softc *sc,
1045 struct ieee80211_vif *vif) 1024 struct ath_chanctx *ctx)
1046{ 1025{
1047 struct ath_softc *sc = hw->priv;
1048 struct ath_hw *ah = sc->sc_ah; 1026 struct ath_hw *ah = sc->sc_ah;
1049 struct ath_common *common = ath9k_hw_common(ah); 1027 struct ath_common *common = ath9k_hw_common(ah);
1050 struct ath9k_vif_iter_data iter_data; 1028 struct ath9k_vif_iter_data iter_data;
1051 enum nl80211_iftype old_opmode = ah->opmode;
1052 1029
1053 ath9k_calculate_iter_data(hw, vif, &iter_data); 1030 ath_chanctx_check_active(sc, ctx);
1031
1032 if (ctx != sc->cur_chan)
1033 return;
1034
1035 ath9k_ps_wakeup(sc);
1036 ath9k_calculate_iter_data(sc, ctx, &iter_data);
1037
1038 if (iter_data.has_hw_macaddr)
1039 ether_addr_copy(common->macaddr, iter_data.hw_macaddr);
1054 1040
1055 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); 1041 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
1056 ath_hw_setbssidmask(common); 1042 ath_hw_setbssidmask(common);
@@ -1073,24 +1059,57 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
1073 1059
1074 ath9k_hw_setopmode(ah); 1060 ath9k_hw_setopmode(ah);
1075 1061
1062 ctx->switch_after_beacon = false;
1076 if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) 1063 if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
1077 ah->imask |= ATH9K_INT_TSFOOR; 1064 ah->imask |= ATH9K_INT_TSFOOR;
1078 else 1065 else {
1079 ah->imask &= ~ATH9K_INT_TSFOOR; 1066 ah->imask &= ~ATH9K_INT_TSFOOR;
1067 if (iter_data.naps == 1 && iter_data.beacons)
1068 ctx->switch_after_beacon = true;
1069 }
1070
1071 ah->imask &= ~ATH9K_INT_SWBA;
1072 if (ah->opmode == NL80211_IFTYPE_STATION) {
1073 bool changed = (iter_data.primary_sta != ctx->primary_sta);
1080 1074
1075 iter_data.beacons = true;
1076 if (iter_data.primary_sta) {
1077 ath9k_set_assoc_state(sc, iter_data.primary_sta,
1078 changed);
1079 if (!ctx->primary_sta ||
1080 !ctx->primary_sta->bss_conf.assoc)
1081 ctx->primary_sta = iter_data.primary_sta;
1082 } else {
1083 ctx->primary_sta = NULL;
1084 memset(common->curbssid, 0, ETH_ALEN);
1085 common->curaid = 0;
1086 ath9k_hw_write_associd(sc->sc_ah);
1087 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1088 ath9k_mci_update_wlan_channels(sc, true);
1089 }
1090 } else if (iter_data.beacons) {
1091 ah->imask |= ATH9K_INT_SWBA;
1092 }
1081 ath9k_hw_set_interrupts(ah); 1093 ath9k_hw_set_interrupts(ah);
1082 1094
1083 /* 1095 if (iter_data.beacons)
1084 * If we are changing the opmode to STATION, 1096 set_bit(ATH_OP_BEACONS, &common->op_flags);
1085 * a beacon sync needs to be done. 1097 else
1086 */ 1098 clear_bit(ATH_OP_BEACONS, &common->op_flags);
1087 if (ah->opmode == NL80211_IFTYPE_STATION && 1099
1088 old_opmode == NL80211_IFTYPE_AP && 1100 if (ah->slottime != iter_data.slottime) {
1089 test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags)) { 1101 ah->slottime = iter_data.slottime;
1090 ieee80211_iterate_active_interfaces_atomic( 1102 ath9k_hw_init_global_settings(ah);
1091 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1092 ath9k_sta_vif_iter, sc);
1093 } 1103 }
1104
1105 if (iter_data.primary_sta)
1106 set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1107 else
1108 clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1109
1110 ctx->primary_sta = iter_data.primary_sta;
1111
1112 ath9k_ps_restore(sc);
1094} 1113}
1095 1114
1096static int ath9k_add_interface(struct ieee80211_hw *hw, 1115static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1101,6 +1120,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1101 struct ath_common *common = ath9k_hw_common(ah); 1120 struct ath_common *common = ath9k_hw_common(ah);
1102 struct ath_vif *avp = (void *)vif->drv_priv; 1121 struct ath_vif *avp = (void *)vif->drv_priv;
1103 struct ath_node *an = &avp->mcast_node; 1122 struct ath_node *an = &avp->mcast_node;
1123 int i;
1104 1124
1105 mutex_lock(&sc->mutex); 1125 mutex_lock(&sc->mutex);
1106 1126
@@ -1115,14 +1135,20 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1115 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); 1135 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1116 sc->nvifs++; 1136 sc->nvifs++;
1117 1137
1118 ath9k_ps_wakeup(sc);
1119 ath9k_calculate_summary_state(hw, vif);
1120 ath9k_ps_restore(sc);
1121
1122 if (ath9k_uses_beacons(vif->type)) 1138 if (ath9k_uses_beacons(vif->type))
1123 ath9k_beacon_assign_slot(sc, vif); 1139 ath9k_beacon_assign_slot(sc, vif);
1124 1140
1125 avp->vif = vif; 1141 avp->vif = vif;
1142 if (!ath9k_use_chanctx) {
1143 avp->chanctx = sc->cur_chan;
1144 list_add_tail(&avp->list, &avp->chanctx->vifs);
1145 }
1146 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1147 vif->hw_queue[i] = i;
1148 if (vif->type == NL80211_IFTYPE_AP)
1149 vif->cab_queue = hw->queues - 2;
1150 else
1151 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1126 1152
1127 an->sc = sc; 1153 an->sc = sc;
1128 an->sta = NULL; 1154 an->sta = NULL;
@@ -1141,6 +1167,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1141{ 1167{
1142 struct ath_softc *sc = hw->priv; 1168 struct ath_softc *sc = hw->priv;
1143 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1169 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1170 struct ath_vif *avp = (void *)vif->drv_priv;
1171 int i;
1144 1172
1145 mutex_lock(&sc->mutex); 1173 mutex_lock(&sc->mutex);
1146 1174
@@ -1157,13 +1185,19 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1157 vif->type = new_type; 1185 vif->type = new_type;
1158 vif->p2p = p2p; 1186 vif->p2p = p2p;
1159 1187
1160 ath9k_ps_wakeup(sc);
1161 ath9k_calculate_summary_state(hw, vif);
1162 ath9k_ps_restore(sc);
1163
1164 if (ath9k_uses_beacons(vif->type)) 1188 if (ath9k_uses_beacons(vif->type))
1165 ath9k_beacon_assign_slot(sc, vif); 1189 ath9k_beacon_assign_slot(sc, vif);
1166 1190
1191 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1192 vif->hw_queue[i] = i;
1193
1194 if (vif->type == NL80211_IFTYPE_AP)
1195 vif->cab_queue = hw->queues - 2;
1196 else
1197 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1198
1199 ath9k_calculate_summary_state(sc, avp->chanctx);
1200
1167 mutex_unlock(&sc->mutex); 1201 mutex_unlock(&sc->mutex);
1168 return 0; 1202 return 0;
1169} 1203}
@@ -1211,14 +1245,12 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1211 1245
1212 sc->nvifs--; 1246 sc->nvifs--;
1213 sc->tx99_vif = NULL; 1247 sc->tx99_vif = NULL;
1248 if (!ath9k_use_chanctx)
1249 list_del(&avp->list);
1214 1250
1215 if (ath9k_uses_beacons(vif->type)) 1251 if (ath9k_uses_beacons(vif->type))
1216 ath9k_beacon_remove_slot(sc, vif); 1252 ath9k_beacon_remove_slot(sc, vif);
1217 1253
1218 ath9k_ps_wakeup(sc);
1219 ath9k_calculate_summary_state(hw, NULL);
1220 ath9k_ps_restore(sc);
1221
1222 ath_tx_node_cleanup(sc, &avp->mcast_node); 1254 ath_tx_node_cleanup(sc, &avp->mcast_node);
1223 1255
1224 mutex_unlock(&sc->mutex); 1256 mutex_unlock(&sc->mutex);
@@ -1345,7 +1377,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1345 struct ath_hw *ah = sc->sc_ah; 1377 struct ath_hw *ah = sc->sc_ah;
1346 struct ath_common *common = ath9k_hw_common(ah); 1378 struct ath_common *common = ath9k_hw_common(ah);
1347 struct ieee80211_conf *conf = &hw->conf; 1379 struct ieee80211_conf *conf = &hw->conf;
1348 bool reset_channel = false; 1380 struct ath_chanctx *ctx = sc->cur_chan;
1349 1381
1350 ath9k_ps_wakeup(sc); 1382 ath9k_ps_wakeup(sc);
1351 mutex_lock(&sc->mutex); 1383 mutex_lock(&sc->mutex);
@@ -1361,7 +1393,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1361 * The chip needs a reset to properly wake up from 1393 * The chip needs a reset to properly wake up from
1362 * full sleep 1394 * full sleep
1363 */ 1395 */
1364 reset_channel = ah->chip_fullsleep; 1396 ath_chanctx_set_channel(sc, ctx, &ctx->chandef);
1365 } 1397 }
1366 } 1398 }
1367 1399
@@ -1391,20 +1423,16 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
1391 } 1423 }
1392 } 1424 }
1393 1425
1394 if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { 1426 if (!ath9k_use_chanctx && (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1395 if (ath_set_channel(sc, &hw->conf.chandef) < 0) { 1427 ctx->offchannel = !!(conf->flags & IEEE80211_CONF_OFFCHANNEL);
1396 ath_err(common, "Unable to set channel\n"); 1428 ath_chanctx_set_channel(sc, ctx, &hw->conf.chandef);
1397 mutex_unlock(&sc->mutex);
1398 ath9k_ps_restore(sc);
1399 return -EINVAL;
1400 }
1401 } 1429 }
1402 1430
1403 if (changed & IEEE80211_CONF_CHANGE_POWER) { 1431 if (changed & IEEE80211_CONF_CHANGE_POWER) {
1404 ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level); 1432 ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
1405 sc->config.txpowlimit = 2 * conf->power_level; 1433 sc->cur_chan->txpower = 2 * conf->power_level;
1406 ath9k_cmn_update_txpow(ah, sc->curtxpow, 1434 ath9k_cmn_update_txpow(ah, sc->curtxpow,
1407 sc->config.txpowlimit, &sc->curtxpow); 1435 sc->cur_chan->txpower, &sc->curtxpow);
1408 } 1436 }
1409 1437
1410 mutex_unlock(&sc->mutex); 1438 mutex_unlock(&sc->mutex);
@@ -1659,58 +1687,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1659 return ret; 1687 return ret;
1660} 1688}
1661 1689
1662static void ath9k_set_assoc_state(struct ath_softc *sc,
1663 struct ieee80211_vif *vif)
1664{
1665 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1666 struct ath_vif *avp = (void *)vif->drv_priv;
1667 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1668 unsigned long flags;
1669
1670 set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1671 avp->primary_sta_vif = true;
1672
1673 /*
1674 * Set the AID, BSSID and do beacon-sync only when
1675 * the HW opmode is STATION.
1676 *
1677 * But the primary bit is set above in any case.
1678 */
1679 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
1680 return;
1681
1682 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1683 common->curaid = bss_conf->aid;
1684 ath9k_hw_write_associd(sc->sc_ah);
1685
1686 common->last_rssi = ATH_RSSI_DUMMY_MARKER;
1687 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1688
1689 spin_lock_irqsave(&sc->sc_pm_lock, flags);
1690 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
1691 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1692
1693 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1694 ath9k_mci_update_wlan_channels(sc, false);
1695
1696 ath_dbg(common, CONFIG,
1697 "Primary Station interface: %pM, BSSID: %pM\n",
1698 vif->addr, common->curbssid);
1699}
1700
1701static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1702{
1703 struct ath_softc *sc = data;
1704 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1705 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1706
1707 if (test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags))
1708 return;
1709
1710 if (bss_conf->assoc)
1711 ath9k_set_assoc_state(sc, vif);
1712}
1713
1714void ath9k_p2p_ps_timer(void *priv) 1690void ath9k_p2p_ps_timer(void *priv)
1715{ 1691{
1716 struct ath_softc *sc = priv; 1692 struct ath_softc *sc = priv;
@@ -1720,7 +1696,11 @@ void ath9k_p2p_ps_timer(void *priv)
1720 struct ath_node *an; 1696 struct ath_node *an;
1721 u32 tsf; 1697 u32 tsf;
1722 1698
1723 if (!avp) 1699 del_timer_sync(&sc->sched.timer);
1700 ath9k_hw_gen_timer_stop(sc->sc_ah, sc->p2p_ps_timer);
1701 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_TSF_TIMER);
1702
1703 if (!avp || avp->chanctx != sc->cur_chan)
1724 return; 1704 return;
1725 1705
1726 tsf = ath9k_hw_gettsf32(sc->sc_ah); 1706 tsf = ath9k_hw_gettsf32(sc->sc_ah);
@@ -1795,26 +1775,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1795 ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", 1775 ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
1796 bss_conf->bssid, bss_conf->assoc); 1776 bss_conf->bssid, bss_conf->assoc);
1797 1777
1798 if (avp->primary_sta_vif && !bss_conf->assoc) { 1778 ath9k_calculate_summary_state(sc, avp->chanctx);
1799 clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); 1779 if (bss_conf->assoc)
1800 avp->primary_sta_vif = false; 1780 ath_chanctx_event(sc, vif, ATH_CHANCTX_EVENT_ASSOC);
1801
1802 if (ah->opmode == NL80211_IFTYPE_STATION)
1803 clear_bit(ATH_OP_BEACONS, &common->op_flags);
1804 }
1805
1806 ieee80211_iterate_active_interfaces_atomic(
1807 sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
1808 ath9k_bss_assoc_iter, sc);
1809
1810 if (!test_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags) &&
1811 ah->opmode == NL80211_IFTYPE_STATION) {
1812 memset(common->curbssid, 0, ETH_ALEN);
1813 common->curaid = 0;
1814 ath9k_hw_write_associd(sc->sc_ah);
1815 if (ath9k_hw_mci_is_enabled(sc->sc_ah))
1816 ath9k_mci_update_wlan_channels(sc, true);
1817 }
1818 } 1781 }
1819 1782
1820 if (changed & BSS_CHANGED_IBSS) { 1783 if (changed & BSS_CHANGED_IBSS) {
@@ -1824,10 +1787,15 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1824 } 1787 }
1825 1788
1826 if ((changed & BSS_CHANGED_BEACON_ENABLED) || 1789 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1827 (changed & BSS_CHANGED_BEACON_INT)) 1790 (changed & BSS_CHANGED_BEACON_INT) ||
1791 (changed & BSS_CHANGED_BEACON_INFO)) {
1792 if (changed & BSS_CHANGED_BEACON_ENABLED)
1793 ath9k_calculate_summary_state(sc, avp->chanctx);
1828 ath9k_beacon_config(sc, vif, changed); 1794 ath9k_beacon_config(sc, vif, changed);
1795 }
1829 1796
1830 if (changed & BSS_CHANGED_ERP_SLOT) { 1797 if ((avp->chanctx == sc->cur_chan) &&
1798 (changed & BSS_CHANGED_ERP_SLOT)) {
1831 if (bss_conf->use_short_slot) 1799 if (bss_conf->use_short_slot)
1832 slottime = 9; 1800 slottime = 9;
1833 else 1801 else
@@ -2032,23 +2000,30 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2032 u32 queues, bool drop) 2000 u32 queues, bool drop)
2033{ 2001{
2034 struct ath_softc *sc = hw->priv; 2002 struct ath_softc *sc = hw->priv;
2003
2004 mutex_lock(&sc->mutex);
2005 __ath9k_flush(hw, queues, drop);
2006 mutex_unlock(&sc->mutex);
2007}
2008
2009void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
2010{
2011 struct ath_softc *sc = hw->priv;
2035 struct ath_hw *ah = sc->sc_ah; 2012 struct ath_hw *ah = sc->sc_ah;
2036 struct ath_common *common = ath9k_hw_common(ah); 2013 struct ath_common *common = ath9k_hw_common(ah);
2037 int timeout = HZ / 5; /* 200 ms */ 2014 int timeout = HZ / 5; /* 200 ms */
2038 bool drain_txq; 2015 bool drain_txq;
2016 int i;
2039 2017
2040 mutex_lock(&sc->mutex);
2041 cancel_delayed_work_sync(&sc->tx_complete_work); 2018 cancel_delayed_work_sync(&sc->tx_complete_work);
2042 2019
2043 if (ah->ah_flags & AH_UNPLUGGED) { 2020 if (ah->ah_flags & AH_UNPLUGGED) {
2044 ath_dbg(common, ANY, "Device has been unplugged!\n"); 2021 ath_dbg(common, ANY, "Device has been unplugged!\n");
2045 mutex_unlock(&sc->mutex);
2046 return; 2022 return;
2047 } 2023 }
2048 2024
2049 if (test_bit(ATH_OP_INVALID, &common->op_flags)) { 2025 if (test_bit(ATH_OP_INVALID, &common->op_flags)) {
2050 ath_dbg(common, ANY, "Device not present\n"); 2026 ath_dbg(common, ANY, "Device not present\n");
2051 mutex_unlock(&sc->mutex);
2052 return; 2027 return;
2053 } 2028 }
2054 2029
@@ -2066,11 +2041,13 @@ static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2066 ath_reset(sc); 2041 ath_reset(sc);
2067 2042
2068 ath9k_ps_restore(sc); 2043 ath9k_ps_restore(sc);
2069 ieee80211_wake_queues(hw); 2044 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
2045 ieee80211_wake_queue(sc->hw,
2046 sc->cur_chan->hw_queue_base + i);
2047 }
2070 } 2048 }
2071 2049
2072 ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); 2050 ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
2073 mutex_unlock(&sc->mutex);
2074} 2051}
2075 2052
2076static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) 2053static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
@@ -2230,6 +2207,403 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
2230 clear_bit(ATH_OP_SCANNING, &common->op_flags); 2207 clear_bit(ATH_OP_SCANNING, &common->op_flags);
2231} 2208}
2232 2209
2210static int ath_scan_channel_duration(struct ath_softc *sc,
2211 struct ieee80211_channel *chan)
2212{
2213 struct cfg80211_scan_request *req = sc->offchannel.scan_req;
2214
2215 if (!req->n_ssids || (chan->flags & IEEE80211_CHAN_NO_IR))
2216 return (HZ / 9); /* ~110 ms */
2217
2218 return (HZ / 16); /* ~60 ms */
2219}
2220
2221static void
2222ath_scan_next_channel(struct ath_softc *sc)
2223{
2224 struct cfg80211_scan_request *req = sc->offchannel.scan_req;
2225 struct ieee80211_channel *chan;
2226
2227 if (sc->offchannel.scan_idx >= req->n_channels) {
2228 sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
2229 ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),
2230 NULL);
2231 return;
2232 }
2233
2234 chan = req->channels[sc->offchannel.scan_idx++];
2235 sc->offchannel.duration = ath_scan_channel_duration(sc, chan);
2236 sc->offchannel.state = ATH_OFFCHANNEL_PROBE_SEND;
2237 ath_chanctx_offchan_switch(sc, chan);
2238}
2239
2240static void ath_offchannel_next(struct ath_softc *sc)
2241{
2242 struct ieee80211_vif *vif;
2243
2244 if (sc->offchannel.scan_req) {
2245 vif = sc->offchannel.scan_vif;
2246 sc->offchannel.chan.txpower = vif->bss_conf.txpower;
2247 ath_scan_next_channel(sc);
2248 } else if (sc->offchannel.roc_vif) {
2249 vif = sc->offchannel.roc_vif;
2250 sc->offchannel.chan.txpower = vif->bss_conf.txpower;
2251 sc->offchannel.duration = sc->offchannel.roc_duration;
2252 sc->offchannel.state = ATH_OFFCHANNEL_ROC_START;
2253 ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan);
2254 } else {
2255 ath_chanctx_switch(sc, ath_chanctx_get_oper_chan(sc, false),
2256 NULL);
2257 sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
2258 if (sc->ps_idle)
2259 ath_cancel_work(sc);
2260 }
2261}
2262
2263static void ath_roc_complete(struct ath_softc *sc, bool abort)
2264{
2265 sc->offchannel.roc_vif = NULL;
2266 sc->offchannel.roc_chan = NULL;
2267 if (!abort)
2268 ieee80211_remain_on_channel_expired(sc->hw);
2269 ath_offchannel_next(sc);
2270 ath9k_ps_restore(sc);
2271}
2272
2273static void ath_scan_complete(struct ath_softc *sc, bool abort)
2274{
2275 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2276
2277 sc->offchannel.scan_req = NULL;
2278 sc->offchannel.scan_vif = NULL;
2279 sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
2280 ieee80211_scan_completed(sc->hw, abort);
2281 clear_bit(ATH_OP_SCANNING, &common->op_flags);
2282 ath_offchannel_next(sc);
2283 ath9k_ps_restore(sc);
2284}
2285
2286static void ath_scan_send_probe(struct ath_softc *sc,
2287 struct cfg80211_ssid *ssid)
2288{
2289 struct cfg80211_scan_request *req = sc->offchannel.scan_req;
2290 struct ieee80211_vif *vif = sc->offchannel.scan_vif;
2291 struct ath_tx_control txctl = {};
2292 struct sk_buff *skb;
2293 struct ieee80211_tx_info *info;
2294 int band = sc->offchannel.chan.chandef.chan->band;
2295
2296 skb = ieee80211_probereq_get(sc->hw, vif,
2297 ssid->ssid, ssid->ssid_len, req->ie_len);
2298 if (!skb)
2299 return;
2300
2301 info = IEEE80211_SKB_CB(skb);
2302 if (req->no_cck)
2303 info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
2304
2305 if (req->ie_len)
2306 memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
2307
2308 skb_set_queue_mapping(skb, IEEE80211_AC_VO);
2309
2310 if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
2311 goto error;
2312
2313 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
2314 txctl.force_channel = true;
2315 if (ath_tx_start(sc->hw, skb, &txctl))
2316 goto error;
2317
2318 return;
2319
2320error:
2321 ieee80211_free_txskb(sc->hw, skb);
2322}
2323
2324static void ath_scan_channel_start(struct ath_softc *sc)
2325{
2326 struct cfg80211_scan_request *req = sc->offchannel.scan_req;
2327 int i;
2328
2329 if (!(sc->cur_chan->chandef.chan->flags & IEEE80211_CHAN_NO_IR) &&
2330 req->n_ssids) {
2331 for (i = 0; i < req->n_ssids; i++)
2332 ath_scan_send_probe(sc, &req->ssids[i]);
2333
2334 }
2335
2336 sc->offchannel.state = ATH_OFFCHANNEL_PROBE_WAIT;
2337 mod_timer(&sc->offchannel.timer, jiffies + sc->offchannel.duration);
2338}
2339
2340void ath_offchannel_channel_change(struct ath_softc *sc)
2341{
2342 switch (sc->offchannel.state) {
2343 case ATH_OFFCHANNEL_PROBE_SEND:
2344 if (!sc->offchannel.scan_req)
2345 return;
2346
2347 if (sc->cur_chan->chandef.chan !=
2348 sc->offchannel.chan.chandef.chan)
2349 return;
2350
2351 ath_scan_channel_start(sc);
2352 break;
2353 case ATH_OFFCHANNEL_IDLE:
2354 if (!sc->offchannel.scan_req)
2355 return;
2356
2357 ath_scan_complete(sc, false);
2358 break;
2359 case ATH_OFFCHANNEL_ROC_START:
2360 if (sc->cur_chan != &sc->offchannel.chan)
2361 break;
2362
2363 sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT;
2364 mod_timer(&sc->offchannel.timer, jiffies +
2365 msecs_to_jiffies(sc->offchannel.duration));
2366 ieee80211_ready_on_channel(sc->hw);
2367 break;
2368 case ATH_OFFCHANNEL_ROC_DONE:
2369 ath_roc_complete(sc, false);
2370 break;
2371 default:
2372 break;
2373 }
2374}
2375
2376void ath_offchannel_timer(unsigned long data)
2377{
2378 struct ath_softc *sc = (struct ath_softc *)data;
2379 struct ath_chanctx *ctx;
2380
2381 switch (sc->offchannel.state) {
2382 case ATH_OFFCHANNEL_PROBE_WAIT:
2383 if (!sc->offchannel.scan_req)
2384 return;
2385
2386 /* get first active channel context */
2387 ctx = ath_chanctx_get_oper_chan(sc, true);
2388 if (ctx->active) {
2389 sc->offchannel.state = ATH_OFFCHANNEL_SUSPEND;
2390 ath_chanctx_switch(sc, ctx, NULL);
2391 mod_timer(&sc->offchannel.timer, jiffies + HZ / 10);
2392 break;
2393 }
2394 /* fall through */
2395 case ATH_OFFCHANNEL_SUSPEND:
2396 if (!sc->offchannel.scan_req)
2397 return;
2398
2399 ath_scan_next_channel(sc);
2400 break;
2401 case ATH_OFFCHANNEL_ROC_START:
2402 case ATH_OFFCHANNEL_ROC_WAIT:
2403 ctx = ath_chanctx_get_oper_chan(sc, false);
2404 sc->offchannel.state = ATH_OFFCHANNEL_ROC_DONE;
2405 ath_chanctx_switch(sc, ctx, NULL);
2406 break;
2407 default:
2408 break;
2409 }
2410}
2411
2412static int ath9k_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2413 struct ieee80211_scan_request *hw_req)
2414{
2415 struct cfg80211_scan_request *req = &hw_req->req;
2416 struct ath_softc *sc = hw->priv;
2417 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2418 int ret = 0;
2419
2420 mutex_lock(&sc->mutex);
2421
2422 if (WARN_ON(sc->offchannel.scan_req)) {
2423 ret = -EBUSY;
2424 goto out;
2425 }
2426
2427 ath9k_ps_wakeup(sc);
2428 set_bit(ATH_OP_SCANNING, &common->op_flags);
2429 sc->offchannel.scan_vif = vif;
2430 sc->offchannel.scan_req = req;
2431 sc->offchannel.scan_idx = 0;
2432
2433 if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE)
2434 ath_offchannel_next(sc);
2435
2436out:
2437 mutex_unlock(&sc->mutex);
2438
2439 return ret;
2440}
2441
2442static void ath9k_cancel_hw_scan(struct ieee80211_hw *hw,
2443 struct ieee80211_vif *vif)
2444{
2445 struct ath_softc *sc = hw->priv;
2446
2447 mutex_lock(&sc->mutex);
2448 del_timer_sync(&sc->offchannel.timer);
2449 ath_scan_complete(sc, true);
2450 mutex_unlock(&sc->mutex);
2451}
2452
2453static int ath9k_remain_on_channel(struct ieee80211_hw *hw,
2454 struct ieee80211_vif *vif,
2455 struct ieee80211_channel *chan, int duration,
2456 enum ieee80211_roc_type type)
2457{
2458 struct ath_softc *sc = hw->priv;
2459 int ret = 0;
2460
2461 mutex_lock(&sc->mutex);
2462
2463 if (WARN_ON(sc->offchannel.roc_vif)) {
2464 ret = -EBUSY;
2465 goto out;
2466 }
2467
2468 ath9k_ps_wakeup(sc);
2469 sc->offchannel.roc_vif = vif;
2470 sc->offchannel.roc_chan = chan;
2471 sc->offchannel.roc_duration = duration;
2472
2473 if (sc->offchannel.state == ATH_OFFCHANNEL_IDLE)
2474 ath_offchannel_next(sc);
2475
2476out:
2477 mutex_unlock(&sc->mutex);
2478
2479 return ret;
2480}
2481
2482static int ath9k_cancel_remain_on_channel(struct ieee80211_hw *hw)
2483{
2484 struct ath_softc *sc = hw->priv;
2485
2486 mutex_lock(&sc->mutex);
2487
2488 del_timer_sync(&sc->offchannel.timer);
2489
2490 if (sc->offchannel.roc_vif) {
2491 if (sc->offchannel.state >= ATH_OFFCHANNEL_ROC_START)
2492 ath_roc_complete(sc, true);
2493 }
2494
2495 mutex_unlock(&sc->mutex);
2496
2497 return 0;
2498}
2499
2500static int ath9k_add_chanctx(struct ieee80211_hw *hw,
2501 struct ieee80211_chanctx_conf *conf)
2502{
2503 struct ath_softc *sc = hw->priv;
2504 struct ath_chanctx *ctx, **ptr;
2505 int pos;
2506
2507 mutex_lock(&sc->mutex);
2508
2509 ath_for_each_chanctx(sc, ctx) {
2510 if (ctx->assigned)
2511 continue;
2512
2513 ptr = (void *) conf->drv_priv;
2514 *ptr = ctx;
2515 ctx->assigned = true;
2516 pos = ctx - &sc->chanctx[0];
2517 ctx->hw_queue_base = pos * IEEE80211_NUM_ACS;
2518 ath_chanctx_set_channel(sc, ctx, &conf->def);
2519 mutex_unlock(&sc->mutex);
2520 return 0;
2521 }
2522 mutex_unlock(&sc->mutex);
2523 return -ENOSPC;
2524}
2525
2526
2527static void ath9k_remove_chanctx(struct ieee80211_hw *hw,
2528 struct ieee80211_chanctx_conf *conf)
2529{
2530 struct ath_softc *sc = hw->priv;
2531 struct ath_chanctx *ctx = ath_chanctx_get(conf);
2532
2533 mutex_lock(&sc->mutex);
2534 ctx->assigned = false;
2535 ctx->hw_queue_base = -1;
2536 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN);
2537 mutex_unlock(&sc->mutex);
2538}
2539
2540static void ath9k_change_chanctx(struct ieee80211_hw *hw,
2541 struct ieee80211_chanctx_conf *conf,
2542 u32 changed)
2543{
2544 struct ath_softc *sc = hw->priv;
2545 struct ath_chanctx *ctx = ath_chanctx_get(conf);
2546
2547 mutex_lock(&sc->mutex);
2548 ath_chanctx_set_channel(sc, ctx, &conf->def);
2549 mutex_unlock(&sc->mutex);
2550}
2551
2552static int ath9k_assign_vif_chanctx(struct ieee80211_hw *hw,
2553 struct ieee80211_vif *vif,
2554 struct ieee80211_chanctx_conf *conf)
2555{
2556 struct ath_softc *sc = hw->priv;
2557 struct ath_vif *avp = (void *)vif->drv_priv;
2558 struct ath_chanctx *ctx = ath_chanctx_get(conf);
2559 int i;
2560
2561 mutex_lock(&sc->mutex);
2562 avp->chanctx = ctx;
2563 list_add_tail(&avp->list, &ctx->vifs);
2564 ath9k_calculate_summary_state(sc, ctx);
2565 for (i = 0; i < IEEE80211_NUM_ACS; i++)
2566 vif->hw_queue[i] = ctx->hw_queue_base + i;
2567 mutex_unlock(&sc->mutex);
2568
2569 return 0;
2570}
2571
2572static void ath9k_unassign_vif_chanctx(struct ieee80211_hw *hw,
2573 struct ieee80211_vif *vif,
2574 struct ieee80211_chanctx_conf *conf)
2575{
2576 struct ath_softc *sc = hw->priv;
2577 struct ath_vif *avp = (void *)vif->drv_priv;
2578 struct ath_chanctx *ctx = ath_chanctx_get(conf);
2579 int ac;
2580
2581 mutex_lock(&sc->mutex);
2582 avp->chanctx = NULL;
2583 list_del(&avp->list);
2584 ath9k_calculate_summary_state(sc, ctx);
2585 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
2586 vif->hw_queue[ac] = IEEE80211_INVAL_HW_QUEUE;
2587 mutex_unlock(&sc->mutex);
2588}
2589
2590void ath9k_fill_chanctx_ops(void)
2591{
2592 if (!ath9k_use_chanctx)
2593 return;
2594
2595 ath9k_ops.hw_scan = ath9k_hw_scan;
2596 ath9k_ops.cancel_hw_scan = ath9k_cancel_hw_scan;
2597 ath9k_ops.remain_on_channel = ath9k_remain_on_channel;
2598 ath9k_ops.cancel_remain_on_channel = ath9k_cancel_remain_on_channel;
2599 ath9k_ops.add_chanctx = ath9k_add_chanctx;
2600 ath9k_ops.remove_chanctx = ath9k_remove_chanctx;
2601 ath9k_ops.change_chanctx = ath9k_change_chanctx;
2602 ath9k_ops.assign_vif_chanctx = ath9k_assign_vif_chanctx;
2603 ath9k_ops.unassign_vif_chanctx = ath9k_unassign_vif_chanctx;
2604 ath9k_ops.mgd_prepare_tx = ath9k_chanctx_force_active;
2605}
2606
2233struct ieee80211_ops ath9k_ops = { 2607struct ieee80211_ops ath9k_ops = {
2234 .tx = ath9k_tx, 2608 .tx = ath9k_tx,
2235 .start = ath9k_start, 2609 .start = ath9k_start,
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index a0dbcc412384..3f7a11edb82a 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -706,7 +706,7 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
706 return; 706 return;
707 707
708 if (setchannel) { 708 if (setchannel) {
709 struct ath9k_hw_cal_data *caldata = &sc->caldata; 709 struct ath9k_hw_cal_data *caldata = &sc->cur_chan->caldata;
710 if (IS_CHAN_HT40PLUS(ah->curchan) && 710 if (IS_CHAN_HT40PLUS(ah->curchan) &&
711 (ah->curchan->channel > caldata->channel) && 711 (ah->curchan->channel > caldata->channel) &&
712 (ah->curchan->channel <= caldata->channel + 20)) 712 (ah->curchan->channel <= caldata->channel + 20))
@@ -720,7 +720,7 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel,
720 mci_hw->concur_tx = concur_tx; 720 mci_hw->concur_tx = concur_tx;
721 721
722 if (old_concur_tx != mci_hw->concur_tx) 722 if (old_concur_tx != mci_hw->concur_tx)
723 ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); 723 ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
724} 724}
725 725
726static void ath9k_mci_stomp_audio(struct ath_softc *sc) 726static void ath9k_mci_stomp_audio(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 4dec09e565ed..7a2b2c5caced 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -843,6 +843,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
843 return -ENODEV; 843 return -ENODEV;
844 } 844 }
845 845
846 ath9k_fill_chanctx_ops();
846 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); 847 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
847 if (!hw) { 848 if (!hw) {
848 dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); 849 dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 9105a92364f7..74ab1d02013b 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -259,7 +259,7 @@ static void ath_edma_start_recv(struct ath_softc *sc)
259 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP); 259 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP);
260 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP); 260 ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP);
261 ath_opmode_init(sc); 261 ath_opmode_init(sc);
262 ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 262 ath9k_hw_startpcureceive(sc->sc_ah, sc->cur_chan->offchannel);
263} 263}
264 264
265static void ath_edma_stop_recv(struct ath_softc *sc) 265static void ath_edma_stop_recv(struct ath_softc *sc)
@@ -374,6 +374,7 @@ void ath_rx_cleanup(struct ath_softc *sc)
374 374
375u32 ath_calcrxfilter(struct ath_softc *sc) 375u32 ath_calcrxfilter(struct ath_softc *sc)
376{ 376{
377 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
377 u32 rfilt; 378 u32 rfilt;
378 379
379 if (config_enabled(CONFIG_ATH9K_TX99)) 380 if (config_enabled(CONFIG_ATH9K_TX99))
@@ -424,6 +425,10 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
424 if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah)) 425 if (AR_SREV_9550(sc->sc_ah) || AR_SREV_9531(sc->sc_ah))
425 rfilt |= ATH9K_RX_FILTER_4ADDRESS; 426 rfilt |= ATH9K_RX_FILTER_4ADDRESS;
426 427
428 if (ath9k_use_chanctx &&
429 test_bit(ATH_OP_SCANNING, &common->op_flags))
430 rfilt |= ATH9K_RX_FILTER_BEACON;
431
427 return rfilt; 432 return rfilt;
428 433
429} 434}
@@ -457,7 +462,7 @@ int ath_startrecv(struct ath_softc *sc)
457 462
458start_recv: 463start_recv:
459 ath_opmode_init(sc); 464 ath_opmode_init(sc);
460 ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)); 465 ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel);
461 466
462 return 0; 467 return 0;
463} 468}
@@ -540,7 +545,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
540 sc->ps_flags &= ~PS_BEACON_SYNC; 545 sc->ps_flags &= ~PS_BEACON_SYNC;
541 ath_dbg(common, PS, 546 ath_dbg(common, PS,
542 "Reconfigure beacon timers based on synchronized timestamp\n"); 547 "Reconfigure beacon timers based on synchronized timestamp\n");
543 if (!(WARN_ON_ONCE(sc->cur_beacon_conf.beacon_interval == 0))) 548 if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0)))
544 ath9k_set_beacon(sc); 549 ath9k_set_beacon(sc);
545 if (sc->p2p_ps_vif) 550 if (sc->p2p_ps_vif)
546 ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); 551 ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
@@ -887,6 +892,11 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
887 return -EINVAL; 892 return -EINVAL;
888 } 893 }
889 894
895 if (rx_stats->is_mybeacon) {
896 sc->sched.next_tbtt = rx_stats->rs_tstamp;
897 ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_BEACON_RECEIVED);
898 }
899
890 ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status); 900 ath9k_cmn_process_rssi(common, hw, rx_stats, rx_status);
891 901
892 rx_status->band = ah->curchan->chan->band; 902 rx_status->band = ah->curchan->chan->band;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index f1bbce3f7774..a1499700bcf2 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -813,6 +813,7 @@
813#define AR_SREV_VERSION_9531 0x500 813#define AR_SREV_VERSION_9531 0x500
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 817
817#define AR_SREV_5416(_ah) \ 818#define AR_SREV_5416(_ah) \
818 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 819 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -958,6 +959,9 @@
958#define AR_SREV_9531_11(_ah) \ 959#define AR_SREV_9531_11(_ah) \
959 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \ 960 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
960 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_11)) 961 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_11))
962#define AR_SREV_9531_20(_ah) \
963 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9531) && \
964 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9531_20))
961 965
962/* NOTE: When adding chips newer than Peacock, add chip check here */ 966/* NOTE: When adding chips newer than Peacock, add chip check here */
963#define AR_SREV_9580_10_OR_LATER(_ah) \ 967#define AR_SREV_9580_10_OR_LATER(_ah) \
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index a65cfb91adca..23972924c774 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -76,7 +76,7 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
76 tx_info = IEEE80211_SKB_CB(skb); 76 tx_info = IEEE80211_SKB_CB(skb);
77 memset(tx_info, 0, sizeof(*tx_info)); 77 memset(tx_info, 0, sizeof(*tx_info));
78 rate = &tx_info->control.rates[0]; 78 rate = &tx_info->control.rates[0];
79 tx_info->band = hw->conf.chandef.chan->band; 79 tx_info->band = sc->cur_chan->chandef.chan->band;
80 tx_info->flags = IEEE80211_TX_CTL_NO_ACK; 80 tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
81 tx_info->control.vif = sc->tx99_vif; 81 tx_info->control.vif = sc->tx99_vif;
82 rate->count = 1; 82 rate->count = 1;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 2879887f5691..a4f4f0da81f6 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -193,6 +193,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
193 u32 wow_triggers_enabled = 0; 193 u32 wow_triggers_enabled = 0;
194 int ret = 0; 194 int ret = 0;
195 195
196 cancel_work_sync(&sc->chanctx_work);
196 mutex_lock(&sc->mutex); 197 mutex_lock(&sc->mutex);
197 198
198 ath_cancel_work(sc); 199 ath_cancel_work(sc);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 66acb2cbd9df..d4927c9a6bae 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -103,9 +103,16 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
103 ieee80211_tx_status(sc->hw, skb); 103 ieee80211_tx_status(sc->hw, skb);
104} 104}
105 105
106static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) 106static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
107 struct ath_atx_tid *tid)
107{ 108{
108 struct ath_atx_ac *ac = tid->ac; 109 struct ath_atx_ac *ac = tid->ac;
110 struct list_head *list;
111 struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
112 struct ath_chanctx *ctx = avp->chanctx;
113
114 if (!ctx)
115 return;
109 116
110 if (tid->sched) 117 if (tid->sched)
111 return; 118 return;
@@ -117,7 +124,9 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
117 return; 124 return;
118 125
119 ac->sched = true; 126 ac->sched = true;
120 list_add_tail(&ac->list, &txq->axq_acq); 127
128 list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
129 list_add_tail(&ac->list, list);
121} 130}
122 131
123static struct ath_frame_info *get_frame_info(struct sk_buff *skb) 132static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -147,7 +156,8 @@ static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
147static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, 156static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
148 struct sk_buff *skb) 157 struct sk_buff *skb)
149{ 158{
150 int q; 159 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
160 int q, hw_queue;
151 161
152 q = skb_get_queue_mapping(skb); 162 q = skb_get_queue_mapping(skb);
153 if (txq == sc->tx.uapsdq) 163 if (txq == sc->tx.uapsdq)
@@ -159,9 +169,10 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
159 if (WARN_ON(--txq->pending_frames < 0)) 169 if (WARN_ON(--txq->pending_frames < 0))
160 txq->pending_frames = 0; 170 txq->pending_frames = 0;
161 171
172 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
162 if (txq->stopped && 173 if (txq->stopped &&
163 txq->pending_frames < sc->tx.txq_max_pending[q]) { 174 txq->pending_frames < sc->tx.txq_max_pending[q]) {
164 ieee80211_wake_queue(sc->hw, q); 175 ieee80211_wake_queue(sc->hw, hw_queue);
165 txq->stopped = false; 176 txq->stopped = false;
166 } 177 }
167} 178}
@@ -626,7 +637,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
626 637
627 skb_queue_splice_tail(&bf_pending, &tid->retry_q); 638 skb_queue_splice_tail(&bf_pending, &tid->retry_q);
628 if (!an->sleeping) { 639 if (!an->sleeping) {
629 ath_tx_queue_tid(txq, tid); 640 ath_tx_queue_tid(sc, txq, tid);
630 641
631 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) 642 if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
632 tid->ac->clear_ps_filter = true; 643 tid->ac->clear_ps_filter = true;
@@ -1483,7 +1494,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
1483 ac->clear_ps_filter = true; 1494 ac->clear_ps_filter = true;
1484 1495
1485 if (ath_tid_has_buffered(tid)) { 1496 if (ath_tid_has_buffered(tid)) {
1486 ath_tx_queue_tid(txq, tid); 1497 ath_tx_queue_tid(sc, txq, tid);
1487 ath_txq_schedule(sc, txq); 1498 ath_txq_schedule(sc, txq);
1488 } 1499 }
1489 1500
@@ -1507,7 +1518,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
1507 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; 1518 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
1508 1519
1509 if (ath_tid_has_buffered(tid)) { 1520 if (ath_tid_has_buffered(tid)) {
1510 ath_tx_queue_tid(txq, tid); 1521 ath_tx_queue_tid(sc, txq, tid);
1511 ath_txq_schedule(sc, txq); 1522 ath_txq_schedule(sc, txq);
1512 } 1523 }
1513 1524
@@ -1642,7 +1653,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
1642 txq->axq_link = NULL; 1653 txq->axq_link = NULL;
1643 __skb_queue_head_init(&txq->complete_q); 1654 __skb_queue_head_init(&txq->complete_q);
1644 INIT_LIST_HEAD(&txq->axq_q); 1655 INIT_LIST_HEAD(&txq->axq_q);
1645 INIT_LIST_HEAD(&txq->axq_acq);
1646 spin_lock_init(&txq->axq_lock); 1656 spin_lock_init(&txq->axq_lock);
1647 txq->axq_depth = 0; 1657 txq->axq_depth = 0;
1648 txq->axq_ampdu_depth = 0; 1658 txq->axq_ampdu_depth = 0;
@@ -1686,7 +1696,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum,
1686int ath_cabq_update(struct ath_softc *sc) 1696int ath_cabq_update(struct ath_softc *sc)
1687{ 1697{
1688 struct ath9k_tx_queue_info qi; 1698 struct ath9k_tx_queue_info qi;
1689 struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; 1699 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
1690 int qnum = sc->beacon.cabq->axq_qnum; 1700 int qnum = sc->beacon.cabq->axq_qnum;
1691 1701
1692 ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); 1702 ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
@@ -1804,7 +1814,7 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
1804 sc->tx.txqsetup &= ~(1<<txq->axq_qnum); 1814 sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
1805} 1815}
1806 1816
1807/* For each axq_acq entry, for each tid, try to schedule packets 1817/* For each acq entry, for each tid, try to schedule packets
1808 * for transmit until ampdu_depth has reached min Q depth. 1818 * for transmit until ampdu_depth has reached min Q depth.
1809 */ 1819 */
1810void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) 1820void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
@@ -1812,19 +1822,31 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1812 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1822 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1813 struct ath_atx_ac *ac, *last_ac; 1823 struct ath_atx_ac *ac, *last_ac;
1814 struct ath_atx_tid *tid, *last_tid; 1824 struct ath_atx_tid *tid, *last_tid;
1825 struct list_head *ac_list;
1815 bool sent = false; 1826 bool sent = false;
1816 1827
1828 if (txq->mac80211_qnum < 0)
1829 return;
1830
1831 spin_lock_bh(&sc->chan_lock);
1832 ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
1833 spin_unlock_bh(&sc->chan_lock);
1834
1817 if (test_bit(ATH_OP_HW_RESET, &common->op_flags) || 1835 if (test_bit(ATH_OP_HW_RESET, &common->op_flags) ||
1818 list_empty(&txq->axq_acq)) 1836 list_empty(ac_list))
1819 return; 1837 return;
1820 1838
1839 spin_lock_bh(&sc->chan_lock);
1821 rcu_read_lock(); 1840 rcu_read_lock();
1822 1841
1823 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); 1842 last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
1824 while (!list_empty(&txq->axq_acq)) { 1843 while (!list_empty(ac_list)) {
1825 bool stop = false; 1844 bool stop = false;
1826 1845
1827 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); 1846 if (sc->cur_chan->stopped)
1847 break;
1848
1849 ac = list_first_entry(ac_list, struct ath_atx_ac, list);
1828 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list); 1850 last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
1829 list_del(&ac->list); 1851 list_del(&ac->list);
1830 ac->sched = false; 1852 ac->sched = false;
@@ -1844,7 +1866,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1844 * are pending for the tid 1866 * are pending for the tid
1845 */ 1867 */
1846 if (ath_tid_has_buffered(tid)) 1868 if (ath_tid_has_buffered(tid))
1847 ath_tx_queue_tid(txq, tid); 1869 ath_tx_queue_tid(sc, txq, tid);
1848 1870
1849 if (stop || tid == last_tid) 1871 if (stop || tid == last_tid)
1850 break; 1872 break;
@@ -1852,7 +1874,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1852 1874
1853 if (!list_empty(&ac->tid_q) && !ac->sched) { 1875 if (!list_empty(&ac->tid_q) && !ac->sched) {
1854 ac->sched = true; 1876 ac->sched = true;
1855 list_add_tail(&ac->list, &txq->axq_acq); 1877 list_add_tail(&ac->list, ac_list);
1856 } 1878 }
1857 1879
1858 if (stop) 1880 if (stop)
@@ -1863,12 +1885,27 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1863 break; 1885 break;
1864 1886
1865 sent = false; 1887 sent = false;
1866 last_ac = list_entry(txq->axq_acq.prev, 1888 last_ac = list_entry(ac_list->prev,
1867 struct ath_atx_ac, list); 1889 struct ath_atx_ac, list);
1868 } 1890 }
1869 } 1891 }
1870 1892
1871 rcu_read_unlock(); 1893 rcu_read_unlock();
1894 spin_unlock_bh(&sc->chan_lock);
1895}
1896
1897void ath_txq_schedule_all(struct ath_softc *sc)
1898{
1899 struct ath_txq *txq;
1900 int i;
1901
1902 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
1903 txq = sc->tx.txq_map[i];
1904
1905 spin_lock_bh(&txq->axq_lock);
1906 ath_txq_schedule(sc, txq);
1907 spin_unlock_bh(&txq->axq_lock);
1908 }
1872} 1909}
1873 1910
1874/***********/ 1911/***********/
@@ -2150,13 +2187,21 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2150 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2187 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2151 struct ieee80211_sta *sta = txctl->sta; 2188 struct ieee80211_sta *sta = txctl->sta;
2152 struct ieee80211_vif *vif = info->control.vif; 2189 struct ieee80211_vif *vif = info->control.vif;
2190 struct ath_vif *avp = NULL;
2153 struct ath_softc *sc = hw->priv; 2191 struct ath_softc *sc = hw->priv;
2154 struct ath_txq *txq = txctl->txq; 2192 struct ath_txq *txq = txctl->txq;
2155 struct ath_atx_tid *tid = NULL; 2193 struct ath_atx_tid *tid = NULL;
2156 struct ath_buf *bf; 2194 struct ath_buf *bf;
2157 int q; 2195 bool queue;
2196 int q, hw_queue;
2158 int ret; 2197 int ret;
2159 2198
2199 if (vif)
2200 avp = (void *)vif->drv_priv;
2201
2202 if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN)
2203 txctl->force_channel = true;
2204
2160 ret = ath_tx_prepare(hw, skb, txctl); 2205 ret = ath_tx_prepare(hw, skb, txctl);
2161 if (ret) 2206 if (ret)
2162 return ret; 2207 return ret;
@@ -2168,24 +2213,39 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2168 */ 2213 */
2169 2214
2170 q = skb_get_queue_mapping(skb); 2215 q = skb_get_queue_mapping(skb);
2216 hw_queue = (info->hw_queue >= sc->hw->queues - 2) ? q : info->hw_queue;
2171 2217
2172 ath_txq_lock(sc, txq); 2218 ath_txq_lock(sc, txq);
2173 if (txq == sc->tx.txq_map[q] && 2219 if (txq == sc->tx.txq_map[q] &&
2174 ++txq->pending_frames > sc->tx.txq_max_pending[q] && 2220 ++txq->pending_frames > sc->tx.txq_max_pending[q] &&
2175 !txq->stopped) { 2221 !txq->stopped) {
2176 ieee80211_stop_queue(sc->hw, q); 2222 ieee80211_stop_queue(sc->hw, hw_queue);
2177 txq->stopped = true; 2223 txq->stopped = true;
2178 } 2224 }
2179 2225
2180 if (txctl->an && ieee80211_is_data_present(hdr->frame_control)) 2226 queue = ieee80211_is_data_present(hdr->frame_control);
2227
2228 /* Force queueing of all frames that belong to a virtual interface on
2229 * a different channel context, to ensure that they are sent on the
2230 * correct channel.
2231 */
2232 if (((avp && avp->chanctx != sc->cur_chan) ||
2233 sc->cur_chan->stopped) && !txctl->force_channel) {
2234 if (!txctl->an)
2235 txctl->an = &avp->mcast_node;
2236 info->flags &= ~IEEE80211_TX_CTL_PS_RESPONSE;
2237 queue = true;
2238 }
2239
2240 if (txctl->an && queue)
2181 tid = ath_get_skb_tid(sc, txctl->an, skb); 2241 tid = ath_get_skb_tid(sc, txctl->an, skb);
2182 2242
2183 if (info->flags & IEEE80211_TX_CTL_PS_RESPONSE) { 2243 if (info->flags & (IEEE80211_TX_CTL_PS_RESPONSE |
2244 IEEE80211_TX_CTL_TX_OFFCHAN)) {
2184 ath_txq_unlock(sc, txq); 2245 ath_txq_unlock(sc, txq);
2185 txq = sc->tx.uapsdq; 2246 txq = sc->tx.uapsdq;
2186 ath_txq_lock(sc, txq); 2247 ath_txq_lock(sc, txq);
2187 } else if (txctl->an && 2248 } else if (txctl->an && queue) {
2188 ieee80211_is_data_present(hdr->frame_control)) {
2189 WARN_ON(tid->ac->txq != txctl->txq); 2249 WARN_ON(tid->ac->txq != txctl->txq);
2190 2250
2191 if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) 2251 if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
@@ -2198,7 +2258,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
2198 TX_STAT_INC(txq->axq_qnum, a_queued_sw); 2258 TX_STAT_INC(txq->axq_qnum, a_queued_sw);
2199 __skb_queue_tail(&tid->buf_q, skb); 2259 __skb_queue_tail(&tid->buf_q, skb);
2200 if (!txctl->an->sleeping) 2260 if (!txctl->an->sleeping)
2201 ath_tx_queue_tid(txq, tid); 2261 ath_tx_queue_tid(sc, txq, tid);
2202 2262
2203 ath_txq_schedule(sc, txq); 2263 ath_txq_schedule(sc, txq);
2204 goto out; 2264 goto out;
@@ -2244,8 +2304,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2244 int max_duration; 2304 int max_duration;
2245 2305
2246 max_duration = 2306 max_duration =
2247 sc->cur_beacon_conf.beacon_interval * 1000 * 2307 sc->cur_chan->beacon.beacon_interval * 1000 *
2248 sc->cur_beacon_conf.dtim_period / ATH_BCBUF; 2308 sc->cur_chan->beacon.dtim_period / ATH_BCBUF;
2249 2309
2250 do { 2310 do {
2251 struct ath_frame_info *fi = get_frame_info(skb); 2311 struct ath_frame_info *fi = get_frame_info(skb);
@@ -2560,6 +2620,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
2560 sc->beacon.tx_processed = true; 2620 sc->beacon.tx_processed = true;
2561 sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); 2621 sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
2562 2622
2623 ath_chanctx_event(sc, NULL,
2624 ATH_CHANCTX_EVENT_BEACON_SENT);
2563 ath9k_csa_update(sc); 2625 ath9k_csa_update(sc);
2564 continue; 2626 continue;
2565 } 2627 }
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 820d4ebd9322..4ac2c208c9ba 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -104,8 +104,8 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
104 return -EOPNOTSUPP; 104 return -EOPNOTSUPP;
105} 105}
106 106
107static int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, 107int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
108 struct station_info *sinfo) 108 struct station_info *sinfo)
109{ 109{
110 struct wmi_notify_req_cmd cmd = { 110 struct wmi_notify_req_cmd cmd = {
111 .cid = cid, 111 .cid = cid,
@@ -287,6 +287,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
287 return -EBUSY; 287 return -EBUSY;
288 } 288 }
289 289
290 wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
290 wil->scan_request = request; 291 wil->scan_request = request;
291 mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); 292 mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
292 293
@@ -443,15 +444,15 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
443 return rc; 444 return rc;
444} 445}
445 446
446static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, 447int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
447 struct wireless_dev *wdev, 448 struct cfg80211_mgmt_tx_params *params,
448 struct cfg80211_mgmt_tx_params *params, 449 u64 *cookie)
449 u64 *cookie)
450{ 450{
451 const u8 *buf = params->buf; 451 const u8 *buf = params->buf;
452 size_t len = params->len; 452 size_t len = params->len;
453 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 453 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
454 int rc; 454 int rc;
455 bool tx_status = false;
455 struct ieee80211_mgmt *mgmt_frame = (void *)buf; 456 struct ieee80211_mgmt *mgmt_frame = (void *)buf;
456 struct wmi_sw_tx_req_cmd *cmd; 457 struct wmi_sw_tx_req_cmd *cmd;
457 struct { 458 struct {
@@ -460,8 +461,10 @@ static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
460 } __packed evt; 461 } __packed evt;
461 462
462 cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL); 463 cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
463 if (!cmd) 464 if (!cmd) {
464 return -ENOMEM; 465 rc = -ENOMEM;
466 goto out;
467 }
465 468
466 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN); 469 memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
467 cmd->len = cpu_to_le16(len); 470 cmd->len = cpu_to_le16(len);
@@ -470,10 +473,12 @@ static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
470 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len, 473 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
471 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); 474 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
472 if (rc == 0) 475 if (rc == 0)
473 rc = evt.evt.status; 476 tx_status = !evt.evt.status;
474 477
475 kfree(cmd); 478 kfree(cmd);
476 479 out:
480 cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
481 tx_status, GFP_KERNEL);
477 return rc; 482 return rc;
478} 483}
479 484
@@ -562,6 +567,34 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
562 return rc; 567 return rc;
563} 568}
564 569
570static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
571{
572 print_hex_dump_bytes("head ", DUMP_PREFIX_OFFSET,
573 b->head, b->head_len);
574 print_hex_dump_bytes("tail ", DUMP_PREFIX_OFFSET,
575 b->tail, b->tail_len);
576 print_hex_dump_bytes("BCON IE ", DUMP_PREFIX_OFFSET,
577 b->beacon_ies, b->beacon_ies_len);
578 print_hex_dump_bytes("PROBE ", DUMP_PREFIX_OFFSET,
579 b->probe_resp, b->probe_resp_len);
580 print_hex_dump_bytes("PROBE IE ", DUMP_PREFIX_OFFSET,
581 b->proberesp_ies, b->proberesp_ies_len);
582 print_hex_dump_bytes("ASSOC IE ", DUMP_PREFIX_OFFSET,
583 b->assocresp_ies, b->assocresp_ies_len);
584}
585
586static void wil_print_crypto(struct wil6210_priv *wil,
587 struct cfg80211_crypto_settings *c)
588{
589 wil_dbg_misc(wil, "WPA versions: 0x%08x cipher group 0x%08x\n",
590 c->wpa_versions, c->cipher_group);
591 wil_dbg_misc(wil, "Pairwise ciphers [%d]\n", c->n_ciphers_pairwise);
592 wil_dbg_misc(wil, "AKM suites [%d]\n", c->n_akm_suites);
593 wil_dbg_misc(wil, "Control port : %d, eth_type 0x%04x no_encrypt %d\n",
594 c->control_port, be16_to_cpu(c->control_port_ethertype),
595 c->control_port_no_encrypt);
596}
597
565static int wil_fix_bcon(struct wil6210_priv *wil, 598static int wil_fix_bcon(struct wil6210_priv *wil,
566 struct cfg80211_beacon_data *bcon) 599 struct cfg80211_beacon_data *bcon)
567{ 600{
@@ -595,8 +628,11 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
595 struct wireless_dev *wdev = ndev->ieee80211_ptr; 628 struct wireless_dev *wdev = ndev->ieee80211_ptr;
596 struct ieee80211_channel *channel = info->chandef.chan; 629 struct ieee80211_channel *channel = info->chandef.chan;
597 struct cfg80211_beacon_data *bcon = &info->beacon; 630 struct cfg80211_beacon_data *bcon = &info->beacon;
631 struct cfg80211_crypto_settings *crypto = &info->crypto;
598 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); 632 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
599 633
634 wil_dbg_misc(wil, "%s()\n", __func__);
635
600 if (!channel) { 636 if (!channel) {
601 wil_err(wil, "AP: No channel???\n"); 637 wil_err(wil, "AP: No channel???\n");
602 return -EINVAL; 638 return -EINVAL;
@@ -604,11 +640,19 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
604 640
605 wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value, 641 wil_dbg_misc(wil, "AP on Channel %d %d MHz, %s\n", channel->hw_value,
606 channel->center_freq, info->privacy ? "secure" : "open"); 642 channel->center_freq, info->privacy ? "secure" : "open");
643 wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
644 info->privacy, info->auth_type);
645 wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
646 info->dtim_period);
607 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET, 647 print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
608 info->ssid, info->ssid_len); 648 info->ssid, info->ssid_len);
649 wil_print_bcon_data(bcon);
650 wil_print_crypto(wil, crypto);
609 651
610 if (wil_fix_bcon(wil, bcon)) 652 if (wil_fix_bcon(wil, bcon)) {
611 wil_dbg_misc(wil, "Fixed bcon\n"); 653 wil_dbg_misc(wil, "Fixed bcon\n");
654 wil_print_bcon_data(bcon);
655 }
612 656
613 mutex_lock(&wil->mutex); 657 mutex_lock(&wil->mutex);
614 658
@@ -663,6 +707,8 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
663 int rc = 0; 707 int rc = 0;
664 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 708 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
665 709
710 wil_dbg_misc(wil, "%s()\n", __func__);
711
666 mutex_lock(&wil->mutex); 712 mutex_lock(&wil->mutex);
667 713
668 rc = wmi_pcp_stop(wil); 714 rc = wmi_pcp_stop(wil);
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 8d4bc4bfb664..a868c5eebe37 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -19,6 +19,7 @@
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/pci.h> 20#include <linux/pci.h>
21#include <linux/rtnetlink.h> 21#include <linux/rtnetlink.h>
22#include <linux/power_supply.h>
22 23
23#include "wil6210.h" 24#include "wil6210.h"
24#include "txrx.h" 25#include "txrx.h"
@@ -69,14 +70,32 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
69 70
70 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 71 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
71 struct vring *vring = &(wil->vring_tx[i]); 72 struct vring *vring = &(wil->vring_tx[i]);
73 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
74
72 if (vring->va) { 75 if (vring->va) {
73 int cid = wil->vring2cid_tid[i][0]; 76 int cid = wil->vring2cid_tid[i][0];
74 int tid = wil->vring2cid_tid[i][1]; 77 int tid = wil->vring2cid_tid[i][1];
78 u32 swhead = vring->swhead;
79 u32 swtail = vring->swtail;
80 int used = (vring->size + swhead - swtail)
81 % vring->size;
82 int avail = vring->size - used - 1;
75 char name[10]; 83 char name[10];
84 /* performance monitoring */
85 cycles_t now = get_cycles();
86 cycles_t idle = txdata->idle * 100;
87 cycles_t total = now - txdata->begin;
88
89 do_div(idle, total);
90 txdata->begin = now;
91 txdata->idle = 0ULL;
92
76 snprintf(name, sizeof(name), "tx_%2d", i); 93 snprintf(name, sizeof(name), "tx_%2d", i);
77 94
78 seq_printf(s, "\n%pM CID %d TID %d\n", 95 seq_printf(s, "\n%pM CID %d TID %d [%3d|%3d] idle %3d%%\n",
79 wil->sta[cid].addr, cid, tid); 96 wil->sta[cid].addr, cid, tid, used, avail,
97 (int)idle);
98
80 wil_print_vring(s, wil, name, vring, '_', 'H'); 99 wil_print_vring(s, wil, name, vring, '_', 'H');
81 } 100 }
82 } 101 }
@@ -231,6 +250,26 @@ static struct dentry *wil_debugfs_create_iomem_x32(const char *name,
231 &fops_iomem_x32); 250 &fops_iomem_x32);
232} 251}
233 252
253static int wil_debugfs_ulong_set(void *data, u64 val)
254{
255 *(ulong *)data = val;
256 return 0;
257}
258static int wil_debugfs_ulong_get(void *data, u64 *val)
259{
260 *val = *(ulong *)data;
261 return 0;
262}
263DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
264 wil_debugfs_ulong_set, "%llu\n");
265
266static struct dentry *wil_debugfs_create_ulong(const char *name, umode_t mode,
267 struct dentry *parent,
268 ulong *value)
269{
270 return debugfs_create_file(name, mode, parent, value, &wil_fops_ulong);
271}
272
234static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, 273static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
235 const char *name, 274 const char *name,
236 struct dentry *parent, u32 off) 275 struct dentry *parent, u32 off)
@@ -284,11 +323,11 @@ static int wil6210_debugfs_create_ITR_CNT(struct wil6210_priv *wil,
284 if (IS_ERR_OR_NULL(d)) 323 if (IS_ERR_OR_NULL(d))
285 return -ENODEV; 324 return -ENODEV;
286 325
287 wil_debugfs_create_iomem_x32("TRSH", S_IRUGO, d, wil->csr + 326 wil_debugfs_create_iomem_x32("TRSH", S_IRUGO | S_IWUSR, d, wil->csr +
288 HOSTADDR(RGF_DMA_ITR_CNT_TRSH)); 327 HOSTADDR(RGF_DMA_ITR_CNT_TRSH));
289 wil_debugfs_create_iomem_x32("DATA", S_IRUGO, d, wil->csr + 328 wil_debugfs_create_iomem_x32("DATA", S_IRUGO | S_IWUSR, d, wil->csr +
290 HOSTADDR(RGF_DMA_ITR_CNT_DATA)); 329 HOSTADDR(RGF_DMA_ITR_CNT_DATA));
291 wil_debugfs_create_iomem_x32("CTL", S_IRUGO, d, wil->csr + 330 wil_debugfs_create_iomem_x32("CTL", S_IRUGO | S_IWUSR, d, wil->csr +
292 HOSTADDR(RGF_DMA_ITR_CNT_CRL)); 331 HOSTADDR(RGF_DMA_ITR_CNT_CRL));
293 332
294 return 0; 333 return 0;
@@ -397,6 +436,124 @@ static const struct file_operations fops_reset = {
397 .write = wil_write_file_reset, 436 .write = wil_write_file_reset,
398 .open = simple_open, 437 .open = simple_open,
399}; 438};
439/*---write channel 1..4 to rxon for it, 0 to rxoff---*/
440static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
441 size_t len, loff_t *ppos)
442{
443 struct wil6210_priv *wil = file->private_data;
444 int rc;
445 long channel;
446 bool on;
447
448 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
449 if (!kbuf)
450 return -ENOMEM;
451 if (copy_from_user(kbuf, buf, len))
452 return -EIO;
453
454 kbuf[len] = '\0';
455 rc = kstrtol(kbuf, 0, &channel);
456 kfree(kbuf);
457 if (rc)
458 return rc;
459
460 if ((channel < 0) || (channel > 4)) {
461 wil_err(wil, "Invalid channel %ld\n", channel);
462 return -EINVAL;
463 }
464 on = !!channel;
465
466 if (on) {
467 rc = wmi_set_channel(wil, (int)channel);
468 if (rc)
469 return rc;
470 }
471
472 rc = wmi_rxon(wil, on);
473 if (rc)
474 return rc;
475
476 return len;
477}
478
479static const struct file_operations fops_rxon = {
480 .write = wil_write_file_rxon,
481 .open = simple_open,
482};
483/*---tx_mgmt---*/
484/* Write mgmt frame to this file to send it */
485static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
486 size_t len, loff_t *ppos)
487{
488 struct wil6210_priv *wil = file->private_data;
489 struct wiphy *wiphy = wil_to_wiphy(wil);
490 struct wireless_dev *wdev = wil_to_wdev(wil);
491 struct cfg80211_mgmt_tx_params params;
492 int rc;
493
494 void *frame = kmalloc(len, GFP_KERNEL);
495 if (!frame)
496 return -ENOMEM;
497
498 if (copy_from_user(frame, buf, len))
499 return -EIO;
500
501 params.buf = frame;
502 params.len = len;
503 params.chan = wdev->preset_chandef.chan;
504
505 rc = wil_cfg80211_mgmt_tx(wiphy, wdev, &params, NULL);
506
507 kfree(frame);
508 wil_info(wil, "%s() -> %d\n", __func__, rc);
509
510 return len;
511}
512
513static const struct file_operations fops_txmgmt = {
514 .write = wil_write_file_txmgmt,
515 .open = simple_open,
516};
517
518/* Write WMI command (w/o mbox header) to this file to send it
519 * WMI starts from wil6210_mbox_hdr_wmi header
520 */
521static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
522 size_t len, loff_t *ppos)
523{
524 struct wil6210_priv *wil = file->private_data;
525 struct wil6210_mbox_hdr_wmi *wmi;
526 void *cmd;
527 int cmdlen = len - sizeof(struct wil6210_mbox_hdr_wmi);
528 u16 cmdid;
529 int rc, rc1;
530
531 if (cmdlen <= 0)
532 return -EINVAL;
533
534 wmi = kmalloc(len, GFP_KERNEL);
535 if (!wmi)
536 return -ENOMEM;
537
538 rc = simple_write_to_buffer(wmi, len, ppos, buf, len);
539 if (rc < 0)
540 return rc;
541
542 cmd = &wmi[1];
543 cmdid = le16_to_cpu(wmi->id);
544
545 rc1 = wmi_send(wil, cmdid, cmd, cmdlen);
546 kfree(wmi);
547
548 wil_info(wil, "%s(0x%04x[%d]) -> %d\n", __func__, cmdid, cmdlen, rc1);
549
550 return rc;
551}
552
553static const struct file_operations fops_wmi = {
554 .write = wil_write_file_wmi,
555 .open = simple_open,
556};
400 557
401static void wil_seq_hexdump(struct seq_file *s, void *p, int len, 558static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
402 const char *prefix) 559 const char *prefix)
@@ -600,8 +757,8 @@ static int wil_temp_debugfs_show(struct seq_file *s, void *data)
600 return 0; 757 return 0;
601 } 758 }
602 759
603 print_temp(s, "MAC temperature :", t_m); 760 print_temp(s, "T_mac =", t_m);
604 print_temp(s, "Radio temperature :", t_r); 761 print_temp(s, "T_radio =", t_r);
605 762
606 return 0; 763 return 0;
607} 764}
@@ -618,6 +775,130 @@ static const struct file_operations fops_temp = {
618 .llseek = seq_lseek, 775 .llseek = seq_lseek,
619}; 776};
620 777
778/*---------freq------------*/
779static int wil_freq_debugfs_show(struct seq_file *s, void *data)
780{
781 struct wil6210_priv *wil = s->private;
782 struct wireless_dev *wdev = wil_to_wdev(wil);
783 u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
784
785 seq_printf(s, "Freq = %d\n", freq);
786
787 return 0;
788}
789
790static int wil_freq_seq_open(struct inode *inode, struct file *file)
791{
792 return single_open(file, wil_freq_debugfs_show, inode->i_private);
793}
794
795static const struct file_operations fops_freq = {
796 .open = wil_freq_seq_open,
797 .release = single_release,
798 .read = seq_read,
799 .llseek = seq_lseek,
800};
801
802/*---------link------------*/
803static int wil_link_debugfs_show(struct seq_file *s, void *data)
804{
805 struct wil6210_priv *wil = s->private;
806 struct station_info sinfo;
807 int i, rc;
808
809 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
810 struct wil_sta_info *p = &wil->sta[i];
811 char *status = "unknown";
812 switch (p->status) {
813 case wil_sta_unused:
814 status = "unused ";
815 break;
816 case wil_sta_conn_pending:
817 status = "pending ";
818 break;
819 case wil_sta_connected:
820 status = "connected";
821 break;
822 }
823 seq_printf(s, "[%d] %pM %s%s\n", i, p->addr, status,
824 (p->data_port_open ? " data_port_open" : ""));
825
826 if (p->status == wil_sta_connected) {
827 rc = wil_cid_fill_sinfo(wil, i, &sinfo);
828 if (rc)
829 return rc;
830
831 seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs);
832 seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs);
833 seq_printf(s, " SQ = %d\n", sinfo.signal);
834 }
835 }
836
837 return 0;
838}
839
840static int wil_link_seq_open(struct inode *inode, struct file *file)
841{
842 return single_open(file, wil_link_debugfs_show, inode->i_private);
843}
844
845static const struct file_operations fops_link = {
846 .open = wil_link_seq_open,
847 .release = single_release,
848 .read = seq_read,
849 .llseek = seq_lseek,
850};
851
852/*---------info------------*/
853static int wil_info_debugfs_show(struct seq_file *s, void *data)
854{
855 struct wil6210_priv *wil = s->private;
856 struct net_device *ndev = wil_to_ndev(wil);
857 int is_ac = power_supply_is_system_supplied();
858 int rx = atomic_xchg(&wil->isr_count_rx, 0);
859 int tx = atomic_xchg(&wil->isr_count_tx, 0);
860 static ulong rxf_old, txf_old;
861 ulong rxf = ndev->stats.rx_packets;
862 ulong txf = ndev->stats.tx_packets;
863 unsigned int i;
864
865 /* >0 : AC; 0 : battery; <0 : error */
866 seq_printf(s, "AC powered : %d\n", is_ac);
867 seq_printf(s, "Rx irqs:packets : %8d : %8ld\n", rx, rxf - rxf_old);
868 seq_printf(s, "Tx irqs:packets : %8d : %8ld\n", tx, txf - txf_old);
869 rxf_old = rxf;
870 txf_old = txf;
871
872
873#define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \
874 " " __stringify(x) : ""
875
876 for (i = 0; i < ndev->num_tx_queues; i++) {
877 struct netdev_queue *txq = netdev_get_tx_queue(ndev, i);
878 unsigned long state = txq->state;
879
880 seq_printf(s, "Tx queue[%i] state : 0x%lx%s%s%s\n", i, state,
881 CHECK_QSTATE(DRV_XOFF),
882 CHECK_QSTATE(STACK_XOFF),
883 CHECK_QSTATE(FROZEN)
884 );
885 }
886#undef CHECK_QSTATE
887 return 0;
888}
889
890static int wil_info_seq_open(struct inode *inode, struct file *file)
891{
892 return single_open(file, wil_info_debugfs_show, inode->i_private);
893}
894
895static const struct file_operations fops_info = {
896 .open = wil_info_seq_open,
897 .release = single_release,
898 .read = seq_read,
899 .llseek = seq_lseek,
900};
901
621/*---------Station matrix------------*/ 902/*---------Station matrix------------*/
622static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) 903static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
623{ 904{
@@ -630,7 +911,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
630 else 911 else
631 seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_'); 912 seq_printf(s, "%c", r->reorder_buf[i] ? '*' : '_');
632 } 913 }
633 seq_puts(s, "]\n"); 914 seq_printf(s, "] last drop 0x%03x\n", r->ssn_last_drop);
634} 915}
635 916
636static int wil_sta_debugfs_show(struct seq_file *s, void *data) 917static int wil_sta_debugfs_show(struct seq_file *s, void *data)
@@ -703,6 +984,8 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
703 debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid); 984 debugfs_create_file("ssid", S_IRUGO | S_IWUSR, dbg, wil, &fops_ssid);
704 debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg, 985 debugfs_create_u32("secure_pcp", S_IRUGO | S_IWUSR, dbg,
705 &wil->secure_pcp); 986 &wil->secure_pcp);
987 wil_debugfs_create_ulong("status", S_IRUGO | S_IWUSR, dbg,
988 &wil->status);
706 989
707 wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg, 990 wil6210_debugfs_create_ISR(wil, "USER_ICR", dbg,
708 HOSTADDR(RGF_USER_USER_ICR)); 991 HOSTADDR(RGF_USER_USER_ICR));
@@ -719,7 +1002,13 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
719 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread); 1002 debugfs_create_file("mem_val", S_IRUGO, dbg, wil, &fops_memread);
720 1003
721 debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset); 1004 debugfs_create_file("reset", S_IWUSR, dbg, wil, &fops_reset);
1005 debugfs_create_file("rxon", S_IWUSR, dbg, wil, &fops_rxon);
1006 debugfs_create_file("tx_mgmt", S_IWUSR, dbg, wil, &fops_txmgmt);
1007 debugfs_create_file("wmi_send", S_IWUSR, dbg, wil, &fops_wmi);
722 debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp); 1008 debugfs_create_file("temp", S_IRUGO, dbg, wil, &fops_temp);
1009 debugfs_create_file("freq", S_IRUGO, dbg, wil, &fops_freq);
1010 debugfs_create_file("link", S_IRUGO, dbg, wil, &fops_link);
1011 debugfs_create_file("info", S_IRUGO, dbg, wil, &fops_info);
723 1012
724 wil->rgf_blob.data = (void * __force)wil->csr + 0; 1013 wil->rgf_blob.data = (void * __force)wil->csr + 0;
725 wil->rgf_blob.size = 0xa000; 1014 wil->rgf_blob.size = 0xa000;
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 73593aa3cd98..67f1002a03a1 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -208,6 +208,7 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
208 208
209 /* Rx IRQ will be enabled when NAPI processing finished */ 209 /* Rx IRQ will be enabled when NAPI processing finished */
210 210
211 atomic_inc(&wil->isr_count_rx);
211 return IRQ_HANDLED; 212 return IRQ_HANDLED;
212} 213}
213 214
@@ -246,6 +247,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
246 247
247 /* Tx IRQ will be enabled when NAPI processing finished */ 248 /* Tx IRQ will be enabled when NAPI processing finished */
248 249
250 atomic_inc(&wil->isr_count_tx);
249 return IRQ_HANDLED; 251 return IRQ_HANDLED;
250} 252}
251 253
@@ -257,6 +259,7 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
257 [1] = "EVENT=FW_ERROR", 259 [1] = "EVENT=FW_ERROR",
258 [2] = NULL, 260 [2] = NULL,
259 }; 261 };
262 wil_err(wil, "Notify about firmware error\n");
260 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 263 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
261} 264}
262 265
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 11e6d9d22eae..53a689ed7c7d 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -61,11 +61,24 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
61static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) 61static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
62{ 62{
63 uint i; 63 uint i;
64 struct net_device *ndev = wil_to_ndev(wil);
65 struct wireless_dev *wdev = wil->wdev;
64 struct wil_sta_info *sta = &wil->sta[cid]; 66 struct wil_sta_info *sta = &wil->sta[cid];
67 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
68 sta->status);
65 69
66 sta->data_port_open = false; 70 sta->data_port_open = false;
67 if (sta->status != wil_sta_unused) { 71 if (sta->status != wil_sta_unused) {
68 wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING); 72 wmi_disconnect_sta(wil, sta->addr, WLAN_REASON_DEAUTH_LEAVING);
73 switch (wdev->iftype) {
74 case NL80211_IFTYPE_AP:
75 case NL80211_IFTYPE_P2P_GO:
76 /* AP-like interface */
77 cfg80211_del_sta(ndev, sta->addr, GFP_KERNEL);
78 break;
79 default:
80 break;
81 }
69 sta->status = wil_sta_unused; 82 sta->status = wil_sta_unused;
70 } 83 }
71 84
@@ -119,11 +132,6 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid)
119 clear_bit(wil_status_fwconnecting, &wil->status); 132 clear_bit(wil_status_fwconnecting, &wil->status);
120 break; 133 break;
121 default: 134 default:
122 /* AP-like interface and monitor:
123 * never scan, always connected
124 */
125 if (bssid)
126 cfg80211_del_sta(ndev, bssid, GFP_KERNEL);
127 break; 135 break;
128 } 136 }
129} 137}
@@ -465,6 +473,7 @@ void wil_link_on(struct wil6210_priv *wil)
465 wil_dbg_misc(wil, "%s()\n", __func__); 473 wil_dbg_misc(wil, "%s()\n", __func__);
466 474
467 netif_carrier_on(ndev); 475 netif_carrier_on(ndev);
476 wil_dbg_misc(wil, "netif_tx_wake : link on\n");
468 netif_tx_wake_all_queues(ndev); 477 netif_tx_wake_all_queues(ndev);
469} 478}
470 479
@@ -475,6 +484,7 @@ void wil_link_off(struct wil6210_priv *wil)
475 wil_dbg_misc(wil, "%s()\n", __func__); 484 wil_dbg_misc(wil, "%s()\n", __func__);
476 485
477 netif_tx_stop_all_queues(ndev); 486 netif_tx_stop_all_queues(ndev);
487 wil_dbg_misc(wil, "netif_tx_stop : link off\n");
478 netif_carrier_off(ndev); 488 netif_carrier_off(ndev);
479} 489}
480 490
@@ -552,6 +562,8 @@ static int __wil_down(struct wil6210_priv *wil)
552 napi_disable(&wil->napi_tx); 562 napi_disable(&wil->napi_tx);
553 563
554 if (wil->scan_request) { 564 if (wil->scan_request) {
565 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
566 wil->scan_request);
555 del_timer_sync(&wil->scan_timer); 567 del_timer_sync(&wil->scan_timer);
556 cfg80211_scan_done(wil->scan_request, true); 568 cfg80211_scan_done(wil->scan_request, true);
557 wil->scan_request = NULL; 569 wil->scan_request = NULL;
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 1e2e07b9d13d..77b6272d93fb 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -15,7 +15,6 @@
15 */ 15 */
16 16
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/debugfs.h>
19#include <linux/pci.h> 18#include <linux/pci.h>
20#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
21 20
@@ -27,11 +26,22 @@ MODULE_PARM_DESC(use_msi,
27 " Use MSI interrupt: " 26 " Use MSI interrupt: "
28 "0 - don't, 1 - (default) - single, or 3"); 27 "0 - don't, 1 - (default) - single, or 3");
29 28
29static bool debug_fw; /* = false; */
30module_param(debug_fw, bool, S_IRUGO);
31MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug");
32
30/* Bus ops */ 33/* Bus ops */
31static int wil_if_pcie_enable(struct wil6210_priv *wil) 34static int wil_if_pcie_enable(struct wil6210_priv *wil)
32{ 35{
33 struct pci_dev *pdev = wil->pdev; 36 struct pci_dev *pdev = wil->pdev;
34 int rc; 37 int rc;
38 /* on platforms with buggy ACPI, pdev->msi_enabled may be set to
39 * allow pci_enable_device to work. This indicates INTx was not routed
40 * and only MSI should be used
41 */
42 int msi_only = pdev->msi_enabled;
43
44 pdev->msi_enabled = 0;
35 45
36 pci_set_master(pdev); 46 pci_set_master(pdev);
37 47
@@ -63,6 +73,12 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
63 73
64 wil->n_msi = use_msi; 74 wil->n_msi = use_msi;
65 75
76 if ((wil->n_msi == 0) && msi_only) {
77 wil_err(wil, "Interrupt pin not routed, unable to use INTx\n");
78 rc = -ENODEV;
79 goto stop_master;
80 }
81
66 rc = wil6210_init_irq(wil, pdev->irq); 82 rc = wil6210_init_irq(wil, pdev->irq);
67 if (rc) 83 if (rc)
68 goto stop_master; 84 goto stop_master;
@@ -71,6 +87,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
71 mutex_lock(&wil->mutex); 87 mutex_lock(&wil->mutex);
72 rc = wil_reset(wil); 88 rc = wil_reset(wil);
73 mutex_unlock(&wil->mutex); 89 mutex_unlock(&wil->mutex);
90 if (debug_fw)
91 rc = 0;
74 if (rc) 92 if (rc)
75 goto release_irq; 93 goto release_irq;
76 94
@@ -119,9 +137,16 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
119 137
120 rc = pci_enable_device(pdev); 138 rc = pci_enable_device(pdev);
121 if (rc) { 139 if (rc) {
122 dev_err(&pdev->dev, "pci_enable_device failed\n"); 140 dev_err(&pdev->dev,
123 return -ENODEV; 141 "pci_enable_device failed, retry with MSI only\n");
142 /* Work around for platforms that can't allocate IRQ:
143 * retry with MSI only
144 */
145 pdev->msi_enabled = 1;
146 rc = pci_enable_device(pdev);
124 } 147 }
148 if (rc)
149 return -ENODEV;
125 /* rollback to err_disable_pdev */ 150 /* rollback to err_disable_pdev */
126 151
127 rc = pci_request_region(pdev, 0, WIL_NAME); 152 rc = pci_request_region(pdev, 0, WIL_NAME);
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 747ae1275877..180ca4793904 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -116,6 +116,7 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
116 116
117 /* frame with out of date sequence number */ 117 /* frame with out of date sequence number */
118 if (seq_less(seq, r->head_seq_num)) { 118 if (seq_less(seq, r->head_seq_num)) {
119 r->ssn_last_drop = seq;
119 dev_kfree_skb(skb); 120 dev_kfree_skb(skb);
120 goto out; 121 goto out;
121 } 122 }
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 0784ef3d4ce2..af4b93e4beb5 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -525,6 +525,17 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
525 ndev->stats.rx_bytes += len; 525 ndev->stats.rx_bytes += len;
526 stats->rx_bytes += len; 526 stats->rx_bytes += len;
527 } 527 }
528 {
529 static const char * const gro_res_str[] = {
530 [GRO_MERGED] = "GRO_MERGED",
531 [GRO_MERGED_FREE] = "GRO_MERGED_FREE",
532 [GRO_HELD] = "GRO_HELD",
533 [GRO_NORMAL] = "GRO_NORMAL",
534 [GRO_DROP] = "GRO_DROP",
535 };
536 wil_dbg_txrx(wil, "Rx complete %d bytes => %s,\n",
537 len, gro_res_str[rc]);
538 }
528} 539}
529 540
530/** 541/**
@@ -760,7 +771,7 @@ static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
760 goto found; 771 goto found;
761 } 772 }
762 773
763 wil_err(wil, "Tx while no vrings active?\n"); 774 wil_dbg_txrx(wil, "Tx while no vrings active?\n");
764 775
765 return NULL; 776 return NULL;
766 777
@@ -881,6 +892,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
881 int nr_frags = skb_shinfo(skb)->nr_frags; 892 int nr_frags = skb_shinfo(skb)->nr_frags;
882 uint f = 0; 893 uint f = 0;
883 int vring_index = vring - wil->vring_tx; 894 int vring_index = vring - wil->vring_tx;
895 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
884 uint i = swhead; 896 uint i = swhead;
885 dma_addr_t pa; 897 dma_addr_t pa;
886 898
@@ -953,6 +965,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
953 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 965 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
954 (const void *)d, sizeof(*d), false); 966 (const void *)d, sizeof(*d), false);
955 967
968 if (wil_vring_is_empty(vring)) /* performance monitoring */
969 txdata->idle += get_cycles() - txdata->last_idle;
970
956 /* advance swhead */ 971 /* advance swhead */
957 wil_vring_advance_head(vring, nr_frags + 1); 972 wil_vring_advance_head(vring, nr_frags + 1);
958 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead); 973 wil_dbg_txrx(wil, "Tx swhead %d -> %d\n", swhead, vring->swhead);
@@ -1016,15 +1031,17 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1016 vring = wil_tx_bcast(wil, skb); 1031 vring = wil_tx_bcast(wil, skb);
1017 } 1032 }
1018 if (!vring) { 1033 if (!vring) {
1019 wil_err(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1034 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1020 goto drop; 1035 goto drop;
1021 } 1036 }
1022 /* set up vring entry */ 1037 /* set up vring entry */
1023 rc = wil_tx_vring(wil, vring, skb); 1038 rc = wil_tx_vring(wil, vring, skb);
1024 1039
1025 /* do we still have enough room in the vring? */ 1040 /* do we still have enough room in the vring? */
1026 if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring)) 1041 if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring)) {
1027 netif_tx_stop_all_queues(wil_to_ndev(wil)); 1042 netif_tx_stop_all_queues(wil_to_ndev(wil));
1043 wil_dbg_txrx(wil, "netif_tx_stop : ring full\n");
1044 }
1028 1045
1029 switch (rc) { 1046 switch (rc) {
1030 case 0: 1047 case 0:
@@ -1132,8 +1149,16 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1132 done++; 1149 done++;
1133 } 1150 }
1134 } 1151 }
1135 if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) 1152
1153 if (wil_vring_is_empty(vring)) { /* performance monitoring */
1154 wil_dbg_txrx(wil, "Ring[%2d] empty\n", ringid);
1155 txdata->last_idle = get_cycles();
1156 }
1157
1158 if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring)) {
1159 wil_dbg_txrx(wil, "netif_tx_wake : ring not full\n");
1136 netif_tx_wake_all_queues(wil_to_ndev(wil)); 1160 netif_tx_wake_all_queues(wil_to_ndev(wil));
1161 }
1137 1162
1138 return done; 1163 return done;
1139} 1164}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index e25edc52398f..424906635f05 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -20,6 +20,7 @@
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <net/cfg80211.h> 22#include <net/cfg80211.h>
23#include <linux/timex.h>
23 24
24#define WIL_NAME "wil6210" 25#define WIL_NAME "wil6210"
25 26
@@ -251,7 +252,7 @@ struct vring {
251 */ 252 */
252struct vring_tx_data { 253struct vring_tx_data {
253 int enabled; 254 int enabled;
254 255 cycles_t idle, last_idle, begin;
255}; 256};
256 257
257enum { /* for wil6210_priv.status */ 258enum { /* for wil6210_priv.status */
@@ -303,6 +304,7 @@ struct wil_tid_ampdu_rx {
303 u16 ssn; 304 u16 ssn;
304 u16 buf_size; 305 u16 buf_size;
305 u16 timeout; 306 u16 timeout;
307 u16 ssn_last_drop;
306 u8 dialog_token; 308 u8 dialog_token;
307 bool first_time; /* is it 1-st time this buffer used? */ 309 bool first_time; /* is it 1-st time this buffer used? */
308}; 310};
@@ -410,6 +412,7 @@ struct wil6210_priv {
410 struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ 412 struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
411 /* statistics */ 413 /* statistics */
412 struct wil6210_stats stats; 414 struct wil6210_stats stats;
415 atomic_t isr_count_rx, isr_count_tx;
413 /* debugfs */ 416 /* debugfs */
414 struct dentry *debug; 417 struct dentry *debug;
415 struct debugfs_blob_wrapper fw_code_blob; 418 struct debugfs_blob_wrapper fw_code_blob;
@@ -504,9 +507,14 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq);
504void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 507void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
505void wil6210_disable_irq(struct wil6210_priv *wil); 508void wil6210_disable_irq(struct wil6210_priv *wil);
506void wil6210_enable_irq(struct wil6210_priv *wil); 509void wil6210_enable_irq(struct wil6210_priv *wil);
510int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
511 struct cfg80211_mgmt_tx_params *params,
512 u64 *cookie);
507 513
508int wil6210_debugfs_init(struct wil6210_priv *wil); 514int wil6210_debugfs_init(struct wil6210_priv *wil);
509void wil6210_debugfs_remove(struct wil6210_priv *wil); 515void wil6210_debugfs_remove(struct wil6210_priv *wil);
516int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
517 struct station_info *sinfo);
510 518
511struct wireless_dev *wil_cfg80211_init(struct device *dev); 519struct wireless_dev *wil_cfg80211_init(struct device *dev);
512void wil_wdev_free(struct wil6210_priv *wil); 520void wil_wdev_free(struct wil6210_priv *wil);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 6cc0e182cc70..a136dab560e2 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -75,6 +75,7 @@ static const struct {
75 {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */ 75 {0x800000, 0x808000, 0x900000}, /* FW data RAM 32k */
76 {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */ 76 {0x840000, 0x860000, 0x908000}, /* peripheral data RAM 128k/96k used */
77 {0x880000, 0x88a000, 0x880000}, /* various RGF */ 77 {0x880000, 0x88a000, 0x880000}, /* various RGF */
78 {0x88b000, 0x88c000, 0x88b000}, /* Pcie_ext_rgf */
78 {0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */ 79 {0x8c0000, 0x949000, 0x8c0000}, /* trivial mapping for upper area */
79 /* 80 /*
80 * 920000..930000 ucode code RAM 81 * 920000..930000 ucode code RAM
@@ -327,6 +328,17 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
327 328
328 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) { 329 if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
329 struct cfg80211_bss *bss; 330 struct cfg80211_bss *bss;
331 u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
332 u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
333 u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
334 const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
335 size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
336 u.beacon.variable);
337 wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
338 wil_dbg_wmi(wil, "TSF : 0x%016llx\n", tsf);
339 wil_dbg_wmi(wil, "Beacon interval : %d\n", bi);
340 wil_hex_dump_wmi("IE ", DUMP_PREFIX_OFFSET, 16, 1, ie_buf,
341 ie_len, true);
330 342
331 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame, 343 bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
332 d_len, signal, GFP_KERNEL); 344 d_len, signal, GFP_KERNEL);
@@ -351,6 +363,9 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
351 bool aborted = (data->status != WMI_SCAN_SUCCESS); 363 bool aborted = (data->status != WMI_SCAN_SUCCESS);
352 364
353 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status); 365 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
366 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
367 wil->scan_request, aborted);
368
354 del_timer_sync(&wil->scan_timer); 369 del_timer_sync(&wil->scan_timer);
355 cfg80211_scan_done(wil->scan_request, aborted); 370 cfg80211_scan_done(wil->scan_request, aborted);
356 wil->scan_request = NULL; 371 wil->scan_request = NULL;
@@ -668,14 +683,12 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
668 683
669 for (n = 0;; n++) { 684 for (n = 0;; n++) {
670 u16 len; 685 u16 len;
686 bool q;
671 687
672 r->head = ioread32(wil->csr + HOST_MBOX + 688 r->head = ioread32(wil->csr + HOST_MBOX +
673 offsetof(struct wil6210_mbox_ctl, rx.head)); 689 offsetof(struct wil6210_mbox_ctl, rx.head));
674 if (r->tail == r->head) { 690 if (r->tail == r->head)
675 if (n == 0) 691 break;
676 wil_dbg_wmi(wil, "No events?\n");
677 return;
678 }
679 692
680 wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n", 693 wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n",
681 r->head, r->tail); 694 r->head, r->tail);
@@ -684,14 +697,14 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
684 sizeof(struct wil6210_mbox_ring_desc)); 697 sizeof(struct wil6210_mbox_ring_desc));
685 if (d_tail.sync == 0) { 698 if (d_tail.sync == 0) {
686 wil_err(wil, "Mbox evt not owned by FW?\n"); 699 wil_err(wil, "Mbox evt not owned by FW?\n");
687 return; 700 break;
688 } 701 }
689 702
690 /* read cmd header from descriptor */ 703 /* read cmd header from descriptor */
691 if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) { 704 if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) {
692 wil_err(wil, "Mbox evt at 0x%08x?\n", 705 wil_err(wil, "Mbox evt at 0x%08x?\n",
693 le32_to_cpu(d_tail.addr)); 706 le32_to_cpu(d_tail.addr));
694 return; 707 break;
695 } 708 }
696 len = le16_to_cpu(hdr.len); 709 len = le16_to_cpu(hdr.len);
697 wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n", 710 wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n",
@@ -705,7 +718,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
705 event.wmi) + len, 4), 718 event.wmi) + len, 4),
706 GFP_KERNEL); 719 GFP_KERNEL);
707 if (!evt) 720 if (!evt)
708 return; 721 break;
709 722
710 evt->event.hdr = hdr; 723 evt->event.hdr = hdr;
711 cmd = (void *)&evt->event.wmi; 724 cmd = (void *)&evt->event.wmi;
@@ -737,14 +750,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
737 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 750 spin_lock_irqsave(&wil->wmi_ev_lock, flags);
738 list_add_tail(&evt->list, &wil->pending_wmi_ev); 751 list_add_tail(&evt->list, &wil->pending_wmi_ev);
739 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags); 752 spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
740 { 753 q = queue_work(wil->wmi_wq, &wil->wmi_event_worker);
741 int q = queue_work(wil->wmi_wq, 754 wil_dbg_wmi(wil, "queue_work -> %d\n", q);
742 &wil->wmi_event_worker);
743 wil_dbg_wmi(wil, "queue_work -> %d\n", q);
744 }
745 } 755 }
746 if (n > 1) 756 /* normally, 1 event per IRQ should be processed */
747 wil_dbg_wmi(wil, "%s -> %d events processed\n", __func__, n); 757 wil_dbg_wmi(wil, "%s -> %d events queued\n", __func__, n);
748} 758}
749 759
750int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 760int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 40fd9b7b1426..d4c6ae3a9210 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -122,6 +122,15 @@ config B43_PIO
122 select SSB_BLOCKIO 122 select SSB_BLOCKIO
123 default y 123 default y
124 124
125config B43_PHY_G
126 bool "Support for G-PHY (802.11g) devices"
127 depends on B43 && B43_SSB
128 default y
129 ---help---
130 This PHY type can be found in the following chipsets:
131 PCI: BCM4306, BCM4311, BCM4318
132 SoC: BCM4712, BCM5352E
133
125config B43_PHY_N 134config B43_PHY_N
126 bool "Support for 802.11n (N-PHY) devices" 135 bool "Support for 802.11n (N-PHY) devices"
127 depends on B43 136 depends on B43
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile
index 098fe9ee7096..6e00b8804ada 100644
--- a/drivers/net/wireless/b43/Makefile
+++ b/drivers/net/wireless/b43/Makefile
@@ -1,13 +1,11 @@
1b43-y += main.o 1b43-y += main.o
2b43-y += bus.o 2b43-y += bus.o
3b43-y += tables.o 3b43-$(CONFIG_B43_PHY_G) += phy_a.o phy_g.o tables.o lo.o wa.o
4b43-$(CONFIG_B43_PHY_N) += tables_nphy.o 4b43-$(CONFIG_B43_PHY_N) += tables_nphy.o
5b43-$(CONFIG_B43_PHY_N) += radio_2055.o 5b43-$(CONFIG_B43_PHY_N) += radio_2055.o
6b43-$(CONFIG_B43_PHY_N) += radio_2056.o 6b43-$(CONFIG_B43_PHY_N) += radio_2056.o
7b43-$(CONFIG_B43_PHY_N) += radio_2057.o 7b43-$(CONFIG_B43_PHY_N) += radio_2057.o
8b43-y += phy_common.o 8b43-y += phy_common.o
9b43-y += phy_g.o
10b43-y += phy_a.o
11b43-$(CONFIG_B43_PHY_N) += phy_n.o 9b43-$(CONFIG_B43_PHY_N) += phy_n.o
12b43-$(CONFIG_B43_PHY_LP) += phy_lp.o 10b43-$(CONFIG_B43_PHY_LP) += phy_lp.o
13b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o 11b43-$(CONFIG_B43_PHY_LP) += tables_lpphy.o
@@ -17,8 +15,6 @@ b43-$(CONFIG_B43_PHY_HT) += radio_2059.o
17b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o 15b43-$(CONFIG_B43_PHY_LCN) += phy_lcn.o tables_phy_lcn.o
18b43-y += sysfs.o 16b43-y += sysfs.o
19b43-y += xmit.o 17b43-y += xmit.o
20b43-y += lo.o
21b43-y += wa.o
22b43-y += dma.o 18b43-y += dma.o
23b43-y += pio.o 19b43-y += pio.o
24b43-y += rfkill.o 20b43-y += rfkill.o
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 0d6a0bb1f876..15aaeb132a32 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -122,7 +122,11 @@ static const struct bcma_device_id b43_bcma_tbl[] = {
122 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), 122 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), 123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
124 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), 124 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
125 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1C, BCMA_ANY_CLASS),
125 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), 126 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
127 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1E, BCMA_ANY_CLASS),
128 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x28, BCMA_ANY_CLASS),
129 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x2A, BCMA_ANY_CLASS),
126 BCMA_CORETABLE_END 130 BCMA_CORETABLE_END
127}; 131};
128MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); 132MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
@@ -2201,52 +2205,82 @@ err_format:
2201 return -EPROTO; 2205 return -EPROTO;
2202} 2206}
2203 2207
2208/* http://bcm-v4.sipsolutions.net/802.11/Init/Firmware */
2204static int b43_try_request_fw(struct b43_request_fw_context *ctx) 2209static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2205{ 2210{
2206 struct b43_wldev *dev = ctx->dev; 2211 struct b43_wldev *dev = ctx->dev;
2207 struct b43_firmware *fw = &ctx->dev->fw; 2212 struct b43_firmware *fw = &ctx->dev->fw;
2213 struct b43_phy *phy = &dev->phy;
2208 const u8 rev = ctx->dev->dev->core_rev; 2214 const u8 rev = ctx->dev->dev->core_rev;
2209 const char *filename; 2215 const char *filename;
2210 u32 tmshigh;
2211 int err; 2216 int err;
2212 2217
2213 /* Files for HT and LCN were found by trying one by one */
2214
2215 /* Get microcode */ 2218 /* Get microcode */
2216 if ((rev >= 5) && (rev <= 10)) { 2219 filename = NULL;
2217 filename = "ucode5"; 2220 switch (rev) {
2218 } else if ((rev >= 11) && (rev <= 12)) { 2221 case 42:
2219 filename = "ucode11"; 2222 if (phy->type == B43_PHYTYPE_AC)
2220 } else if (rev == 13) { 2223 filename = "ucode42";
2221 filename = "ucode13"; 2224 break;
2222 } else if (rev == 14) { 2225 case 40:
2223 filename = "ucode14"; 2226 if (phy->type == B43_PHYTYPE_AC)
2224 } else if (rev == 15) { 2227 filename = "ucode40";
2228 break;
2229 case 33:
2230 if (phy->type == B43_PHYTYPE_LCN40)
2231 filename = "ucode33_lcn40";
2232 break;
2233 case 30:
2234 if (phy->type == B43_PHYTYPE_N)
2235 filename = "ucode30_mimo";
2236 break;
2237 case 29:
2238 if (phy->type == B43_PHYTYPE_HT)
2239 filename = "ucode29_mimo";
2240 break;
2241 case 26:
2242 if (phy->type == B43_PHYTYPE_HT)
2243 filename = "ucode26_mimo";
2244 break;
2245 case 28:
2246 case 25:
2247 if (phy->type == B43_PHYTYPE_N)
2248 filename = "ucode25_mimo";
2249 else if (phy->type == B43_PHYTYPE_LCN)
2250 filename = "ucode25_lcn";
2251 break;
2252 case 24:
2253 if (phy->type == B43_PHYTYPE_LCN)
2254 filename = "ucode24_lcn";
2255 break;
2256 case 23:
2257 if (phy->type == B43_PHYTYPE_N)
2258 filename = "ucode16_mimo";
2259 break;
2260 case 16 ... 19:
2261 if (phy->type == B43_PHYTYPE_N)
2262 filename = "ucode16_mimo";
2263 else if (phy->type == B43_PHYTYPE_LP)
2264 filename = "ucode16_lp";
2265 break;
2266 case 15:
2225 filename = "ucode15"; 2267 filename = "ucode15";
2226 } else { 2268 break;
2227 switch (dev->phy.type) { 2269 case 14:
2228 case B43_PHYTYPE_N: 2270 filename = "ucode14";
2229 if (rev >= 16) 2271 break;
2230 filename = "ucode16_mimo"; 2272 case 13:
2231 else 2273 filename = "ucode13";
2232 goto err_no_ucode; 2274 break;
2233 break; 2275 case 11 ... 12:
2234 case B43_PHYTYPE_HT: 2276 filename = "ucode11";
2235 if (rev == 29) 2277 break;
2236 filename = "ucode29_mimo"; 2278 case 5 ... 10:
2237 else 2279 filename = "ucode5";
2238 goto err_no_ucode; 2280 break;
2239 break;
2240 case B43_PHYTYPE_LCN:
2241 if (rev == 24)
2242 filename = "ucode24_mimo";
2243 else
2244 goto err_no_ucode;
2245 break;
2246 default:
2247 goto err_no_ucode;
2248 }
2249 } 2281 }
2282 if (!filename)
2283 goto err_no_ucode;
2250 err = b43_do_request_fw(ctx, filename, &fw->ucode, true); 2284 err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
2251 if (err) 2285 if (err)
2252 goto err_load; 2286 goto err_load;
@@ -2268,117 +2302,121 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2268 goto err_load; 2302 goto err_load;
2269 2303
2270 /* Get initvals */ 2304 /* Get initvals */
2305 filename = NULL;
2271 switch (dev->phy.type) { 2306 switch (dev->phy.type) {
2272 case B43_PHYTYPE_A:
2273 if ((rev >= 5) && (rev <= 10)) {
2274 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
2275 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
2276 filename = "a0g1initvals5";
2277 else
2278 filename = "a0g0initvals5";
2279 } else
2280 goto err_no_initvals;
2281 break;
2282 case B43_PHYTYPE_G: 2307 case B43_PHYTYPE_G:
2283 if ((rev >= 5) && (rev <= 10)) 2308 if (rev == 13)
2284 filename = "b0g0initvals5";
2285 else if (rev >= 13)
2286 filename = "b0g0initvals13"; 2309 filename = "b0g0initvals13";
2287 else 2310 else if (rev >= 5 && rev <= 10)
2288 goto err_no_initvals; 2311 filename = "b0g0initvals5";
2289 break; 2312 break;
2290 case B43_PHYTYPE_N: 2313 case B43_PHYTYPE_N:
2291 if (rev >= 16) 2314 if (rev == 30)
2315 filename = "n16initvals30";
2316 else if (rev == 28 || rev == 25)
2317 filename = "n0initvals25";
2318 else if (rev == 24)
2319 filename = "n0initvals24";
2320 else if (rev == 23)
2321 filename = "n0initvals16"; /* What about n0initvals22? */
2322 else if (rev >= 16 && rev <= 18)
2292 filename = "n0initvals16"; 2323 filename = "n0initvals16";
2293 else if ((rev >= 11) && (rev <= 12)) 2324 else if (rev >= 11 && rev <= 12)
2294 filename = "n0initvals11"; 2325 filename = "n0initvals11";
2295 else
2296 goto err_no_initvals;
2297 break; 2326 break;
2298 case B43_PHYTYPE_LP: 2327 case B43_PHYTYPE_LP:
2299 if (rev == 13) 2328 if (rev >= 16 && rev <= 18)
2300 filename = "lp0initvals13"; 2329 filename = "lp0initvals16";
2330 else if (rev == 15)
2331 filename = "lp0initvals15";
2301 else if (rev == 14) 2332 else if (rev == 14)
2302 filename = "lp0initvals14"; 2333 filename = "lp0initvals14";
2303 else if (rev >= 15) 2334 else if (rev == 13)
2304 filename = "lp0initvals15"; 2335 filename = "lp0initvals13";
2305 else
2306 goto err_no_initvals;
2307 break; 2336 break;
2308 case B43_PHYTYPE_HT: 2337 case B43_PHYTYPE_HT:
2309 if (rev == 29) 2338 if (rev == 29)
2310 filename = "ht0initvals29"; 2339 filename = "ht0initvals29";
2311 else 2340 else if (rev == 26)
2312 goto err_no_initvals; 2341 filename = "ht0initvals26";
2313 break; 2342 break;
2314 case B43_PHYTYPE_LCN: 2343 case B43_PHYTYPE_LCN:
2315 if (rev == 24) 2344 if (rev == 24)
2316 filename = "lcn0initvals24"; 2345 filename = "lcn0initvals24";
2317 else
2318 goto err_no_initvals;
2319 break; 2346 break;
2320 default: 2347 case B43_PHYTYPE_LCN40:
2321 goto err_no_initvals; 2348 if (rev == 33)
2349 filename = "lcn400initvals33";
2350 break;
2351 case B43_PHYTYPE_AC:
2352 if (rev == 42)
2353 filename = "ac1initvals42";
2354 else if (rev == 40)
2355 filename = "ac0initvals40";
2356 break;
2322 } 2357 }
2358 if (!filename)
2359 goto err_no_initvals;
2323 err = b43_do_request_fw(ctx, filename, &fw->initvals, false); 2360 err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
2324 if (err) 2361 if (err)
2325 goto err_load; 2362 goto err_load;
2326 2363
2327 /* Get bandswitch initvals */ 2364 /* Get bandswitch initvals */
2365 filename = NULL;
2328 switch (dev->phy.type) { 2366 switch (dev->phy.type) {
2329 case B43_PHYTYPE_A:
2330 if ((rev >= 5) && (rev <= 10)) {
2331 tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
2332 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
2333 filename = "a0g1bsinitvals5";
2334 else
2335 filename = "a0g0bsinitvals5";
2336 } else if (rev >= 11)
2337 filename = NULL;
2338 else
2339 goto err_no_initvals;
2340 break;
2341 case B43_PHYTYPE_G: 2367 case B43_PHYTYPE_G:
2342 if ((rev >= 5) && (rev <= 10)) 2368 if (rev == 13)
2369 filename = "b0g0bsinitvals13";
2370 else if (rev >= 5 && rev <= 10)
2343 filename = "b0g0bsinitvals5"; 2371 filename = "b0g0bsinitvals5";
2344 else if (rev >= 11)
2345 filename = NULL;
2346 else
2347 goto err_no_initvals;
2348 break; 2372 break;
2349 case B43_PHYTYPE_N: 2373 case B43_PHYTYPE_N:
2350 if (rev >= 16) 2374 if (rev == 30)
2375 filename = "n16bsinitvals30";
2376 else if (rev == 28 || rev == 25)
2377 filename = "n0bsinitvals25";
2378 else if (rev == 24)
2379 filename = "n0bsinitvals24";
2380 else if (rev == 23)
2381 filename = "n0bsinitvals16"; /* What about n0bsinitvals22? */
2382 else if (rev >= 16 && rev <= 18)
2351 filename = "n0bsinitvals16"; 2383 filename = "n0bsinitvals16";
2352 else if ((rev >= 11) && (rev <= 12)) 2384 else if (rev >= 11 && rev <= 12)
2353 filename = "n0bsinitvals11"; 2385 filename = "n0bsinitvals11";
2354 else
2355 goto err_no_initvals;
2356 break; 2386 break;
2357 case B43_PHYTYPE_LP: 2387 case B43_PHYTYPE_LP:
2358 if (rev == 13) 2388 if (rev >= 16 && rev <= 18)
2359 filename = "lp0bsinitvals13"; 2389 filename = "lp0bsinitvals16";
2390 else if (rev == 15)
2391 filename = "lp0bsinitvals15";
2360 else if (rev == 14) 2392 else if (rev == 14)
2361 filename = "lp0bsinitvals14"; 2393 filename = "lp0bsinitvals14";
2362 else if (rev >= 15) 2394 else if (rev == 13)
2363 filename = "lp0bsinitvals15"; 2395 filename = "lp0bsinitvals13";
2364 else
2365 goto err_no_initvals;
2366 break; 2396 break;
2367 case B43_PHYTYPE_HT: 2397 case B43_PHYTYPE_HT:
2368 if (rev == 29) 2398 if (rev == 29)
2369 filename = "ht0bsinitvals29"; 2399 filename = "ht0bsinitvals29";
2370 else 2400 else if (rev == 26)
2371 goto err_no_initvals; 2401 filename = "ht0bsinitvals26";
2372 break; 2402 break;
2373 case B43_PHYTYPE_LCN: 2403 case B43_PHYTYPE_LCN:
2374 if (rev == 24) 2404 if (rev == 24)
2375 filename = "lcn0bsinitvals24"; 2405 filename = "lcn0bsinitvals24";
2376 else
2377 goto err_no_initvals;
2378 break; 2406 break;
2379 default: 2407 case B43_PHYTYPE_LCN40:
2380 goto err_no_initvals; 2408 if (rev == 33)
2409 filename = "lcn400bsinitvals33";
2410 break;
2411 case B43_PHYTYPE_AC:
2412 if (rev == 42)
2413 filename = "ac1bsinitvals42";
2414 else if (rev == 40)
2415 filename = "ac0bsinitvals40";
2416 break;
2381 } 2417 }
2418 if (!filename)
2419 goto err_no_initvals;
2382 err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false); 2420 err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
2383 if (err) 2421 if (err)
2384 goto err_load; 2422 goto err_load;
@@ -3798,38 +3836,29 @@ static void b43_set_retry_limits(struct b43_wldev *dev,
3798static int b43_op_config(struct ieee80211_hw *hw, u32 changed) 3836static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3799{ 3837{
3800 struct b43_wl *wl = hw_to_b43_wl(hw); 3838 struct b43_wl *wl = hw_to_b43_wl(hw);
3801 struct b43_wldev *dev; 3839 struct b43_wldev *dev = wl->current_dev;
3802 struct b43_phy *phy; 3840 struct b43_phy *phy = &dev->phy;
3803 struct ieee80211_conf *conf = &hw->conf; 3841 struct ieee80211_conf *conf = &hw->conf;
3804 int antenna; 3842 int antenna;
3805 int err = 0; 3843 int err = 0;
3806 bool reload_bss = false;
3807 3844
3808 mutex_lock(&wl->mutex); 3845 mutex_lock(&wl->mutex);
3809
3810 dev = wl->current_dev;
3811
3812 b43_mac_suspend(dev); 3846 b43_mac_suspend(dev);
3813 3847
3814 /* Switch the band (if necessary). This might change the active core. */ 3848 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
3815 err = b43_switch_band(dev, conf->chandef.chan); 3849 phy->chandef = &conf->chandef;
3816 if (err) 3850 phy->channel = conf->chandef.chan->hw_value;
3817 goto out_unlock_mutex;
3818
3819 /* Need to reload all settings if the core changed */
3820 if (dev != wl->current_dev) {
3821 dev = wl->current_dev;
3822 changed = ~0;
3823 reload_bss = true;
3824 }
3825 3851
3826 phy = &dev->phy; 3852 /* Switch the band (if necessary). */
3853 err = b43_switch_band(dev, conf->chandef.chan);
3854 if (err)
3855 goto out_mac_enable;
3827 3856
3828 if (conf_is_ht(conf)) 3857 /* Switch to the requested channel.
3829 phy->is_40mhz = 3858 * The firmware takes care of races with the TX handler.
3830 (conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf)); 3859 */
3831 else 3860 b43_switch_channel(dev, phy->channel);
3832 phy->is_40mhz = false; 3861 }
3833 3862
3834 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) 3863 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
3835 b43_set_retry_limits(dev, conf->short_frame_max_tx_count, 3864 b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
@@ -3838,11 +3867,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3838 if (!changed) 3867 if (!changed)
3839 goto out_mac_enable; 3868 goto out_mac_enable;
3840 3869
3841 /* Switch to the requested channel.
3842 * The firmware takes care of races with the TX handler. */
3843 if (conf->chandef.chan->hw_value != phy->channel)
3844 b43_switch_channel(dev, conf->chandef.chan->hw_value);
3845
3846 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR); 3870 dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
3847 3871
3848 /* Adjust the desired TX power level. */ 3872 /* Adjust the desired TX power level. */
@@ -3878,12 +3902,8 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3878 3902
3879out_mac_enable: 3903out_mac_enable:
3880 b43_mac_enable(dev); 3904 b43_mac_enable(dev);
3881out_unlock_mutex:
3882 mutex_unlock(&wl->mutex); 3905 mutex_unlock(&wl->mutex);
3883 3906
3884 if (wl->vif && reload_bss)
3885 b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
3886
3887 return err; 3907 return err;
3888} 3908}
3889 3909
@@ -4309,6 +4329,7 @@ static char *b43_phy_name(struct b43_wldev *dev, u8 phy_type)
4309static int b43_phy_versioning(struct b43_wldev *dev) 4329static int b43_phy_versioning(struct b43_wldev *dev)
4310{ 4330{
4311 struct b43_phy *phy = &dev->phy; 4331 struct b43_phy *phy = &dev->phy;
4332 const u8 core_rev = dev->dev->core_rev;
4312 u32 tmp; 4333 u32 tmp;
4313 u8 analog_type; 4334 u8 analog_type;
4314 u8 phy_type; 4335 u8 phy_type;
@@ -4323,20 +4344,20 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4323 analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT; 4344 analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
4324 phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT; 4345 phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
4325 phy_rev = (tmp & B43_PHYVER_VERSION); 4346 phy_rev = (tmp & B43_PHYVER_VERSION);
4347
4348 /* LCNXN is continuation of N which run out of revisions */
4349 if (phy_type == B43_PHYTYPE_LCNXN) {
4350 phy_type = B43_PHYTYPE_N;
4351 phy_rev += 16;
4352 }
4353
4326 switch (phy_type) { 4354 switch (phy_type) {
4327 case B43_PHYTYPE_A: 4355#ifdef CONFIG_B43_PHY_G
4328 if (phy_rev >= 4)
4329 unsupported = 1;
4330 break;
4331 case B43_PHYTYPE_B:
4332 if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
4333 && phy_rev != 7)
4334 unsupported = 1;
4335 break;
4336 case B43_PHYTYPE_G: 4356 case B43_PHYTYPE_G:
4337 if (phy_rev > 9) 4357 if (phy_rev > 9)
4338 unsupported = 1; 4358 unsupported = 1;
4339 break; 4359 break;
4360#endif
4340#ifdef CONFIG_B43_PHY_N 4361#ifdef CONFIG_B43_PHY_N
4341 case B43_PHYTYPE_N: 4362 case B43_PHYTYPE_N:
4342 if (phy_rev > 9) 4363 if (phy_rev > 9)
@@ -4374,7 +4395,15 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4374 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev); 4395 analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
4375 4396
4376 /* Get RADIO versioning */ 4397 /* Get RADIO versioning */
4377 if (dev->dev->core_rev >= 24) { 4398 if (core_rev == 40 || core_rev == 42) {
4399 radio_manuf = 0x17F;
4400
4401 b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 0);
4402 radio_rev = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4403
4404 b43_write16(dev, B43_MMIO_RADIO24_CONTROL, 1);
4405 radio_ver = b43_read16(dev, B43_MMIO_RADIO24_DATA);
4406 } else if (core_rev >= 24) {
4378 u16 radio24[3]; 4407 u16 radio24[3];
4379 4408
4380 for (tmp = 0; tmp < 3; tmp++) { 4409 for (tmp = 0; tmp < 3; tmp++) {
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index a6c38104693d..25e40432d68b 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -573,7 +573,7 @@ static void b43_aphy_op_pwork_60sec(struct b43_wldev *dev)
573{//TODO 573{//TODO
574} 574}
575 575
576const struct b43_phy_operations b43_phyops_a = { 576static const struct b43_phy_operations b43_phyops_a = {
577 .allocate = b43_aphy_op_allocate, 577 .allocate = b43_aphy_op_allocate,
578 .free = b43_aphy_op_free, 578 .free = b43_aphy_op_free,
579 .prepare_structs = b43_aphy_op_prepare_structs, 579 .prepare_structs = b43_aphy_op_prepare_structs,
diff --git a/drivers/net/wireless/b43/phy_a.h b/drivers/net/wireless/b43/phy_a.h
index 5cfaab7b16ee..f7d0d929a374 100644
--- a/drivers/net/wireless/b43/phy_a.h
+++ b/drivers/net/wireless/b43/phy_a.h
@@ -123,8 +123,4 @@ struct b43_phy_a {
123 */ 123 */
124void b43_phy_inita(struct b43_wldev *dev); 124void b43_phy_inita(struct b43_wldev *dev);
125 125
126
127struct b43_phy_operations;
128extern const struct b43_phy_operations b43_phyops_a;
129
130#endif /* LINUX_B43_PHY_A_H_ */ 126#endif /* LINUX_B43_PHY_A_H_ */
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 08244b3b327e..3cbef21b4726 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -45,11 +45,10 @@ int b43_phy_allocate(struct b43_wldev *dev)
45 phy->ops = NULL; 45 phy->ops = NULL;
46 46
47 switch (phy->type) { 47 switch (phy->type) {
48 case B43_PHYTYPE_A:
49 phy->ops = &b43_phyops_a;
50 break;
51 case B43_PHYTYPE_G: 48 case B43_PHYTYPE_G:
49#ifdef CONFIG_B43_PHY_G
52 phy->ops = &b43_phyops_g; 50 phy->ops = &b43_phyops_g;
51#endif
53 break; 52 break;
54 case B43_PHYTYPE_N: 53 case B43_PHYTYPE_N:
55#ifdef CONFIG_B43_PHY_N 54#ifdef CONFIG_B43_PHY_N
@@ -94,7 +93,13 @@ int b43_phy_init(struct b43_wldev *dev)
94 const struct b43_phy_operations *ops = phy->ops; 93 const struct b43_phy_operations *ops = phy->ops;
95 int err; 94 int err;
96 95
97 phy->channel = ops->get_default_chan(dev); 96 /* During PHY init we need to use some channel. On the first init this
97 * function is called *before* b43_op_config, so our pointer is NULL.
98 */
99 if (!phy->chandef) {
100 phy->chandef = &dev->wl->hw->conf.chandef;
101 phy->channel = phy->chandef->chan->hw_value;
102 }
98 103
99 phy->ops->switch_analog(dev, true); 104 phy->ops->switch_analog(dev, true);
100 b43_software_rfkill(dev, false); 105 b43_software_rfkill(dev, false);
@@ -106,9 +111,7 @@ int b43_phy_init(struct b43_wldev *dev)
106 } 111 }
107 phy->do_full_init = false; 112 phy->do_full_init = false;
108 113
109 /* Make sure to switch hardware and firmware (SHM) to 114 err = b43_switch_channel(dev, phy->channel);
110 * the default channel. */
111 err = b43_switch_channel(dev, ops->get_default_chan(dev));
112 if (err) { 115 if (err) {
113 b43err(dev->wl, "PHY init: Channel switch to default failed\n"); 116 b43err(dev->wl, "PHY init: Channel switch to default failed\n");
114 goto err_phy_exit; 117 goto err_phy_exit;
@@ -408,9 +411,6 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
408 u16 channelcookie, savedcookie; 411 u16 channelcookie, savedcookie;
409 int err; 412 int err;
410 413
411 if (new_channel == B43_DEFAULT_CHANNEL)
412 new_channel = phy->ops->get_default_chan(dev);
413
414 /* First we set the channel radio code to prevent the 414 /* First we set the channel radio code to prevent the
415 * firmware from sending ghost packets. 415 * firmware from sending ghost packets.
416 */ 416 */
@@ -428,7 +428,6 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel)
428 if (err) 428 if (err)
429 goto err_restore_cookie; 429 goto err_restore_cookie;
430 430
431 dev->phy.channel = new_channel;
432 /* Wait for the radio to tune to the channel and stabilize. */ 431 /* Wait for the radio to tune to the channel and stabilize. */
433 msleep(8); 432 msleep(8);
434 433
@@ -547,10 +546,9 @@ void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on)
547} 546}
548 547
549 548
550bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type) 549bool b43_is_40mhz(struct b43_wldev *dev)
551{ 550{
552 return (channel_type == NL80211_CHAN_HT40MINUS || 551 return dev->phy.chandef->width == NL80211_CHAN_WIDTH_40;
553 channel_type == NL80211_CHAN_HT40PLUS);
554} 552}
555 553
556/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */ 554/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 4ad6240d9ff4..3912274f71e3 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -228,9 +228,6 @@ struct b43_phy {
228 bool supports_2ghz; 228 bool supports_2ghz;
229 bool supports_5ghz; 229 bool supports_5ghz;
230 230
231 /* HT info */
232 bool is_40mhz;
233
234 /* Is GMODE (2 GHz mode) bit enabled? */ 231 /* Is GMODE (2 GHz mode) bit enabled? */
235 bool gmode; 232 bool gmode;
236 233
@@ -267,9 +264,8 @@ struct b43_phy {
267 unsigned long next_txpwr_check_time; 264 unsigned long next_txpwr_check_time;
268 265
269 /* Current channel */ 266 /* Current channel */
267 struct cfg80211_chan_def *chandef;
270 unsigned int channel; 268 unsigned int channel;
271 u16 channel_freq;
272 enum nl80211_channel_type channel_type;
273 269
274 /* PHY TX errors counter. */ 270 /* PHY TX errors counter. */
275 atomic_t txerr_cnt; 271 atomic_t txerr_cnt;
@@ -400,10 +396,6 @@ void b43_phy_take_out_of_reset(struct b43_wldev *dev);
400 * b43_switch_channel - Switch to another channel 396 * b43_switch_channel - Switch to another channel
401 */ 397 */
402int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel); 398int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
403/**
404 * B43_DEFAULT_CHANNEL - Switch to the default channel.
405 */
406#define B43_DEFAULT_CHANNEL UINT_MAX
407 399
408/** 400/**
409 * b43_software_rfkill - Turn the radio ON or OFF in software. 401 * b43_software_rfkill - Turn the radio ON or OFF in software.
@@ -454,7 +446,7 @@ int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
454 */ 446 */
455void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on); 447void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
456 448
457bool b43_channel_type_is_40mhz(enum nl80211_channel_type channel_type); 449bool b43_is_40mhz(struct b43_wldev *dev);
458 450
459void b43_phy_force_clock(struct b43_wldev *dev, bool force); 451void b43_phy_force_clock(struct b43_wldev *dev, bool force);
460 452
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 5d6833f18498..f2974c6b1c01 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -596,7 +596,7 @@ static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
596 u8 target[3]; 596 u8 target[3];
597 s16 a1[3], b0[3], b1[3]; 597 s16 a1[3], b0[3], b1[3];
598 598
599 u16 freq = dev->phy.channel_freq; 599 u16 freq = dev->phy.chandef->chan->center_freq;
600 int i, c; 600 int i, c;
601 601
602 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 602 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 86569f6a8705..50ca6f87d5e8 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -590,7 +590,103 @@ static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
590 * Radio 0x2057 590 * Radio 0x2057
591 **************************************************/ 591 **************************************************/
592 592
593/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rcal */ 593static void b43_radio_2057_chantab_upload(struct b43_wldev *dev,
594 const struct b43_nphy_chantabent_rev7 *e_r7,
595 const struct b43_nphy_chantabent_rev7_2g *e_r7_2g)
596{
597 if (e_r7_2g) {
598 b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7_2g->radio_vcocal_countval0);
599 b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7_2g->radio_vcocal_countval1);
600 b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7_2g->radio_rfpll_refmaster_sparextalsize);
601 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7_2g->radio_rfpll_loopfilter_r1);
602 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7_2g->radio_rfpll_loopfilter_c2);
603 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7_2g->radio_rfpll_loopfilter_c1);
604 b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7_2g->radio_cp_kpd_idac);
605 b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7_2g->radio_rfpll_mmd0);
606 b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7_2g->radio_rfpll_mmd1);
607 b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7_2g->radio_vcobuf_tune);
608 b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7_2g->radio_logen_mx2g_tune);
609 b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7_2g->radio_logen_indbuf2g_tune);
610 b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7_2g->radio_txmix2g_tune_boost_pu_core0);
611 b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7_2g->radio_pad2g_tune_pus_core0);
612 b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7_2g->radio_lna2g_tune_core0);
613 b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7_2g->radio_txmix2g_tune_boost_pu_core1);
614 b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7_2g->radio_pad2g_tune_pus_core1);
615 b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7_2g->radio_lna2g_tune_core1);
616
617 } else {
618 b43_radio_write(dev, R2057_VCOCAL_COUNTVAL0, e_r7->radio_vcocal_countval0);
619 b43_radio_write(dev, R2057_VCOCAL_COUNTVAL1, e_r7->radio_vcocal_countval1);
620 b43_radio_write(dev, R2057_RFPLL_REFMASTER_SPAREXTALSIZE, e_r7->radio_rfpll_refmaster_sparextalsize);
621 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, e_r7->radio_rfpll_loopfilter_r1);
622 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, e_r7->radio_rfpll_loopfilter_c2);
623 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, e_r7->radio_rfpll_loopfilter_c1);
624 b43_radio_write(dev, R2057_CP_KPD_IDAC, e_r7->radio_cp_kpd_idac);
625 b43_radio_write(dev, R2057_RFPLL_MMD0, e_r7->radio_rfpll_mmd0);
626 b43_radio_write(dev, R2057_RFPLL_MMD1, e_r7->radio_rfpll_mmd1);
627 b43_radio_write(dev, R2057_VCOBUF_TUNE, e_r7->radio_vcobuf_tune);
628 b43_radio_write(dev, R2057_LOGEN_MX2G_TUNE, e_r7->radio_logen_mx2g_tune);
629 b43_radio_write(dev, R2057_LOGEN_MX5G_TUNE, e_r7->radio_logen_mx5g_tune);
630 b43_radio_write(dev, R2057_LOGEN_INDBUF2G_TUNE, e_r7->radio_logen_indbuf2g_tune);
631 b43_radio_write(dev, R2057_LOGEN_INDBUF5G_TUNE, e_r7->radio_logen_indbuf5g_tune);
632 b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE0, e_r7->radio_txmix2g_tune_boost_pu_core0);
633 b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE0, e_r7->radio_pad2g_tune_pus_core0);
634 b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE0, e_r7->radio_pga_boost_tune_core0);
635 b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE0, e_r7->radio_txmix5g_boost_tune_core0);
636 b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE0, e_r7->radio_pad5g_tune_misc_pus_core0);
637 b43_radio_write(dev, R2057_LNA2G_TUNE_CORE0, e_r7->radio_lna2g_tune_core0);
638 b43_radio_write(dev, R2057_LNA5G_TUNE_CORE0, e_r7->radio_lna5g_tune_core0);
639 b43_radio_write(dev, R2057_TXMIX2G_TUNE_BOOST_PU_CORE1, e_r7->radio_txmix2g_tune_boost_pu_core1);
640 b43_radio_write(dev, R2057_PAD2G_TUNE_PUS_CORE1, e_r7->radio_pad2g_tune_pus_core1);
641 b43_radio_write(dev, R2057_PGA_BOOST_TUNE_CORE1, e_r7->radio_pga_boost_tune_core1);
642 b43_radio_write(dev, R2057_TXMIX5G_BOOST_TUNE_CORE1, e_r7->radio_txmix5g_boost_tune_core1);
643 b43_radio_write(dev, R2057_PAD5G_TUNE_MISC_PUS_CORE1, e_r7->radio_pad5g_tune_misc_pus_core1);
644 b43_radio_write(dev, R2057_LNA2G_TUNE_CORE1, e_r7->radio_lna2g_tune_core1);
645 b43_radio_write(dev, R2057_LNA5G_TUNE_CORE1, e_r7->radio_lna5g_tune_core1);
646 }
647}
648
649static void b43_radio_2057_setup(struct b43_wldev *dev,
650 const struct b43_nphy_chantabent_rev7 *tabent_r7,
651 const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g)
652{
653 struct b43_phy *phy = &dev->phy;
654
655 b43_radio_2057_chantab_upload(dev, tabent_r7, tabent_r7_2g);
656
657 switch (phy->radio_rev) {
658 case 0 ... 4:
659 case 6:
660 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
661 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x3f);
662 b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
663 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
664 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
665 } else {
666 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_R1, 0x1f);
667 b43_radio_write(dev, R2057_CP_KPD_IDAC, 0x3f);
668 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C1, 0x8);
669 b43_radio_write(dev, R2057_RFPLL_LOOPFILTER_C2, 0x8);
670 }
671 break;
672 /* TODO */
673 }
674
675 /* TODO */
676
677 usleep_range(50, 100);
678
679 /* VCO calibration */
680 b43_radio_mask(dev, R2057_RFPLL_MISC_EN, ~0x01);
681 b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x04);
682 b43_radio_set(dev, R2057_RFPLL_MISC_CAL_RESETN, 0x4);
683 b43_radio_set(dev, R2057_RFPLL_MISC_EN, 0x01);
684 usleep_range(300, 600);
685}
686
687/* Calibrate resistors in LPF of PLL?
688 * http://bcm-v4.sipsolutions.net/PHY/radio205x_rcal
689 */
594static u8 b43_radio_2057_rcal(struct b43_wldev *dev) 690static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
595{ 691{
596 struct b43_phy *phy = &dev->phy; 692 struct b43_phy *phy = &dev->phy;
@@ -603,15 +699,25 @@ static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
603 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1); 699 b43_radio_maskset(dev, 0x1ca, ~0x2, 0x1);
604 } 700 }
605 701
702 /* Enable */
606 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1); 703 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x1);
607 udelay(10); 704 udelay(10);
608 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x3); 705
609 if (!b43_radio_wait_value(dev, R2057_RCCAL_N1_1, 1, 1, 100, 1000000)) { 706 /* Start */
707 b43_radio_set(dev, R2057_RCAL_CONFIG, 0x2);
708 usleep_range(100, 200);
709
710 /* Stop */
711 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
712
713 /* Wait and check for result */
714 if (!b43_radio_wait_value(dev, R2057_RCAL_STATUS, 1, 1, 100, 1000000)) {
610 b43err(dev->wl, "Radio 0x2057 rcal timeout\n"); 715 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
611 return 0; 716 return 0;
612 } 717 }
613 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x2);
614 tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E; 718 tmp = b43_radio_read(dev, R2057_RCAL_STATUS) & 0x3E;
719
720 /* Disable */
615 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1); 721 b43_radio_mask(dev, R2057_RCAL_CONFIG, ~0x1);
616 722
617 if (phy->radio_rev == 5) { 723 if (phy->radio_rev == 5) {
@@ -627,7 +733,9 @@ static u8 b43_radio_2057_rcal(struct b43_wldev *dev)
627 return tmp & 0x3e; 733 return tmp & 0x3e;
628} 734}
629 735
630/* http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal */ 736/* Calibrate the internal RC oscillator?
737 * http://bcm-v4.sipsolutions.net/PHY/radio2057_rccal
738 */
631static u16 b43_radio_2057_rccal(struct b43_wldev *dev) 739static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
632{ 740{
633 struct b43_phy *phy = &dev->phy; 741 struct b43_phy *phy = &dev->phy;
@@ -635,49 +743,76 @@ static u16 b43_radio_2057_rccal(struct b43_wldev *dev)
635 phy->radio_rev == 6); 743 phy->radio_rev == 6);
636 u16 tmp; 744 u16 tmp;
637 745
746 /* Setup cal */
638 if (special) { 747 if (special) {
639 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61); 748 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x61);
640 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0); 749 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xC0);
641 } else { 750 } else {
642 b43_radio_write(dev, 0x1AE, 0x61); 751 b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x61);
643 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1); 752 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xE1);
644 } 753 }
645 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E); 754 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
755
756 /* Start, wait, stop */
646 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55); 757 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
647 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500, 758 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
648 5000000)) 759 5000000))
649 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n"); 760 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
761 usleep_range(35, 70);
650 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15); 762 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
763 usleep_range(70, 140);
764
765 /* Setup cal */
651 if (special) { 766 if (special) {
652 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69); 767 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x69);
653 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0); 768 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
654 } else { 769 } else {
655 b43_radio_write(dev, 0x1AE, 0x69); 770 b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x69);
656 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5); 771 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xD5);
657 } 772 }
658 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E); 773 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
774
775 /* Start, wait, stop */
776 usleep_range(35, 70);
659 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55); 777 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
660 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500, 778 usleep_range(70, 140);
779 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
661 5000000)) 780 5000000))
662 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n"); 781 b43dbg(dev->wl, "Radio 0x2057 rccal timeout\n");
782 usleep_range(35, 70);
663 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15); 783 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
784 usleep_range(70, 140);
785
786 /* Setup cal */
664 if (special) { 787 if (special) {
665 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73); 788 b43_radio_write(dev, R2057_RCCAL_MASTER, 0x73);
666 b43_radio_write(dev, R2057_RCCAL_X1, 0x28); 789 b43_radio_write(dev, R2057_RCCAL_X1, 0x28);
667 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0); 790 b43_radio_write(dev, R2057_RCCAL_TRC0, 0xB0);
668 } else { 791 } else {
669 b43_radio_write(dev, 0x1AE, 0x73); 792 b43_radio_write(dev, R2057v7_RCCAL_MASTER, 0x73);
670 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E); 793 b43_radio_write(dev, R2057_RCCAL_X1, 0x6E);
671 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99); 794 b43_radio_write(dev, R2057_RCCAL_TRC0, 0x99);
672 } 795 }
796
797 /* Start, wait, stop */
798 usleep_range(35, 70);
673 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55); 799 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x55);
674 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 1, 1, 500, 800 usleep_range(70, 140);
801 if (!b43_radio_wait_value(dev, R2057_RCCAL_DONE_OSCCAP, 2, 2, 500,
675 5000000)) { 802 5000000)) {
676 b43err(dev->wl, "Radio 0x2057 rcal timeout\n"); 803 b43err(dev->wl, "Radio 0x2057 rcal timeout\n");
677 return 0; 804 return 0;
678 } 805 }
679 tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP); 806 tmp = b43_radio_read(dev, R2057_RCCAL_DONE_OSCCAP);
807 usleep_range(35, 70);
680 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15); 808 b43_radio_write(dev, R2057_RCCAL_START_R1_Q1_P1, 0x15);
809 usleep_range(70, 140);
810
811 if (special)
812 b43_radio_mask(dev, R2057_RCCAL_MASTER, ~0x1);
813 else
814 b43_radio_mask(dev, R2057v7_RCCAL_MASTER, ~0x1);
815
681 return tmp; 816 return tmp;
682} 817}
683 818
@@ -798,6 +933,7 @@ static void b43_chantab_radio_2056_upload(struct b43_wldev *dev,
798static void b43_radio_2056_setup(struct b43_wldev *dev, 933static void b43_radio_2056_setup(struct b43_wldev *dev,
799 const struct b43_nphy_channeltab_entry_rev3 *e) 934 const struct b43_nphy_channeltab_entry_rev3 *e)
800{ 935{
936 struct b43_phy *phy = &dev->phy;
801 struct ssb_sprom *sprom = dev->dev->bus_sprom; 937 struct ssb_sprom *sprom = dev->dev->bus_sprom;
802 enum ieee80211_band band = b43_current_band(dev->wl); 938 enum ieee80211_band band = b43_current_band(dev->wl);
803 u16 offset; 939 u16 offset;
@@ -895,7 +1031,7 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
895 offset | B2056_TX_MIXG_BOOST_TUNE, 1031 offset | B2056_TX_MIXG_BOOST_TUNE,
896 mixg_boost); 1032 mixg_boost);
897 } else { 1033 } else {
898 bias = dev->phy.is_40mhz ? 0x40 : 0x20; 1034 bias = b43_is_40mhz(dev) ? 0x40 : 0x20;
899 b43_radio_write(dev, 1035 b43_radio_write(dev,
900 offset | B2056_TX_INTPAG_IMAIN_STAT, 1036 offset | B2056_TX_INTPAG_IMAIN_STAT,
901 bias); 1037 bias);
@@ -909,7 +1045,7 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
909 b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee); 1045 b43_radio_write(dev, offset | B2056_TX_PA_SPARE1, 0xee);
910 } 1046 }
911 } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) { 1047 } else if (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ) {
912 u16 freq = dev->phy.channel_freq; 1048 u16 freq = phy->chandef->chan->center_freq;
913 if (freq < 5100) { 1049 if (freq < 5100) {
914 paa_boost = 0xA; 1050 paa_boost = 0xA;
915 pada_boost = 0x77; 1051 pada_boost = 0x77;
@@ -1210,8 +1346,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1210 u16 bw, len, rot, angle; 1346 u16 bw, len, rot, angle;
1211 struct b43_c32 *samples; 1347 struct b43_c32 *samples;
1212 1348
1213 1349 bw = b43_is_40mhz(dev) ? 40 : 20;
1214 bw = (dev->phy.is_40mhz) ? 40 : 20;
1215 len = bw << 3; 1350 len = bw << 3;
1216 1351
1217 if (test) { 1352 if (test) {
@@ -1220,7 +1355,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1220 else 1355 else
1221 bw = 80; 1356 bw = 80;
1222 1357
1223 if (dev->phy.is_40mhz) 1358 if (b43_is_40mhz(dev))
1224 bw <<= 1; 1359 bw <<= 1;
1225 1360
1226 len = bw << 1; 1361 len = bw << 1;
@@ -1248,7 +1383,8 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max,
1248 1383
1249/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */ 1384/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RunSamples */
1250static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops, 1385static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1251 u16 wait, bool iqmode, bool dac_test) 1386 u16 wait, bool iqmode, bool dac_test,
1387 bool modify_bbmult)
1252{ 1388{
1253 struct b43_phy_n *nphy = dev->phy.n; 1389 struct b43_phy_n *nphy = dev->phy.n;
1254 int i; 1390 int i;
@@ -1262,12 +1398,10 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1262 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000; 1398 nphy->bb_mult_save = (tmp & 0xFFFF) | 0x80000000;
1263 } 1399 }
1264 1400
1265 /* TODO: add modify_bbmult argument */ 1401 if (modify_bbmult) {
1266 if (!dev->phy.is_40mhz) 1402 tmp = !b43_is_40mhz(dev) ? 0x6464 : 0x4747;
1267 tmp = 0x6464; 1403 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1268 else 1404 }
1269 tmp = 0x4747;
1270 b43_ntab_write(dev, B43_NTAB16(15, 87), tmp);
1271 1405
1272 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1)); 1406 b43_phy_write(dev, B43_NPHY_SAMP_DEPCNT, (samps - 1));
1273 1407
@@ -1285,10 +1419,8 @@ static void b43_nphy_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
1285 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF); 1419 b43_phy_mask(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x7FFF);
1286 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000); 1420 b43_phy_set(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8000);
1287 } else { 1421 } else {
1288 if (dac_test) 1422 tmp = dac_test ? 5 : 1;
1289 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 5); 1423 b43_phy_write(dev, B43_NPHY_SAMP_CMD, tmp);
1290 else
1291 b43_phy_write(dev, B43_NPHY_SAMP_CMD, 1);
1292 } 1424 }
1293 for (i = 0; i < 100; i++) { 1425 for (i = 0; i < 100; i++) {
1294 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) { 1426 if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & 1)) {
@@ -1675,6 +1807,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, enum n_rssi_type rssi_type,
1675/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ 1807/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1676static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) 1808static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1677{ 1809{
1810 struct b43_phy *phy = &dev->phy;
1678 struct b43_phy_n *nphy = dev->phy.n; 1811 struct b43_phy_n *nphy = dev->phy.n;
1679 1812
1680 u16 saved_regs_phy_rfctl[2]; 1813 u16 saved_regs_phy_rfctl[2];
@@ -1897,9 +2030,9 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1897 2030
1898 /* Remember for which channel we store configuration */ 2031 /* Remember for which channel we store configuration */
1899 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 2032 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
1900 nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq; 2033 nphy->rssical_chanspec_2G.center_freq = phy->chandef->chan->center_freq;
1901 else 2034 else
1902 nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq; 2035 nphy->rssical_chanspec_5G.center_freq = phy->chandef->chan->center_freq;
1903 2036
1904 /* End of calibration, restore configuration */ 2037 /* End of calibration, restore configuration */
1905 b43_nphy_classifier(dev, 7, class); 2038 b43_nphy_classifier(dev, 7, class);
@@ -2192,7 +2325,7 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
2192 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84); 2325 b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 0x84);
2193 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84); 2326 b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 0x84);
2194 2327
2195 if (!dev->phy.is_40mhz) { 2328 if (!b43_is_40mhz(dev)) {
2196 /* Set dwell lengths */ 2329 /* Set dwell lengths */
2197 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B); 2330 b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 0x002B);
2198 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B); 2331 b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 0x002B);
@@ -2206,7 +2339,7 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
2206 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, 2339 b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES,
2207 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21); 2340 ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, 21);
2208 2341
2209 if (!dev->phy.is_40mhz) { 2342 if (!b43_is_40mhz(dev)) {
2210 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, 2343 b43_phy_maskset(dev, B43_NPHY_C1_CGAINI,
2211 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1); 2344 ~B43_NPHY_C1_CGAINI_GAINBKOFF, 0x1);
2212 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, 2345 b43_phy_maskset(dev, B43_NPHY_C2_CGAINI,
@@ -2221,12 +2354,12 @@ static void b43_nphy_gain_ctl_workarounds_rev1_2(struct b43_wldev *dev)
2221 2354
2222 if (nphy->gain_boost) { 2355 if (nphy->gain_boost) {
2223 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ && 2356 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ &&
2224 dev->phy.is_40mhz) 2357 b43_is_40mhz(dev))
2225 code = 4; 2358 code = 4;
2226 else 2359 else
2227 code = 5; 2360 code = 5;
2228 } else { 2361 } else {
2229 code = dev->phy.is_40mhz ? 6 : 7; 2362 code = b43_is_40mhz(dev) ? 6 : 7;
2230 } 2363 }
2231 2364
2232 /* Set HPVGA2 index */ 2365 /* Set HPVGA2 index */
@@ -2298,7 +2431,7 @@ static void b43_nphy_gain_ctl_workarounds(struct b43_wldev *dev)
2298static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset) 2431static u16 b43_nphy_read_lpf_ctl(struct b43_wldev *dev, u16 offset)
2299{ 2432{
2300 if (!offset) 2433 if (!offset)
2301 offset = (dev->phy.is_40mhz) ? 0x159 : 0x154; 2434 offset = b43_is_40mhz(dev) ? 0x159 : 0x154;
2302 return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7; 2435 return b43_ntab_read(dev, B43_NTAB16(7, offset)) & 0x7;
2303} 2436}
2304 2437
@@ -2371,13 +2504,13 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2371 lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159); 2504 lpf_40 = b43_nphy_read_lpf_ctl(dev, 0x159);
2372 lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152); 2505 lpf_11b = b43_nphy_read_lpf_ctl(dev, 0x152);
2373 if (b43_nphy_ipa(dev)) { 2506 if (b43_nphy_ipa(dev)) {
2374 if ((phy->radio_rev == 5 && phy->is_40mhz) || 2507 if ((phy->radio_rev == 5 && b43_is_40mhz(dev)) ||
2375 phy->radio_rev == 7 || phy->radio_rev == 8) { 2508 phy->radio_rev == 7 || phy->radio_rev == 8) {
2376 bcap_val = b43_radio_read(dev, 0x16b); 2509 bcap_val = b43_radio_read(dev, 0x16b);
2377 scap_val = b43_radio_read(dev, 0x16a); 2510 scap_val = b43_radio_read(dev, 0x16a);
2378 scap_val_11b = scap_val; 2511 scap_val_11b = scap_val;
2379 bcap_val_11b = bcap_val; 2512 bcap_val_11b = bcap_val;
2380 if (phy->radio_rev == 5 && phy->is_40mhz) { 2513 if (phy->radio_rev == 5 && b43_is_40mhz(dev)) {
2381 scap_val_11n_20 = scap_val; 2514 scap_val_11n_20 = scap_val;
2382 bcap_val_11n_20 = bcap_val; 2515 bcap_val_11n_20 = bcap_val;
2383 scap_val_11n_40 = bcap_val_11n_40 = 0xc; 2516 scap_val_11n_40 = bcap_val_11n_40 = 0xc;
@@ -2519,7 +2652,7 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2519 } 2652 }
2520 } 2653 }
2521 } else if (phy->radio_rev == 7 || phy->radio_rev == 8) { 2654 } else if (phy->radio_rev == 7 || phy->radio_rev == 8) {
2522 if (!phy->is_40mhz) { 2655 if (!b43_is_40mhz(dev)) {
2523 b43_radio_write(dev, 0x5F, 0x14); 2656 b43_radio_write(dev, 0x5F, 0x14);
2524 b43_radio_write(dev, 0xE8, 0x12); 2657 b43_radio_write(dev, 0xE8, 0x12);
2525 } else { 2658 } else {
@@ -2528,7 +2661,7 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2528 } 2661 }
2529 } 2662 }
2530 } else { 2663 } else {
2531 u16 freq = phy->channel_freq; 2664 u16 freq = phy->chandef->chan->center_freq;
2532 if ((freq >= 5180 && freq <= 5230) || 2665 if ((freq >= 5180 && freq <= 5230) ||
2533 (freq >= 5745 && freq <= 5805)) { 2666 (freq >= 5745 && freq <= 5805)) {
2534 b43_radio_write(dev, 0x7D, 0xFF); 2667 b43_radio_write(dev, 0x7D, 0xFF);
@@ -2592,7 +2725,7 @@ static void b43_nphy_workarounds_rev7plus(struct b43_wldev *dev)
2592 b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77); 2725 b43_ntab_write(dev, B43_NTAB16(7, 0x123), 0x77);
2593 b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77); 2726 b43_ntab_write(dev, B43_NTAB16(7, 0x12A), 0x77);
2594 2727
2595 if (!phy->is_40mhz) { 2728 if (!b43_is_40mhz(dev)) {
2596 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D); 2729 b43_ntab_write(dev, B43_NTAB32(16, 0x03), 0x18D);
2597 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D); 2730 b43_ntab_write(dev, B43_NTAB32(16, 0x7F), 0x18D);
2598 } else { 2731 } else {
@@ -2691,7 +2824,7 @@ static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
2691 2824
2692 b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700); 2825 b43_phy_maskset(dev, B43_NPHY_SGILTRNOFFSET, 0xF0FF, 0x0700);
2693 2826
2694 if (!dev->phy.is_40mhz) { 2827 if (!b43_is_40mhz(dev)) {
2695 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D); 2828 b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
2696 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D); 2829 b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
2697 } else { 2830 } else {
@@ -2946,12 +3079,13 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
2946 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone 3079 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TXTone
2947 */ 3080 */
2948static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val, 3081static int b43_nphy_tx_tone(struct b43_wldev *dev, u32 freq, u16 max_val,
2949 bool iqmode, bool dac_test) 3082 bool iqmode, bool dac_test, bool modify_bbmult)
2950{ 3083{
2951 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test); 3084 u16 samp = b43_nphy_gen_load_samples(dev, freq, max_val, dac_test);
2952 if (samp == 0) 3085 if (samp == 0)
2953 return -1; 3086 return -1;
2954 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test); 3087 b43_nphy_run_samples(dev, samp, 0xFFFF, 0, iqmode, dac_test,
3088 modify_bbmult);
2955 return 0; 3089 return 0;
2956} 3090}
2957 3091
@@ -3114,7 +3248,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
3114 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, 3248 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
3115 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A); 3249 ~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
3116 3250
3117 if (dev->phy.rev < 2 && dev->phy.is_40mhz) 3251 if (dev->phy.rev < 2 && b43_is_40mhz(dev))
3118 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW); 3252 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
3119 } else { 3253 } else {
3120 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, 3254 b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
@@ -3168,7 +3302,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
3168 else if (dev->phy.rev < 2) 3302 else if (dev->phy.rev < 2)
3169 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40); 3303 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
3170 3304
3171 if (dev->phy.rev < 2 && dev->phy.is_40mhz) 3305 if (dev->phy.rev < 2 && b43_is_40mhz(dev))
3172 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW); 3306 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
3173 3307
3174 if (b43_nphy_ipa(dev)) { 3308 if (b43_nphy_ipa(dev)) {
@@ -3184,12 +3318,13 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
3184/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */ 3318/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrFix */
3185static void b43_nphy_tx_power_fix(struct b43_wldev *dev) 3319static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
3186{ 3320{
3321 struct b43_phy *phy = &dev->phy;
3187 struct b43_phy_n *nphy = dev->phy.n; 3322 struct b43_phy_n *nphy = dev->phy.n;
3188 struct ssb_sprom *sprom = dev->dev->bus_sprom; 3323 struct ssb_sprom *sprom = dev->dev->bus_sprom;
3189 3324
3190 u8 txpi[2], bbmult, i; 3325 u8 txpi[2], bbmult, i;
3191 u16 tmp, radio_gain, dac_gain; 3326 u16 tmp, radio_gain, dac_gain;
3192 u16 freq = dev->phy.channel_freq; 3327 u16 freq = phy->chandef->chan->center_freq;
3193 u32 txgain; 3328 u32 txgain;
3194 /* u32 gaintbl; rev3+ */ 3329 /* u32 gaintbl; rev3+ */
3195 3330
@@ -3234,7 +3369,11 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
3234 */ 3369 */
3235 3370
3236 for (i = 0; i < 2; i++) { 3371 for (i = 0; i < 2; i++) {
3237 txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]); 3372 const u32 *table = b43_nphy_get_tx_gain_table(dev);
3373
3374 if (!table)
3375 break;
3376 txgain = *(table + txpi[i]);
3238 3377
3239 if (dev->phy.rev >= 3) 3378 if (dev->phy.rev >= 3)
3240 radio_gain = (txgain >> 16) & 0x1FFFF; 3379 radio_gain = (txgain >> 16) & 0x1FFFF;
@@ -3388,7 +3527,7 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
3388 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false); 3527 b43_nphy_rf_ctl_override(dev, 0x2000, 0, 3, false);
3389 3528
3390 b43_nphy_stop_playback(dev); 3529 b43_nphy_stop_playback(dev);
3391 b43_nphy_tx_tone(dev, 0xFA0, 0, false, false); 3530 b43_nphy_tx_tone(dev, 4000, 0, false, false, false);
3392 udelay(20); 3531 udelay(20);
3393 tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1); 3532 tmp = b43_nphy_poll_rssi(dev, N_RSSI_TSSI_2G, rssi, 1);
3394 b43_nphy_stop_playback(dev); 3533 b43_nphy_stop_playback(dev);
@@ -3439,21 +3578,21 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
3439 delta = 0; 3578 delta = 0;
3440 switch (stf_mode) { 3579 switch (stf_mode) {
3441 case 0: 3580 case 0:
3442 if (dev->phy.is_40mhz && dev->phy.rev >= 5) { 3581 if (b43_is_40mhz(dev) && dev->phy.rev >= 5) {
3443 idx = 68; 3582 idx = 68;
3444 } else { 3583 } else {
3445 delta = 1; 3584 delta = 1;
3446 idx = dev->phy.is_40mhz ? 52 : 4; 3585 idx = b43_is_40mhz(dev) ? 52 : 4;
3447 } 3586 }
3448 break; 3587 break;
3449 case 1: 3588 case 1:
3450 idx = dev->phy.is_40mhz ? 76 : 28; 3589 idx = b43_is_40mhz(dev) ? 76 : 28;
3451 break; 3590 break;
3452 case 2: 3591 case 2:
3453 idx = dev->phy.is_40mhz ? 84 : 36; 3592 idx = b43_is_40mhz(dev) ? 84 : 36;
3454 break; 3593 break;
3455 case 3: 3594 case 3:
3456 idx = dev->phy.is_40mhz ? 92 : 44; 3595 idx = b43_is_40mhz(dev) ? 92 : 44;
3457 break; 3596 break;
3458 } 3597 }
3459 3598
@@ -3474,6 +3613,7 @@ static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev)
3474/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ 3613/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */
3475static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) 3614static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
3476{ 3615{
3616 struct b43_phy *phy = &dev->phy;
3477 struct b43_phy_n *nphy = dev->phy.n; 3617 struct b43_phy_n *nphy = dev->phy.n;
3478 struct ssb_sprom *sprom = dev->dev->bus_sprom; 3618 struct ssb_sprom *sprom = dev->dev->bus_sprom;
3479 3619
@@ -3483,7 +3623,7 @@ static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev)
3483 s32 num, den, pwr; 3623 s32 num, den, pwr;
3484 u32 regval[64]; 3624 u32 regval[64];
3485 3625
3486 u16 freq = dev->phy.channel_freq; 3626 u16 freq = phy->chandef->chan->center_freq;
3487 u16 tmp; 3627 u16 tmp;
3488 u16 r; /* routing */ 3628 u16 r; /* routing */
3489 u8 i, c; 3629 u8 i, c;
@@ -3647,6 +3787,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
3647 int i; 3787 int i;
3648 3788
3649 table = b43_nphy_get_tx_gain_table(dev); 3789 table = b43_nphy_get_tx_gain_table(dev);
3790 if (!table)
3791 return;
3792
3650 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); 3793 b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
3651 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); 3794 b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
3652 3795
@@ -3705,21 +3848,28 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
3705 } 3848 }
3706} 3849}
3707 3850
3708/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */ 3851/*
3709static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev) 3852 * TX low-pass filter bandwidth setup
3853 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw
3854 */
3855static void b43_nphy_tx_lpf_bw(struct b43_wldev *dev)
3710{ 3856{
3711 u16 tmp; 3857 u16 tmp;
3712 3858
3713 if (dev->phy.rev >= 3) { 3859 if (dev->phy.rev < 3 || dev->phy.rev >= 7)
3714 if (b43_nphy_ipa(dev)) { 3860 return;
3715 tmp = 4;
3716 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
3717 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
3718 }
3719 3861
3720 tmp = 1; 3862 if (b43_nphy_ipa(dev))
3863 tmp = b43_is_40mhz(dev) ? 5 : 4;
3864 else
3865 tmp = b43_is_40mhz(dev) ? 3 : 1;
3866 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
3867 (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
3868
3869 if (b43_nphy_ipa(dev)) {
3870 tmp = b43_is_40mhz(dev) ? 4 : 1;
3721 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2, 3871 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
3722 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp); 3872 (tmp << 9) | (tmp << 6) | (tmp << 3) | tmp);
3723 } 3873 }
3724} 3874}
3725 3875
@@ -3992,7 +4142,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev)
3992 4142
3993 if (nphy->gband_spurwar_en) { 4143 if (nphy->gband_spurwar_en) {
3994 /* TODO: N PHY Adjust Analog Pfbw (7) */ 4144 /* TODO: N PHY Adjust Analog Pfbw (7) */
3995 if (channel == 11 && dev->phy.is_40mhz) 4145 if (channel == 11 && b43_is_40mhz(dev))
3996 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/ 4146 ; /* TODO: N PHY Adjust Min Noise Var(2, tone, noise)*/
3997 else 4147 else
3998 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/ 4148 ; /* TODO: N PHY Adjust Min Noise Var(0, NULL, NULL)*/
@@ -4286,7 +4436,7 @@ static void b43_nphy_int_pa_set_tx_dig_filters(struct b43_wldev *dev)
4286 b43_phy_write(dev, B43_PHY_N(offset[i] + j), 4436 b43_phy_write(dev, B43_PHY_N(offset[i] + j),
4287 tbl_tx_filter_coef_rev4[i][j]); 4437 tbl_tx_filter_coef_rev4[i][j]);
4288 4438
4289 if (dev->phy.is_40mhz) { 4439 if (b43_is_40mhz(dev)) {
4290 for (j = 0; j < 15; j++) 4440 for (j = 0; j < 15; j++)
4291 b43_phy_write(dev, B43_PHY_N(offset[0] + j), 4441 b43_phy_write(dev, B43_PHY_N(offset[0] + j),
4292 tbl_tx_filter_coef_rev4[3][j]); 4442 tbl_tx_filter_coef_rev4[3][j]);
@@ -4345,6 +4495,9 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
4345 4495
4346 for (i = 0; i < 2; ++i) { 4496 for (i = 0; i < 2; ++i) {
4347 table = b43_nphy_get_tx_gain_table(dev); 4497 table = b43_nphy_get_tx_gain_table(dev);
4498 if (!table)
4499 break;
4500
4348 if (dev->phy.rev >= 3) { 4501 if (dev->phy.rev >= 3) {
4349 target.ipa[i] = (table[index[i]] >> 16) & 0xF; 4502 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
4350 target.pad[i] = (table[index[i]] >> 20) & 0xF; 4503 target.pad[i] = (table[index[i]] >> 20) & 0xF;
@@ -4500,8 +4653,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev)
4500 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); 4653 txcal_radio_regs[2] = b43_radio_read(dev, 0x8D);
4501 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); 4654 txcal_radio_regs[3] = b43_radio_read(dev, 0xBC);
4502 } 4655 }
4503 iqcal_chanspec->center_freq = dev->phy.channel_freq; 4656 iqcal_chanspec->center_freq = dev->phy.chandef->chan->center_freq;
4504 iqcal_chanspec->channel_type = dev->phy.channel_type; 4657 iqcal_chanspec->channel_type =
4658 cfg80211_get_chandef_type(dev->phy.chandef);
4505 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table); 4659 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table);
4506 4660
4507 if (nphy->hang_avoid) 4661 if (nphy->hang_avoid)
@@ -4581,6 +4735,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
4581 struct nphy_txgains target, 4735 struct nphy_txgains target,
4582 bool full, bool mphase) 4736 bool full, bool mphase)
4583{ 4737{
4738 struct b43_phy *phy = &dev->phy;
4584 struct b43_phy_n *nphy = dev->phy.n; 4739 struct b43_phy_n *nphy = dev->phy.n;
4585 int i; 4740 int i;
4586 int error = 0; 4741 int error = 0;
@@ -4621,7 +4776,7 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
4621 (dev->phy.rev == 5 && nphy->ipa2g_on && 4776 (dev->phy.rev == 5 && nphy->ipa2g_on &&
4622 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); 4777 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
4623 if (phy6or5x) { 4778 if (phy6or5x) {
4624 if (dev->phy.is_40mhz) { 4779 if (b43_is_40mhz(dev)) {
4625 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18, 4780 b43_ntab_write_bulk(dev, B43_NTAB16(15, 0), 18,
4626 tbl_tx_iqlo_cal_loft_ladder_40); 4781 tbl_tx_iqlo_cal_loft_ladder_40);
4627 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18, 4782 b43_ntab_write_bulk(dev, B43_NTAB16(15, 32), 18,
@@ -4636,16 +4791,16 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
4636 4791
4637 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); 4792 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
4638 4793
4639 if (!dev->phy.is_40mhz) 4794 if (!b43_is_40mhz(dev))
4640 freq = 2500; 4795 freq = 2500;
4641 else 4796 else
4642 freq = 5000; 4797 freq = 5000;
4643 4798
4644 if (nphy->mphase_cal_phase_id > 2) 4799 if (nphy->mphase_cal_phase_id > 2)
4645 b43_nphy_run_samples(dev, (dev->phy.is_40mhz ? 40 : 20) * 8, 4800 b43_nphy_run_samples(dev, (b43_is_40mhz(dev) ? 40 : 20) * 8,
4646 0xFFFF, 0, true, false); 4801 0xFFFF, 0, true, false, false);
4647 else 4802 else
4648 error = b43_nphy_tx_tone(dev, freq, 250, true, false); 4803 error = b43_nphy_tx_tone(dev, freq, 250, true, false, false);
4649 4804
4650 if (error == 0) { 4805 if (error == 0) {
4651 if (nphy->mphase_cal_phase_id > 2) { 4806 if (nphy->mphase_cal_phase_id > 2) {
@@ -4773,9 +4928,9 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
4773 nphy->txiqlocal_bestc); 4928 nphy->txiqlocal_bestc);
4774 nphy->txiqlocal_coeffsvalid = true; 4929 nphy->txiqlocal_coeffsvalid = true;
4775 nphy->txiqlocal_chanspec.center_freq = 4930 nphy->txiqlocal_chanspec.center_freq =
4776 dev->phy.channel_freq; 4931 phy->chandef->chan->center_freq;
4777 nphy->txiqlocal_chanspec.channel_type = 4932 nphy->txiqlocal_chanspec.channel_type =
4778 dev->phy.channel_type; 4933 cfg80211_get_chandef_type(phy->chandef);
4779 } else { 4934 } else {
4780 length = 11; 4935 length = 11;
4781 if (dev->phy.rev < 3) 4936 if (dev->phy.rev < 3)
@@ -4811,8 +4966,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev)
4811 bool equal = true; 4966 bool equal = true;
4812 4967
4813 if (!nphy->txiqlocal_coeffsvalid || 4968 if (!nphy->txiqlocal_coeffsvalid ||
4814 nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq || 4969 nphy->txiqlocal_chanspec.center_freq != dev->phy.chandef->chan->center_freq ||
4815 nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type) 4970 nphy->txiqlocal_chanspec.channel_type != cfg80211_get_chandef_type(dev->phy.chandef))
4816 return; 4971 return;
4817 4972
4818 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); 4973 b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer);
@@ -4968,11 +5123,11 @@ static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
4968 if (playtone) { 5123 if (playtone) {
4969 ret = b43_nphy_tx_tone(dev, 4000, 5124 ret = b43_nphy_tx_tone(dev, 4000,
4970 (nphy->rxcalparams & 0xFFFF), 5125 (nphy->rxcalparams & 0xFFFF),
4971 false, false); 5126 false, false, true);
4972 playtone = false; 5127 playtone = false;
4973 } else { 5128 } else {
4974 b43_nphy_run_samples(dev, 160, 0xFFFF, 0, 5129 b43_nphy_run_samples(dev, 160, 0xFFFF, 0, false,
4975 false, false); 5130 false, true);
4976 } 5131 }
4977 5132
4978 if (ret == 0) { 5133 if (ret == 0) {
@@ -5344,7 +5499,7 @@ static int b43_phy_initn(struct b43_wldev *dev)
5344 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320); 5499 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
5345 if (phy->rev >= 3 && phy->rev <= 6) 5500 if (phy->rev >= 3 && phy->rev <= 6)
5346 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032); 5501 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0032);
5347 b43_nphy_tx_lp_fbw(dev); 5502 b43_nphy_tx_lpf_bw(dev);
5348 if (phy->rev >= 3) 5503 if (phy->rev >= 3)
5349 b43_nphy_spur_workaround(dev); 5504 b43_nphy_spur_workaround(dev);
5350 5505
@@ -5430,14 +5585,14 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
5430 if (dev->phy.rev < 3) 5585 if (dev->phy.rev < 3)
5431 b43_nphy_adjust_lna_gain_table(dev); 5586 b43_nphy_adjust_lna_gain_table(dev);
5432 5587
5433 b43_nphy_tx_lp_fbw(dev); 5588 b43_nphy_tx_lpf_bw(dev);
5434 5589
5435 if (dev->phy.rev >= 3 && 5590 if (dev->phy.rev >= 3 &&
5436 dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) { 5591 dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
5437 bool avoid = false; 5592 bool avoid = false;
5438 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) { 5593 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
5439 avoid = true; 5594 avoid = true;
5440 } else if (!b43_channel_type_is_40mhz(phy->channel_type)) { 5595 } else if (!b43_is_40mhz(dev)) {
5441 if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14) 5596 if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
5442 avoid = true; 5597 avoid = true;
5443 } else { /* 40MHz */ 5598 } else { /* 40MHz */
@@ -5484,10 +5639,17 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
5484 5639
5485 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL; 5640 const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
5486 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL; 5641 const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
5642 const struct b43_nphy_chantabent_rev7 *tabent_r7 = NULL;
5643 const struct b43_nphy_chantabent_rev7_2g *tabent_r7_2g = NULL;
5487 5644
5488 u8 tmp; 5645 u8 tmp;
5489 5646
5490 if (dev->phy.rev >= 3) { 5647 if (phy->rev >= 7) {
5648 r2057_get_chantabent_rev7(dev, channel->center_freq,
5649 &tabent_r7, &tabent_r7_2g);
5650 if (!tabent_r7 && !tabent_r7_2g)
5651 return -ESRCH;
5652 } else if (phy->rev >= 3) {
5491 tabent_r3 = b43_nphy_get_chantabent_rev3(dev, 5653 tabent_r3 = b43_nphy_get_chantabent_rev3(dev,
5492 channel->center_freq); 5654 channel->center_freq);
5493 if (!tabent_r3) 5655 if (!tabent_r3)
@@ -5502,20 +5664,36 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
5502 /* Channel is set later in common code, but we need to set it on our 5664 /* Channel is set later in common code, but we need to set it on our
5503 own to let this function's subcalls work properly. */ 5665 own to let this function's subcalls work properly. */
5504 phy->channel = channel->hw_value; 5666 phy->channel = channel->hw_value;
5505 phy->channel_freq = channel->center_freq;
5506 5667
5668#if 0
5507 if (b43_channel_type_is_40mhz(phy->channel_type) != 5669 if (b43_channel_type_is_40mhz(phy->channel_type) !=
5508 b43_channel_type_is_40mhz(channel_type)) 5670 b43_channel_type_is_40mhz(channel_type))
5509 ; /* TODO: BMAC BW Set (channel_type) */ 5671 ; /* TODO: BMAC BW Set (channel_type) */
5672#endif
5510 5673
5511 if (channel_type == NL80211_CHAN_HT40PLUS) 5674 if (channel_type == NL80211_CHAN_HT40PLUS) {
5512 b43_phy_set(dev, B43_NPHY_RXCTL, 5675 b43_phy_set(dev, B43_NPHY_RXCTL, B43_NPHY_RXCTL_BSELU20);
5513 B43_NPHY_RXCTL_BSELU20); 5676 if (phy->rev >= 7)
5514 else if (channel_type == NL80211_CHAN_HT40MINUS) 5677 b43_phy_set(dev, 0x310, 0x8000);
5515 b43_phy_mask(dev, B43_NPHY_RXCTL, 5678 } else if (channel_type == NL80211_CHAN_HT40MINUS) {
5516 ~B43_NPHY_RXCTL_BSELU20); 5679 b43_phy_mask(dev, B43_NPHY_RXCTL, ~B43_NPHY_RXCTL_BSELU20);
5680 if (phy->rev >= 7)
5681 b43_phy_mask(dev, 0x310, (u16)~0x8000);
5682 }
5517 5683
5518 if (dev->phy.rev >= 3) { 5684 if (phy->rev >= 7) {
5685 const struct b43_phy_n_sfo_cfg *phy_regs = tabent_r7 ?
5686 &(tabent_r7->phy_regs) : &(tabent_r7_2g->phy_regs);
5687
5688 if (phy->radio_rev <= 4 || phy->radio_rev == 6) {
5689 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 2 : 0;
5690 b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE0, ~2, tmp);
5691 b43_radio_maskset(dev, R2057_TIA_CONFIG_CORE1, ~2, tmp);
5692 }
5693
5694 b43_radio_2057_setup(dev, tabent_r7, tabent_r7_2g);
5695 b43_nphy_channel_setup(dev, phy_regs, channel);
5696 } else if (phy->rev >= 3) {
5519 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0; 5697 tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0;
5520 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); 5698 b43_radio_maskset(dev, 0x08, 0xFFFB, tmp);
5521 b43_radio_2056_setup(dev, tabent_r3); 5699 b43_radio_2056_setup(dev, tabent_r3);
diff --git a/drivers/net/wireless/b43/radio_2057.c b/drivers/net/wireless/b43/radio_2057.c
index d61d6830c5c7..df3574545819 100644
--- a/drivers/net/wireless/b43/radio_2057.c
+++ b/drivers/net/wireless/b43/radio_2057.c
@@ -26,7 +26,7 @@
26#include "radio_2057.h" 26#include "radio_2057.h"
27#include "phy_common.h" 27#include "phy_common.h"
28 28
29static u16 r2057_rev4_init[42][2] = { 29static u16 r2057_rev4_init[][2] = {
30 { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, 30 { 0x0E, 0x20 }, { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 },
31 { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff }, 31 { 0x35, 0x26 }, { 0x3C, 0xff }, { 0x3D, 0xff }, { 0x3E, 0xff },
32 { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 }, 32 { 0x3F, 0xff }, { 0x62, 0x33 }, { 0x8A, 0xf0 }, { 0x8B, 0x10 },
@@ -40,7 +40,7 @@ static u16 r2057_rev4_init[42][2] = {
40 { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, 40 { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
41}; 41};
42 42
43static u16 r2057_rev5_init[44][2] = { 43static u16 r2057_rev5_init[][2] = {
44 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 }, 44 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
45 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, 45 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
46 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, 46 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
@@ -54,7 +54,7 @@ static u16 r2057_rev5_init[44][2] = {
54 { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 }, 54 { 0x1AC, 0x00 }, { 0x1B7, 0x0c }, { 0x1C1, 0x01 }, { 0x1C2, 0x80 },
55}; 55};
56 56
57static u16 r2057_rev5a_init[45][2] = { 57static u16 r2057_rev5a_init[][2] = {
58 { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 }, 58 { 0x00, 0x15 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x23, 0x6 },
59 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, 59 { 0x31, 0x00 }, { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 },
60 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, 60 { 0x59, 0x88 }, { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f },
@@ -69,7 +69,7 @@ static u16 r2057_rev5a_init[45][2] = {
69 { 0x1C2, 0x80 }, 69 { 0x1C2, 0x80 },
70}; 70};
71 71
72static u16 r2057_rev7_init[54][2] = { 72static u16 r2057_rev7_init[][2] = {
73 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 }, 73 { 0x00, 0x00 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
74 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 }, 74 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
75 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 }, 75 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x13 },
@@ -86,7 +86,8 @@ static u16 r2057_rev7_init[54][2] = {
86 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 }, 86 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
87}; 87};
88 88
89static u16 r2057_rev8_init[54][2] = { 89/* TODO: Which devices should use it?
90static u16 r2057_rev8_init[][2] = {
90 { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 }, 91 { 0x00, 0x08 }, { 0x01, 0x57 }, { 0x02, 0x20 }, { 0x31, 0x00 },
91 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 }, 92 { 0x32, 0x00 }, { 0x33, 0x00 }, { 0x51, 0x70 }, { 0x59, 0x88 },
92 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f }, 93 { 0x5C, 0x20 }, { 0x62, 0x33 }, { 0x63, 0x0f }, { 0x64, 0x0f },
@@ -102,6 +103,47 @@ static u16 r2057_rev8_init[54][2] = {
102 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 }, 103 { 0x1A6, 0x00 }, { 0x1AA, 0x00 }, { 0x1AB, 0x00 }, { 0x1AC, 0x00 },
103 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 }, 104 { 0x1B7, 0x05 }, { 0x1C2, 0xa0 },
104}; 105};
106*/
107
108#define RADIOREGS7(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
109 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
110 r20, r21, r22, r23, r24, r25, r26, r27) \
111 .radio_vcocal_countval0 = r00, \
112 .radio_vcocal_countval1 = r01, \
113 .radio_rfpll_refmaster_sparextalsize = r02, \
114 .radio_rfpll_loopfilter_r1 = r03, \
115 .radio_rfpll_loopfilter_c2 = r04, \
116 .radio_rfpll_loopfilter_c1 = r05, \
117 .radio_cp_kpd_idac = r06, \
118 .radio_rfpll_mmd0 = r07, \
119 .radio_rfpll_mmd1 = r08, \
120 .radio_vcobuf_tune = r09, \
121 .radio_logen_mx2g_tune = r10, \
122 .radio_logen_mx5g_tune = r11, \
123 .radio_logen_indbuf2g_tune = r12, \
124 .radio_logen_indbuf5g_tune = r13, \
125 .radio_txmix2g_tune_boost_pu_core0 = r14, \
126 .radio_pad2g_tune_pus_core0 = r15, \
127 .radio_pga_boost_tune_core0 = r16, \
128 .radio_txmix5g_boost_tune_core0 = r17, \
129 .radio_pad5g_tune_misc_pus_core0 = r18, \
130 .radio_lna2g_tune_core0 = r19, \
131 .radio_lna5g_tune_core0 = r20, \
132 .radio_txmix2g_tune_boost_pu_core1 = r21, \
133 .radio_pad2g_tune_pus_core1 = r22, \
134 .radio_pga_boost_tune_core1 = r23, \
135 .radio_txmix5g_boost_tune_core1 = r24, \
136 .radio_pad5g_tune_misc_pus_core1 = r25, \
137 .radio_lna2g_tune_core1 = r26, \
138 .radio_lna5g_tune_core1 = r27
139
140#define PHYREGS(r0, r1, r2, r3, r4, r5) \
141 .phy_regs.phy_bw1a = r0, \
142 .phy_regs.phy_bw2 = r1, \
143 .phy_regs.phy_bw3 = r2, \
144 .phy_regs.phy_bw4 = r3, \
145 .phy_regs.phy_bw5 = r4, \
146 .phy_regs.phy_bw6 = r5
105 147
106void r2057_upload_inittabs(struct b43_wldev *dev) 148void r2057_upload_inittabs(struct b43_wldev *dev)
107{ 149{
@@ -109,33 +151,69 @@ void r2057_upload_inittabs(struct b43_wldev *dev)
109 u16 *table = NULL; 151 u16 *table = NULL;
110 u16 size, i; 152 u16 size, i;
111 153
112 if (phy->rev == 7) { 154 switch (phy->rev) {
155 case 7:
113 table = r2057_rev4_init[0]; 156 table = r2057_rev4_init[0];
114 size = ARRAY_SIZE(r2057_rev4_init); 157 size = ARRAY_SIZE(r2057_rev4_init);
115 } else if (phy->rev == 8 || phy->rev == 9) { 158 break;
159 case 8:
116 if (phy->radio_rev == 5) { 160 if (phy->radio_rev == 5) {
117 if (phy->radio_rev == 8) { 161 table = r2057_rev5_init[0];
118 table = r2057_rev5_init[0]; 162 size = ARRAY_SIZE(r2057_rev5_init);
119 size = ARRAY_SIZE(r2057_rev5_init);
120 } else {
121 table = r2057_rev5a_init[0];
122 size = ARRAY_SIZE(r2057_rev5a_init);
123 }
124 } else if (phy->radio_rev == 7) { 163 } else if (phy->radio_rev == 7) {
125 table = r2057_rev7_init[0]; 164 table = r2057_rev7_init[0];
126 size = ARRAY_SIZE(r2057_rev7_init); 165 size = ARRAY_SIZE(r2057_rev7_init);
127 } else if (phy->radio_rev == 9) {
128 table = r2057_rev8_init[0];
129 size = ARRAY_SIZE(r2057_rev8_init);
130 } 166 }
167 break;
168 case 9:
169 if (phy->radio_rev == 5) {
170 table = r2057_rev5a_init[0];
171 size = ARRAY_SIZE(r2057_rev5a_init);
172 }
173 break;
131 } 174 }
132 175
176 B43_WARN_ON(!table);
177
133 if (table) { 178 if (table) {
134 for (i = 0; i < 10; i++) { 179 for (i = 0; i < size; i++, table += 2)
135 pr_info("radio_write 0x%X ", *table); 180 b43_radio_write(dev, table[0], table[1]);
136 table++; 181 }
137 pr_info("0x%X\n", *table); 182}
138 table++; 183
184void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
185 const struct b43_nphy_chantabent_rev7 **tabent_r7,
186 const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g)
187{
188 struct b43_phy *phy = &dev->phy;
189 const struct b43_nphy_chantabent_rev7 *e_r7 = NULL;
190 const struct b43_nphy_chantabent_rev7_2g *e_r7_2g = NULL;
191 unsigned int len, i;
192
193 *tabent_r7 = NULL;
194 *tabent_r7_2g = NULL;
195
196 /* TODO */
197 switch (phy->rev) {
198 default:
199 break;
200 }
201
202 if (e_r7) {
203 for (i = 0; i < len; i++, e_r7++) {
204 if (e_r7->freq == freq) {
205 *tabent_r7 = e_r7;
206 return;
207 }
208 }
209 } else if (e_r7_2g) {
210 for (i = 0; i < len; i++, e_r7_2g++) {
211 if (e_r7_2g->freq == freq) {
212 *tabent_r7_2g = e_r7_2g;
213 return;
214 }
139 } 215 }
216 } else {
217 B43_WARN_ON(1);
140 } 218 }
141} 219}
diff --git a/drivers/net/wireless/b43/radio_2057.h b/drivers/net/wireless/b43/radio_2057.h
index eeebd8fbeb0d..675d1bb64429 100644
--- a/drivers/net/wireless/b43/radio_2057.h
+++ b/drivers/net/wireless/b43/radio_2057.h
@@ -425,6 +425,72 @@
425 425
426#define R2057_VCM_MASK 0x7 426#define R2057_VCM_MASK 0x7
427 427
428struct b43_nphy_chantabent_rev7 {
429 /* The channel frequency in MHz */
430 u16 freq;
431 /* Radio regs values on channelswitch */
432 u8 radio_vcocal_countval0;
433 u8 radio_vcocal_countval1;
434 u8 radio_rfpll_refmaster_sparextalsize;
435 u8 radio_rfpll_loopfilter_r1;
436 u8 radio_rfpll_loopfilter_c2;
437 u8 radio_rfpll_loopfilter_c1;
438 u8 radio_cp_kpd_idac;
439 u8 radio_rfpll_mmd0;
440 u8 radio_rfpll_mmd1;
441 u8 radio_vcobuf_tune;
442 u8 radio_logen_mx2g_tune;
443 u8 radio_logen_mx5g_tune;
444 u8 radio_logen_indbuf2g_tune;
445 u8 radio_logen_indbuf5g_tune;
446 u8 radio_txmix2g_tune_boost_pu_core0;
447 u8 radio_pad2g_tune_pus_core0;
448 u8 radio_pga_boost_tune_core0;
449 u8 radio_txmix5g_boost_tune_core0;
450 u8 radio_pad5g_tune_misc_pus_core0;
451 u8 radio_lna2g_tune_core0;
452 u8 radio_lna5g_tune_core0;
453 u8 radio_txmix2g_tune_boost_pu_core1;
454 u8 radio_pad2g_tune_pus_core1;
455 u8 radio_pga_boost_tune_core1;
456 u8 radio_txmix5g_boost_tune_core1;
457 u8 radio_pad5g_tune_misc_pus_core1;
458 u8 radio_lna2g_tune_core1;
459 u8 radio_lna5g_tune_core1;
460 /* PHY res values on channelswitch */
461 struct b43_phy_n_sfo_cfg phy_regs;
462};
463
464struct b43_nphy_chantabent_rev7_2g {
465 /* The channel frequency in MHz */
466 u16 freq;
467 /* Radio regs values on channelswitch */
468 u8 radio_vcocal_countval0;
469 u8 radio_vcocal_countval1;
470 u8 radio_rfpll_refmaster_sparextalsize;
471 u8 radio_rfpll_loopfilter_r1;
472 u8 radio_rfpll_loopfilter_c2;
473 u8 radio_rfpll_loopfilter_c1;
474 u8 radio_cp_kpd_idac;
475 u8 radio_rfpll_mmd0;
476 u8 radio_rfpll_mmd1;
477 u8 radio_vcobuf_tune;
478 u8 radio_logen_mx2g_tune;
479 u8 radio_logen_indbuf2g_tune;
480 u8 radio_txmix2g_tune_boost_pu_core0;
481 u8 radio_pad2g_tune_pus_core0;
482 u8 radio_lna2g_tune_core0;
483 u8 radio_txmix2g_tune_boost_pu_core1;
484 u8 radio_pad2g_tune_pus_core1;
485 u8 radio_lna2g_tune_core1;
486 /* PHY regs values on channelswitch */
487 struct b43_phy_n_sfo_cfg phy_regs;
488};
489
428void r2057_upload_inittabs(struct b43_wldev *dev); 490void r2057_upload_inittabs(struct b43_wldev *dev);
429 491
492void r2057_get_chantabent_rev7(struct b43_wldev *dev, u16 freq,
493 const struct b43_nphy_chantabent_rev7 **tabent_r7,
494 const struct b43_nphy_chantabent_rev7_2g **tabent_r7_2g);
495
430#endif /* B43_RADIO_2057_H_ */ 496#endif /* B43_RADIO_2057_H_ */
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4047c05e3807..b28dce950e1f 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -2146,7 +2146,196 @@ static const u16 b43_ntab_antswctl_r3[4][32] = {
2146 } 2146 }
2147}; 2147};
2148 2148
2149/* TX gain tables */ 2149/* static tables, PHY revision >= 7 */
2150
2151/* Copied from brcmsmac (5.75.11) */
2152static const u32 b43_ntab_tmap_r7[] = {
2153 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2154 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2155 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
2156 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
2157 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
2158 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2159 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2160 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2161 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
2162 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
2163 0xf1111110, 0x11111111, 0x11f11111, 0x00011111,
2164 0x11110000, 0x1111f111, 0x11111111, 0x111111f1,
2165 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00088aaa,
2166 0xaaaa0000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2167 0xaaa8aaa0, 0x8aaa8aaa, 0xaa8a8a8a, 0x000aaa88,
2168 0x8aaa0000, 0xaaa8a888, 0x8aa88a8a, 0x8a88a888,
2169 0x08080a00, 0x0a08080a, 0x080a0a08, 0x00080808,
2170 0x080a0000, 0x080a0808, 0x080a0808, 0x0a0a0a08,
2171 0xa0a0a0a0, 0x80a0a080, 0x8080a0a0, 0x00008080,
2172 0x80a00000, 0x80a080a0, 0xa080a0a0, 0x8080a0a0,
2173 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2174 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2175 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2176 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2177 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2178 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2179 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2180 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2181 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2182 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2183 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2184 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2185 0x99999000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2186 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2187 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2188 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
2189 0x22000000, 0x2222b222, 0x22222222, 0x222222b2,
2190 0xb2222220, 0x22222222, 0x22d22222, 0x00000222,
2191 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2192 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2193 0x33000000, 0x3333b333, 0x33333333, 0x333333b3,
2194 0xb3333330, 0x33333333, 0x33d33333, 0x00000333,
2195 0x22000000, 0x2222a222, 0x22222222, 0x222222a2,
2196 0xa2222220, 0x22222222, 0x22c22222, 0x00000222,
2197 0x99b99b00, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2198 0x9b99bb99, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2199 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2200 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
2201 0x22222200, 0x2222f222, 0x22222222, 0x222222f2,
2202 0x22222222, 0x22222222, 0x22f22222, 0x00000222,
2203 0x11000000, 0x1111f111, 0x11111111, 0x11111111,
2204 0xf1111111, 0x11111111, 0x11f11111, 0x01111111,
2205 0xbb9bb900, 0xb9b9bb99, 0xb99bbbbb, 0xbbbb9b9b,
2206 0xb9bb99bb, 0xb99999b9, 0xb9b9b99b, 0x00000bbb,
2207 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2208 0xa8aa88aa, 0xa88888a8, 0xa8a8a88a, 0x0a888aaa,
2209 0xaa000000, 0xa8a8aa88, 0xa88aaaaa, 0xaaaa8a8a,
2210 0xa8aa88a0, 0xa88888a8, 0xa8a8a88a, 0x00000aaa,
2211 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2212 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2213 0xbbbbbb00, 0x999bbbbb, 0x9bb99b9b, 0xb9b9b9bb,
2214 0xb9b99bbb, 0xb9b9b9bb, 0xb9bb9b99, 0x00000999,
2215 0x8a000000, 0xaa88a888, 0xa88888aa, 0xa88a8a88,
2216 0xa88aa88a, 0x88a8aaaa, 0xa8aa8aaa, 0x0888a88a,
2217 0x0b0b0b00, 0x090b0b0b, 0x0b090b0b, 0x0909090b,
2218 0x09090b0b, 0x09090b0b, 0x09090b09, 0x00000909,
2219 0x0a000000, 0x0a080808, 0x080a080a, 0x080a0a08,
2220 0x080a080a, 0x0808080a, 0x0a0a0a08, 0x0808080a,
2221 0xb0b0b000, 0x9090b0b0, 0x90b09090, 0xb0b0b090,
2222 0xb0b090b0, 0x90b0b0b0, 0xb0b09090, 0x00000090,
2223 0x80000000, 0xa080a080, 0xa08080a0, 0xa0808080,
2224 0xa080a080, 0x80a0a0a0, 0xa0a080a0, 0x00a0a0a0,
2225 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
2226 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
2227 0x11000000, 0x1111f111, 0x11111111, 0x111111f1,
2228 0xf1111110, 0x11111111, 0x11f11111, 0x00000111,
2229 0x33000000, 0x3333f333, 0x33333333, 0x333333f3,
2230 0xf3333330, 0x33333333, 0x33f33333, 0x00000333,
2231 0x22000000, 0x2222f222, 0x22222222, 0x222222f2,
2232 0xf2222220, 0x22222222, 0x22f22222, 0x00000222,
2233 0x99000000, 0x9b9b99bb, 0x9bb99999, 0x9999b9b9,
2234 0x9b99bb90, 0x9bbbbb9b, 0x9b9b9bb9, 0x00000999,
2235 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2236 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2237 0x88888000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2238 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2239 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2240 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00aaa888,
2241 0x88a88a00, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2242 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x000aa888,
2243 0x88880000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2244 0x8a88aa88, 0x8aaaaa8a, 0x8a8a8aa8, 0x08aaa888,
2245 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2246 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2247 0x11000000, 0x1111a111, 0x11111111, 0x111111a1,
2248 0xa1111110, 0x11111111, 0x11c11111, 0x00000111,
2249 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2250 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2251 0x88000000, 0x8a8a88aa, 0x8aa88888, 0x8888a8a8,
2252 0x8a88aa80, 0x8aaaaa8a, 0x8a8a8aa8, 0x00000888,
2253 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2254 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2255 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2256 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2257 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2258 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2259 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2260 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2261 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2262 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2263 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2264 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2265};
2266
2267/* Extracted from MMIO dump of 6.30.223.141 */
2268static const u32 b43_ntab_noisevar_r7[] = {
2269 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2270 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2271 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2272 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2273 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2274 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2275 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2276 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2277 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2278 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2279 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2280 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2281 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2282 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2283 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2284 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2285 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2286 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2287 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2288 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2289 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2290 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2291 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2292 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2293 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2294 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2295 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2296 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2297 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2298 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2299 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2300 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2301 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2302 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2303 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2304 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2305 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2306 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2307 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2308 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2309 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2310 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2311 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2312 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2313 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2314 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2315 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2316 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2317 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2318 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2319 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2320 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2321 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2322 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2323 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2324 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2325 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2326 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2327 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2328 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2329 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2330 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2331 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2332 0x020c020c, 0x0000014d, 0x020c020c, 0x0000014d,
2333};
2334
2335/**************************************************
2336 * TX gain tables
2337 **************************************************/
2338
2150static const u32 b43_ntab_tx_gain_rev0_1_2[] = { 2339static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
2151 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, 2340 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
2152 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, 2341 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
@@ -2182,7 +2371,9 @@ static const u32 b43_ntab_tx_gain_rev0_1_2[] = {
2182 0x03801442, 0x03801344, 0x03801342, 0x00002b00, 2371 0x03801442, 0x03801344, 0x03801342, 0x00002b00,
2183}; 2372};
2184 2373
2185static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 2374/* EPA 2 GHz */
2375
2376static const u32 b43_ntab_tx_gain_epa_rev3_2g[] = {
2186 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, 2377 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
2187 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, 2378 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
2188 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, 2379 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
@@ -2217,7 +2408,9 @@ static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
2217 0x1041003c, 0x1041003b, 0x10410039, 0x10410037, 2408 0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
2218}; 2409};
2219 2410
2220static const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 2411/* EPA 5 GHz */
2412
2413static const u32 b43_ntab_tx_gain_epa_rev3_5g[] = {
2221 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, 2414 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
2222 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, 2415 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
2223 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, 2416 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
@@ -2252,7 +2445,7 @@ static const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
2252 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037, 2445 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
2253}; 2446};
2254 2447
2255static const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 2448static const u32 b43_ntab_tx_gain_epa_rev4_5g[] = {
2256 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, 2449 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
2257 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, 2450 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
2258 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, 2451 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
@@ -2287,7 +2480,7 @@ static const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
2287 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034, 2480 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
2288}; 2481};
2289 2482
2290static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 2483static const u32 b43_ntab_tx_gain_epa_rev5_5g[] = {
2291 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, 2484 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
2292 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, 2485 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
2293 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, 2486 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
@@ -2322,7 +2515,9 @@ static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
2322 0x0062003b, 0x00620039, 0x00620037, 0x00620035, 2515 0x0062003b, 0x00620039, 0x00620037, 0x00620035,
2323}; 2516};
2324 2517
2325static const u32 txpwrctrl_tx_gain_ipa[] = { 2518/* IPA 2 GHz */
2519
2520static const u32 b43_ntab_tx_gain_ipa_rev3_2g[] = {
2326 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, 2521 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
2327 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, 2522 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
2328 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, 2523 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
@@ -2357,7 +2552,7 @@ static const u32 txpwrctrl_tx_gain_ipa[] = {
2357 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025, 2552 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
2358}; 2553};
2359 2554
2360static const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 2555static const u32 b43_ntab_tx_gain_ipa_rev5_2g[] = {
2361 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, 2556 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
2362 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, 2557 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
2363 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, 2558 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
@@ -2392,7 +2587,7 @@ static const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
2392 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025, 2587 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
2393}; 2588};
2394 2589
2395static const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 2590static const u32 b43_ntab_tx_gain_ipa_rev6_2g[] = {
2396 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, 2591 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
2397 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, 2592 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
2398 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, 2593 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
@@ -2427,7 +2622,45 @@ static const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
2427 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025, 2622 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
2428}; 2623};
2429 2624
2430static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 2625/* Extracted from MMIO dump of 6.30.223.141 */
2626static const u32 b43_ntab_tx_gain_ipa_2057_rev9_2g[] = {
2627 0x60ff0031, 0x60e7002c, 0x60cf002a, 0x60c70029,
2628 0x60b70029, 0x60a70029, 0x609f002a, 0x6097002b,
2629 0x6087002e, 0x60770031, 0x606f0032, 0x60670034,
2630 0x60670031, 0x605f0033, 0x605f0031, 0x60570033,
2631 0x60570030, 0x6057002d, 0x6057002b, 0x604f002d,
2632 0x604f002b, 0x604f0029, 0x604f0026, 0x60470029,
2633 0x60470027, 0x603f0029, 0x603f0027, 0x603f0025,
2634 0x60370029, 0x60370027, 0x60370024, 0x602f002a,
2635 0x602f0028, 0x602f0026, 0x602f0024, 0x6027002a,
2636 0x60270028, 0x60270026, 0x60270024, 0x60270022,
2637 0x601f002b, 0x601f0029, 0x601f0027, 0x601f0024,
2638 0x601f0022, 0x601f0020, 0x601f001f, 0x601f001d,
2639 0x60170029, 0x60170027, 0x60170025, 0x60170023,
2640 0x60170021, 0x6017001f, 0x6017001d, 0x6017001c,
2641 0x6017001a, 0x60170018, 0x60170018, 0x60170016,
2642 0x60170015, 0x600f0029, 0x600f0027, 0x600f0025,
2643 0x600f0023, 0x600f0021, 0x600f001f, 0x600f001d,
2644 0x600f001c, 0x600f001a, 0x600f0019, 0x600f0018,
2645 0x600f0016, 0x600f0015, 0x600f0115, 0x600f0215,
2646 0x600f0315, 0x600f0415, 0x600f0515, 0x600f0615,
2647 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2648 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2649 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2650 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2651 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2652 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2653 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2654 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2655 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2656 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2657 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2658 0x600f0715, 0x600f0715, 0x600f0715, 0x600f0715,
2659};
2660
2661/* IPA 2 5Hz */
2662
2663static const u32 b43_ntab_tx_gain_ipa_rev3_5g[] = {
2431 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, 2664 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
2432 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, 2665 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
2433 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, 2666 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
@@ -2462,6 +2695,42 @@ static const u32 txpwrctrl_tx_gain_ipa_5g[] = {
2462 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f, 2695 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
2463}; 2696};
2464 2697
2698/* Extracted from MMIO dump of 6.30.223.141 */
2699static const u32 b43_ntab_tx_gain_ipa_2057_rev9_5g[] = {
2700 0x7f7f0053, 0x7f7f004b, 0x7f7f0044, 0x7f7f003f,
2701 0x7f7f0039, 0x7f7f0035, 0x7f7f0032, 0x7f7f0030,
2702 0x7f7f002d, 0x7e7f0030, 0x7e7f002d, 0x7d7f0032,
2703 0x7d7f002f, 0x7d7f002c, 0x7c7f0032, 0x7c7f0030,
2704 0x7c7f002d, 0x7b7f0030, 0x7b7f002e, 0x7b7f002b,
2705 0x7a7f0032, 0x7a7f0030, 0x7a7f002d, 0x7a7f002b,
2706 0x797f0030, 0x797f002e, 0x797f002b, 0x797f0029,
2707 0x787f0030, 0x787f002d, 0x787f002b, 0x777f0032,
2708 0x777f0030, 0x777f002d, 0x777f002b, 0x767f0031,
2709 0x767f002f, 0x767f002c, 0x767f002a, 0x757f0031,
2710 0x757f002f, 0x757f002c, 0x757f002a, 0x747f0030,
2711 0x747f002d, 0x747f002b, 0x737f0032, 0x737f002f,
2712 0x737f002c, 0x737f002a, 0x727f0030, 0x727f002d,
2713 0x727f002b, 0x727f0029, 0x717f0030, 0x717f002d,
2714 0x717f002b, 0x707f0031, 0x707f002f, 0x707f002c,
2715 0x707f002a, 0x707f0027, 0x707f0025, 0x707f0023,
2716 0x707f0021, 0x707f001f, 0x707f001d, 0x707f001c,
2717 0x707f001a, 0x707f0019, 0x707f0017, 0x707f0016,
2718 0x707f0015, 0x707f0014, 0x707f0012, 0x707f0012,
2719 0x707f0011, 0x707f0010, 0x707f000f, 0x707f000e,
2720 0x707f000d, 0x707f000d, 0x707f000c, 0x707f000b,
2721 0x707f000a, 0x707f000a, 0x707f0009, 0x707f0008,
2722 0x707f0008, 0x707f0008, 0x707f0008, 0x707f0007,
2723 0x707f0007, 0x707f0006, 0x707f0006, 0x707f0006,
2724 0x707f0005, 0x707f0005, 0x707f0005, 0x707f0004,
2725 0x707f0004, 0x707f0004, 0x707f0003, 0x707f0003,
2726 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
2727 0x707f0003, 0x707f0003, 0x707f0003, 0x707f0003,
2728 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
2729 0x707f0002, 0x707f0002, 0x707f0002, 0x707f0002,
2730 0x707f0002, 0x707f0001, 0x707f0001, 0x707f0001,
2731 0x707f0001, 0x707f0001, 0x707f0001, 0x707f0001,
2732};
2733
2465const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = { 2734const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = {
2466 -114, -108, -98, -91, -84, -78, -70, -62, 2735 -114, -108, -98, -91, -84, -78, -70, -62,
2467 -54, -46, -39, -31, -23, -15, -8, 0 2736 -54, -46, -39, -31, -23, -15, -8, 0
@@ -3031,6 +3300,91 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset,
3031 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \ 3300 b43_ntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
3032 } while (0) 3301 } while (0)
3033 3302
3303static void b43_nphy_tables_init_shared_lut(struct b43_wldev *dev)
3304{
3305 ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3);
3306 ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
3307 ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
3308 ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
3309 ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
3310 ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
3311 ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
3312 ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
3313 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
3314 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
3315}
3316
3317static void b43_nphy_tables_init_rev7_volatile(struct b43_wldev *dev)
3318{
3319 struct ssb_sprom *sprom = dev->dev->bus_sprom;
3320 u8 antswlut;
3321 int core, offset, i;
3322
3323 const int antswlut0_offsets[] = { 0, 4, 8, }; /* Offsets for values */
3324 const u8 antswlut0_values[][3] = {
3325 { 0x2, 0x12, 0x8 }, /* Core 0 */
3326 { 0x2, 0x18, 0x2 }, /* Core 1 */
3327 };
3328
3329 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
3330 antswlut = sprom->fem.ghz5.antswlut;
3331 else
3332 antswlut = sprom->fem.ghz2.antswlut;
3333
3334 switch (antswlut) {
3335 case 0:
3336 for (core = 0; core < 2; core++) {
3337 for (i = 0; i < ARRAY_SIZE(antswlut0_values[0]); i++) {
3338 offset = core ? 0x20 : 0x00;
3339 offset += antswlut0_offsets[i];
3340 b43_ntab_write(dev, B43_NTAB8(9, offset),
3341 antswlut0_values[core][i]);
3342 }
3343 }
3344 break;
3345 default:
3346 b43err(dev->wl, "Unsupported antswlut: %d\n", antswlut);
3347 break;
3348 }
3349}
3350
3351static void b43_nphy_tables_init_rev16(struct b43_wldev *dev)
3352{
3353 /* Static tables */
3354 if (dev->phy.do_full_init) {
3355 ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
3356 b43_nphy_tables_init_shared_lut(dev);
3357 }
3358
3359 /* Volatile tables */
3360 b43_nphy_tables_init_rev7_volatile(dev);
3361}
3362
3363static void b43_nphy_tables_init_rev7(struct b43_wldev *dev)
3364{
3365 /* Static tables */
3366 if (dev->phy.do_full_init) {
3367 ntab_upload(dev, B43_NTAB_FRAMESTRUCT_R3, b43_ntab_framestruct_r3);
3368 ntab_upload(dev, B43_NTAB_PILOT_R3, b43_ntab_pilot_r3);
3369 ntab_upload(dev, B43_NTAB_TMAP_R7, b43_ntab_tmap_r7);
3370 ntab_upload(dev, B43_NTAB_INTLEVEL_R3, b43_ntab_intlevel_r3);
3371 ntab_upload(dev, B43_NTAB_TDTRN_R3, b43_ntab_tdtrn_r3);
3372 ntab_upload(dev, B43_NTAB_NOISEVAR_R7, b43_ntab_noisevar_r7);
3373 ntab_upload(dev, B43_NTAB_MCS_R3, b43_ntab_mcs_r3);
3374 ntab_upload(dev, B43_NTAB_TDI20A0_R3, b43_ntab_tdi20a0_r3);
3375 ntab_upload(dev, B43_NTAB_TDI20A1_R3, b43_ntab_tdi20a1_r3);
3376 ntab_upload(dev, B43_NTAB_TDI40A0_R3, b43_ntab_tdi40a0_r3);
3377 ntab_upload(dev, B43_NTAB_TDI40A1_R3, b43_ntab_tdi40a1_r3);
3378 ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3379 ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3380 ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3381 b43_nphy_tables_init_shared_lut(dev);
3382 }
3383
3384 /* Volatile tables */
3385 b43_nphy_tables_init_rev7_volatile(dev);
3386}
3387
3034static void b43_nphy_tables_init_rev3(struct b43_wldev *dev) 3388static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
3035{ 3389{
3036 struct ssb_sprom *sprom = dev->dev->bus_sprom; 3390 struct ssb_sprom *sprom = dev->dev->bus_sprom;
@@ -3057,16 +3411,7 @@ static void b43_nphy_tables_init_rev3(struct b43_wldev *dev)
3057 ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3); 3411 ntab_upload(dev, B43_NTAB_PILOTLT_R3, b43_ntab_pilotlt_r3);
3058 ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3); 3412 ntab_upload(dev, B43_NTAB_CHANEST_R3, b43_ntab_channelest_r3);
3059 ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3); 3413 ntab_upload(dev, B43_NTAB_FRAMELT_R3, b43_ntab_framelookup_r3);
3060 ntab_upload(dev, B43_NTAB_C0_ESTPLT_R3, b43_ntab_estimatepowerlt0_r3); 3414 b43_nphy_tables_init_shared_lut(dev);
3061 ntab_upload(dev, B43_NTAB_C1_ESTPLT_R3, b43_ntab_estimatepowerlt1_r3);
3062 ntab_upload(dev, B43_NTAB_C0_ADJPLT_R3, b43_ntab_adjustpower0_r3);
3063 ntab_upload(dev, B43_NTAB_C1_ADJPLT_R3, b43_ntab_adjustpower1_r3);
3064 ntab_upload(dev, B43_NTAB_C0_GAINCTL_R3, b43_ntab_gainctl0_r3);
3065 ntab_upload(dev, B43_NTAB_C1_GAINCTL_R3, b43_ntab_gainctl1_r3);
3066 ntab_upload(dev, B43_NTAB_C0_IQLT_R3, b43_ntab_iqlt0_r3);
3067 ntab_upload(dev, B43_NTAB_C1_IQLT_R3, b43_ntab_iqlt1_r3);
3068 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH_R3, b43_ntab_loftlt0_r3);
3069 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH_R3, b43_ntab_loftlt1_r3);
3070 } 3415 }
3071 3416
3072 /* Volatile tables */ 3417 /* Volatile tables */
@@ -3115,7 +3460,11 @@ static void b43_nphy_tables_init_rev0(struct b43_wldev *dev)
3115/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */ 3460/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables */
3116void b43_nphy_tables_init(struct b43_wldev *dev) 3461void b43_nphy_tables_init(struct b43_wldev *dev)
3117{ 3462{
3118 if (dev->phy.rev >= 3) 3463 if (dev->phy.rev >= 16)
3464 b43_nphy_tables_init_rev16(dev);
3465 else if (dev->phy.rev >= 7)
3466 b43_nphy_tables_init_rev7(dev);
3467 else if (dev->phy.rev >= 3)
3119 b43_nphy_tables_init_rev3(dev); 3468 b43_nphy_tables_init_rev3(dev);
3120 else 3469 else
3121 b43_nphy_tables_init_rev0(dev); 3470 b43_nphy_tables_init_rev0(dev);
@@ -3124,23 +3473,45 @@ void b43_nphy_tables_init(struct b43_wldev *dev)
3124/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ 3473/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
3125static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) 3474static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
3126{ 3475{
3476 struct b43_phy *phy = &dev->phy;
3477
3127 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 3478 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
3128 if (dev->phy.rev >= 6) { 3479 switch (phy->rev) {
3129 if (dev->dev->chip_id == 47162) 3480 case 16:
3130 return txpwrctrl_tx_gain_ipa_rev5; 3481 if (phy->radio_rev == 9)
3131 return txpwrctrl_tx_gain_ipa_rev6; 3482 return b43_ntab_tx_gain_ipa_2057_rev9_2g;
3132 } else if (dev->phy.rev >= 5) { 3483 case 6:
3133 return txpwrctrl_tx_gain_ipa_rev5; 3484 if (dev->dev->chip_id == BCMA_CHIP_ID_BCM47162)
3134 } else { 3485 return b43_ntab_tx_gain_ipa_rev5_2g;
3135 return txpwrctrl_tx_gain_ipa; 3486 return b43_ntab_tx_gain_ipa_rev6_2g;
3487 case 5:
3488 return b43_ntab_tx_gain_ipa_rev5_2g;
3489 case 4:
3490 case 3:
3491 return b43_ntab_tx_gain_ipa_rev3_2g;
3492 default:
3493 b43err(dev->wl,
3494 "No 2GHz IPA gain table available for this device\n");
3495 return NULL;
3136 } 3496 }
3137 } else { 3497 } else {
3138 return txpwrctrl_tx_gain_ipa_5g; 3498 switch (phy->rev) {
3499 case 16:
3500 if (phy->radio_rev == 9)
3501 return b43_ntab_tx_gain_ipa_2057_rev9_5g;
3502 case 3 ... 6:
3503 return b43_ntab_tx_gain_ipa_rev3_5g;
3504 default:
3505 b43err(dev->wl,
3506 "No 5GHz IPA gain table available for this device\n");
3507 return NULL;
3508 }
3139 } 3509 }
3140} 3510}
3141 3511
3142const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev) 3512const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
3143{ 3513{
3514 struct b43_phy *phy = &dev->phy;
3144 enum ieee80211_band band = b43_current_band(dev->wl); 3515 enum ieee80211_band band = b43_current_band(dev->wl);
3145 struct ssb_sprom *sprom = dev->dev->bus_sprom; 3516 struct ssb_sprom *sprom = dev->dev->bus_sprom;
3146 3517
@@ -3152,19 +3523,36 @@ const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev)
3152 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { 3523 (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) {
3153 return b43_nphy_get_ipa_gain_table(dev); 3524 return b43_nphy_get_ipa_gain_table(dev);
3154 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { 3525 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
3155 if (dev->phy.rev == 3) 3526 switch (phy->rev) {
3156 return b43_ntab_tx_gain_rev3_5ghz; 3527 case 6:
3157 if (dev->phy.rev == 4) 3528 case 5:
3529 return b43_ntab_tx_gain_epa_rev5_5g;
3530 case 4:
3158 return sprom->fem.ghz5.extpa_gain == 3 ? 3531 return sprom->fem.ghz5.extpa_gain == 3 ?
3159 b43_ntab_tx_gain_rev4_5ghz : 3532 b43_ntab_tx_gain_epa_rev4_5g :
3160 b43_ntab_tx_gain_rev4_5ghz; /* FIXME */ 3533 b43_ntab_tx_gain_epa_rev4_5g; /* FIXME */
3161 else 3534 case 3:
3162 return b43_ntab_tx_gain_rev5plus_5ghz; 3535 return b43_ntab_tx_gain_epa_rev3_5g;
3536 default:
3537 b43err(dev->wl,
3538 "No 5GHz EPA gain table available for this device\n");
3539 return NULL;
3540 }
3163 } else { 3541 } else {
3164 if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3) 3542 switch (phy->rev) {
3165 return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */ 3543 case 6:
3166 else 3544 case 5:
3167 return b43_ntab_tx_gain_rev3plus_2ghz; 3545 if (sprom->fem.ghz5.extpa_gain == 3)
3546 return b43_ntab_tx_gain_epa_rev3_2g; /* FIXME */
3547 /* fall through */
3548 case 4:
3549 case 3:
3550 return b43_ntab_tx_gain_epa_rev3_2g;
3551 default:
3552 b43err(dev->wl,
3553 "No 2GHz EPA gain table available for this device\n");
3554 return NULL;
3555 }
3168 } 3556 }
3169} 3557}
3170 3558
@@ -3191,7 +3579,7 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
3191 /* Some workarounds to the workarounds... */ 3579 /* Some workarounds to the workarounds... */
3192 if (ghz5 && dev->phy.rev >= 6) { 3580 if (ghz5 && dev->phy.rev >= 6) {
3193 if (dev->phy.radio_rev == 11 && 3581 if (dev->phy.radio_rev == 11 &&
3194 !b43_channel_type_is_40mhz(dev->phy.channel_type)) 3582 !b43_is_40mhz(dev))
3195 e->cliplo_gain = 0x2d; 3583 e->cliplo_gain = 0x2d;
3196 } else if (!ghz5 && dev->phy.rev >= 5) { 3584 } else if (!ghz5 && dev->phy.rev >= 5) {
3197 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a, 3585 static const int gain_data[] = {0x0062, 0x0064, 0x006a, 0x106a,
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 3a58aee4c4cf..3ce2e6f3a278 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -165,6 +165,10 @@ struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent(
165#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */ 165#define B43_NTAB_C1_LOFEEDTH_R3 B43_NTAB16(27, 448) /* Local Oscillator Feed Through lookup 1 */
166#define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576) 166#define B43_NTAB_C1_PAPD_COMP_R3 B43_NTAB16(27, 576)
167 167
168/* Static N-PHY tables, PHY revision >= 7 */
169#define B43_NTAB_TMAP_R7 B43_NTAB32(12, 0) /* TM AP */
170#define B43_NTAB_NOISEVAR_R7 B43_NTAB32(16, 0) /* noise variance */
171
168#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18 172#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
169#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18 173#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
170#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18 174#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 98e67c18f276..4cffb2ee3673 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -34,7 +34,8 @@ brcmfmac-objs += \
34 dhd_common.o \ 34 dhd_common.o \
35 dhd_linux.o \ 35 dhd_linux.o \
36 firmware.o \ 36 firmware.o \
37 btcoex.o 37 btcoex.o \
38 vendor.o
38brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ 39brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
39 dhd_sdio.o \ 40 dhd_sdio.o \
40 bcmsdh.o 41 bcmsdh.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
index 0cb591b050b3..a29ac4977b3a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
@@ -157,7 +157,7 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
157 */ 157 */
158 158
159 /* save current */ 159 /* save current */
160 brcmf_dbg(TRACE, "new SCO/eSCO coex algo {save & override}\n"); 160 brcmf_dbg(INFO, "new SCO/eSCO coex algo {save & override}\n");
161 brcmf_btcoex_params_read(ifp, 50, &btci->reg50); 161 brcmf_btcoex_params_read(ifp, 50, &btci->reg50);
162 brcmf_btcoex_params_read(ifp, 51, &btci->reg51); 162 brcmf_btcoex_params_read(ifp, 51, &btci->reg51);
163 brcmf_btcoex_params_read(ifp, 64, &btci->reg64); 163 brcmf_btcoex_params_read(ifp, 64, &btci->reg64);
@@ -165,7 +165,7 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
165 brcmf_btcoex_params_read(ifp, 71, &btci->reg71); 165 brcmf_btcoex_params_read(ifp, 71, &btci->reg71);
166 166
167 btci->saved_regs_part2 = true; 167 btci->saved_regs_part2 = true;
168 brcmf_dbg(TRACE, 168 brcmf_dbg(INFO,
169 "saved bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", 169 "saved bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
170 btci->reg50, btci->reg51, btci->reg64, 170 btci->reg50, btci->reg51, btci->reg64,
171 btci->reg65, btci->reg71); 171 btci->reg65, btci->reg71);
@@ -179,21 +179,21 @@ static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
179 179
180 } else if (btci->saved_regs_part2) { 180 } else if (btci->saved_regs_part2) {
181 /* restore previously saved bt params */ 181 /* restore previously saved bt params */
182 brcmf_dbg(TRACE, "Do new SCO/eSCO coex algo {restore}\n"); 182 brcmf_dbg(INFO, "Do new SCO/eSCO coex algo {restore}\n");
183 brcmf_btcoex_params_write(ifp, 50, btci->reg50); 183 brcmf_btcoex_params_write(ifp, 50, btci->reg50);
184 brcmf_btcoex_params_write(ifp, 51, btci->reg51); 184 brcmf_btcoex_params_write(ifp, 51, btci->reg51);
185 brcmf_btcoex_params_write(ifp, 64, btci->reg64); 185 brcmf_btcoex_params_write(ifp, 64, btci->reg64);
186 brcmf_btcoex_params_write(ifp, 65, btci->reg65); 186 brcmf_btcoex_params_write(ifp, 65, btci->reg65);
187 brcmf_btcoex_params_write(ifp, 71, btci->reg71); 187 brcmf_btcoex_params_write(ifp, 71, btci->reg71);
188 188
189 brcmf_dbg(TRACE, 189 brcmf_dbg(INFO,
190 "restored bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n", 190 "restored bt_params[50,51,64,65,71]: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
191 btci->reg50, btci->reg51, btci->reg64, 191 btci->reg50, btci->reg51, btci->reg64,
192 btci->reg65, btci->reg71); 192 btci->reg65, btci->reg71);
193 193
194 btci->saved_regs_part2 = false; 194 btci->saved_regs_part2 = false;
195 } else { 195 } else {
196 brcmf_err("attempted to restore not saved BTCOEX params\n"); 196 brcmf_dbg(INFO, "attempted to restore not saved BTCOEX params\n");
197 } 197 }
198} 198}
199 199
@@ -219,14 +219,14 @@ static bool brcmf_btcoex_is_sco_active(struct brcmf_if *ifp)
219 break; 219 break;
220 } 220 }
221 221
222 brcmf_dbg(TRACE, "sample[%d], btc_params 27:%x\n", i, param27); 222 brcmf_dbg(INFO, "sample[%d], btc_params 27:%x\n", i, param27);
223 223
224 if ((param27 & 0x6) == 2) { /* count both sco & esco */ 224 if ((param27 & 0x6) == 2) { /* count both sco & esco */
225 sco_id_cnt++; 225 sco_id_cnt++;
226 } 226 }
227 227
228 if (sco_id_cnt > 2) { 228 if (sco_id_cnt > 2) {
229 brcmf_dbg(TRACE, 229 brcmf_dbg(INFO,
230 "sco/esco detected, pkt id_cnt:%d samples:%d\n", 230 "sco/esco detected, pkt id_cnt:%d samples:%d\n",
231 sco_id_cnt, i); 231 sco_id_cnt, i);
232 res = true; 232 res = true;
@@ -250,7 +250,7 @@ static void btcmf_btcoex_save_part1(struct brcmf_btcoex_info *btci)
250 brcmf_btcoex_params_read(ifp, 41, &btci->reg41); 250 brcmf_btcoex_params_read(ifp, 41, &btci->reg41);
251 brcmf_btcoex_params_read(ifp, 68, &btci->reg68); 251 brcmf_btcoex_params_read(ifp, 68, &btci->reg68);
252 btci->saved_regs_part1 = true; 252 btci->saved_regs_part1 = true;
253 brcmf_dbg(TRACE, 253 brcmf_dbg(INFO,
254 "saved btc_params regs (66,41,68) 0x%x 0x%x 0x%x\n", 254 "saved btc_params regs (66,41,68) 0x%x 0x%x 0x%x\n",
255 btci->reg66, btci->reg41, 255 btci->reg66, btci->reg41,
256 btci->reg68); 256 btci->reg68);
@@ -270,7 +270,7 @@ static void brcmf_btcoex_restore_part1(struct brcmf_btcoex_info *btci)
270 brcmf_btcoex_params_write(ifp, 66, btci->reg66); 270 brcmf_btcoex_params_write(ifp, 66, btci->reg66);
271 brcmf_btcoex_params_write(ifp, 41, btci->reg41); 271 brcmf_btcoex_params_write(ifp, 41, btci->reg41);
272 brcmf_btcoex_params_write(ifp, 68, btci->reg68); 272 brcmf_btcoex_params_write(ifp, 68, btci->reg68);
273 brcmf_dbg(TRACE, 273 brcmf_dbg(INFO,
274 "restored btc_params regs {66,41,68} 0x%x 0x%x 0x%x\n", 274 "restored btc_params regs {66,41,68} 0x%x 0x%x 0x%x\n",
275 btci->reg66, btci->reg41, 275 btci->reg66, btci->reg41,
276 btci->reg68); 276 btci->reg68);
@@ -307,7 +307,7 @@ static void brcmf_btcoex_handler(struct work_struct *work)
307 /* DHCP started provide OPPORTUNITY window 307 /* DHCP started provide OPPORTUNITY window
308 to get DHCP address 308 to get DHCP address
309 */ 309 */
310 brcmf_dbg(TRACE, "DHCP started\n"); 310 brcmf_dbg(INFO, "DHCP started\n");
311 btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN; 311 btci->bt_state = BRCMF_BT_DHCP_OPPR_WIN;
312 if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) { 312 if (btci->timeout < BRCMF_BTCOEX_OPPR_WIN_TIME) {
313 mod_timer(&btci->timer, btci->timer.expires); 313 mod_timer(&btci->timer, btci->timer.expires);
@@ -322,12 +322,12 @@ static void brcmf_btcoex_handler(struct work_struct *work)
322 322
323 case BRCMF_BT_DHCP_OPPR_WIN: 323 case BRCMF_BT_DHCP_OPPR_WIN:
324 if (btci->dhcp_done) { 324 if (btci->dhcp_done) {
325 brcmf_dbg(TRACE, "DHCP done before T1 expiration\n"); 325 brcmf_dbg(INFO, "DHCP done before T1 expiration\n");
326 goto idle; 326 goto idle;
327 } 327 }
328 328
329 /* DHCP is not over yet, start lowering BT priority */ 329 /* DHCP is not over yet, start lowering BT priority */
330 brcmf_dbg(TRACE, "DHCP T1:%d expired\n", 330 brcmf_dbg(INFO, "DHCP T1:%d expired\n",
331 BRCMF_BTCOEX_OPPR_WIN_TIME); 331 BRCMF_BTCOEX_OPPR_WIN_TIME);
332 brcmf_btcoex_boost_wifi(btci, true); 332 brcmf_btcoex_boost_wifi(btci, true);
333 333
@@ -339,9 +339,9 @@ static void brcmf_btcoex_handler(struct work_struct *work)
339 339
340 case BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT: 340 case BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT:
341 if (btci->dhcp_done) 341 if (btci->dhcp_done)
342 brcmf_dbg(TRACE, "DHCP done before T2 expiration\n"); 342 brcmf_dbg(INFO, "DHCP done before T2 expiration\n");
343 else 343 else
344 brcmf_dbg(TRACE, "DHCP T2:%d expired\n", 344 brcmf_dbg(INFO, "DHCP T2:%d expired\n",
345 BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT); 345 BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT);
346 346
347 goto idle; 347 goto idle;
@@ -440,13 +440,13 @@ static void brcmf_btcoex_dhcp_end(struct brcmf_btcoex_info *btci)
440 /* Stop any bt timer because DHCP session is done */ 440 /* Stop any bt timer because DHCP session is done */
441 btci->dhcp_done = true; 441 btci->dhcp_done = true;
442 if (btci->timer_on) { 442 if (btci->timer_on) {
443 brcmf_dbg(TRACE, "disable BT DHCP Timer\n"); 443 brcmf_dbg(INFO, "disable BT DHCP Timer\n");
444 btci->timer_on = false; 444 btci->timer_on = false;
445 del_timer_sync(&btci->timer); 445 del_timer_sync(&btci->timer);
446 446
447 /* schedule worker if transition to IDLE is needed */ 447 /* schedule worker if transition to IDLE is needed */
448 if (btci->bt_state != BRCMF_BT_DHCP_IDLE) { 448 if (btci->bt_state != BRCMF_BT_DHCP_IDLE) {
449 brcmf_dbg(TRACE, "bt_state:%d\n", 449 brcmf_dbg(INFO, "bt_state:%d\n",
450 btci->bt_state); 450 btci->bt_state);
451 schedule_work(&btci->work); 451 schedule_work(&btci->work);
452 } 452 }
@@ -472,7 +472,7 @@ int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
472 472
473 switch (mode) { 473 switch (mode) {
474 case BRCMF_BTCOEX_DISABLED: 474 case BRCMF_BTCOEX_DISABLED:
475 brcmf_dbg(TRACE, "DHCP session starts\n"); 475 brcmf_dbg(INFO, "DHCP session starts\n");
476 if (btci->bt_state != BRCMF_BT_DHCP_IDLE) 476 if (btci->bt_state != BRCMF_BT_DHCP_IDLE)
477 return -EBUSY; 477 return -EBUSY;
478 /* Start BT timer only for SCO connection */ 478 /* Start BT timer only for SCO connection */
@@ -484,14 +484,14 @@ int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
484 break; 484 break;
485 485
486 case BRCMF_BTCOEX_ENABLED: 486 case BRCMF_BTCOEX_ENABLED:
487 brcmf_dbg(TRACE, "DHCP session ends\n"); 487 brcmf_dbg(INFO, "DHCP session ends\n");
488 if (btci->bt_state != BRCMF_BT_DHCP_IDLE && 488 if (btci->bt_state != BRCMF_BT_DHCP_IDLE &&
489 vif == btci->vif) { 489 vif == btci->vif) {
490 brcmf_btcoex_dhcp_end(btci); 490 brcmf_btcoex_dhcp_end(btci);
491 } 491 }
492 break; 492 break;
493 default: 493 default:
494 brcmf_dbg(TRACE, "Unknown mode, ignored\n"); 494 brcmf_dbg(INFO, "Unknown mode, ignored\n");
495 } 495 }
496 return 0; 496 return 0;
497} 497}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 16f9ab2568a8..a8998eb60d22 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -49,16 +49,6 @@
49 */ 49 */
50#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 50#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
51 51
52/* Bus independent dongle command */
53struct brcmf_dcmd {
54 uint cmd; /* common dongle cmd definition */
55 void *buf; /* pointer to user buffer */
56 uint len; /* length of user buffer */
57 u8 set; /* get or set request (optional) */
58 uint used; /* bytes read or written (optional) */
59 uint needed; /* bytes needed (optional) */
60};
61
62/** 52/**
63 * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info 53 * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info
64 * 54 *
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index ed3e32ce8c23..d991f8e3d9ec 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -282,6 +282,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
282 ptr = strrchr(buf, ' ') + 1; 282 ptr = strrchr(buf, ' ') + 1;
283 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); 283 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
284 284
285 /* set mpc */
286 err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
287 if (err) {
288 brcmf_err("failed setting mpc\n");
289 goto done;
290 }
291
285 /* 292 /*
286 * Setup timeout if Beacons are lost and roam is off to report 293 * Setup timeout if Beacons are lost and roam is off to report
287 * link down 294 * link down
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 59a5af5bf994..ded328f80cd1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -54,7 +54,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
54 if (err >= 0) 54 if (err >= 0)
55 err = 0; 55 err = 0;
56 else 56 else
57 brcmf_err("Failed err=%d\n", err); 57 brcmf_dbg(FIL, "Failed err=%d\n", err);
58 58
59 return err; 59 return err;
60} 60}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index f3445ac627e4..588fdbdb3255 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -708,7 +708,7 @@ static s32 brcmf_p2p_escan(struct brcmf_p2p_info *p2p, u32 num_chans,
708 active = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS; 708 active = P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS;
709 else if (num_chans == AF_PEER_SEARCH_CNT) 709 else if (num_chans == AF_PEER_SEARCH_CNT)
710 active = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS; 710 active = P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS;
711 else if (wl_get_vif_state_all(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED)) 711 else if (brcmf_get_vif_state_any(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED))
712 active = -1; 712 active = -1;
713 else 713 else
714 active = P2PAPI_SCAN_DWELL_TIME_MS; 714 active = P2PAPI_SCAN_DWELL_TIME_MS;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 6db51a666f61..839bcda9465a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -29,32 +29,24 @@
29#include "usb_rdl.h" 29#include "usb_rdl.h"
30#include "usb.h" 30#include "usb.h"
31 31
32#define IOCTL_RESP_TIMEOUT 2000 32#define IOCTL_RESP_TIMEOUT 2000
33 33
34#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ 34#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */
35#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 35#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10
36 36
37#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle 37#define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle
38 has boot up */ 38 has boot up */
39#define BRCMF_USB_NRXQ 50 39#define BRCMF_USB_NRXQ 50
40#define BRCMF_USB_NTXQ 50 40#define BRCMF_USB_NTXQ 50
41 41
42#define CONFIGDESC(usb) (&((usb)->actconfig)->desc) 42#define BRCMF_USB_CBCTL_WRITE 0
43#define IFPTR(usb, idx) ((usb)->actconfig->interface[(idx)]) 43#define BRCMF_USB_CBCTL_READ 1
44#define IFALTS(usb, idx) (IFPTR((usb), (idx))->altsetting[0]) 44#define BRCMF_USB_MAX_PKT_SIZE 1600
45#define IFDESC(usb, idx) IFALTS((usb), (idx)).desc
46#define IFEPDESC(usb, idx, ep) (IFALTS((usb), (idx)).endpoint[(ep)]).desc
47 45
48#define CONTROL_IF 0 46#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
49#define BULK_IF 0 47#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
50 48#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
51#define BRCMF_USB_CBCTL_WRITE 0 49#define BRCMF_USB_43569_FW_NAME "brcm/brcmfmac43569.bin"
52#define BRCMF_USB_CBCTL_READ 1
53#define BRCMF_USB_MAX_PKT_SIZE 1600
54
55#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
56#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
57#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
58 50
59struct brcmf_usb_image { 51struct brcmf_usb_image {
60 struct list_head list; 52 struct list_head list;
@@ -70,7 +62,7 @@ struct brcmf_usbdev_info {
70 struct list_head rx_postq; 62 struct list_head rx_postq;
71 struct list_head tx_freeq; 63 struct list_head tx_freeq;
72 struct list_head tx_postq; 64 struct list_head tx_postq;
73 uint rx_pipe, tx_pipe, rx_pipe2; 65 uint rx_pipe, tx_pipe;
74 66
75 int rx_low_watermark; 67 int rx_low_watermark;
76 int tx_low_watermark; 68 int tx_low_watermark;
@@ -97,6 +89,7 @@ struct brcmf_usbdev_info {
97 int ctl_completed; 89 int ctl_completed;
98 wait_queue_head_t ioctl_resp_wait; 90 wait_queue_head_t ioctl_resp_wait;
99 ulong ctl_op; 91 ulong ctl_op;
92 u8 ifnum;
100 93
101 struct urb *bulk_urb; /* used for FW download */ 94 struct urb *bulk_urb; /* used for FW download */
102}; 95};
@@ -576,7 +569,6 @@ fail:
576static int brcmf_usb_up(struct device *dev) 569static int brcmf_usb_up(struct device *dev)
577{ 570{
578 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 571 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
579 u16 ifnum;
580 572
581 brcmf_dbg(USB, "Enter\n"); 573 brcmf_dbg(USB, "Enter\n");
582 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) 574 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
@@ -589,21 +581,19 @@ static int brcmf_usb_up(struct device *dev)
589 devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0); 581 devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
590 devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0); 582 devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);
591 583
592 ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;
593
594 /* CTL Write */ 584 /* CTL Write */
595 devinfo->ctl_write.bRequestType = 585 devinfo->ctl_write.bRequestType =
596 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 586 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
597 devinfo->ctl_write.bRequest = 0; 587 devinfo->ctl_write.bRequest = 0;
598 devinfo->ctl_write.wValue = cpu_to_le16(0); 588 devinfo->ctl_write.wValue = cpu_to_le16(0);
599 devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum); 589 devinfo->ctl_write.wIndex = cpu_to_le16(devinfo->ifnum);
600 590
601 /* CTL Read */ 591 /* CTL Read */
602 devinfo->ctl_read.bRequestType = 592 devinfo->ctl_read.bRequestType =
603 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; 593 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
604 devinfo->ctl_read.bRequest = 1; 594 devinfo->ctl_read.bRequest = 1;
605 devinfo->ctl_read.wValue = cpu_to_le16(0); 595 devinfo->ctl_read.wValue = cpu_to_le16(0);
606 devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum); 596 devinfo->ctl_read.wIndex = cpu_to_le16(devinfo->ifnum);
607 } 597 }
608 brcmf_usb_rx_fill_all(devinfo); 598 brcmf_usb_rx_fill_all(devinfo);
609 return 0; 599 return 0;
@@ -642,19 +632,19 @@ brcmf_usb_sync_complete(struct urb *urb)
642 brcmf_usb_ioctl_resp_wake(devinfo); 632 brcmf_usb_ioctl_resp_wake(devinfo);
643} 633}
644 634
645static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd, 635static int brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
646 void *buffer, int buflen) 636 void *buffer, int buflen)
647{ 637{
648 int ret = 0; 638 int ret;
649 char *tmpbuf; 639 char *tmpbuf;
650 u16 size; 640 u16 size;
651 641
652 if ((!devinfo) || (devinfo->ctl_urb == NULL)) 642 if ((!devinfo) || (devinfo->ctl_urb == NULL))
653 return false; 643 return -EINVAL;
654 644
655 tmpbuf = kmalloc(buflen, GFP_ATOMIC); 645 tmpbuf = kmalloc(buflen, GFP_ATOMIC);
656 if (!tmpbuf) 646 if (!tmpbuf)
657 return false; 647 return -ENOMEM;
658 648
659 size = buflen; 649 size = buflen;
660 devinfo->ctl_urb->transfer_buffer_length = size; 650 devinfo->ctl_urb->transfer_buffer_length = size;
@@ -675,14 +665,16 @@ static bool brcmf_usb_dl_cmd(struct brcmf_usbdev_info *devinfo, u8 cmd,
675 ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC); 665 ret = usb_submit_urb(devinfo->ctl_urb, GFP_ATOMIC);
676 if (ret < 0) { 666 if (ret < 0) {
677 brcmf_err("usb_submit_urb failed %d\n", ret); 667 brcmf_err("usb_submit_urb failed %d\n", ret);
678 kfree(tmpbuf); 668 goto finalize;
679 return false;
680 } 669 }
681 670
682 ret = brcmf_usb_ioctl_resp_wait(devinfo); 671 if (!brcmf_usb_ioctl_resp_wait(devinfo))
683 memcpy(buffer, tmpbuf, buflen); 672 ret = -ETIMEDOUT;
684 kfree(tmpbuf); 673 else
674 memcpy(buffer, tmpbuf, buflen);
685 675
676finalize:
677 kfree(tmpbuf);
686 return ret; 678 return ret;
687} 679}
688 680
@@ -724,6 +716,7 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
724{ 716{
725 struct bootrom_id_le id; 717 struct bootrom_id_le id;
726 u32 loop_cnt; 718 u32 loop_cnt;
719 int err;
727 720
728 brcmf_dbg(USB, "Enter\n"); 721 brcmf_dbg(USB, "Enter\n");
729 722
@@ -732,7 +725,9 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
732 mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); 725 mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT);
733 loop_cnt++; 726 loop_cnt++;
734 id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ 727 id.chip = cpu_to_le32(0xDEAD); /* Get the ID */
735 brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); 728 err = brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id));
729 if ((err) && (err != -ETIMEDOUT))
730 return err;
736 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) 731 if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID))
737 break; 732 break;
738 } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); 733 } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT);
@@ -794,8 +789,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
794 } 789 }
795 790
796 /* 1) Prepare USB boot loader for runtime image */ 791 /* 1) Prepare USB boot loader for runtime image */
797 brcmf_usb_dl_cmd(devinfo, DL_START, &state, 792 brcmf_usb_dl_cmd(devinfo, DL_START, &state, sizeof(state));
798 sizeof(struct rdl_state_le));
799 793
800 rdlstate = le32_to_cpu(state.state); 794 rdlstate = le32_to_cpu(state.state);
801 rdlbytes = le32_to_cpu(state.bytes); 795 rdlbytes = le32_to_cpu(state.bytes);
@@ -839,10 +833,10 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
839 dlpos += sendlen; 833 dlpos += sendlen;
840 sent += sendlen; 834 sent += sendlen;
841 } 835 }
842 if (!brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, 836 err = brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state,
843 sizeof(struct rdl_state_le))) { 837 sizeof(state));
844 brcmf_err("DL_GETSTATE Failed xxxx\n"); 838 if (err) {
845 err = -EINVAL; 839 brcmf_err("DL_GETSTATE Failed\n");
846 goto fail; 840 goto fail;
847 } 841 }
848 842
@@ -898,13 +892,12 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
898 return -EINVAL; 892 return -EINVAL;
899 893
900 /* Check we are runnable */ 894 /* Check we are runnable */
901 brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, 895 state.state = 0;
902 sizeof(struct rdl_state_le)); 896 brcmf_usb_dl_cmd(devinfo, DL_GETSTATE, &state, sizeof(state));
903 897
904 /* Start the image */ 898 /* Start the image */
905 if (state.state == cpu_to_le32(DL_RUNNABLE)) { 899 if (state.state == cpu_to_le32(DL_RUNNABLE)) {
906 if (!brcmf_usb_dl_cmd(devinfo, DL_GO, &state, 900 if (brcmf_usb_dl_cmd(devinfo, DL_GO, &state, sizeof(state)))
907 sizeof(struct rdl_state_le)))
908 return -ENODEV; 901 return -ENODEV;
909 if (brcmf_usb_resetcfg(devinfo)) 902 if (brcmf_usb_resetcfg(devinfo))
910 return -ENODEV; 903 return -ENODEV;
@@ -928,6 +921,9 @@ static bool brcmf_usb_chip_support(int chipid, int chiprev)
928 return (chiprev == 3); 921 return (chiprev == 3);
929 case 43242: 922 case 43242:
930 return true; 923 return true;
924 case 43566:
925 case 43569:
926 return true;
931 default: 927 default:
932 break; 928 break;
933 } 929 }
@@ -1028,6 +1024,9 @@ static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
1028 return BRCMF_USB_43236_FW_NAME; 1024 return BRCMF_USB_43236_FW_NAME;
1029 case 43242: 1025 case 43242:
1030 return BRCMF_USB_43242_FW_NAME; 1026 return BRCMF_USB_43242_FW_NAME;
1027 case 43566:
1028 case 43569:
1029 return BRCMF_USB_43569_FW_NAME;
1031 default: 1030 default:
1032 return NULL; 1031 return NULL;
1033 } 1032 }
@@ -1221,15 +1220,15 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
1221static int 1220static int
1222brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 1221brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1223{ 1222{
1224 int ep;
1225 struct usb_endpoint_descriptor *endpoint;
1226 int ret = 0;
1227 struct usb_device *usb = interface_to_usbdev(intf); 1223 struct usb_device *usb = interface_to_usbdev(intf);
1228 int num_of_eps;
1229 u8 endpoint_num;
1230 struct brcmf_usbdev_info *devinfo; 1224 struct brcmf_usbdev_info *devinfo;
1225 struct usb_interface_descriptor *desc;
1226 struct usb_endpoint_descriptor *endpoint;
1227 int ret = 0;
1228 u32 num_of_eps;
1229 u8 endpoint_num, ep;
1231 1230
1232 brcmf_dbg(USB, "Enter\n"); 1231 brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct);
1233 1232
1234 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); 1233 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
1235 if (devinfo == NULL) 1234 if (devinfo == NULL)
@@ -1237,92 +1236,71 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1237 1236
1238 devinfo->usbdev = usb; 1237 devinfo->usbdev = usb;
1239 devinfo->dev = &usb->dev; 1238 devinfo->dev = &usb->dev;
1240
1241 usb_set_intfdata(intf, devinfo); 1239 usb_set_intfdata(intf, devinfo);
1242 1240
1243 /* Check that the device supports only one configuration */ 1241 /* Check that the device supports only one configuration */
1244 if (usb->descriptor.bNumConfigurations != 1) { 1242 if (usb->descriptor.bNumConfigurations != 1) {
1245 ret = -1; 1243 brcmf_err("Number of configurations: %d not supported\n",
1246 goto fail; 1244 usb->descriptor.bNumConfigurations);
1247 } 1245 ret = -ENODEV;
1248
1249 if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
1250 ret = -1;
1251 goto fail; 1246 goto fail;
1252 } 1247 }
1253 1248
1254 /* 1249 if ((usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) &&
1255 * Only the BDC interface configuration is supported: 1250 (usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
1256 * Device class: USB_CLASS_VENDOR_SPEC 1251 (usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS_CONTROLLER)) {
1257 * if0 class: USB_CLASS_VENDOR_SPEC 1252 brcmf_err("Device class: 0x%x not supported\n",
1258 * if0/ep0: control 1253 usb->descriptor.bDeviceClass);
1259 * if0/ep1: bulk in 1254 ret = -ENODEV;
1260 * if0/ep2: bulk out (ok if swapped with bulk in)
1261 */
1262 if (CONFIGDESC(usb)->bNumInterfaces != 1) {
1263 ret = -1;
1264 goto fail; 1255 goto fail;
1265 } 1256 }
1266 1257
1267 /* Check interface */ 1258 desc = &intf->altsetting[0].desc;
1268 if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC || 1259 if ((desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) ||
1269 IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 || 1260 (desc->bInterfaceSubClass != 2) ||
1270 IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff) { 1261 (desc->bInterfaceProtocol != 0xff)) {
1271 brcmf_err("invalid control interface: class %d, subclass %d, proto %d\n", 1262 brcmf_err("non WLAN interface %d: 0x%x:0x%x:0x%x\n",
1272 IFDESC(usb, CONTROL_IF).bInterfaceClass, 1263 desc->bInterfaceNumber, desc->bInterfaceClass,
1273 IFDESC(usb, CONTROL_IF).bInterfaceSubClass, 1264 desc->bInterfaceSubClass, desc->bInterfaceProtocol);
1274 IFDESC(usb, CONTROL_IF).bInterfaceProtocol); 1265 ret = -ENODEV;
1275 ret = -1;
1276 goto fail; 1266 goto fail;
1277 } 1267 }
1278 1268
1279 /* Check control endpoint */ 1269 num_of_eps = desc->bNumEndpoints;
1280 endpoint = &IFEPDESC(usb, CONTROL_IF, 0); 1270 for (ep = 0; ep < num_of_eps; ep++) {
1281 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 1271 endpoint = &intf->altsetting[0].endpoint[ep].desc;
1282 != USB_ENDPOINT_XFER_INT) { 1272 endpoint_num = usb_endpoint_num(endpoint);
1283 brcmf_err("invalid control endpoint %d\n", 1273 if (!usb_endpoint_xfer_bulk(endpoint))
1284 endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); 1274 continue;
1285 ret = -1; 1275 if (usb_endpoint_dir_in(endpoint)) {
1286 goto fail; 1276 if (!devinfo->rx_pipe)
1287 }
1288
1289 devinfo->rx_pipe = 0;
1290 devinfo->rx_pipe2 = 0;
1291 devinfo->tx_pipe = 0;
1292 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
1293
1294 /* Check data endpoints and get pipes */
1295 for (ep = 1; ep <= num_of_eps; ep++) {
1296 endpoint = &IFEPDESC(usb, BULK_IF, ep);
1297 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1298 USB_ENDPOINT_XFER_BULK) {
1299 brcmf_err("invalid data endpoint %d\n", ep);
1300 ret = -1;
1301 goto fail;
1302 }
1303
1304 endpoint_num = endpoint->bEndpointAddress &
1305 USB_ENDPOINT_NUMBER_MASK;
1306 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1307 == USB_DIR_IN) {
1308 if (!devinfo->rx_pipe) {
1309 devinfo->rx_pipe = 1277 devinfo->rx_pipe =
1310 usb_rcvbulkpipe(usb, endpoint_num); 1278 usb_rcvbulkpipe(usb, endpoint_num);
1311 } else {
1312 devinfo->rx_pipe2 =
1313 usb_rcvbulkpipe(usb, endpoint_num);
1314 }
1315 } else { 1279 } else {
1316 devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num); 1280 if (!devinfo->tx_pipe)
1281 devinfo->tx_pipe =
1282 usb_sndbulkpipe(usb, endpoint_num);
1317 } 1283 }
1318 } 1284 }
1285 if (devinfo->rx_pipe == 0) {
1286 brcmf_err("No RX (in) Bulk EP found\n");
1287 ret = -ENODEV;
1288 goto fail;
1289 }
1290 if (devinfo->tx_pipe == 0) {
1291 brcmf_err("No TX (out) Bulk EP found\n");
1292 ret = -ENODEV;
1293 goto fail;
1294 }
1295
1296 devinfo->ifnum = desc->bInterfaceNumber;
1319 1297
1320 if (usb->speed == USB_SPEED_SUPER) 1298 if (usb->speed == USB_SPEED_SUPER)
1321 brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n"); 1299 brcmf_dbg(USB, "Broadcom super speed USB WLAN interface detected\n");
1322 else if (usb->speed == USB_SPEED_HIGH) 1300 else if (usb->speed == USB_SPEED_HIGH)
1323 brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); 1301 brcmf_dbg(USB, "Broadcom high speed USB WLAN interface detected\n");
1324 else 1302 else
1325 brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); 1303 brcmf_dbg(USB, "Broadcom full speed USB WLAN interface detected\n");
1326 1304
1327 ret = brcmf_usb_probe_cb(devinfo); 1305 ret = brcmf_usb_probe_cb(devinfo);
1328 if (ret) 1306 if (ret)
@@ -1332,11 +1310,9 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1332 return 0; 1310 return 0;
1333 1311
1334fail: 1312fail:
1335 brcmf_err("failed with errno %d\n", ret);
1336 kfree(devinfo); 1313 kfree(devinfo);
1337 usb_set_intfdata(intf, NULL); 1314 usb_set_intfdata(intf, NULL);
1338 return ret; 1315 return ret;
1339
1340} 1316}
1341 1317
1342static void 1318static void
@@ -1381,6 +1357,7 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
1381{ 1357{
1382 struct usb_device *usb = interface_to_usbdev(intf); 1358 struct usb_device *usb = interface_to_usbdev(intf);
1383 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1359 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1360
1384 brcmf_dbg(USB, "Enter\n"); 1361 brcmf_dbg(USB, "Enter\n");
1385 1362
1386 return brcmf_fw_get_firmwares(&usb->dev, 0, 1363 return brcmf_fw_get_firmwares(&usb->dev, 0,
@@ -1392,12 +1369,14 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
1392#define BRCMF_USB_DEVICE_ID_43143 0xbd1e 1369#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
1393#define BRCMF_USB_DEVICE_ID_43236 0xbd17 1370#define BRCMF_USB_DEVICE_ID_43236 0xbd17
1394#define BRCMF_USB_DEVICE_ID_43242 0xbd1f 1371#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
1372#define BRCMF_USB_DEVICE_ID_43569 0xbd27
1395#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc 1373#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
1396 1374
1397static struct usb_device_id brcmf_usb_devid_table[] = { 1375static struct usb_device_id brcmf_usb_devid_table[] = {
1398 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) }, 1376 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
1399 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) }, 1377 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
1400 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) }, 1378 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
1379 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43569) },
1401 /* special entry for device with firmware loaded and running */ 1380 /* special entry for device with firmware loaded and running */
1402 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, 1381 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
1403 { } 1382 { }
@@ -1407,6 +1386,7 @@ MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
1407MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); 1386MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
1408MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); 1387MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
1409MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); 1388MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
1389MODULE_FIRMWARE(BRCMF_USB_43569_FW_NAME);
1410 1390
1411static struct usb_driver brcmf_usbdrvr = { 1391static struct usb_driver brcmf_usbdrvr = {
1412 .name = KBUILD_MODNAME, 1392 .name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.c b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
new file mode 100644
index 000000000000..5960d827508c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.c
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) 2014 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/vmalloc.h>
18#include <net/cfg80211.h>
19#include <net/netlink.h>
20
21#include <brcmu_wifi.h>
22#include "fwil_types.h"
23#include "dhd.h"
24#include "p2p.h"
25#include "dhd_dbg.h"
26#include "wl_cfg80211.h"
27#include "vendor.h"
28#include "fwil.h"
29
30static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy *wiphy,
31 struct wireless_dev *wdev,
32 const void *data, int len)
33{
34 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
35 struct net_device *ndev = cfg_to_ndev(cfg);
36 const struct brcmf_vndr_dcmd_hdr *cmdhdr = data;
37 struct sk_buff *reply;
38 int ret, payload, ret_len;
39 void *dcmd_buf = NULL, *wr_pointer;
40 u16 msglen, maxmsglen = PAGE_SIZE - 0x100;
41
42 brcmf_dbg(TRACE, "cmd %x set %d len %d\n", cmdhdr->cmd, cmdhdr->set,
43 cmdhdr->len);
44
45 len -= sizeof(struct brcmf_vndr_dcmd_hdr);
46 ret_len = cmdhdr->len;
47 if (ret_len > 0 || len > 0) {
48 if (len > BRCMF_DCMD_MAXLEN) {
49 brcmf_err("oversize input buffer %d\n", len);
50 len = BRCMF_DCMD_MAXLEN;
51 }
52 if (ret_len > BRCMF_DCMD_MAXLEN) {
53 brcmf_err("oversize return buffer %d\n", ret_len);
54 ret_len = BRCMF_DCMD_MAXLEN;
55 }
56 payload = max(ret_len, len) + 1;
57 dcmd_buf = vzalloc(payload);
58 if (NULL == dcmd_buf)
59 return -ENOMEM;
60
61 memcpy(dcmd_buf, (void *)cmdhdr + cmdhdr->offset, len);
62 *(char *)(dcmd_buf + len) = '\0';
63 }
64
65 if (cmdhdr->set)
66 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), cmdhdr->cmd,
67 dcmd_buf, ret_len);
68 else
69 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), cmdhdr->cmd,
70 dcmd_buf, ret_len);
71 if (ret != 0)
72 goto exit;
73
74 wr_pointer = dcmd_buf;
75 while (ret_len > 0) {
76 msglen = ret_len > maxmsglen ? maxmsglen : ret_len;
77 ret_len -= msglen;
78 payload = msglen + sizeof(msglen);
79 reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
80 if (NULL == reply) {
81 ret = -ENOMEM;
82 break;
83 }
84
85 if (nla_put(reply, BRCMF_NLATTR_DATA, msglen, wr_pointer) ||
86 nla_put_u16(reply, BRCMF_NLATTR_LEN, msglen)) {
87 kfree_skb(reply);
88 ret = -ENOBUFS;
89 break;
90 }
91
92 ret = cfg80211_vendor_cmd_reply(reply);
93 if (ret)
94 break;
95
96 wr_pointer += msglen;
97 }
98
99exit:
100 vfree(dcmd_buf);
101
102 return ret;
103}
104
105const struct wiphy_vendor_command brcmf_vendor_cmds[] = {
106 {
107 {
108 .vendor_id = BROADCOM_OUI,
109 .subcmd = BRCMF_VNDR_CMDS_DCMD
110 },
111 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
112 WIPHY_VENDOR_CMD_NEED_NETDEV,
113 .doit = brcmf_cfg80211_vndr_cmds_dcmd_handler
114 },
115};
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/vendor.h b/drivers/net/wireless/brcm80211/brcmfmac/vendor.h
new file mode 100644
index 000000000000..061b7bfa2e1c
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/vendor.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 2014 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef _vendor_h_
18#define _vendor_h_
19
20#define BROADCOM_OUI 0x001018
21
22enum brcmf_vndr_cmds {
23 BRCMF_VNDR_CMDS_UNSPEC,
24 BRCMF_VNDR_CMDS_DCMD,
25 BRCMF_VNDR_CMDS_LAST
26};
27
28/**
29 * enum brcmf_nlattrs - nl80211 message attributes
30 *
31 * @BRCMF_NLATTR_LEN: message body length
32 * @BRCMF_NLATTR_DATA: message body
33 */
34enum brcmf_nlattrs {
35 BRCMF_NLATTR_UNSPEC,
36
37 BRCMF_NLATTR_LEN,
38 BRCMF_NLATTR_DATA,
39
40 __BRCMF_NLATTR_AFTER_LAST,
41 BRCMF_NLATTR_MAX = __BRCMF_NLATTR_AFTER_LAST - 1
42};
43
44/**
45 * struct brcmf_vndr_dcmd_hdr - message header for cfg80211 vendor command dcmd
46 * support
47 *
48 * @cmd: common dongle cmd definition
49 * @len: length of expecting return buffer
50 * @offset: offset of data buffer
51 * @set: get or set request(optional)
52 * @magic: magic number for verification
53 */
54struct brcmf_vndr_dcmd_hdr {
55 uint cmd;
56 int len;
57 uint offset;
58 uint set;
59 uint magic;
60};
61
62extern const struct wiphy_vendor_command brcmf_vendor_cmds[];
63
64#endif /* _vendor_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index d8fa276e368b..9682cf213ec4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -19,6 +19,7 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/vmalloc.h>
22#include <net/cfg80211.h> 23#include <net/cfg80211.h>
23#include <net/netlink.h> 24#include <net/netlink.h>
24 25
@@ -33,6 +34,7 @@
33#include "btcoex.h" 34#include "btcoex.h"
34#include "wl_cfg80211.h" 35#include "wl_cfg80211.h"
35#include "fwil.h" 36#include "fwil.h"
37#include "vendor.h"
36 38
37#define BRCMF_SCAN_IE_LEN_MAX 2048 39#define BRCMF_SCAN_IE_LEN_MAX 2048
38#define BRCMF_PNO_VERSION 2 40#define BRCMF_PNO_VERSION 2
@@ -588,6 +590,12 @@ static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
588 } 590 }
589} 591}
590 592
593static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
594{
595 if ((brcmf_get_chip_info(ifp) >> 4) == 0x4329)
596 brcmf_set_mpc(ifp, mpc);
597}
598
591void brcmf_set_mpc(struct brcmf_if *ifp, int mpc) 599void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
592{ 600{
593 s32 err = 0; 601 s32 err = 0;
@@ -641,7 +649,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
641 brcmf_err("Scan abort failed\n"); 649 brcmf_err("Scan abort failed\n");
642 } 650 }
643 651
644 brcmf_set_mpc(ifp, 1); 652 brcmf_scan_config_mpc(ifp, 1);
645 653
646 /* 654 /*
647 * e-scan can be initiated by scheduled scan 655 * e-scan can be initiated by scheduled scan
@@ -920,7 +928,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
920 brcmf_err("error (%d)\n", err); 928 brcmf_err("error (%d)\n", err);
921 return err; 929 return err;
922 } 930 }
923 brcmf_set_mpc(ifp, 0); 931 brcmf_scan_config_mpc(ifp, 0);
924 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; 932 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
925 results->version = 0; 933 results->version = 0;
926 results->count = 0; 934 results->count = 0;
@@ -928,7 +936,7 @@ brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
928 936
929 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START); 937 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
930 if (err) 938 if (err)
931 brcmf_set_mpc(ifp, 1); 939 brcmf_scan_config_mpc(ifp, 1);
932 return err; 940 return err;
933} 941}
934 942
@@ -1019,7 +1027,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1019 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err); 1027 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1020 goto scan_out; 1028 goto scan_out;
1021 } 1029 }
1022 brcmf_set_mpc(ifp, 0); 1030 brcmf_scan_config_mpc(ifp, 0);
1023 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, 1031 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1024 &sr->ssid_le, sizeof(sr->ssid_le)); 1032 &sr->ssid_le, sizeof(sr->ssid_le));
1025 if (err) { 1033 if (err) {
@@ -1029,7 +1037,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1029 else 1037 else
1030 brcmf_err("WLC_SCAN error (%d)\n", err); 1038 brcmf_err("WLC_SCAN error (%d)\n", err);
1031 1039
1032 brcmf_set_mpc(ifp, 1); 1040 brcmf_scan_config_mpc(ifp, 1);
1033 goto scan_out; 1041 goto scan_out;
1034 } 1042 }
1035 } 1043 }
@@ -1331,7 +1339,6 @@ static s32
1331brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1339brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1332{ 1340{
1333 struct brcmf_if *ifp = netdev_priv(ndev); 1341 struct brcmf_if *ifp = netdev_priv(ndev);
1334 s32 err = 0;
1335 1342
1336 brcmf_dbg(TRACE, "Enter\n"); 1343 brcmf_dbg(TRACE, "Enter\n");
1337 if (!check_vif_up(ifp->vif)) 1344 if (!check_vif_up(ifp->vif))
@@ -1341,7 +1348,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1341 1348
1342 brcmf_dbg(TRACE, "Exit\n"); 1349 brcmf_dbg(TRACE, "Exit\n");
1343 1350
1344 return err; 1351 return 0;
1345} 1352}
1346 1353
1347static s32 brcmf_set_wpa_version(struct net_device *ndev, 1354static s32 brcmf_set_wpa_version(struct net_device *ndev,
@@ -2388,7 +2395,6 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2388 struct cfg80211_bss *bss; 2395 struct cfg80211_bss *bss;
2389 struct ieee80211_supported_band *band; 2396 struct ieee80211_supported_band *band;
2390 struct brcmu_chan ch; 2397 struct brcmu_chan ch;
2391 s32 err = 0;
2392 u16 channel; 2398 u16 channel;
2393 u32 freq; 2399 u32 freq;
2394 u16 notify_capability; 2400 u16 notify_capability;
@@ -2438,7 +2444,7 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2438 2444
2439 cfg80211_put_bss(wiphy, bss); 2445 cfg80211_put_bss(wiphy, bss);
2440 2446
2441 return err; 2447 return 0;
2442} 2448}
2443 2449
2444static struct brcmf_bss_info_le * 2450static struct brcmf_bss_info_le *
@@ -2690,7 +2696,6 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2690{ 2696{
2691 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 2697 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2692 s32 status; 2698 s32 status;
2693 s32 err = 0;
2694 struct brcmf_escan_result_le *escan_result_le; 2699 struct brcmf_escan_result_le *escan_result_le;
2695 struct brcmf_bss_info_le *bss_info_le; 2700 struct brcmf_bss_info_le *bss_info_le;
2696 struct brcmf_bss_info_le *bss = NULL; 2701 struct brcmf_bss_info_le *bss = NULL;
@@ -2781,7 +2786,7 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2781 status); 2786 status);
2782 } 2787 }
2783exit: 2788exit:
2784 return err; 2789 return 0;
2785} 2790}
2786 2791
2787static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) 2792static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
@@ -3260,35 +3265,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3260 return 0; 3265 return 0;
3261} 3266}
3262 3267
3263#ifdef CONFIG_NL80211_TESTMODE
3264static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3265 struct wireless_dev *wdev,
3266 void *data, int len)
3267{
3268 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3269 struct net_device *ndev = cfg_to_ndev(cfg);
3270 struct brcmf_dcmd *dcmd = data;
3271 struct sk_buff *reply;
3272 int ret;
3273
3274 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3275 dcmd->buf, dcmd->len);
3276
3277 if (dcmd->set)
3278 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3279 dcmd->buf, dcmd->len);
3280 else
3281 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3282 dcmd->buf, dcmd->len);
3283 if (ret == 0) {
3284 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3285 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3286 ret = cfg80211_testmode_reply(reply);
3287 }
3288 return ret;
3289}
3290#endif
3291
3292static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp) 3268static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3293{ 3269{
3294 s32 err; 3270 s32 err;
@@ -3507,7 +3483,6 @@ static s32
3507brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, 3483brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3508 struct parsed_vndr_ies *vndr_ies) 3484 struct parsed_vndr_ies *vndr_ies)
3509{ 3485{
3510 s32 err = 0;
3511 struct brcmf_vs_tlv *vndrie; 3486 struct brcmf_vs_tlv *vndrie;
3512 struct brcmf_tlv *ie; 3487 struct brcmf_tlv *ie;
3513 struct parsed_vndr_ie_info *parsed_info; 3488 struct parsed_vndr_ie_info *parsed_info;
@@ -3560,7 +3535,7 @@ next:
3560 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len + 3535 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3561 TLV_HDR_LEN); 3536 TLV_HDR_LEN);
3562 } 3537 }
3563 return err; 3538 return 0;
3564} 3539}
3565 3540
3566static u32 3541static u32
@@ -4307,7 +4282,6 @@ static struct cfg80211_ops wl_cfg80211_ops = {
4307 .crit_proto_start = brcmf_cfg80211_crit_proto_start, 4282 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4308 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, 4283 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4309 .tdls_oper = brcmf_cfg80211_tdls_oper, 4284 .tdls_oper = brcmf_cfg80211_tdls_oper,
4310 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4311}; 4285};
4312 4286
4313static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 4287static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
@@ -4412,6 +4386,11 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4412 brcmf_dbg(INFO, "Registering custom regulatory\n"); 4386 brcmf_dbg(INFO, "Registering custom regulatory\n");
4413 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; 4387 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4414 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 4388 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4389
4390 /* vendor commands/events support */
4391 wiphy->vendor_commands = brcmf_vendor_cmds;
4392 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
4393
4415 err = wiphy_register(wiphy); 4394 err = wiphy_register(wiphy);
4416 if (err < 0) { 4395 if (err < 0) {
4417 brcmf_err("Could not register wiphy device (%d)\n", err); 4396 brcmf_err("Could not register wiphy device (%d)\n", err);
@@ -4650,7 +4629,6 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4650 struct brcmf_if *ifp = netdev_priv(ndev); 4629 struct brcmf_if *ifp = netdev_priv(ndev);
4651 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4630 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); 4631 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4653 s32 err = 0;
4654 4632
4655 brcmf_dbg(TRACE, "Enter\n"); 4633 brcmf_dbg(TRACE, "Enter\n");
4656 4634
@@ -4676,7 +4654,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4676 completed ? "succeeded" : "failed"); 4654 completed ? "succeeded" : "failed");
4677 } 4655 }
4678 brcmf_dbg(TRACE, "Exit\n"); 4656 brcmf_dbg(TRACE, "Exit\n");
4679 return err; 4657 return 0;
4680} 4658}
4681 4659
4682static s32 4660static s32
@@ -4768,7 +4746,6 @@ brcmf_notify_roaming_status(struct brcmf_if *ifp,
4768 const struct brcmf_event_msg *e, void *data) 4746 const struct brcmf_event_msg *e, void *data)
4769{ 4747{
4770 struct brcmf_cfg80211_info *cfg = ifp->drvr->config; 4748 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4771 s32 err = 0;
4772 u32 event = e->event_code; 4749 u32 event = e->event_code;
4773 u32 status = e->status; 4750 u32 status = e->status;
4774 4751
@@ -4779,7 +4756,7 @@ brcmf_notify_roaming_status(struct brcmf_if *ifp,
4779 brcmf_bss_connect_done(cfg, ifp->ndev, e, true); 4756 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4780 } 4757 }
4781 4758
4782 return err; 4759 return 0;
4783} 4760}
4784 4761
4785static s32 4762static s32
@@ -5057,6 +5034,9 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5057 err = brcmf_fil_iovar_int_set(ifp, "obss_coex", 5034 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5058 BRCMF_OBSS_COEX_AUTO); 5035 BRCMF_OBSS_COEX_AUTO);
5059 } 5036 }
5037 /* clear for now and rely on update later */
5038 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false;
5039 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0;
5060 5040
5061 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1); 5041 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5062 if (err) { 5042 if (err) {
@@ -5625,16 +5605,15 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5625 return wdev->iftype; 5605 return wdev->iftype;
5626} 5606}
5627 5607
5628u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state) 5608bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state)
5629{ 5609{
5630 struct brcmf_cfg80211_vif *vif; 5610 struct brcmf_cfg80211_vif *vif;
5631 bool result = 0;
5632 5611
5633 list_for_each_entry(vif, &cfg->vif_list, list) { 5612 list_for_each_entry(vif, &cfg->vif_list, list) {
5634 if (test_bit(state, &vif->sme_state)) 5613 if (test_bit(state, &vif->sme_state))
5635 result++; 5614 return true;
5636 } 5615 }
5637 return result; 5616 return false;
5638} 5617}
5639 5618
5640static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event, 5619static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 283c525a44f7..f9fb10998e79 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -477,7 +477,7 @@ const struct brcmf_tlv *
477brcmf_parse_tlvs(const void *buf, int buflen, uint key); 477brcmf_parse_tlvs(const void *buf, int buflen, uint key);
478u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, 478u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
479 struct ieee80211_channel *ch); 479 struct ieee80211_channel *ch);
480u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state); 480bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state);
481void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, 481void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
482 struct brcmf_cfg80211_vif *vif); 482 struct brcmf_cfg80211_vif *vif);
483bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); 483bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
index b0fd807f2b2b..57ecc05802e9 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -1538,11 +1538,7 @@ static s8
1538wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band, 1538wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band,
1539 u8 rate) 1539 u8 rate)
1540{ 1540{
1541 s8 offset = 0; 1541 return 0;
1542
1543 if (!pi->user_txpwr_at_rfport)
1544 return offset;
1545 return offset;
1546} 1542}
1547 1543
1548void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) 1544void wlc_phy_txpower_recalc_target(struct brcms_phy *pi)
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
index 9afcd4ce3368..b2fb6c632092 100644
--- a/drivers/net/wireless/cw1200/scan.c
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -53,9 +53,10 @@ static int cw1200_scan_start(struct cw1200_common *priv, struct wsm_scan *scan)
53 53
54int cw1200_hw_scan(struct ieee80211_hw *hw, 54int cw1200_hw_scan(struct ieee80211_hw *hw,
55 struct ieee80211_vif *vif, 55 struct ieee80211_vif *vif,
56 struct cfg80211_scan_request *req) 56 struct ieee80211_scan_request *hw_req)
57{ 57{
58 struct cw1200_common *priv = hw->priv; 58 struct cw1200_common *priv = hw->priv;
59 struct cfg80211_scan_request *req = &hw_req->req;
59 struct wsm_template_frame frame = { 60 struct wsm_template_frame frame = {
60 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST, 61 .frame_type = WSM_FRAME_TYPE_PROBE_REQUEST,
61 }; 62 };
diff --git a/drivers/net/wireless/cw1200/scan.h b/drivers/net/wireless/cw1200/scan.h
index 5a8296ccfa82..cc75459e5784 100644
--- a/drivers/net/wireless/cw1200/scan.h
+++ b/drivers/net/wireless/cw1200/scan.h
@@ -41,7 +41,7 @@ struct cw1200_scan {
41 41
42int cw1200_hw_scan(struct ieee80211_hw *hw, 42int cw1200_hw_scan(struct ieee80211_hw *hw,
43 struct ieee80211_vif *vif, 43 struct ieee80211_vif *vif,
44 struct cfg80211_scan_request *req); 44 struct ieee80211_scan_request *hw_req);
45void cw1200_scan_work(struct work_struct *work); 45void cw1200_scan_work(struct work_struct *work);
46void cw1200_scan_timeout(struct work_struct *work); 46void cw1200_scan_timeout(struct work_struct *work);
47void cw1200_clear_recent_scan_work(struct work_struct *work); 47void cw1200_clear_recent_scan_work(struct work_struct *work);
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index cd0cad7f7759..5b84664db13b 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -2289,7 +2289,6 @@ static int cw1200_upload_null(struct cw1200_common *priv)
2289 2289
2290static int cw1200_upload_qosnull(struct cw1200_common *priv) 2290static int cw1200_upload_qosnull(struct cw1200_common *priv)
2291{ 2291{
2292 int ret = 0;
2293 /* TODO: This needs to be implemented 2292 /* TODO: This needs to be implemented
2294 2293
2295 struct wsm_template_frame frame = { 2294 struct wsm_template_frame frame = {
@@ -2306,7 +2305,7 @@ static int cw1200_upload_qosnull(struct cw1200_common *priv)
2306 dev_kfree_skb(frame.skb); 2305 dev_kfree_skb(frame.skb);
2307 2306
2308 */ 2307 */
2309 return ret; 2308 return 0;
2310} 2309}
2311 2310
2312static int cw1200_enable_beaconing(struct cw1200_common *priv, 2311static int cw1200_enable_beaconing(struct cw1200_common *priv,
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 3adb24021a28..5f31b72a4921 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -100,8 +100,7 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
100 int i; 100 int i;
101 101
102 for (i = 0; i < MAX_NETWORK_COUNT; i++) { 102 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
103 if (ieee->networks[i]->ibss_dfs) 103 kfree(ieee->networks[i]->ibss_dfs);
104 kfree(ieee->networks[i]->ibss_dfs);
105 kfree(ieee->networks[i]); 104 kfree(ieee->networks[i]);
106 } 105 }
107} 106}
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index ecc674627e6e..03de7467aecf 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -1572,8 +1572,9 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
1572 1572
1573int 1573int
1574il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1574il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1575 struct cfg80211_scan_request *req) 1575 struct ieee80211_scan_request *hw_req)
1576{ 1576{
1577 struct cfg80211_scan_request *req = &hw_req->req;
1577 struct il_priv *il = hw->priv; 1578 struct il_priv *il = hw->priv;
1578 int ret; 1579 int ret;
1579 1580
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index ea5c0f863c4e..5b972798bdff 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1787,7 +1787,7 @@ int il_scan_cancel(struct il_priv *il);
1787int il_scan_cancel_timeout(struct il_priv *il, unsigned long ms); 1787int il_scan_cancel_timeout(struct il_priv *il, unsigned long ms);
1788void il_force_scan_end(struct il_priv *il); 1788void il_force_scan_end(struct il_priv *il);
1789int il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1789int il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1790 struct cfg80211_scan_request *req); 1790 struct ieee80211_scan_request *hw_req);
1791void il_internal_short_hw_scan(struct il_priv *il); 1791void il_internal_short_hw_scan(struct il_priv *il);
1792int il_force_reset(struct il_priv *il, bool external); 1792int il_force_reset(struct il_priv *il, bool external);
1793u16 il_fill_probe_req(struct il_priv *il, struct ieee80211_mgmt *frame, 1793u16 il_fill_probe_req(struct il_priv *il, struct ieee80211_mgmt *frame,
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 29af7b51e370..afb98f4fdaf3 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1495,9 +1495,10 @@ static int iwlagn_mac_change_interface(struct ieee80211_hw *hw,
1495 1495
1496static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw, 1496static int iwlagn_mac_hw_scan(struct ieee80211_hw *hw,
1497 struct ieee80211_vif *vif, 1497 struct ieee80211_vif *vif,
1498 struct cfg80211_scan_request *req) 1498 struct ieee80211_scan_request *hw_req)
1499{ 1499{
1500 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1500 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1501 struct cfg80211_scan_request *req = &hw_req->req;
1501 int ret; 1502 int ret;
1502 1503
1503 IWL_DEBUG_MAC80211(priv, "enter\n"); 1504 IWL_DEBUG_MAC80211(priv, "enter\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/power.c b/drivers/net/wireless/iwlwifi/dvm/power.c
index f2c1439566b5..760c45c34ef3 100644
--- a/drivers/net/wireless/iwlwifi/dvm/power.c
+++ b/drivers/net/wireless/iwlwifi/dvm/power.c
@@ -40,6 +40,10 @@
40#include "commands.h" 40#include "commands.h"
41#include "power.h" 41#include "power.h"
42 42
43static bool force_cam;
44module_param(force_cam, bool, 0644);
45MODULE_PARM_DESC(force_cam, "force continuously aware mode (no power saving at all)");
46
43/* 47/*
44 * Setting power level allows the card to go to sleep when not busy. 48 * Setting power level allows the card to go to sleep when not busy.
45 * 49 *
@@ -288,6 +292,11 @@ static void iwl_power_build_cmd(struct iwl_priv *priv,
288 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; 292 bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS;
289 int dtimper; 293 int dtimper;
290 294
295 if (force_cam) {
296 iwl_power_sleep_cam_cmd(priv, cmd);
297 return;
298 }
299
291 dtimper = priv->hw->conf.ps_dtim_period ?: 1; 300 dtimper = priv->hw->conf.ps_dtim_period ?: 1;
292 301
293 if (priv->wowlan) 302 if (priv->wowlan)
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index ed50de6362ed..6dc5dd3ced44 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1068,13 +1068,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1068 /* recalculate basic rates */ 1068 /* recalculate basic rates */
1069 iwl_calc_basic_rates(priv, ctx); 1069 iwl_calc_basic_rates(priv, ctx);
1070 1070
1071 /*
1072 * force CTS-to-self frames protection if RTS-CTS is not preferred
1073 * one aggregation protection method
1074 */
1075 if (!priv->hw_params.use_rts_for_aggregation)
1076 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1077
1078 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || 1071 if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
1079 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) 1072 !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
1080 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; 1073 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -1480,11 +1473,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
1480 else 1473 else
1481 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; 1474 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1482 1475
1483 if (bss_conf->use_cts_prot)
1484 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1485 else
1486 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
1487
1488 memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); 1476 memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
1489 1477
1490 if (vif->type == NL80211_IFTYPE_AP || 1478 if (vif->type == NL80211_IFTYPE_AP ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 51c41531d81d..51486cc9d943 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -67,7 +67,7 @@
67#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
68 68
69/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
70#define IWL8000_UCODE_API_MAX 8 70#define IWL8000_UCODE_API_MAX 9
71 71
72/* Oldest version we won't warn about */ 72/* Oldest version we won't warn about */
73#define IWL8000_UCODE_API_OK 8 73#define IWL8000_UCODE_API_OK 8
@@ -119,10 +119,9 @@ const struct iwl_cfg iwl8260_2ac_cfg = {
119 .ht_params = &iwl8000_ht_params, 119 .ht_params = &iwl8000_ht_params,
120 .nvm_ver = IWL8000_NVM_VERSION, 120 .nvm_ver = IWL8000_NVM_VERSION,
121 .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 121 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
122 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
123}; 122};
124 123
125const struct iwl_cfg iwl8260_n_cfg = { 124const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
126 .name = "Intel(R) Dual Band Wireless-AC 8260", 125 .name = "Intel(R) Dual Band Wireless-AC 8260",
127 .fw_name_pre = IWL8000_FW_PRE, 126 .fw_name_pre = IWL8000_FW_PRE,
128 IWL_DEVICE_8000, 127 IWL_DEVICE_8000,
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index b7047905f41a..034c2fc4b69f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -337,7 +337,7 @@ extern const struct iwl_cfg iwl7265_2ac_cfg;
337extern const struct iwl_cfg iwl7265_2n_cfg; 337extern const struct iwl_cfg iwl7265_2n_cfg;
338extern const struct iwl_cfg iwl7265_n_cfg; 338extern const struct iwl_cfg iwl7265_n_cfg;
339extern const struct iwl_cfg iwl8260_2ac_cfg; 339extern const struct iwl_cfg iwl8260_2ac_cfg;
340extern const struct iwl_cfg iwl8260_n_cfg; 340extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
341#endif /* CONFIG_IWLMVM */ 341#endif /* CONFIG_IWLMVM */
342 342
343#endif /* __IWL_CONFIG_H__ */ 343#endif /* __IWL_CONFIG_H__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index f2a5c12269a3..77e3178040b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -155,6 +155,8 @@ static struct iwlwifi_opmode_table {
155 [MVM_OP_MODE] = { .name = "iwlmvm", .ops = NULL }, 155 [MVM_OP_MODE] = { .name = "iwlmvm", .ops = NULL },
156}; 156};
157 157
158#define IWL_DEFAULT_SCAN_CHANNELS 40
159
158/* 160/*
159 * struct fw_sec: Just for the image parsing proccess. 161 * struct fw_sec: Just for the image parsing proccess.
160 * For the fw storage we are using struct fw_desc. 162 * For the fw storage we are using struct fw_desc.
@@ -565,6 +567,8 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
565 } 567 }
566 568
567 drv->fw.ucode_ver = le32_to_cpu(ucode->ver); 569 drv->fw.ucode_ver = le32_to_cpu(ucode->ver);
570 memcpy(drv->fw.human_readable, ucode->human_readable,
571 sizeof(drv->fw.human_readable));
568 build = le32_to_cpu(ucode->build); 572 build = le32_to_cpu(ucode->build);
569 573
570 if (build) 574 if (build)
@@ -819,6 +823,12 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
819 if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len)) 823 if (iwl_store_cscheme(&drv->fw, tlv_data, tlv_len))
820 goto invalid_tlv_len; 824 goto invalid_tlv_len;
821 break; 825 break;
826 case IWL_UCODE_TLV_N_SCAN_CHANNELS:
827 if (tlv_len != sizeof(u32))
828 goto invalid_tlv_len;
829 capa->n_scan_channels =
830 le32_to_cpup((__le32 *)tlv_data);
831 break;
822 default: 832 default:
823 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); 833 IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type);
824 break; 834 break;
@@ -973,6 +983,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
973 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; 983 fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH;
974 fw->ucode_capa.standard_phy_calibration_size = 984 fw->ucode_capa.standard_phy_calibration_size =
975 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE; 985 IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
986 fw->ucode_capa.n_scan_channels = IWL_DEFAULT_SCAN_CHANNELS;
976 987
977 if (!api_ok) 988 if (!api_ok)
978 api_ok = api_max; 989 api_ok = api_max;
@@ -1394,3 +1405,7 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
1394 int, S_IRUGO); 1405 int, S_IRUGO);
1395MODULE_PARM_DESC(power_level, 1406MODULE_PARM_DESC(power_level,
1396 "default power save level (range from 1 - 5, default: 1)"); 1407 "default power save level (range from 1 - 5, default: 1)");
1408
1409module_param_named(fw_monitor, iwlwifi_mod_params.fw_monitor, bool, S_IRUGO);
1410MODULE_PARM_DESC(fw_monitor,
1411 "firmware monitor - to debug FW (default: false - needs lots of memory)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index c44cf1149648..07ff7e0028ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -779,7 +779,6 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
779 if (cfg->ht_params->ht40_bands & BIT(band)) { 779 if (cfg->ht_params->ht40_bands & BIT(band)) {
780 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 780 ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
781 ht_info->cap |= IEEE80211_HT_CAP_SGI_40; 781 ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
782 ht_info->mcs.rx_mask[4] = 0x01;
783 max_bit_rate = MAX_BIT_RATE_40_MHZ; 782 max_bit_rate = MAX_BIT_RATE_40_MHZ;
784 } 783 }
785 784
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index 2953ffceda38..c39a0b899e83 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -74,12 +74,17 @@
74 * @IWL_FW_ERROR_DUMP_RXF: 74 * @IWL_FW_ERROR_DUMP_RXF:
75 * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as 75 * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
76 * &struct iwl_fw_error_dump_txcmd packets 76 * &struct iwl_fw_error_dump_txcmd packets
77 * @IWL_FW_ERROR_DUMP_DEV_FW_INFO: struct %iwl_fw_error_dump_info
78 * info on the device / firmware.
79 * @IWL_FW_ERROR_DUMP_FW_MONITOR: firmware monitor
77 */ 80 */
78enum iwl_fw_error_dump_type { 81enum iwl_fw_error_dump_type {
79 IWL_FW_ERROR_DUMP_SRAM = 0, 82 IWL_FW_ERROR_DUMP_SRAM = 0,
80 IWL_FW_ERROR_DUMP_REG = 1, 83 IWL_FW_ERROR_DUMP_REG = 1,
81 IWL_FW_ERROR_DUMP_RXF = 2, 84 IWL_FW_ERROR_DUMP_RXF = 2,
82 IWL_FW_ERROR_DUMP_TXCMD = 3, 85 IWL_FW_ERROR_DUMP_TXCMD = 3,
86 IWL_FW_ERROR_DUMP_DEV_FW_INFO = 4,
87 IWL_FW_ERROR_DUMP_FW_MONITOR = 5,
83 88
84 IWL_FW_ERROR_DUMP_MAX, 89 IWL_FW_ERROR_DUMP_MAX,
85}; 90};
@@ -87,8 +92,8 @@ enum iwl_fw_error_dump_type {
87/** 92/**
88 * struct iwl_fw_error_dump_data - data for one type 93 * struct iwl_fw_error_dump_data - data for one type
89 * @type: %enum iwl_fw_error_dump_type 94 * @type: %enum iwl_fw_error_dump_type
90 * @len: the length starting from %data - must be a multiplier of 4. 95 * @len: the length starting from %data
91 * @data: the data itself padded to be a multiplier of 4. 96 * @data: the data itself
92 */ 97 */
93struct iwl_fw_error_dump_data { 98struct iwl_fw_error_dump_data {
94 __le32 type; 99 __le32 type;
@@ -120,13 +125,50 @@ struct iwl_fw_error_dump_txcmd {
120 u8 data[]; 125 u8 data[];
121} __packed; 126} __packed;
122 127
128enum iwl_fw_error_dump_family {
129 IWL_FW_ERROR_DUMP_FAMILY_7 = 7,
130 IWL_FW_ERROR_DUMP_FAMILY_8 = 8,
131};
132
133/**
134 * struct iwl_fw_error_dump_info - info on the device / firmware
135 * @device_family: the family of the device (7 / 8)
136 * @hw_step: the step of the device
137 * @fw_human_readable: human readable FW version
138 * @dev_human_readable: name of the device
139 * @bus_human_readable: name of the bus used
140 */
141struct iwl_fw_error_dump_info {
142 __le32 device_family;
143 __le32 hw_step;
144 u8 fw_human_readable[FW_VER_HUMAN_READABLE_SZ];
145 u8 dev_human_readable[64];
146 u8 bus_human_readable[8];
147} __packed;
148
149/**
150 * struct iwl_fw_error_dump_fw_mon - FW monitor data
151 * @fw_mon_wr_ptr: the position of the write pointer in the cyclic buffer
152 * @fw_mon_base_ptr: base pointer of the data
153 * @fw_mon_cycle_cnt: number of wrap arounds
154 * @reserved: for future use
155 * @data: captured data
156 */
157struct iwl_fw_error_dump_fw_mon {
158 __le32 fw_mon_wr_ptr;
159 __le32 fw_mon_base_ptr;
160 __le32 fw_mon_cycle_cnt;
161 __le32 reserved[3];
162 u8 data[];
163} __packed;
164
123/** 165/**
124 * iwl_mvm_fw_error_next_data - advance fw error dump data pointer 166 * iwl_fw_error_next_data - advance fw error dump data pointer
125 * @data: previous data block 167 * @data: previous data block
126 * Returns: next data block 168 * Returns: next data block
127 */ 169 */
128static inline struct iwl_fw_error_dump_data * 170static inline struct iwl_fw_error_dump_data *
129iwl_mvm_fw_error_next_data(struct iwl_fw_error_dump_data *data) 171iwl_fw_error_next_data(struct iwl_fw_error_dump_data *data)
130{ 172{
131 return (void *)(data->data + le32_to_cpu(data->len)); 173 return (void *)(data->data + le32_to_cpu(data->len));
132} 174}
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index b45e576a4b57..929a8063354c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -128,6 +128,7 @@ enum iwl_ucode_tlv_type {
128 IWL_UCODE_TLV_CSCHEME = 28, 128 IWL_UCODE_TLV_CSCHEME = 28,
129 IWL_UCODE_TLV_API_CHANGES_SET = 29, 129 IWL_UCODE_TLV_API_CHANGES_SET = 29,
130 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30, 130 IWL_UCODE_TLV_ENABLED_CAPABILITIES = 30,
131 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
131}; 132};
132 133
133struct iwl_ucode_tlv { 134struct iwl_ucode_tlv {
@@ -136,7 +137,8 @@ struct iwl_ucode_tlv {
136 u8 data[0]; 137 u8 data[0];
137}; 138};
138 139
139#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 140#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
141#define FW_VER_HUMAN_READABLE_SZ 64
140 142
141struct iwl_tlv_ucode_header { 143struct iwl_tlv_ucode_header {
142 /* 144 /*
@@ -147,7 +149,7 @@ struct iwl_tlv_ucode_header {
147 */ 149 */
148 __le32 zero; 150 __le32 zero;
149 __le32 magic; 151 __le32 magic;
150 u8 human_readable[64]; 152 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
151 __le32 ver; /* major/minor/API/serial */ 153 __le32 ver; /* major/minor/API/serial */
152 __le32 build; 154 __le32 build;
153 __le64 ignore; 155 __le64 ignore;
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 0aa7c0085c9f..1bb5193c5b1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -65,6 +65,8 @@
65#include <linux/types.h> 65#include <linux/types.h>
66#include <net/mac80211.h> 66#include <net/mac80211.h>
67 67
68#include "iwl-fw-file.h"
69
68/** 70/**
69 * enum iwl_ucode_tlv_flag - ucode API flags 71 * enum iwl_ucode_tlv_flag - ucode API flags
70 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously 72 * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
@@ -88,6 +90,7 @@
88 * P2P client interfaces simultaneously if they are in different bindings. 90 * P2P client interfaces simultaneously if they are in different bindings.
89 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and 91 * @IWL_UCODE_TLV_FLAGS_P2P_BSS_PS_SCM: support power save on BSS station and
90 * P2P client interfaces simultaneously if they are in same bindings. 92 * P2P client interfaces simultaneously if they are in same bindings.
93 * @IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT: General support for uAPSD
91 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save 94 * @IWL_UCODE_TLV_FLAGS_P2P_PS_UAPSD: P2P client supports uAPSD power save
92 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering. 95 * @IWL_UCODE_TLV_FLAGS_BCAST_FILTERING: uCode supports broadcast filtering.
93 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients 96 * @IWL_UCODE_TLV_FLAGS_GO_UAPSD: AP/GO interfaces support uAPSD clients
@@ -117,11 +120,19 @@ enum iwl_ucode_tlv_flag {
117/** 120/**
118 * enum iwl_ucode_tlv_api - ucode api 121 * enum iwl_ucode_tlv_api - ucode api
119 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field. 122 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
123 * @IWL_UCODE_TLV_CAPA_EXTENDED_BEACON: Support Extended beacon notification
124 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
120 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. 125 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
126 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
127 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
121 */ 128 */
122enum iwl_ucode_tlv_api { 129enum iwl_ucode_tlv_api {
123 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), 130 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
131 IWL_UCODE_TLV_CAPA_EXTENDED_BEACON = BIT(1),
132 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
124 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), 133 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
134 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
135 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
125}; 136};
126 137
127/** 138/**
@@ -178,6 +189,7 @@ enum iwl_ucode_sec {
178 189
179struct iwl_ucode_capabilities { 190struct iwl_ucode_capabilities {
180 u32 max_probe_length; 191 u32 max_probe_length;
192 u32 n_scan_channels;
181 u32 standard_phy_calibration_size; 193 u32 standard_phy_calibration_size;
182 u32 flags; 194 u32 flags;
183 u32 api[IWL_API_ARRAY_SIZE]; 195 u32 api[IWL_API_ARRAY_SIZE];
@@ -311,6 +323,7 @@ struct iwl_fw {
311 bool mvm_fw; 323 bool mvm_fw;
312 324
313 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS]; 325 struct ieee80211_cipher_scheme cs[IWL_UCODE_MAX_CS];
326 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
314}; 327};
315 328
316#endif /* __iwl_fw_h__ */ 329#endif /* __iwl_fw_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d051857729ab..f2d39cb011fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
103 * @power_level: power level, default = 1 103 * @power_level: power level, default = 1
104 * @debug_level: levels are IWL_DL_* 104 * @debug_level: levels are IWL_DL_*
105 * @ant_coupling: antenna coupling in dB, default = 0 105 * @ant_coupling: antenna coupling in dB, default = 0
106 * @fw_monitor: allow to use firmware monitor
106 */ 107 */
107struct iwl_mod_params { 108struct iwl_mod_params {
108 int sw_crypto; 109 int sw_crypto;
@@ -120,6 +121,7 @@ struct iwl_mod_params {
120 int ant_coupling; 121 int ant_coupling;
121 char *nvm_file; 122 char *nvm_file;
122 bool uapsd_disable; 123 bool uapsd_disable;
124 bool fw_monitor;
123}; 125};
124 126
125#endif /* #__iwl_modparams_h__ */ 127#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 85eee79c495c..018af2957d3b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -63,6 +63,7 @@
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include <linux/etherdevice.h> 65#include <linux/etherdevice.h>
66#include <linux/pci.h>
66#include "iwl-drv.h" 67#include "iwl-drv.h"
67#include "iwl-modparams.h" 68#include "iwl-modparams.h"
68#include "iwl-nvm-parse.h" 69#include "iwl-nvm-parse.h"
@@ -87,8 +88,10 @@ enum wkp_nvm_offsets {
87 88
88enum family_8000_nvm_offsets { 89enum family_8000_nvm_offsets {
89 /* NVM HW-Section offset (in words) definitions */ 90 /* NVM HW-Section offset (in words) definitions */
90 HW_ADDR0_FAMILY_8000 = 0x12, 91 HW_ADDR0_WFPM_FAMILY_8000 = 0x12,
91 HW_ADDR1_FAMILY_8000 = 0x16, 92 HW_ADDR1_WFPM_FAMILY_8000 = 0x16,
93 HW_ADDR0_PCIE_FAMILY_8000 = 0x8A,
94 HW_ADDR1_PCIE_FAMILY_8000 = 0x8E,
92 MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1, 95 MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
93 96
94 /* NVM SW-Section offset (in words) definitions */ 97 /* NVM SW-Section offset (in words) definitions */
@@ -174,7 +177,9 @@ static struct ieee80211_rate iwl_cfg80211_rates[] = {
174 * @NVM_CHANNEL_IBSS: usable as an IBSS channel 177 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
175 * @NVM_CHANNEL_ACTIVE: active scanning allowed 178 * @NVM_CHANNEL_ACTIVE: active scanning allowed
176 * @NVM_CHANNEL_RADAR: radar detection required 179 * @NVM_CHANNEL_RADAR: radar detection required
177 * @NVM_CHANNEL_DFS: dynamic freq selection candidate 180 * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
181 * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
182 * on same channel on 2.4 or same UNII band on 5.2
178 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?) 183 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
179 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?) 184 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
180 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?) 185 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
@@ -185,7 +190,8 @@ enum iwl_nvm_channel_flags {
185 NVM_CHANNEL_IBSS = BIT(1), 190 NVM_CHANNEL_IBSS = BIT(1),
186 NVM_CHANNEL_ACTIVE = BIT(3), 191 NVM_CHANNEL_ACTIVE = BIT(3),
187 NVM_CHANNEL_RADAR = BIT(4), 192 NVM_CHANNEL_RADAR = BIT(4),
188 NVM_CHANNEL_DFS = BIT(7), 193 NVM_CHANNEL_INDOOR_ONLY = BIT(5),
194 NVM_CHANNEL_GO_CONCURRENT = BIT(6),
189 NVM_CHANNEL_WIDE = BIT(8), 195 NVM_CHANNEL_WIDE = BIT(8),
190 NVM_CHANNEL_40MHZ = BIT(9), 196 NVM_CHANNEL_40MHZ = BIT(9),
191 NVM_CHANNEL_80MHZ = BIT(10), 197 NVM_CHANNEL_80MHZ = BIT(10),
@@ -273,6 +279,16 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
273 if (ch_flags & NVM_CHANNEL_RADAR) 279 if (ch_flags & NVM_CHANNEL_RADAR)
274 channel->flags |= IEEE80211_CHAN_RADAR; 280 channel->flags |= IEEE80211_CHAN_RADAR;
275 281
282 if (ch_flags & NVM_CHANNEL_INDOOR_ONLY)
283 channel->flags |= IEEE80211_CHAN_INDOOR_ONLY;
284
285 /* Set the GO concurrent flag only in case that NO_IR is set.
286 * Otherwise it is meaningless
287 */
288 if ((ch_flags & NVM_CHANNEL_GO_CONCURRENT) &&
289 (channel->flags & IEEE80211_CHAN_NO_IR))
290 channel->flags |= IEEE80211_CHAN_GO_CONCURRENT;
291
276 /* Initialize regulatory-based run-time data */ 292 /* Initialize regulatory-based run-time data */
277 293
278 /* 294 /*
@@ -282,7 +298,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
282 channel->max_power = DEFAULT_MAX_TX_POWER; 298 channel->max_power = DEFAULT_MAX_TX_POWER;
283 is_5ghz = channel->band == IEEE80211_BAND_5GHZ; 299 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
284 IWL_DEBUG_EEPROM(dev, 300 IWL_DEBUG_EEPROM(dev,
285 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", 301 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
286 channel->hw_value, 302 channel->hw_value,
287 is_5ghz ? "5.2" : "2.4", 303 is_5ghz ? "5.2" : "2.4",
288 CHECK_AND_PRINT_I(VALID), 304 CHECK_AND_PRINT_I(VALID),
@@ -290,7 +306,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
290 CHECK_AND_PRINT_I(ACTIVE), 306 CHECK_AND_PRINT_I(ACTIVE),
291 CHECK_AND_PRINT_I(RADAR), 307 CHECK_AND_PRINT_I(RADAR),
292 CHECK_AND_PRINT_I(WIDE), 308 CHECK_AND_PRINT_I(WIDE),
293 CHECK_AND_PRINT_I(DFS), 309 CHECK_AND_PRINT_I(INDOOR_ONLY),
310 CHECK_AND_PRINT_I(GO_CONCURRENT),
294 ch_flags, 311 ch_flags,
295 channel->max_power, 312 channel->max_power,
296 ((ch_flags & NVM_CHANNEL_IBSS) && 313 ((ch_flags & NVM_CHANNEL_IBSS) &&
@@ -462,7 +479,8 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
462 data->hw_addr[5] = hw_addr[4]; 479 data->hw_addr[5] = hw_addr[4];
463} 480}
464 481
465static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg, 482static void iwl_set_hw_address_family_8000(struct device *dev,
483 const struct iwl_cfg *cfg,
466 struct iwl_nvm_data *data, 484 struct iwl_nvm_data *data,
467 const __le16 *mac_override, 485 const __le16 *mac_override,
468 const __le16 *nvm_hw) 486 const __le16 *nvm_hw)
@@ -481,20 +499,64 @@ static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
481 data->hw_addr[4] = hw_addr[5]; 499 data->hw_addr[4] = hw_addr[5];
482 data->hw_addr[5] = hw_addr[4]; 500 data->hw_addr[5] = hw_addr[4];
483 501
484 if (is_valid_ether_addr(hw_addr)) 502 if (is_valid_ether_addr(data->hw_addr))
485 return; 503 return;
504
505 IWL_ERR_DEV(dev,
506 "mac address from nvm override section is not valid\n");
486 } 507 }
487 508
488 /* take the MAC address from the OTP */ 509 if (nvm_hw) {
489 hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000); 510 /* read the MAC address from OTP */
490 data->hw_addr[0] = hw_addr[3]; 511 if (!dev_is_pci(dev) || (data->nvm_version < 0xE08)) {
491 data->hw_addr[1] = hw_addr[2]; 512 /* read the mac address from the WFPM location */
492 data->hw_addr[2] = hw_addr[1]; 513 hw_addr = (const u8 *)(nvm_hw +
493 data->hw_addr[3] = hw_addr[0]; 514 HW_ADDR0_WFPM_FAMILY_8000);
515 data->hw_addr[0] = hw_addr[3];
516 data->hw_addr[1] = hw_addr[2];
517 data->hw_addr[2] = hw_addr[1];
518 data->hw_addr[3] = hw_addr[0];
519
520 hw_addr = (const u8 *)(nvm_hw +
521 HW_ADDR1_WFPM_FAMILY_8000);
522 data->hw_addr[4] = hw_addr[1];
523 data->hw_addr[5] = hw_addr[0];
524 } else if ((data->nvm_version >= 0xE08) &&
525 (data->nvm_version < 0xE0B)) {
526 /* read "reverse order" from the PCIe location */
527 hw_addr = (const u8 *)(nvm_hw +
528 HW_ADDR0_PCIE_FAMILY_8000);
529 data->hw_addr[5] = hw_addr[2];
530 data->hw_addr[4] = hw_addr[1];
531 data->hw_addr[3] = hw_addr[0];
532
533 hw_addr = (const u8 *)(nvm_hw +
534 HW_ADDR1_PCIE_FAMILY_8000);
535 data->hw_addr[2] = hw_addr[3];
536 data->hw_addr[1] = hw_addr[2];
537 data->hw_addr[0] = hw_addr[1];
538 } else {
539 /* read from the PCIe location */
540 hw_addr = (const u8 *)(nvm_hw +
541 HW_ADDR0_PCIE_FAMILY_8000);
542 data->hw_addr[5] = hw_addr[0];
543 data->hw_addr[4] = hw_addr[1];
544 data->hw_addr[3] = hw_addr[2];
545
546 hw_addr = (const u8 *)(nvm_hw +
547 HW_ADDR1_PCIE_FAMILY_8000);
548 data->hw_addr[2] = hw_addr[1];
549 data->hw_addr[1] = hw_addr[2];
550 data->hw_addr[0] = hw_addr[3];
551 }
552 if (!is_valid_ether_addr(data->hw_addr))
553 IWL_ERR_DEV(dev,
554 "mac address from hw section is not valid\n");
555
556 return;
557 }
494 558
495 hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000); 559 IWL_ERR_DEV(dev, "mac address is not found\n");
496 data->hw_addr[4] = hw_addr[1];
497 data->hw_addr[5] = hw_addr[0];
498} 560}
499 561
500struct iwl_nvm_data * 562struct iwl_nvm_data *
@@ -556,7 +618,8 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
556 rx_chains); 618 rx_chains);
557 } else { 619 } else {
558 /* MAC address in family 8000 */ 620 /* MAC address in family 8000 */
559 iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw); 621 iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
622 nvm_hw);
560 623
561 iwl_init_sbands(dev, cfg, data, regulatory, 624 iwl_init_sbands(dev, cfg, data, regulatory,
562 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 625 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 4997e27672b3..47033a35a402 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -359,4 +359,10 @@ enum secure_load_status_reg {
359#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10) 359#define RXF_LD_FENCE_OFFSET_ADDR (0xa00c10)
360#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c) 360#define RXF_FIFO_RD_FENCE_ADDR (0xa00c0c)
361 361
362/* FW monitor */
363#define MON_BUFF_BASE_ADDR (0xa03c3c)
364#define MON_BUFF_END_ADDR (0xa03c40)
365#define MON_BUFF_WRPTR (0xa03c44)
366#define MON_BUFF_CYCLE_CNT (0xa03c48)
367
362#endif /* __iwl_prph_h__ */ 368#endif /* __iwl_prph_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index c30d7f64ec1e..a28235913c2c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_IWLMVM) += iwlmvm.o
2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o 2iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o coex.o 5iwlmvm-y += power.o coex.o coex_legacy.o
6iwlmvm-y += tt.o offloading.o 6iwlmvm-y += tt.o offloading.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o 8iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index c8c3b38228f0..8110fe00bf55 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -70,47 +70,8 @@
70#include "mvm.h" 70#include "mvm.h"
71#include "iwl-debug.h" 71#include "iwl-debug.h"
72 72
73#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
74 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
75 ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
76
77static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
78 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
79 BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
80 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
81 BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
82 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
83 BT_COEX_PRIO_TBL_PRIO_LOW, 0),
84 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
85 BT_COEX_PRIO_TBL_PRIO_LOW, 1),
86 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
87 BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
88 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
89 BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
90 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
91 BT_COEX_PRIO_TBL_DISABLED, 0),
92 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
93 BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
94 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
95 BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
96 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
97 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
98 0, 0, 0, 0, 0, 0,
99};
100
101#undef EVENT_PRIO_ANT
102
103#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
104#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
105#define BT_ANTENNA_COUPLING_THRESHOLD (30) 73#define BT_ANTENNA_COUPLING_THRESHOLD (30)
106 74
107static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
108{
109 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, 0,
110 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
111 &iwl_bt_prio_tbl);
112}
113
114const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { 75const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = {
115 [BT_KILL_MSK_DEFAULT] = 0xffff0000, 76 [BT_KILL_MSK_DEFAULT] = 0xffff0000,
116 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, 77 [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff,
@@ -519,6 +480,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
519 struct ieee80211_chanctx_conf *chanctx_conf; 480 struct ieee80211_chanctx_conf *chanctx_conf;
520 enum iwl_bt_coex_lut_type ret; 481 enum iwl_bt_coex_lut_type ret;
521 u16 phy_ctx_id; 482 u16 phy_ctx_id;
483 u32 primary_ch_phy_id, secondary_ch_phy_id;
522 484
523 /* 485 /*
524 * Checking that we hold mvm->mutex is a good idea, but the rate 486 * Checking that we hold mvm->mutex is a good idea, but the rate
@@ -535,7 +497,7 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
535 if (!chanctx_conf || 497 if (!chanctx_conf ||
536 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) { 498 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
537 rcu_read_unlock(); 499 rcu_read_unlock();
538 return BT_COEX_LOOSE_LUT; 500 return BT_COEX_INVALID_LUT;
539 } 501 }
540 502
541 ret = BT_COEX_TX_DIS_LUT; 503 ret = BT_COEX_TX_DIS_LUT;
@@ -546,10 +508,13 @@ iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
546 } 508 }
547 509
548 phy_ctx_id = *((u16 *)chanctx_conf->drv_priv); 510 phy_ctx_id = *((u16 *)chanctx_conf->drv_priv);
511 primary_ch_phy_id = le32_to_cpu(mvm->last_bt_ci_cmd.primary_ch_phy_id);
512 secondary_ch_phy_id =
513 le32_to_cpu(mvm->last_bt_ci_cmd.secondary_ch_phy_id);
549 514
550 if (mvm->last_bt_ci_cmd.primary_ch_phy_id == phy_ctx_id) 515 if (primary_ch_phy_id == phy_ctx_id)
551 ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut); 516 ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut);
552 else if (mvm->last_bt_ci_cmd.secondary_ch_phy_id == phy_ctx_id) 517 else if (secondary_ch_phy_id == phy_ctx_id)
553 ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut); 518 ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut);
554 /* else - default = TX TX disallowed */ 519 /* else - default = TX TX disallowed */
555 520
@@ -567,59 +532,63 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
567 .dataflags = { IWL_HCMD_DFL_NOCOPY, }, 532 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
568 }; 533 };
569 int ret; 534 int ret;
570 u32 flags; 535 u32 mode;
571 536
572 ret = iwl_send_bt_prio_tbl(mvm); 537 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
573 if (ret) 538 return iwl_send_bt_init_conf_old(mvm);
574 return ret;
575 539
576 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL); 540 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
577 if (!bt_cmd) 541 if (!bt_cmd)
578 return -ENOMEM; 542 return -ENOMEM;
579 cmd.data[0] = bt_cmd; 543 cmd.data[0] = bt_cmd;
580 544
581 bt_cmd->max_kill = 5; 545 lockdep_assert_held(&mvm->mutex);
582 bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
583 bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
584 bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
585 bt_cmd->bt4_tx_rx_max_freq0 = 15;
586 bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
587 bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
588
589 flags = iwlwifi_mod_params.bt_coex_active ?
590 BT_COEX_NW : BT_COEX_DISABLE;
591 bt_cmd->flags = cpu_to_le32(flags);
592
593 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE |
594 BT_VALID_BT_PRIO_BOOST |
595 BT_VALID_MAX_KILL |
596 BT_VALID_3W_TMRS |
597 BT_VALID_KILL_ACK |
598 BT_VALID_KILL_CTS |
599 BT_VALID_REDUCED_TX_POWER |
600 BT_VALID_LUT |
601 BT_VALID_WIFI_RX_SW_PRIO_BOOST |
602 BT_VALID_WIFI_TX_SW_PRIO_BOOST |
603 BT_VALID_ANT_ISOLATION |
604 BT_VALID_ANT_ISOLATION_THRS |
605 BT_VALID_TXTX_DELTA_FREQ_THRS |
606 BT_VALID_TXRX_MAX_FREQ_0 |
607 BT_VALID_SYNC_TO_SCO);
608 546
609 if (IWL_MVM_BT_COEX_SYNC2SCO) 547 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) {
610 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); 548 u32 mode;
611 549
612 if (IWL_MVM_BT_COEX_CORUNNING) { 550 switch (mvm->bt_force_ant_mode) {
613 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 | 551 case BT_FORCE_ANT_BT:
614 BT_VALID_CORUN_LUT_40); 552 mode = BT_COEX_BT;
615 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING); 553 break;
554 case BT_FORCE_ANT_WIFI:
555 mode = BT_COEX_WIFI;
556 break;
557 default:
558 WARN_ON(1);
559 mode = 0;
560 }
561
562 bt_cmd->mode = cpu_to_le32(mode);
563 goto send_cmd;
616 } 564 }
617 565
566 bt_cmd->max_kill = cpu_to_le32(5);
567 bt_cmd->bt4_antenna_isolation_thr =
568 cpu_to_le32(BT_ANTENNA_COUPLING_THRESHOLD);
569 bt_cmd->bt4_tx_tx_delta_freq_thr = cpu_to_le32(15);
570 bt_cmd->bt4_tx_rx_max_freq0 = cpu_to_le32(15);
571 bt_cmd->override_primary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
572 bt_cmd->override_secondary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
573
574 mode = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE;
575 bt_cmd->mode = cpu_to_le32(mode);
576
577 if (IWL_MVM_BT_COEX_SYNC2SCO)
578 bt_cmd->enabled_modules |=
579 cpu_to_le32(BT_COEX_SYNC2SCO_ENABLED);
580
581 if (IWL_MVM_BT_COEX_CORUNNING)
582 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_CORUN_ENABLED);
583
618 if (IWL_MVM_BT_COEX_MPLUT) { 584 if (IWL_MVM_BT_COEX_MPLUT) {
619 bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT); 585 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_MPLUT_ENABLED);
620 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT); 586 bt_cmd->enabled_modules |=
587 cpu_to_le32(BT_COEX_MPLUT_BOOST_ENABLED);
621 } 588 }
622 589
590 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_HIGH_BAND_RET);
591
623 if (mvm->cfg->bt_shared_single_ant) 592 if (mvm->cfg->bt_shared_single_ant)
624 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, 593 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
625 sizeof(iwl_single_shared_ant)); 594 sizeof(iwl_single_shared_ant));
@@ -627,21 +596,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
627 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup, 596 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
628 sizeof(iwl_combined_lookup)); 597 sizeof(iwl_combined_lookup));
629 598
630 /* Take first Co-running block LUT to get started */ 599 memcpy(&bt_cmd->mplut_prio_boost, iwl_bt_prio_boost,
631 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[0].lut20,
632 sizeof(bt_cmd->bt4_corun_lut20));
633 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[0].lut20,
634 sizeof(bt_cmd->bt4_corun_lut40));
635
636 memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
637 sizeof(iwl_bt_prio_boost)); 600 sizeof(iwl_bt_prio_boost));
638 memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut, 601 memcpy(&bt_cmd->multiprio_lut, iwl_bt_mprio_lut,
639 sizeof(iwl_bt_mprio_lut)); 602 sizeof(iwl_bt_mprio_lut));
640 bt_cmd->kill_ack_msk =
641 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
642 bt_cmd->kill_cts_msk =
643 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
644 603
604send_cmd:
645 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); 605 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
646 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd)); 606 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
647 607
@@ -651,19 +611,12 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
651 return ret; 611 return ret;
652} 612}
653 613
654static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, 614static int iwl_mvm_bt_udpate_sw_boost(struct iwl_mvm *mvm,
655 bool reduced_tx_power) 615 bool reduced_tx_power)
656{ 616{
657 enum iwl_bt_kill_msk bt_kill_msk; 617 enum iwl_bt_kill_msk bt_kill_msk;
658 struct iwl_bt_coex_cmd *bt_cmd; 618 struct iwl_bt_coex_sw_boost_update_cmd cmd = {};
659 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; 619 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
660 struct iwl_host_cmd cmd = {
661 .id = BT_CONFIG,
662 .data[0] = &bt_cmd,
663 .len = { sizeof(*bt_cmd), },
664 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
665 };
666 int ret = 0;
667 620
668 lockdep_assert_held(&mvm->mutex); 621 lockdep_assert_held(&mvm->mutex);
669 622
@@ -693,40 +646,30 @@ static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
693 646
694 mvm->bt_kill_msk = bt_kill_msk; 647 mvm->bt_kill_msk = bt_kill_msk;
695 648
696 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL); 649 cmd.boost_values[0].kill_ack_msk =
697 if (!bt_cmd) 650 cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
698 return -ENOMEM; 651 cmd.boost_values[0].kill_cts_msk =
699 cmd.data[0] = bt_cmd; 652 cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
700 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
701 653
702 bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); 654 cmd.boost_values[1].kill_ack_msk = cmd.boost_values[0].kill_ack_msk;
703 bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); 655 cmd.boost_values[2].kill_cts_msk = cmd.boost_values[0].kill_cts_msk;
704 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE | 656 cmd.boost_values[1].kill_ack_msk = cmd.boost_values[0].kill_ack_msk;
705 BT_VALID_KILL_ACK | 657 cmd.boost_values[2].kill_cts_msk = cmd.boost_values[0].kill_cts_msk;
706 BT_VALID_KILL_CTS);
707 658
708 IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n", 659 IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n",
709 iwl_bt_ack_kill_msk[bt_kill_msk], 660 iwl_bt_ack_kill_msk[bt_kill_msk],
710 iwl_bt_cts_kill_msk[bt_kill_msk]); 661 iwl_bt_cts_kill_msk[bt_kill_msk]);
711 662
712 ret = iwl_mvm_send_cmd(mvm, &cmd); 663 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_SW_BOOST, 0,
713 664 sizeof(cmd), &cmd);
714 kfree(bt_cmd);
715 return ret;
716} 665}
717 666
718static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, 667static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
719 bool enable) 668 bool enable)
720{ 669{
721 struct iwl_bt_coex_cmd *bt_cmd; 670 struct iwl_bt_coex_reduced_txp_update_cmd cmd = {};
722 /* Send ASYNC since this can be sent from an atomic context */
723 struct iwl_host_cmd cmd = {
724 .id = BT_CONFIG,
725 .len = { sizeof(*bt_cmd), },
726 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
727 .flags = CMD_ASYNC,
728 };
729 struct iwl_mvm_sta *mvmsta; 671 struct iwl_mvm_sta *mvmsta;
672 u32 value;
730 int ret; 673 int ret;
731 674
732 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); 675 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
@@ -737,27 +680,20 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
737 if (mvmsta->bt_reduced_txpower == enable) 680 if (mvmsta->bt_reduced_txpower == enable)
738 return 0; 681 return 0;
739 682
740 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC); 683 value = mvmsta->sta_id;
741 if (!bt_cmd)
742 return -ENOMEM;
743 cmd.data[0] = bt_cmd;
744 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
745
746 bt_cmd->valid_bit_msk =
747 cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER);
748 bt_cmd->bt_reduced_tx_power = sta_id;
749 684
750 if (enable) 685 if (enable)
751 bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT; 686 value |= BT_REDUCED_TX_POWER_BIT;
752 687
753 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n", 688 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
754 enable ? "en" : "dis", sta_id); 689 enable ? "en" : "dis", sta_id);
755 690
691 cmd.reduced_txp = cpu_to_le32(value);
756 mvmsta->bt_reduced_txpower = enable; 692 mvmsta->bt_reduced_txpower = enable;
757 693
758 ret = iwl_mvm_send_cmd(mvm, &cmd); 694 ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_REDUCED_TXP, CMD_ASYNC,
695 sizeof(cmd), &cmd);
759 696
760 kfree(bt_cmd);
761 return ret; 697 return ret;
762} 698}
763 699
@@ -780,9 +716,9 @@ void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
780 716
781 mvmvif->bf_data.last_bt_coex_event = rssi; 717 mvmvif->bf_data.last_bt_coex_event = rssi;
782 mvmvif->bf_data.bt_coex_max_thold = 718 mvmvif->bf_data.bt_coex_max_thold =
783 enable ? BT_ENABLE_REDUCED_TXPOWER_THRESHOLD : 0; 719 enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0;
784 mvmvif->bf_data.bt_coex_min_thold = 720 mvmvif->bf_data.bt_coex_min_thold =
785 enable ? BT_DISABLE_REDUCED_TXPOWER_THRESHOLD : 0; 721 enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0;
786} 722}
787 723
788/* must be called under rcu_read_lock */ 724/* must be called under rcu_read_lock */
@@ -851,10 +787,13 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
851 if (!vif->bss_conf.assoc) 787 if (!vif->bss_conf.assoc)
852 smps_mode = IEEE80211_SMPS_AUTOMATIC; 788 smps_mode = IEEE80211_SMPS_AUTOMATIC;
853 789
790 if (IWL_COEX_IS_RRC_ON(mvm->last_bt_notif.ttc_rrc_status,
791 mvmvif->phy_ctxt->id))
792 smps_mode = IEEE80211_SMPS_AUTOMATIC;
793
854 IWL_DEBUG_COEX(data->mvm, 794 IWL_DEBUG_COEX(data->mvm,
855 "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n", 795 "mac %d: bt_activity_grading %d smps_req %d\n",
856 mvmvif->id, data->notif->bt_status, bt_activity_grading, 796 mvmvif->id, bt_activity_grading, smps_mode);
857 smps_mode);
858 797
859 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode); 798 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
860 799
@@ -906,7 +845,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
906 */ 845 */
907 if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT || 846 if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
908 mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc || 847 mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc ||
909 !data->notif->bt_status) { 848 le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF) {
910 data->reduced_tx_power = false; 849 data->reduced_tx_power = false;
911 iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false); 850 iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
912 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); 851 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
@@ -919,7 +858,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
919 /* if the RSSI isn't valid, fake it is very low */ 858 /* if the RSSI isn't valid, fake it is very low */
920 if (!ave_rssi) 859 if (!ave_rssi)
921 ave_rssi = -100; 860 ave_rssi = -100;
922 if (ave_rssi > BT_ENABLE_REDUCED_TXPOWER_THRESHOLD) { 861 if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
923 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true)) 862 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
924 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); 863 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
925 864
@@ -930,7 +869,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
930 * the iteration, if one interface's rssi isn't good enough, 869 * the iteration, if one interface's rssi isn't good enough,
931 * bt_kill_msk will be set to default values. 870 * bt_kill_msk will be set to default values.
932 */ 871 */
933 } else if (ave_rssi < BT_DISABLE_REDUCED_TXPOWER_THRESHOLD) { 872 } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
934 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) 873 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
935 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); 874 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
936 875
@@ -955,6 +894,10 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
955 struct iwl_bt_coex_ci_cmd cmd = {}; 894 struct iwl_bt_coex_ci_cmd cmd = {};
956 u8 ci_bw_idx; 895 u8 ci_bw_idx;
957 896
897 /* Ignore updates if we are in force mode */
898 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
899 return;
900
958 rcu_read_lock(); 901 rcu_read_lock();
959 ieee80211_iterate_active_interfaces_atomic( 902 ieee80211_iterate_active_interfaces_atomic(
960 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 903 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
@@ -969,9 +912,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
969 912
970 if (chan->def.width < NL80211_CHAN_WIDTH_40) { 913 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
971 ci_bw_idx = 0; 914 ci_bw_idx = 0;
972 cmd.co_run_bw_primary = 0;
973 } else { 915 } else {
974 cmd.co_run_bw_primary = 1;
975 if (chan->def.center_freq1 > 916 if (chan->def.center_freq1 >
976 chan->def.chan->center_freq) 917 chan->def.chan->center_freq)
977 ci_bw_idx = 2; 918 ci_bw_idx = 2;
@@ -981,7 +922,8 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
981 922
982 cmd.bt_primary_ci = 923 cmd.bt_primary_ci =
983 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; 924 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
984 cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv); 925 cmd.primary_ch_phy_id =
926 cpu_to_le32(*((u16 *)data.primary->drv_priv));
985 } 927 }
986 928
987 if (data.secondary) { 929 if (data.secondary) {
@@ -993,9 +935,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
993 935
994 if (chan->def.width < NL80211_CHAN_WIDTH_40) { 936 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
995 ci_bw_idx = 0; 937 ci_bw_idx = 0;
996 cmd.co_run_bw_secondary = 0;
997 } else { 938 } else {
998 cmd.co_run_bw_secondary = 1;
999 if (chan->def.center_freq1 > 939 if (chan->def.center_freq1 >
1000 chan->def.chan->center_freq) 940 chan->def.chan->center_freq)
1001 ci_bw_idx = 2; 941 ci_bw_idx = 2;
@@ -1005,7 +945,8 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
1005 945
1006 cmd.bt_secondary_ci = 946 cmd.bt_secondary_ci =
1007 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; 947 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
1008 cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv); 948 cmd.secondary_ch_phy_id =
949 cpu_to_le32(*((u16 *)data.secondary->drv_priv));
1009 } 950 }
1010 951
1011 rcu_read_unlock(); 952 rcu_read_unlock();
@@ -1025,7 +966,7 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
1025 */ 966 */
1026 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; 967 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
1027 968
1028 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) 969 if (iwl_mvm_bt_udpate_sw_boost(mvm, data.reduced_tx_power))
1029 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); 970 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
1030} 971}
1031 972
@@ -1036,11 +977,10 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
1036 struct iwl_rx_packet *pkt = rxb_addr(rxb); 977 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1037 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; 978 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
1038 979
980 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
981 return iwl_mvm_rx_bt_coex_notif_old(mvm, rxb, dev_cmd);
1039 982
1040 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); 983 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
1041 IWL_DEBUG_COEX(mvm, "\tBT status: %s\n",
1042 notif->bt_status ? "ON" : "OFF");
1043 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
1044 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); 984 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
1045 IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n", 985 IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
1046 le32_to_cpu(notif->primary_ch_lut)); 986 le32_to_cpu(notif->primary_ch_lut));
@@ -1048,8 +988,6 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
1048 le32_to_cpu(notif->secondary_ch_lut)); 988 le32_to_cpu(notif->secondary_ch_lut));
1049 IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n", 989 IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
1050 le32_to_cpu(notif->bt_activity_grading)); 990 le32_to_cpu(notif->bt_activity_grading));
1051 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
1052 notif->bt_agg_traffic_load);
1053 991
1054 /* remember this notification for future use: rssi fluctuations */ 992 /* remember this notification for future use: rssi fluctuations */
1055 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); 993 memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif));
@@ -1119,8 +1057,17 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1119 }; 1057 };
1120 int ret; 1058 int ret;
1121 1059
1060 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
1061 iwl_mvm_bt_rssi_event_old(mvm, vif, rssi_event);
1062 return;
1063 }
1064
1122 lockdep_assert_held(&mvm->mutex); 1065 lockdep_assert_held(&mvm->mutex);
1123 1066
1067 /* Ignore updates if we are in force mode */
1068 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
1069 return;
1070
1124 /* 1071 /*
1125 * Rssi update while not associated - can happen since the statistics 1072 * Rssi update while not associated - can happen since the statistics
1126 * are handled asynchronously 1073 * are handled asynchronously
@@ -1129,7 +1076,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1129 return; 1076 return;
1130 1077
1131 /* No BT - reports should be disabled */ 1078 /* No BT - reports should be disabled */
1132 if (!mvm->last_bt_notif.bt_status) 1079 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF)
1133 return; 1080 return;
1134 1081
1135 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, 1082 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
@@ -1160,7 +1107,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1160 */ 1107 */
1161 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces; 1108 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
1162 1109
1163 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) 1110 if (iwl_mvm_bt_udpate_sw_boost(mvm, data.reduced_tx_power))
1164 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); 1111 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
1165} 1112}
1166 1113
@@ -1171,15 +1118,23 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
1171 struct ieee80211_sta *sta) 1118 struct ieee80211_sta *sta)
1172{ 1119{
1173 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1120 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1121 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
1122 struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
1174 enum iwl_bt_coex_lut_type lut_type; 1123 enum iwl_bt_coex_lut_type lut_type;
1175 1124
1125 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1126 return iwl_mvm_coex_agg_time_limit_old(mvm, sta);
1127
1128 if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
1129 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1130
1176 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 1131 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
1177 BT_HIGH_TRAFFIC) 1132 BT_HIGH_TRAFFIC)
1178 return LINK_QUAL_AGG_TIME_LIMIT_DEF; 1133 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1179 1134
1180 lut_type = iwl_get_coex_type(mvm, mvmsta->vif); 1135 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
1181 1136
1182 if (lut_type == BT_COEX_LOOSE_LUT) 1137 if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT)
1183 return LINK_QUAL_AGG_TIME_LIMIT_DEF; 1138 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1184 1139
1185 /* tight coex, high bt traffic, reduce AGG time limit */ 1140 /* tight coex, high bt traffic, reduce AGG time limit */
@@ -1190,18 +1145,37 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
1190 struct ieee80211_sta *sta) 1145 struct ieee80211_sta *sta)
1191{ 1146{
1192 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 1147 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1148 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
1149 struct iwl_mvm_phy_ctxt *phy_ctxt = mvmvif->phy_ctxt;
1150 enum iwl_bt_coex_lut_type lut_type;
1151
1152 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1153 return iwl_mvm_coex_agg_time_limit_old(mvm, sta);
1154
1155 if (IWL_COEX_IS_TTC_ON(mvm->last_bt_notif.ttc_rrc_status, phy_ctxt->id))
1156 return true;
1193 1157
1194 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < 1158 if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) <
1195 BT_HIGH_TRAFFIC) 1159 BT_HIGH_TRAFFIC)
1196 return true; 1160 return true;
1197 1161
1198 /* 1162 /*
1199 * In Tight, BT can't Rx while we Tx, so use both antennas since BT is 1163 * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
1200 * already killed. 1164 * since BT is already killed.
1201 * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we 1165 * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
1202 * Tx. 1166 * we Tx.
1167 * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO.
1203 */ 1168 */
1204 return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT; 1169 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
1170 return lut_type != BT_COEX_LOOSE_LUT;
1171}
1172
1173bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm)
1174{
1175 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1176 return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm);
1177
1178 return le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) == BT_OFF;
1205} 1179}
1206 1180
1207bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, 1181bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
@@ -1209,6 +1183,9 @@ bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
1209{ 1183{
1210 u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); 1184 u32 bt_activity = le32_to_cpu(mvm->last_bt_notif.bt_activity_grading);
1211 1185
1186 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1187 return iwl_mvm_bt_coex_is_tpc_allowed_old(mvm, band);
1188
1212 if (band != IEEE80211_BAND_2GHZ) 1189 if (band != IEEE80211_BAND_2GHZ)
1213 return false; 1190 return false;
1214 1191
@@ -1249,6 +1226,11 @@ u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
1249 1226
1250void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm) 1227void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm)
1251{ 1228{
1229 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
1230 iwl_mvm_bt_coex_vif_change_old(mvm);
1231 return;
1232 }
1233
1252 iwl_mvm_bt_coex_notif_handle(mvm); 1234 iwl_mvm_bt_coex_notif_handle(mvm);
1253} 1235}
1254 1236
@@ -1258,22 +1240,22 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1258{ 1240{
1259 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1241 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1260 u32 ant_isolation = le32_to_cpup((void *)pkt->data); 1242 u32 ant_isolation = le32_to_cpup((void *)pkt->data);
1243 struct iwl_bt_coex_corun_lut_update_cmd cmd = {};
1261 u8 __maybe_unused lower_bound, upper_bound; 1244 u8 __maybe_unused lower_bound, upper_bound;
1262 int ret;
1263 u8 lut; 1245 u8 lut;
1264 1246
1265 struct iwl_bt_coex_cmd *bt_cmd; 1247 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1266 struct iwl_host_cmd cmd = { 1248 return iwl_mvm_rx_ant_coupling_notif_old(mvm, rxb, dev_cmd);
1267 .id = BT_CONFIG,
1268 .len = { sizeof(*bt_cmd), },
1269 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1270 };
1271 1249
1272 if (!IWL_MVM_BT_COEX_CORUNNING) 1250 if (!IWL_MVM_BT_COEX_CORUNNING)
1273 return 0; 1251 return 0;
1274 1252
1275 lockdep_assert_held(&mvm->mutex); 1253 lockdep_assert_held(&mvm->mutex);
1276 1254
1255 /* Ignore updates if we are in force mode */
1256 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
1257 return 0;
1258
1277 if (ant_isolation == mvm->last_ant_isol) 1259 if (ant_isolation == mvm->last_ant_isol)
1278 return 0; 1260 return 0;
1279 1261
@@ -1298,25 +1280,13 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
1298 1280
1299 mvm->last_corun_lut = lut; 1281 mvm->last_corun_lut = lut;
1300 1282
1301 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
1302 if (!bt_cmd)
1303 return 0;
1304 cmd.data[0] = bt_cmd;
1305
1306 bt_cmd->flags = cpu_to_le32(BT_COEX_NW);
1307 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
1308 BT_VALID_CORUN_LUT_20 |
1309 BT_VALID_CORUN_LUT_40);
1310
1311 /* For the moment, use the same LUT for 20GHz and 40GHz */ 1283 /* For the moment, use the same LUT for 20GHz and 40GHz */
1312 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[lut].lut20, 1284 memcpy(&cmd.corun_lut20, antenna_coupling_ranges[lut].lut20,
1313 sizeof(bt_cmd->bt4_corun_lut20)); 1285 sizeof(cmd.corun_lut20));
1314
1315 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
1316 sizeof(bt_cmd->bt4_corun_lut40));
1317 1286
1318 ret = iwl_mvm_send_cmd(mvm, &cmd); 1287 memcpy(&cmd.corun_lut40, antenna_coupling_ranges[lut].lut20,
1288 sizeof(cmd.corun_lut40));
1319 1289
1320 kfree(bt_cmd); 1290 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_CORUN_LUT, 0,
1321 return ret; 1291 sizeof(cmd), &cmd);
1322} 1292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
new file mode 100644
index 000000000000..ce50363d314b
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -0,0 +1,1332 @@
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) 2013 - 2014 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/ieee80211.h>
65#include <linux/etherdevice.h>
66#include <net/mac80211.h>
67
68#include "fw-api-coex.h"
69#include "iwl-modparams.h"
70#include "mvm.h"
71#include "iwl-debug.h"
72
73#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
74 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
75 ((_shrd_ant) << BT_COEX_PRIO_TBL_SHRD_ANT_POS))
76
77static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = {
78 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB1,
79 BT_COEX_PRIO_TBL_PRIO_BYPASS, 0),
80 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_INIT_CALIB2,
81 BT_COEX_PRIO_TBL_PRIO_BYPASS, 1),
82 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1,
83 BT_COEX_PRIO_TBL_PRIO_LOW, 0),
84 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2,
85 BT_COEX_PRIO_TBL_PRIO_LOW, 1),
86 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1,
87 BT_COEX_PRIO_TBL_PRIO_HIGH, 0),
88 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2,
89 BT_COEX_PRIO_TBL_PRIO_HIGH, 1),
90 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_DTIM,
91 BT_COEX_PRIO_TBL_DISABLED, 0),
92 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN52,
93 BT_COEX_PRIO_TBL_PRIO_COEX_OFF, 0),
94 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_SCAN24,
95 BT_COEX_PRIO_TBL_PRIO_COEX_ON, 0),
96 EVENT_PRIO_ANT(BT_COEX_PRIO_TBL_EVT_IDLE,
97 BT_COEX_PRIO_TBL_PRIO_COEX_IDLE, 0),
98 0, 0, 0, 0, 0, 0,
99};
100
101#undef EVENT_PRIO_ANT
102
103#define BT_ANTENNA_COUPLING_THRESHOLD (30)
104
105static int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm)
106{
107 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
108 return 0;
109
110 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, 0,
111 sizeof(struct iwl_bt_coex_prio_tbl_cmd),
112 &iwl_bt_prio_tbl);
113}
114
115static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = {
116 cpu_to_le32(0xf0f0f0f0), /* 50% */
117 cpu_to_le32(0xc0c0c0c0), /* 25% */
118 cpu_to_le32(0xfcfcfcfc), /* 75% */
119 cpu_to_le32(0xfefefefe), /* 87.5% */
120};
121
122static const __le32 iwl_single_shared_ant[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
123 {
124 cpu_to_le32(0x40000000),
125 cpu_to_le32(0x00000000),
126 cpu_to_le32(0x44000000),
127 cpu_to_le32(0x00000000),
128 cpu_to_le32(0x40000000),
129 cpu_to_le32(0x00000000),
130 cpu_to_le32(0x44000000),
131 cpu_to_le32(0x00000000),
132 cpu_to_le32(0xc0004000),
133 cpu_to_le32(0xf0005000),
134 cpu_to_le32(0xc0004000),
135 cpu_to_le32(0xf0005000),
136 },
137 {
138 cpu_to_le32(0x40000000),
139 cpu_to_le32(0x00000000),
140 cpu_to_le32(0x44000000),
141 cpu_to_le32(0x00000000),
142 cpu_to_le32(0x40000000),
143 cpu_to_le32(0x00000000),
144 cpu_to_le32(0x44000000),
145 cpu_to_le32(0x00000000),
146 cpu_to_le32(0xc0004000),
147 cpu_to_le32(0xf0005000),
148 cpu_to_le32(0xc0004000),
149 cpu_to_le32(0xf0005000),
150 },
151 {
152 cpu_to_le32(0x40000000),
153 cpu_to_le32(0x00000000),
154 cpu_to_le32(0x44000000),
155 cpu_to_le32(0x00000000),
156 cpu_to_le32(0x40000000),
157 cpu_to_le32(0x00000000),
158 cpu_to_le32(0x44000000),
159 cpu_to_le32(0x00000000),
160 cpu_to_le32(0xc0004000),
161 cpu_to_le32(0xf0005000),
162 cpu_to_le32(0xc0004000),
163 cpu_to_le32(0xf0005000),
164 },
165};
166
167static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
168 {
169 /* Tight */
170 cpu_to_le32(0xaaaaaaaa),
171 cpu_to_le32(0xaaaaaaaa),
172 cpu_to_le32(0xaeaaaaaa),
173 cpu_to_le32(0xaaaaaaaa),
174 cpu_to_le32(0xcc00ff28),
175 cpu_to_le32(0x0000aaaa),
176 cpu_to_le32(0xcc00aaaa),
177 cpu_to_le32(0x0000aaaa),
178 cpu_to_le32(0xc0004000),
179 cpu_to_le32(0x00004000),
180 cpu_to_le32(0xf0005000),
181 cpu_to_le32(0xf0005000),
182 },
183 {
184 /* Loose */
185 cpu_to_le32(0xaaaaaaaa),
186 cpu_to_le32(0xaaaaaaaa),
187 cpu_to_le32(0xaaaaaaaa),
188 cpu_to_le32(0xaaaaaaaa),
189 cpu_to_le32(0xcc00ff28),
190 cpu_to_le32(0x0000aaaa),
191 cpu_to_le32(0xcc00aaaa),
192 cpu_to_le32(0x0000aaaa),
193 cpu_to_le32(0x00000000),
194 cpu_to_le32(0x00000000),
195 cpu_to_le32(0xf0005000),
196 cpu_to_le32(0xf0005000),
197 },
198 {
199 /* Tx Tx disabled */
200 cpu_to_le32(0xaaaaaaaa),
201 cpu_to_le32(0xaaaaaaaa),
202 cpu_to_le32(0xeeaaaaaa),
203 cpu_to_le32(0xaaaaaaaa),
204 cpu_to_le32(0xcc00ff28),
205 cpu_to_le32(0x0000aaaa),
206 cpu_to_le32(0xcc00aaaa),
207 cpu_to_le32(0x0000aaaa),
208 cpu_to_le32(0xc0004000),
209 cpu_to_le32(0xc0004000),
210 cpu_to_le32(0xf0005000),
211 cpu_to_le32(0xf0005000),
212 },
213};
214
215/* 20MHz / 40MHz below / 40Mhz above*/
216static const __le64 iwl_ci_mask[][3] = {
217 /* dummy entry for channel 0 */
218 {cpu_to_le64(0), cpu_to_le64(0), cpu_to_le64(0)},
219 {
220 cpu_to_le64(0x0000001FFFULL),
221 cpu_to_le64(0x0ULL),
222 cpu_to_le64(0x00007FFFFFULL),
223 },
224 {
225 cpu_to_le64(0x000000FFFFULL),
226 cpu_to_le64(0x0ULL),
227 cpu_to_le64(0x0003FFFFFFULL),
228 },
229 {
230 cpu_to_le64(0x000003FFFCULL),
231 cpu_to_le64(0x0ULL),
232 cpu_to_le64(0x000FFFFFFCULL),
233 },
234 {
235 cpu_to_le64(0x00001FFFE0ULL),
236 cpu_to_le64(0x0ULL),
237 cpu_to_le64(0x007FFFFFE0ULL),
238 },
239 {
240 cpu_to_le64(0x00007FFF80ULL),
241 cpu_to_le64(0x00007FFFFFULL),
242 cpu_to_le64(0x01FFFFFF80ULL),
243 },
244 {
245 cpu_to_le64(0x0003FFFC00ULL),
246 cpu_to_le64(0x0003FFFFFFULL),
247 cpu_to_le64(0x0FFFFFFC00ULL),
248 },
249 {
250 cpu_to_le64(0x000FFFF000ULL),
251 cpu_to_le64(0x000FFFFFFCULL),
252 cpu_to_le64(0x3FFFFFF000ULL),
253 },
254 {
255 cpu_to_le64(0x007FFF8000ULL),
256 cpu_to_le64(0x007FFFFFE0ULL),
257 cpu_to_le64(0xFFFFFF8000ULL),
258 },
259 {
260 cpu_to_le64(0x01FFFE0000ULL),
261 cpu_to_le64(0x01FFFFFF80ULL),
262 cpu_to_le64(0xFFFFFE0000ULL),
263 },
264 {
265 cpu_to_le64(0x0FFFF00000ULL),
266 cpu_to_le64(0x0FFFFFFC00ULL),
267 cpu_to_le64(0x0ULL),
268 },
269 {
270 cpu_to_le64(0x3FFFC00000ULL),
271 cpu_to_le64(0x3FFFFFF000ULL),
272 cpu_to_le64(0x0)
273 },
274 {
275 cpu_to_le64(0xFFFE000000ULL),
276 cpu_to_le64(0xFFFFFF8000ULL),
277 cpu_to_le64(0x0)
278 },
279 {
280 cpu_to_le64(0xFFF8000000ULL),
281 cpu_to_le64(0xFFFFFE0000ULL),
282 cpu_to_le64(0x0)
283 },
284 {
285 cpu_to_le64(0xFFC0000000ULL),
286 cpu_to_le64(0x0ULL),
287 cpu_to_le64(0x0ULL)
288 },
289};
290
291static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = {
292 cpu_to_le32(0x28412201),
293 cpu_to_le32(0x11118451),
294};
295
296struct corunning_block_luts {
297 u8 range;
298 __le32 lut20[BT_COEX_CORUN_LUT_SIZE];
299};
300
301/*
302 * Ranges for the antenna coupling calibration / co-running block LUT:
303 * LUT0: [ 0, 12[
304 * LUT1: [12, 20[
305 * LUT2: [20, 21[
306 * LUT3: [21, 23[
307 * LUT4: [23, 27[
308 * LUT5: [27, 30[
309 * LUT6: [30, 32[
310 * LUT7: [32, 33[
311 * LUT8: [33, - [
312 */
313static const struct corunning_block_luts antenna_coupling_ranges[] = {
314 {
315 .range = 0,
316 .lut20 = {
317 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
318 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
319 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
320 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
321 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
322 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
323 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
324 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
325 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
326 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
327 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
328 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
329 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
330 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
331 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
332 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
333 },
334 },
335 {
336 .range = 12,
337 .lut20 = {
338 cpu_to_le32(0x00000001), cpu_to_le32(0x00000000),
339 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
340 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
341 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
342 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
343 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
344 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
345 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),
348 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
349 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
350 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
351 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
352 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
353 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
354 },
355 },
356 {
357 .range = 20,
358 .lut20 = {
359 cpu_to_le32(0x00000002), cpu_to_le32(0x00000000),
360 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
361 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
362 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
363 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
364 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
365 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
366 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),
369 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
370 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
371 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
372 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
373 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
374 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
375 },
376 },
377 {
378 .range = 21,
379 .lut20 = {
380 cpu_to_le32(0x00000003), cpu_to_le32(0x00000000),
381 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
382 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
383 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
384 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
385 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
386 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
387 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),
390 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
391 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
392 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
393 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
394 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
395 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
396 },
397 },
398 {
399 .range = 23,
400 .lut20 = {
401 cpu_to_le32(0x00000004), cpu_to_le32(0x00000000),
402 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
403 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
404 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
405 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
406 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
407 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
408 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),
411 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
412 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
413 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
414 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
415 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
416 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
417 },
418 },
419 {
420 .range = 27,
421 .lut20 = {
422 cpu_to_le32(0x00000005), cpu_to_le32(0x00000000),
423 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
424 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
425 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
426 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
427 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
428 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
429 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),
432 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
433 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
434 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
435 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
436 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
437 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
438 },
439 },
440 {
441 .range = 30,
442 .lut20 = {
443 cpu_to_le32(0x00000006), cpu_to_le32(0x00000000),
444 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
445 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
446 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
447 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
448 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
449 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
450 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),
453 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
454 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
455 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
456 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
457 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
458 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
459 },
460 },
461 {
462 .range = 32,
463 .lut20 = {
464 cpu_to_le32(0x00000007), cpu_to_le32(0x00000000),
465 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
466 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
467 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
468 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
469 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
470 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
471 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),
474 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
475 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
476 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
477 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
478 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
479 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
480 },
481 },
482 {
483 .range = 33,
484 .lut20 = {
485 cpu_to_le32(0x00000008), cpu_to_le32(0x00000000),
486 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
487 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
488 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
489 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
490 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
491 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
492 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),
495 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
496 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
497 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
498 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
499 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
500 cpu_to_le32(0x00000000), cpu_to_le32(0x00000000),
501 },
502 },
503};
504
505static enum iwl_bt_coex_lut_type
506iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif)
507{
508 struct ieee80211_chanctx_conf *chanctx_conf;
509 enum iwl_bt_coex_lut_type ret;
510 u16 phy_ctx_id;
511
512 /*
513 * Checking that we hold mvm->mutex is a good idea, but the rate
514 * control can't acquire the mutex since it runs in Tx path.
515 * So this is racy in that case, but in the worst case, the AMPDU
516 * size limit will be wrong for a short time which is not a big
517 * issue.
518 */
519
520 rcu_read_lock();
521
522 chanctx_conf = rcu_dereference(vif->chanctx_conf);
523
524 if (!chanctx_conf ||
525 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
526 rcu_read_unlock();
527 return BT_COEX_INVALID_LUT;
528 }
529
530 ret = BT_COEX_TX_DIS_LUT;
531
532 if (mvm->cfg->bt_shared_single_ant) {
533 rcu_read_unlock();
534 return ret;
535 }
536
537 phy_ctx_id = *((u16 *)chanctx_conf->drv_priv);
538
539 if (mvm->last_bt_ci_cmd_old.primary_ch_phy_id == phy_ctx_id)
540 ret = le32_to_cpu(mvm->last_bt_notif_old.primary_ch_lut);
541 else if (mvm->last_bt_ci_cmd_old.secondary_ch_phy_id == phy_ctx_id)
542 ret = le32_to_cpu(mvm->last_bt_notif_old.secondary_ch_lut);
543 /* else - default = TX TX disallowed */
544
545 rcu_read_unlock();
546
547 return ret;
548}
549
550int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
551{
552 struct iwl_bt_coex_cmd_old *bt_cmd;
553 struct iwl_host_cmd cmd = {
554 .id = BT_CONFIG,
555 .len = { sizeof(*bt_cmd), },
556 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
557 };
558 int ret;
559 u32 flags;
560
561 ret = iwl_send_bt_prio_tbl(mvm);
562 if (ret)
563 return ret;
564
565 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
566 if (!bt_cmd)
567 return -ENOMEM;
568 cmd.data[0] = bt_cmd;
569
570 lockdep_assert_held(&mvm->mutex);
571
572 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS)) {
573 switch (mvm->bt_force_ant_mode) {
574 case BT_FORCE_ANT_AUTO:
575 flags = BT_COEX_AUTO_OLD;
576 break;
577 case BT_FORCE_ANT_BT:
578 flags = BT_COEX_BT_OLD;
579 break;
580 case BT_FORCE_ANT_WIFI:
581 flags = BT_COEX_WIFI_OLD;
582 break;
583 default:
584 WARN_ON(1);
585 flags = 0;
586 }
587
588 bt_cmd->flags = cpu_to_le32(flags);
589 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE);
590 goto send_cmd;
591 }
592
593 bt_cmd->max_kill = 5;
594 bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD;
595 bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling;
596 bt_cmd->bt4_tx_tx_delta_freq_thr = 15;
597 bt_cmd->bt4_tx_rx_max_freq0 = 15;
598 bt_cmd->override_primary_lut = BT_COEX_INVALID_LUT;
599 bt_cmd->override_secondary_lut = BT_COEX_INVALID_LUT;
600
601 flags = iwlwifi_mod_params.bt_coex_active ?
602 BT_COEX_NW_OLD : BT_COEX_DISABLE_OLD;
603 bt_cmd->flags = cpu_to_le32(flags);
604
605 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE |
606 BT_VALID_BT_PRIO_BOOST |
607 BT_VALID_MAX_KILL |
608 BT_VALID_3W_TMRS |
609 BT_VALID_KILL_ACK |
610 BT_VALID_KILL_CTS |
611 BT_VALID_REDUCED_TX_POWER |
612 BT_VALID_LUT |
613 BT_VALID_WIFI_RX_SW_PRIO_BOOST |
614 BT_VALID_WIFI_TX_SW_PRIO_BOOST |
615 BT_VALID_ANT_ISOLATION |
616 BT_VALID_ANT_ISOLATION_THRS |
617 BT_VALID_TXTX_DELTA_FREQ_THRS |
618 BT_VALID_TXRX_MAX_FREQ_0 |
619 BT_VALID_SYNC_TO_SCO);
620
621 if (IWL_MVM_BT_COEX_SYNC2SCO)
622 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
623
624 if (IWL_MVM_BT_COEX_CORUNNING) {
625 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
626 BT_VALID_CORUN_LUT_40);
627 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
628 }
629
630 if (IWL_MVM_BT_COEX_MPLUT) {
631 bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
632 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
633 }
634
635 if (mvm->cfg->bt_shared_single_ant)
636 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
637 sizeof(iwl_single_shared_ant));
638 else
639 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
640 sizeof(iwl_combined_lookup));
641
642 /* Take first Co-running block LUT to get started */
643 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[0].lut20,
644 sizeof(bt_cmd->bt4_corun_lut20));
645 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[0].lut20,
646 sizeof(bt_cmd->bt4_corun_lut40));
647
648 memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost,
649 sizeof(iwl_bt_prio_boost));
650 memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut,
651 sizeof(iwl_bt_mprio_lut));
652 bt_cmd->kill_ack_msk =
653 cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]);
654 bt_cmd->kill_cts_msk =
655 cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]);
656
657send_cmd:
658 memset(&mvm->last_bt_notif_old, 0, sizeof(mvm->last_bt_notif_old));
659 memset(&mvm->last_bt_ci_cmd_old, 0, sizeof(mvm->last_bt_ci_cmd_old));
660
661 ret = iwl_mvm_send_cmd(mvm, &cmd);
662
663 kfree(bt_cmd);
664 return ret;
665}
666
667static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm,
668 bool reduced_tx_power)
669{
670 enum iwl_bt_kill_msk bt_kill_msk;
671 struct iwl_bt_coex_cmd_old *bt_cmd;
672 struct iwl_bt_coex_profile_notif_old *notif = &mvm->last_bt_notif_old;
673 struct iwl_host_cmd cmd = {
674 .id = BT_CONFIG,
675 .data[0] = &bt_cmd,
676 .len = { sizeof(*bt_cmd), },
677 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
678 };
679 int ret = 0;
680
681 lockdep_assert_held(&mvm->mutex);
682
683 if (reduced_tx_power) {
684 /* Reduced Tx power has precedence on the type of the profile */
685 bt_kill_msk = BT_KILL_MSK_REDUCED_TXPOW;
686 } else {
687 /* Low latency BT profile is active: give higher prio to BT */
688 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
689 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
690 BT_MBOX_MSG(notif, 3, SNIFF_STATE))
691 bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
692 else
693 bt_kill_msk = BT_KILL_MSK_DEFAULT;
694 }
695
696 IWL_DEBUG_COEX(mvm,
697 "Update kill_msk: %d - SCO %sactive A2DP %sactive SNIFF %sactive\n",
698 bt_kill_msk,
699 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
700 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
701 BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
702
703 /* Don't send HCMD if there is no update */
704 if (bt_kill_msk == mvm->bt_kill_msk)
705 return 0;
706
707 mvm->bt_kill_msk = bt_kill_msk;
708
709 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
710 if (!bt_cmd)
711 return -ENOMEM;
712 cmd.data[0] = bt_cmd;
713 bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
714
715 bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
716 bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
717 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
718 BT_VALID_KILL_ACK |
719 BT_VALID_KILL_CTS);
720
721 IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n",
722 iwl_bt_ack_kill_msk[bt_kill_msk],
723 iwl_bt_cts_kill_msk[bt_kill_msk]);
724
725 ret = iwl_mvm_send_cmd(mvm, &cmd);
726
727 kfree(bt_cmd);
728 return ret;
729}
730
731static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
732 bool enable)
733{
734 struct iwl_bt_coex_cmd_old *bt_cmd;
735 /* Send ASYNC since this can be sent from an atomic context */
736 struct iwl_host_cmd cmd = {
737 .id = BT_CONFIG,
738 .len = { sizeof(*bt_cmd), },
739 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
740 .flags = CMD_ASYNC,
741 };
742 struct iwl_mvm_sta *mvmsta;
743 int ret;
744
745 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id);
746 if (!mvmsta)
747 return 0;
748
749 /* nothing to do */
750 if (mvmsta->bt_reduced_txpower == enable)
751 return 0;
752
753 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_ATOMIC);
754 if (!bt_cmd)
755 return -ENOMEM;
756 cmd.data[0] = bt_cmd;
757 bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
758
759 bt_cmd->valid_bit_msk =
760 cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER);
761 bt_cmd->bt_reduced_tx_power = sta_id;
762
763 if (enable)
764 bt_cmd->bt_reduced_tx_power |= BT_REDUCED_TX_POWER_BIT;
765
766 IWL_DEBUG_COEX(mvm, "%sable reduced Tx Power for sta %d\n",
767 enable ? "en" : "dis", sta_id);
768
769 mvmsta->bt_reduced_txpower = enable;
770
771 ret = iwl_mvm_send_cmd(mvm, &cmd);
772
773 kfree(bt_cmd);
774 return ret;
775}
776
777struct iwl_bt_iterator_data {
778 struct iwl_bt_coex_profile_notif_old *notif;
779 struct iwl_mvm *mvm;
780 u32 num_bss_ifaces;
781 bool reduced_tx_power;
782 struct ieee80211_chanctx_conf *primary;
783 struct ieee80211_chanctx_conf *secondary;
784 bool primary_ll;
785};
786
787static inline
788void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm,
789 struct ieee80211_vif *vif,
790 bool enable, int rssi)
791{
792 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
793
794 mvmvif->bf_data.last_bt_coex_event = rssi;
795 mvmvif->bf_data.bt_coex_max_thold =
796 enable ? -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH : 0;
797 mvmvif->bf_data.bt_coex_min_thold =
798 enable ? -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH : 0;
799}
800
801/* must be called under rcu_read_lock */
802static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
803 struct ieee80211_vif *vif)
804{
805 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
806 struct iwl_bt_iterator_data *data = _data;
807 struct iwl_mvm *mvm = data->mvm;
808 struct ieee80211_chanctx_conf *chanctx_conf;
809 enum ieee80211_smps_mode smps_mode;
810 u32 bt_activity_grading;
811 int ave_rssi;
812
813 lockdep_assert_held(&mvm->mutex);
814
815 switch (vif->type) {
816 case NL80211_IFTYPE_STATION:
817 /* Count BSSes vifs */
818 data->num_bss_ifaces++;
819 /* default smps_mode for BSS / P2P client is AUTOMATIC */
820 smps_mode = IEEE80211_SMPS_AUTOMATIC;
821 break;
822 case NL80211_IFTYPE_AP:
823 /* default smps_mode for AP / GO is OFF */
824 smps_mode = IEEE80211_SMPS_OFF;
825 if (!mvmvif->ap_ibss_active) {
826 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
827 smps_mode);
828 return;
829 }
830
831 /* the Ack / Cts kill mask must be default if AP / GO */
832 data->reduced_tx_power = false;
833 break;
834 default:
835 return;
836 }
837
838 chanctx_conf = rcu_dereference(vif->chanctx_conf);
839
840 /* If channel context is invalid or not on 2.4GHz .. */
841 if ((!chanctx_conf ||
842 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ)) {
843 /* ... relax constraints and disable rssi events */
844 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
845 smps_mode);
846 data->reduced_tx_power = false;
847 if (vif->type == NL80211_IFTYPE_STATION) {
848 iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
849 false);
850 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
851 }
852 return;
853 }
854
855 bt_activity_grading = le32_to_cpu(data->notif->bt_activity_grading);
856 if (bt_activity_grading >= BT_HIGH_TRAFFIC)
857 smps_mode = IEEE80211_SMPS_STATIC;
858 else if (bt_activity_grading >= BT_LOW_TRAFFIC)
859 smps_mode = vif->type == NL80211_IFTYPE_AP ?
860 IEEE80211_SMPS_OFF :
861 IEEE80211_SMPS_DYNAMIC;
862
863 /* relax SMPS contraints for next association */
864 if (!vif->bss_conf.assoc)
865 smps_mode = IEEE80211_SMPS_AUTOMATIC;
866
867 IWL_DEBUG_COEX(data->mvm,
868 "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n",
869 mvmvif->id, data->notif->bt_status, bt_activity_grading,
870 smps_mode);
871
872 iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode);
873
874 /* low latency is always primary */
875 if (iwl_mvm_vif_low_latency(mvmvif)) {
876 data->primary_ll = true;
877
878 data->secondary = data->primary;
879 data->primary = chanctx_conf;
880 }
881
882 if (vif->type == NL80211_IFTYPE_AP) {
883 if (!mvmvif->ap_ibss_active)
884 return;
885
886 if (chanctx_conf == data->primary)
887 return;
888
889 if (!data->primary_ll) {
890 /*
891 * downgrade the current primary no matter what its
892 * type is.
893 */
894 data->secondary = data->primary;
895 data->primary = chanctx_conf;
896 } else {
897 /* there is low latency vif - we will be secondary */
898 data->secondary = chanctx_conf;
899 }
900 return;
901 }
902
903 /*
904 * STA / P2P Client, try to be primary if first vif. If we are in low
905 * latency mode, we are already in primary and just don't do much
906 */
907 if (!data->primary || data->primary == chanctx_conf)
908 data->primary = chanctx_conf;
909 else if (!data->secondary)
910 /* if secondary is not NULL, it might be a GO */
911 data->secondary = chanctx_conf;
912
913 /*
914 * don't reduce the Tx power if one of these is true:
915 * we are in LOOSE
916 * single share antenna product
917 * BT is active
918 * we are associated
919 */
920 if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT ||
921 mvm->cfg->bt_shared_single_ant || !vif->bss_conf.assoc ||
922 !data->notif->bt_status) {
923 data->reduced_tx_power = false;
924 iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false);
925 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0);
926 return;
927 }
928
929 /* try to get the avg rssi from fw */
930 ave_rssi = mvmvif->bf_data.ave_beacon_signal;
931
932 /* if the RSSI isn't valid, fake it is very low */
933 if (!ave_rssi)
934 ave_rssi = -100;
935 if (ave_rssi > -IWL_MVM_BT_COEX_EN_RED_TXP_THRESH) {
936 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true))
937 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
938
939 /*
940 * bt_kill_msk can be BT_KILL_MSK_REDUCED_TXPOW only if all the
941 * BSS / P2P clients have rssi above threshold.
942 * We set the bt_kill_msk to BT_KILL_MSK_REDUCED_TXPOW before
943 * the iteration, if one interface's rssi isn't good enough,
944 * bt_kill_msk will be set to default values.
945 */
946 } else if (ave_rssi < -IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH) {
947 if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false))
948 IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n");
949
950 /*
951 * One interface hasn't rssi above threshold, bt_kill_msk must
952 * be set to default values.
953 */
954 data->reduced_tx_power = false;
955 }
956
957 /* Begin to monitor the RSSI: it may influence the reduced Tx power */
958 iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, true, ave_rssi);
959}
960
961static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
962{
963 struct iwl_bt_iterator_data data = {
964 .mvm = mvm,
965 .notif = &mvm->last_bt_notif_old,
966 .reduced_tx_power = true,
967 };
968 struct iwl_bt_coex_ci_cmd_old cmd = {};
969 u8 ci_bw_idx;
970
971 /* Ignore updates if we are in force mode */
972 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
973 return;
974
975 rcu_read_lock();
976 ieee80211_iterate_active_interfaces_atomic(
977 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
978 iwl_mvm_bt_notif_iterator, &data);
979
980 if (data.primary) {
981 struct ieee80211_chanctx_conf *chan = data.primary;
982
983 if (WARN_ON(!chan->def.chan)) {
984 rcu_read_unlock();
985 return;
986 }
987
988 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
989 ci_bw_idx = 0;
990 cmd.co_run_bw_primary = 0;
991 } else {
992 cmd.co_run_bw_primary = 1;
993 if (chan->def.center_freq1 >
994 chan->def.chan->center_freq)
995 ci_bw_idx = 2;
996 else
997 ci_bw_idx = 1;
998 }
999
1000 cmd.bt_primary_ci =
1001 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
1002 cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv);
1003 }
1004
1005 if (data.secondary) {
1006 struct ieee80211_chanctx_conf *chan = data.secondary;
1007
1008 if (WARN_ON(!data.secondary->def.chan)) {
1009 rcu_read_unlock();
1010 return;
1011 }
1012
1013 if (chan->def.width < NL80211_CHAN_WIDTH_40) {
1014 ci_bw_idx = 0;
1015 cmd.co_run_bw_secondary = 0;
1016 } else {
1017 cmd.co_run_bw_secondary = 1;
1018 if (chan->def.center_freq1 >
1019 chan->def.chan->center_freq)
1020 ci_bw_idx = 2;
1021 else
1022 ci_bw_idx = 1;
1023 }
1024
1025 cmd.bt_secondary_ci =
1026 iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx];
1027 cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv);
1028 }
1029
1030 rcu_read_unlock();
1031
1032 /* Don't spam the fw with the same command over and over */
1033 if (memcmp(&cmd, &mvm->last_bt_ci_cmd_old, sizeof(cmd))) {
1034 if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_CI, 0,
1035 sizeof(cmd), &cmd))
1036 IWL_ERR(mvm, "Failed to send BT_CI cmd\n");
1037 memcpy(&mvm->last_bt_ci_cmd_old, &cmd, sizeof(cmd));
1038 }
1039
1040 /*
1041 * If there are no BSS / P2P client interfaces, reduced Tx Power is
1042 * irrelevant since it is based on the RSSI coming from the beacon.
1043 * Use BT_KILL_MSK_DEFAULT in that case.
1044 */
1045 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
1046
1047 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
1048 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
1049}
1050
1051int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
1052 struct iwl_rx_cmd_buffer *rxb,
1053 struct iwl_device_cmd *dev_cmd)
1054{
1055 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1056 struct iwl_bt_coex_profile_notif_old *notif = (void *)pkt->data;
1057
1058 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
1059 IWL_DEBUG_COEX(mvm, "\tBT status: %s\n",
1060 notif->bt_status ? "ON" : "OFF");
1061 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
1062 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
1063 IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n",
1064 le32_to_cpu(notif->primary_ch_lut));
1065 IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n",
1066 le32_to_cpu(notif->secondary_ch_lut));
1067 IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n",
1068 le32_to_cpu(notif->bt_activity_grading));
1069 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
1070 notif->bt_agg_traffic_load);
1071
1072 /* remember this notification for future use: rssi fluctuations */
1073 memcpy(&mvm->last_bt_notif_old, notif, sizeof(mvm->last_bt_notif_old));
1074
1075 iwl_mvm_bt_coex_notif_handle(mvm);
1076
1077 /*
1078 * This is an async handler for a notification, returning anything other
1079 * than 0 doesn't make sense even if HCMD failed.
1080 */
1081 return 0;
1082}
1083
1084static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac,
1085 struct ieee80211_vif *vif)
1086{
1087 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
1088 struct iwl_bt_iterator_data *data = _data;
1089 struct iwl_mvm *mvm = data->mvm;
1090
1091 struct ieee80211_sta *sta;
1092 struct iwl_mvm_sta *mvmsta;
1093
1094 struct ieee80211_chanctx_conf *chanctx_conf;
1095
1096 rcu_read_lock();
1097 chanctx_conf = rcu_dereference(vif->chanctx_conf);
1098 /* If channel context is invalid or not on 2.4GHz - don't count it */
1099 if (!chanctx_conf ||
1100 chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) {
1101 rcu_read_unlock();
1102 return;
1103 }
1104 rcu_read_unlock();
1105
1106 if (vif->type != NL80211_IFTYPE_STATION ||
1107 mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
1108 return;
1109
1110 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id],
1111 lockdep_is_held(&mvm->mutex));
1112
1113 /* This can happen if the station has been removed right now */
1114 if (IS_ERR_OR_NULL(sta))
1115 return;
1116
1117 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1118
1119 data->num_bss_ifaces++;
1120
1121 /*
1122 * This interface doesn't support reduced Tx power (because of low
1123 * RSSI probably), then set bt_kill_msk to default values.
1124 */
1125 if (!mvmsta->bt_reduced_txpower)
1126 data->reduced_tx_power = false;
1127 /* else - possibly leave it to BT_KILL_MSK_REDUCED_TXPOW */
1128}
1129
1130void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1131 enum ieee80211_rssi_event rssi_event)
1132{
1133 struct iwl_mvm_vif *mvmvif = (void *)vif->drv_priv;
1134 struct iwl_bt_iterator_data data = {
1135 .mvm = mvm,
1136 .reduced_tx_power = true,
1137 };
1138 int ret;
1139
1140 lockdep_assert_held(&mvm->mutex);
1141
1142 /* Ignore updates if we are in force mode */
1143 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
1144 return;
1145
1146 /*
1147 * Rssi update while not associated - can happen since the statistics
1148 * are handled asynchronously
1149 */
1150 if (mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)
1151 return;
1152
1153 /* No BT - reports should be disabled */
1154 if (!mvm->last_bt_notif_old.bt_status)
1155 return;
1156
1157 IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid,
1158 rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW");
1159
1160 /*
1161 * Check if rssi is good enough for reduced Tx power, but not in loose
1162 * scheme.
1163 */
1164 if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant ||
1165 iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT)
1166 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id,
1167 false);
1168 else
1169 ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, true);
1170
1171 if (ret)
1172 IWL_ERR(mvm, "couldn't send BT_CONFIG HCMD upon RSSI event\n");
1173
1174 ieee80211_iterate_active_interfaces_atomic(
1175 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1176 iwl_mvm_bt_rssi_iterator, &data);
1177
1178 /*
1179 * If there are no BSS / P2P client interfaces, reduced Tx Power is
1180 * irrelevant since it is based on the RSSI coming from the beacon.
1181 * Use BT_KILL_MSK_DEFAULT in that case.
1182 */
1183 data.reduced_tx_power = data.reduced_tx_power && data.num_bss_ifaces;
1184
1185 if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power))
1186 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
1187}
1188
1189#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
1190#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200)
1191
1192u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
1193 struct ieee80211_sta *sta)
1194{
1195 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1196 enum iwl_bt_coex_lut_type lut_type;
1197
1198 if (le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading) <
1199 BT_HIGH_TRAFFIC)
1200 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1201
1202 if (mvm->last_bt_notif_old.ttc_enabled)
1203 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1204
1205 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
1206
1207 if (lut_type == BT_COEX_LOOSE_LUT || lut_type == BT_COEX_INVALID_LUT)
1208 return LINK_QUAL_AGG_TIME_LIMIT_DEF;
1209
1210 /* tight coex, high bt traffic, reduce AGG time limit */
1211 return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT;
1212}
1213
1214bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
1215 struct ieee80211_sta *sta)
1216{
1217 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
1218 enum iwl_bt_coex_lut_type lut_type;
1219
1220 if (mvm->last_bt_notif_old.ttc_enabled)
1221 return true;
1222
1223 if (le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading) <
1224 BT_HIGH_TRAFFIC)
1225 return true;
1226
1227 /*
1228 * In Tight / TxTxDis, BT can't Rx while we Tx, so use both antennas
1229 * since BT is already killed.
1230 * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while
1231 * we Tx.
1232 * When we are in 5GHz, we'll get BT_COEX_INVALID_LUT allowing MIMO.
1233 */
1234 lut_type = iwl_get_coex_type(mvm, mvmsta->vif);
1235 return lut_type != BT_COEX_LOOSE_LUT;
1236}
1237
1238bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm)
1239{
1240 u32 ag = le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1241 return ag == BT_OFF;
1242}
1243
1244bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
1245 enum ieee80211_band band)
1246{
1247 u32 bt_activity =
1248 le32_to_cpu(mvm->last_bt_notif_old.bt_activity_grading);
1249
1250 if (band != IEEE80211_BAND_2GHZ)
1251 return false;
1252
1253 return bt_activity >= BT_LOW_TRAFFIC;
1254}
1255
1256void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm)
1257{
1258 iwl_mvm_bt_coex_notif_handle(mvm);
1259}
1260
1261int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
1262 struct iwl_rx_cmd_buffer *rxb,
1263 struct iwl_device_cmd *dev_cmd)
1264{
1265 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1266 u32 ant_isolation = le32_to_cpup((void *)pkt->data);
1267 u8 __maybe_unused lower_bound, upper_bound;
1268 int ret;
1269 u8 lut;
1270
1271 struct iwl_bt_coex_cmd_old *bt_cmd;
1272 struct iwl_host_cmd cmd = {
1273 .id = BT_CONFIG,
1274 .len = { sizeof(*bt_cmd), },
1275 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1276 };
1277
1278 if (!IWL_MVM_BT_COEX_CORUNNING)
1279 return 0;
1280
1281 lockdep_assert_held(&mvm->mutex);
1282
1283 /* Ignore updates if we are in force mode */
1284 if (unlikely(mvm->bt_force_ant_mode != BT_FORCE_ANT_DIS))
1285 return 0;
1286
1287 if (ant_isolation == mvm->last_ant_isol)
1288 return 0;
1289
1290 for (lut = 0; lut < ARRAY_SIZE(antenna_coupling_ranges) - 1; lut++)
1291 if (ant_isolation < antenna_coupling_ranges[lut + 1].range)
1292 break;
1293
1294 lower_bound = antenna_coupling_ranges[lut].range;
1295
1296 if (lut < ARRAY_SIZE(antenna_coupling_ranges) - 1)
1297 upper_bound = antenna_coupling_ranges[lut + 1].range;
1298 else
1299 upper_bound = antenna_coupling_ranges[lut].range;
1300
1301 IWL_DEBUG_COEX(mvm, "Antenna isolation=%d in range [%d,%d[, lut=%d\n",
1302 ant_isolation, lower_bound, upper_bound, lut);
1303
1304 mvm->last_ant_isol = ant_isolation;
1305
1306 if (mvm->last_corun_lut == lut)
1307 return 0;
1308
1309 mvm->last_corun_lut = lut;
1310
1311 bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL);
1312 if (!bt_cmd)
1313 return 0;
1314 cmd.data[0] = bt_cmd;
1315
1316 bt_cmd->flags = cpu_to_le32(BT_COEX_NW_OLD);
1317 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE |
1318 BT_VALID_CORUN_LUT_20 |
1319 BT_VALID_CORUN_LUT_40);
1320
1321 /* For the moment, use the same LUT for 20GHz and 40GHz */
1322 memcpy(bt_cmd->bt4_corun_lut20, antenna_coupling_ranges[lut].lut20,
1323 sizeof(bt_cmd->bt4_corun_lut20));
1324
1325 memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
1326 sizeof(bt_cmd->bt4_corun_lut40));
1327
1328 ret = iwl_mvm_send_cmd(mvm, &cmd);
1329
1330 kfree(bt_cmd);
1331 return ret;
1332}
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index 51685693af2e..ca79f7160573 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -79,6 +79,8 @@
79#define IWL_MVM_PS_SNOOZE_WINDOW 50 79#define IWL_MVM_PS_SNOOZE_WINDOW 50
80#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25 80#define IWL_MVM_WOWLAN_PS_SNOOZE_WINDOW 25
81#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64 81#define IWL_MVM_LOWLAT_QUOTA_MIN_PERCENT 64
82#define IWL_MVM_BT_COEX_EN_RED_TXP_THRESH 62
83#define IWL_MVM_BT_COEX_DIS_RED_TXP_THRESH 65
82#define IWL_MVM_BT_COEX_SYNC2SCO 1 84#define IWL_MVM_BT_COEX_SYNC2SCO 1
83#define IWL_MVM_BT_COEX_CORUNNING 1 85#define IWL_MVM_BT_COEX_CORUNNING 1
84#define IWL_MVM_BT_COEX_MPLUT 1 86#define IWL_MVM_BT_COEX_MPLUT 1
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 29ca72695eaa..f131ef0ec5b3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -312,20 +312,69 @@ static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf,
312 BT_MBOX_MSG(notif, _num, _field), \ 312 BT_MBOX_MSG(notif, _num, _field), \
313 true ? "\n" : ", "); 313 true ? "\n" : ", ");
314 314
315static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, 315static
316 size_t count, loff_t *ppos) 316int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf,
317 int pos, int bufsz)
317{ 318{
318 struct iwl_mvm *mvm = file->private_data; 319 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
319 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
320 char *buf;
321 int ret, pos = 0, bufsz = sizeof(char) * 1024;
322 320
323 buf = kmalloc(bufsz, GFP_KERNEL); 321 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
324 if (!buf) 322 BT_MBOX_PRINT(0, LE_PROF1, false);
325 return -ENOMEM; 323 BT_MBOX_PRINT(0, LE_PROF2, false);
324 BT_MBOX_PRINT(0, LE_PROF_OTHER, false);
325 BT_MBOX_PRINT(0, CHL_SEQ_N, false);
326 BT_MBOX_PRINT(0, INBAND_S, false);
327 BT_MBOX_PRINT(0, LE_MIN_RSSI, false);
328 BT_MBOX_PRINT(0, LE_SCAN, false);
329 BT_MBOX_PRINT(0, LE_ADV, false);
330 BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false);
331 BT_MBOX_PRINT(0, OPEN_CON_1, true);
326 332
327 mutex_lock(&mvm->mutex); 333 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n");
334
335 BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false);
336 BT_MBOX_PRINT(1, IP_SR, false);
337 BT_MBOX_PRINT(1, LE_MSTR, false);
338 BT_MBOX_PRINT(1, AGGR_TRFC_LD, false);
339 BT_MBOX_PRINT(1, MSG_TYPE, false);
340 BT_MBOX_PRINT(1, SSN, true);
341
342 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n");
343
344 BT_MBOX_PRINT(2, SNIFF_ACT, false);
345 BT_MBOX_PRINT(2, PAG, false);
346 BT_MBOX_PRINT(2, INQUIRY, false);
347 BT_MBOX_PRINT(2, CONN, false);
348 BT_MBOX_PRINT(2, SNIFF_INTERVAL, false);
349 BT_MBOX_PRINT(2, DISC, false);
350 BT_MBOX_PRINT(2, SCO_TX_ACT, false);
351 BT_MBOX_PRINT(2, SCO_RX_ACT, false);
352 BT_MBOX_PRINT(2, ESCO_RE_TX, false);
353 BT_MBOX_PRINT(2, SCO_DURATION, true);
354
355 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n");
356
357 BT_MBOX_PRINT(3, SCO_STATE, false);
358 BT_MBOX_PRINT(3, SNIFF_STATE, false);
359 BT_MBOX_PRINT(3, A2DP_STATE, false);
360 BT_MBOX_PRINT(3, ACL_STATE, false);
361 BT_MBOX_PRINT(3, MSTR_STATE, false);
362 BT_MBOX_PRINT(3, OBX_STATE, false);
363 BT_MBOX_PRINT(3, OPEN_CON_2, false);
364 BT_MBOX_PRINT(3, TRAFFIC_LOAD, false);
365 BT_MBOX_PRINT(3, CHL_SEQN_LSB, false);
366 BT_MBOX_PRINT(3, INBAND_P, false);
367 BT_MBOX_PRINT(3, MSG_TYPE_2, false);
368 BT_MBOX_PRINT(3, SSN_2, false);
369 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
370
371 return pos;
372}
328 373
374static
375int iwl_mvm_coex_dump_mbox_old(struct iwl_bt_coex_profile_notif_old *notif,
376 char *buf, int pos, int bufsz)
377{
329 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); 378 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n");
330 379
331 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); 380 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false);
@@ -378,25 +427,59 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
378 BT_MBOX_PRINT(3, SSN_2, false); 427 BT_MBOX_PRINT(3, SSN_2, false);
379 BT_MBOX_PRINT(3, UPDATE_REQUEST, true); 428 BT_MBOX_PRINT(3, UPDATE_REQUEST, true);
380 429
381 pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", 430 return pos;
382 notif->bt_status); 431}
383 pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", 432
384 notif->bt_open_conn); 433static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf,
385 pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", 434 size_t count, loff_t *ppos)
386 notif->bt_traffic_load); 435{
387 pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", 436 struct iwl_mvm *mvm = file->private_data;
388 notif->bt_agg_traffic_load); 437 char *buf;
389 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", 438 int ret, pos = 0, bufsz = sizeof(char) * 1024;
390 notif->bt_ci_compliance); 439
391 pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n", 440 buf = kmalloc(bufsz, GFP_KERNEL);
392 le32_to_cpu(notif->primary_ch_lut)); 441 if (!buf)
393 pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n", 442 return -ENOMEM;
394 le32_to_cpu(notif->secondary_ch_lut)); 443
395 pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n", 444 mutex_lock(&mvm->mutex);
396 le32_to_cpu(notif->bt_activity_grading)); 445
397 pos += scnprintf(buf+pos, bufsz-pos, 446 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
398 "antenna isolation = %d CORUN LUT index = %d\n", 447 struct iwl_bt_coex_profile_notif_old *notif =
399 mvm->last_ant_isol, mvm->last_corun_lut); 448 &mvm->last_bt_notif_old;
449
450 pos += iwl_mvm_coex_dump_mbox_old(notif, buf, pos, bufsz);
451
452 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
453 notif->bt_ci_compliance);
454 pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
455 le32_to_cpu(notif->primary_ch_lut));
456 pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
457 le32_to_cpu(notif->secondary_ch_lut));
458 pos += scnprintf(buf+pos,
459 bufsz-pos, "bt_activity_grading = %d\n",
460 le32_to_cpu(notif->bt_activity_grading));
461 pos += scnprintf(buf+pos, bufsz-pos,
462 "antenna isolation = %d CORUN LUT index = %d\n",
463 mvm->last_ant_isol, mvm->last_corun_lut);
464 } else {
465 struct iwl_bt_coex_profile_notif *notif =
466 &mvm->last_bt_notif;
467
468 pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz);
469
470 pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n",
471 notif->bt_ci_compliance);
472 pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n",
473 le32_to_cpu(notif->primary_ch_lut));
474 pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n",
475 le32_to_cpu(notif->secondary_ch_lut));
476 pos += scnprintf(buf+pos,
477 bufsz-pos, "bt_activity_grading = %d\n",
478 le32_to_cpu(notif->bt_activity_grading));
479 pos += scnprintf(buf+pos, bufsz-pos,
480 "antenna isolation = %d CORUN LUT index = %d\n",
481 mvm->last_ant_isol, mvm->last_corun_lut);
482 }
400 483
401 mutex_unlock(&mvm->mutex); 484 mutex_unlock(&mvm->mutex);
402 485
@@ -411,28 +494,48 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
411 size_t count, loff_t *ppos) 494 size_t count, loff_t *ppos)
412{ 495{
413 struct iwl_mvm *mvm = file->private_data; 496 struct iwl_mvm *mvm = file->private_data;
414 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
415 char buf[256]; 497 char buf[256];
416 int bufsz = sizeof(buf); 498 int bufsz = sizeof(buf);
417 int pos = 0; 499 int pos = 0;
418 500
419 mutex_lock(&mvm->mutex); 501 mutex_lock(&mvm->mutex);
420 502
421 pos += scnprintf(buf+pos, bufsz-pos, "Channel inhibition CMD\n"); 503 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) {
422 pos += scnprintf(buf+pos, bufsz-pos, 504 struct iwl_bt_coex_ci_cmd_old *cmd = &mvm->last_bt_ci_cmd_old;
423 "\tPrimary Channel Bitmap 0x%016llx Fat: %d\n", 505
424 le64_to_cpu(cmd->bt_primary_ci), 506 pos += scnprintf(buf+pos, bufsz-pos,
425 !!cmd->co_run_bw_primary); 507 "Channel inhibition CMD\n");
426 pos += scnprintf(buf+pos, bufsz-pos, 508 pos += scnprintf(buf+pos, bufsz-pos,
427 "\tSecondary Channel Bitmap 0x%016llx Fat: %d\n", 509 "\tPrimary Channel Bitmap 0x%016llx\n",
428 le64_to_cpu(cmd->bt_secondary_ci), 510 le64_to_cpu(cmd->bt_primary_ci));
429 !!cmd->co_run_bw_secondary); 511 pos += scnprintf(buf+pos, bufsz-pos,
430 512 "\tSecondary Channel Bitmap 0x%016llx\n",
431 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n"); 513 le64_to_cpu(cmd->bt_secondary_ci));
432 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n", 514
433 iwl_bt_ack_kill_msk[mvm->bt_kill_msk]); 515 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
434 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n", 516 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
435 iwl_bt_cts_kill_msk[mvm->bt_kill_msk]); 517 iwl_bt_ack_kill_msk[mvm->bt_kill_msk]);
518 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
519 iwl_bt_cts_kill_msk[mvm->bt_kill_msk]);
520
521 } else {
522 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
523
524 pos += scnprintf(buf+pos, bufsz-pos,
525 "Channel inhibition CMD\n");
526 pos += scnprintf(buf+pos, bufsz-pos,
527 "\tPrimary Channel Bitmap 0x%016llx\n",
528 le64_to_cpu(cmd->bt_primary_ci));
529 pos += scnprintf(buf+pos, bufsz-pos,
530 "\tSecondary Channel Bitmap 0x%016llx\n",
531 le64_to_cpu(cmd->bt_secondary_ci));
532
533 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
534 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n",
535 iwl_bt_ack_kill_msk[mvm->bt_kill_msk]);
536 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n",
537 iwl_bt_cts_kill_msk[mvm->bt_kill_msk]);
538 }
436 539
437 mutex_unlock(&mvm->mutex); 540 mutex_unlock(&mvm->mutex);
438 541
@@ -455,6 +558,43 @@ iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf,
455 return count; 558 return count;
456} 559}
457 560
561static ssize_t
562iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
563 size_t count, loff_t *ppos)
564{
565 static const char * const modes_str[BT_FORCE_ANT_MAX] = {
566 [BT_FORCE_ANT_DIS] = "dis",
567 [BT_FORCE_ANT_AUTO] = "auto",
568 [BT_FORCE_ANT_BT] = "bt",
569 [BT_FORCE_ANT_WIFI] = "wifi",
570 };
571 int ret, bt_force_ant_mode;
572
573 for (bt_force_ant_mode = 0;
574 bt_force_ant_mode < ARRAY_SIZE(modes_str);
575 bt_force_ant_mode++) {
576 if (!strcmp(buf, modes_str[bt_force_ant_mode]))
577 break;
578 }
579
580 if (bt_force_ant_mode >= ARRAY_SIZE(modes_str))
581 return -EINVAL;
582
583 ret = 0;
584 mutex_lock(&mvm->mutex);
585 if (mvm->bt_force_ant_mode == bt_force_ant_mode)
586 goto out;
587
588 mvm->bt_force_ant_mode = bt_force_ant_mode;
589 IWL_DEBUG_COEX(mvm, "Force mode: %s\n",
590 modes_str[mvm->bt_force_ant_mode]);
591 ret = iwl_send_bt_init_conf(mvm);
592
593out:
594 mutex_unlock(&mvm->mutex);
595 return ret ?: count;
596}
597
458#define PRINT_STATS_LE32(_str, _val) \ 598#define PRINT_STATS_LE32(_str, _val) \
459 pos += scnprintf(buf + pos, bufsz - pos, \ 599 pos += scnprintf(buf + pos, bufsz - pos, \
460 fmt_table, _str, \ 600 fmt_table, _str, \
@@ -1101,6 +1241,7 @@ MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
1101MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); 1241MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
1102MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); 1242MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
1103MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10); 1243MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
1244MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10);
1104MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1245MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8);
1105MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8); 1246MVM_DEBUGFS_READ_WRITE_FILE_OPS(d0i3_refs, 8);
1106 1247
@@ -1142,6 +1283,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
1142 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); 1283 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
1143 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR); 1284 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, S_IWUSR);
1144 MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, S_IWUSR); 1285 MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, S_IWUSR);
1286 MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, S_IWUSR);
1145 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 1287 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir,
1146 S_IWUSR | S_IRUSR); 1288 S_IWUSR | S_IRUSR);
1147 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR); 1289 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, S_IWUSR | S_IRUSR);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index 5fe82c29c8ad..ab12aaa43034 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -72,10 +72,13 @@
72 * enum iwl_bt_coex_flags - flags for BT_COEX command 72 * enum iwl_bt_coex_flags - flags for BT_COEX command
73 * @BT_COEX_MODE_POS: 73 * @BT_COEX_MODE_POS:
74 * @BT_COEX_MODE_MSK: 74 * @BT_COEX_MODE_MSK:
75 * @BT_COEX_DISABLE: 75 * @BT_COEX_DISABLE_OLD:
76 * @BT_COEX_2W: 76 * @BT_COEX_2W_OLD:
77 * @BT_COEX_3W: 77 * @BT_COEX_3W_OLD:
78 * @BT_COEX_NW: 78 * @BT_COEX_NW_OLD:
79 * @BT_COEX_AUTO_OLD:
80 * @BT_COEX_BT_OLD: Antenna is for BT (manufacuring tests)
81 * @BT_COEX_WIFI_OLD: Antenna is for BT (manufacuring tests)
79 * @BT_COEX_SYNC2SCO: 82 * @BT_COEX_SYNC2SCO:
80 * @BT_COEX_CORUNNING: 83 * @BT_COEX_CORUNNING:
81 * @BT_COEX_MPLUT: 84 * @BT_COEX_MPLUT:
@@ -85,10 +88,13 @@
85enum iwl_bt_coex_flags { 88enum iwl_bt_coex_flags {
86 BT_COEX_MODE_POS = 3, 89 BT_COEX_MODE_POS = 3,
87 BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS, 90 BT_COEX_MODE_MSK = BITS(3) << BT_COEX_MODE_POS,
88 BT_COEX_DISABLE = 0x0 << BT_COEX_MODE_POS, 91 BT_COEX_DISABLE_OLD = 0x0 << BT_COEX_MODE_POS,
89 BT_COEX_2W = 0x1 << BT_COEX_MODE_POS, 92 BT_COEX_2W_OLD = 0x1 << BT_COEX_MODE_POS,
90 BT_COEX_3W = 0x2 << BT_COEX_MODE_POS, 93 BT_COEX_3W_OLD = 0x2 << BT_COEX_MODE_POS,
91 BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, 94 BT_COEX_NW_OLD = 0x3 << BT_COEX_MODE_POS,
95 BT_COEX_AUTO_OLD = 0x5 << BT_COEX_MODE_POS,
96 BT_COEX_BT_OLD = 0x6 << BT_COEX_MODE_POS,
97 BT_COEX_WIFI_OLD = 0x7 << BT_COEX_MODE_POS,
92 BT_COEX_SYNC2SCO = BIT(7), 98 BT_COEX_SYNC2SCO = BIT(7),
93 BT_COEX_CORUNNING = BIT(8), 99 BT_COEX_CORUNNING = BIT(8),
94 BT_COEX_MPLUT = BIT(9), 100 BT_COEX_MPLUT = BIT(9),
@@ -151,7 +157,7 @@ enum iwl_bt_coex_lut_type {
151#define BT_REDUCED_TX_POWER_BIT BIT(7) 157#define BT_REDUCED_TX_POWER_BIT BIT(7)
152 158
153/** 159/**
154 * struct iwl_bt_coex_cmd - bt coex configuration command 160 * struct iwl_bt_coex_cmd_old - bt coex configuration command
155 * @flags:&enum iwl_bt_coex_flags 161 * @flags:&enum iwl_bt_coex_flags
156 * @max_kill: 162 * @max_kill:
157 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power 163 * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power
@@ -176,7 +182,7 @@ enum iwl_bt_coex_lut_type {
176 * 182 *
177 * The structure is used for the BT_COEX command. 183 * The structure is used for the BT_COEX command.
178 */ 184 */
179struct iwl_bt_coex_cmd { 185struct iwl_bt_coex_cmd_old {
180 __le32 flags; 186 __le32 flags;
181 u8 max_kill; 187 u8 max_kill;
182 u8 bt_reduced_tx_power; 188 u8 bt_reduced_tx_power;
@@ -202,26 +208,117 @@ struct iwl_bt_coex_cmd {
202 __le32 valid_bit_msk; 208 __le32 valid_bit_msk;
203} __packed; /* BT_COEX_CMD_API_S_VER_5 */ 209} __packed; /* BT_COEX_CMD_API_S_VER_5 */
204 210
211enum iwl_bt_coex_mode {
212 BT_COEX_DISABLE = 0x0,
213 BT_COEX_NW = 0x1,
214 BT_COEX_BT = 0x2,
215 BT_COEX_WIFI = 0x3,
216}; /* BT_COEX_MODES_E */
217
218enum iwl_bt_coex_enabled_modules {
219 BT_COEX_MPLUT_ENABLED = BIT(0),
220 BT_COEX_MPLUT_BOOST_ENABLED = BIT(1),
221 BT_COEX_SYNC2SCO_ENABLED = BIT(2),
222 BT_COEX_CORUN_ENABLED = BIT(3),
223 BT_COEX_HIGH_BAND_RET = BIT(4),
224}; /* BT_COEX_MODULES_ENABLE_E_VER_1 */
225
226/**
227 * struct iwl_bt_coex_cmd - bt coex configuration command
228 * @mode: enum %iwl_bt_coex_mode
229 * @enabled_modules: enum %iwl_bt_coex_enabled_modules
230 * @max_kill: max count of Tx retries due to kill from PTA
231 * @override_primary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
232 * should be set by default
233 * @override_secondary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
234 * should be set by default
235 * @bt4_antenna_isolation_thr: antenna threshold value
236 * @bt4_tx_tx_delta_freq_thr: TxTx delta frequency
237 * @bt4_tx_rx_max_freq0: TxRx max frequency
238 * @multiprio_lut: multi priority LUT configuration
239 * @mplut_prio_boost: BT priority boost registers
240 * @decision_lut: PTA decision LUT, per Prio-Ch
241 *
242 * The structure is used for the BT_COEX command.
243 */
244struct iwl_bt_coex_cmd {
245 __le32 mode;
246 __le32 enabled_modules;
247
248 __le32 max_kill;
249 __le32 override_primary_lut;
250 __le32 override_secondary_lut;
251 __le32 bt4_antenna_isolation_thr;
252
253 __le32 bt4_tx_tx_delta_freq_thr;
254 __le32 bt4_tx_rx_max_freq0;
255
256 __le32 multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE];
257 __le32 mplut_prio_boost[BT_COEX_BOOST_SIZE];
258
259 __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE];
260} __packed; /* BT_COEX_CMD_API_S_VER_6 */
261
262/**
263 * struct iwl_bt_coex_corun_lut_update - bt coex update the corun lut
264 * @corun_lut20: co-running 20 MHz LUT configuration
265 * @corun_lut40: co-running 40 MHz LUT configuration
266 *
267 * The structure is used for the BT_COEX_UPDATE_CORUN_LUT command.
268 */
269struct iwl_bt_coex_corun_lut_update_cmd {
270 __le32 corun_lut20[BT_COEX_CORUN_LUT_SIZE];
271 __le32 corun_lut40[BT_COEX_CORUN_LUT_SIZE];
272} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
273
274/**
275 * struct iwl_bt_coex_sw_boost - SW boost values
276 * @wifi_tx_prio_boost: SW boost of wifi tx priority
277 * @wifi_rx_prio_boost: SW boost of wifi rx priority
278 * @kill_ack_msk: kill ACK mask. 1 - Tx ACK, 0 - kill Tx of ACK.
279 * @kill_cts_msk: kill CTS mask. 1 - Tx CTS, 0 - kill Tx of CTS.
280 */
281struct iwl_bt_coex_sw_boost {
282 __le32 wifi_tx_prio_boost;
283 __le32 wifi_rx_prio_boost;
284 __le32 kill_ack_msk;
285 __le32 kill_cts_msk;
286};
287
288/**
289 * struct iwl_bt_coex_sw_boost_update_cmd - command to update the SW boost
290 * @boost_values: check struct %iwl_bt_coex_sw_boost - one for each channel
291 * primary / secondary / low priority
292 */
293struct iwl_bt_coex_sw_boost_update_cmd {
294 struct iwl_bt_coex_sw_boost boost_values[3];
295} __packed; /* BT_COEX_UPDATE_SW_BOOST_S_VER_1 */
296
297/**
298 * struct iwl_bt_coex_reduced_txp_update_cmd
299 * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
300 * bits are the sta_id (value)
301 */
302struct iwl_bt_coex_reduced_txp_update_cmd {
303 __le32 reduced_txp;
304} __packed; /* BT_COEX_UPDATE_REDUCED_TX_POWER_API_S_VER_1 */
305
205/** 306/**
206 * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command 307 * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command
207 * @bt_primary_ci: 308 * @bt_primary_ci:
208 * @bt_secondary_ci:
209 * @co_run_bw_primary:
210 * @co_run_bw_secondary:
211 * @primary_ch_phy_id: 309 * @primary_ch_phy_id:
310 * @bt_secondary_ci:
212 * @secondary_ch_phy_id: 311 * @secondary_ch_phy_id:
213 * 312 *
214 * Used for BT_COEX_CI command 313 * Used for BT_COEX_CI command
215 */ 314 */
216struct iwl_bt_coex_ci_cmd { 315struct iwl_bt_coex_ci_cmd {
217 __le64 bt_primary_ci; 316 __le64 bt_primary_ci;
218 __le64 bt_secondary_ci; 317 __le32 primary_ch_phy_id;
219 318
220 u8 co_run_bw_primary; 319 __le64 bt_secondary_ci;
221 u8 co_run_bw_secondary; 320 __le32 secondary_ch_phy_id;
222 u8 primary_ch_phy_id; 321} __packed; /* BT_CI_MSG_API_S_VER_2 */
223 u8 secondary_ch_phy_id;
224} __packed; /* BT_CI_MSG_API_S_VER_1 */
225 322
226#define BT_MBOX(n_dw, _msg, _pos, _nbits) \ 323#define BT_MBOX(n_dw, _msg, _pos, _nbits) \
227 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ 324 BT_MBOX##n_dw##_##_msg##_POS = (_pos), \
@@ -290,33 +387,40 @@ enum iwl_bt_activity_grading {
290 BT_HIGH_TRAFFIC = 3, 387 BT_HIGH_TRAFFIC = 3,
291}; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */ 388}; /* BT_COEX_BT_ACTIVITY_GRADING_API_E_VER_1 */
292 389
390enum iwl_bt_ci_compliance {
391 BT_CI_COMPLIANCE_NONE = 0,
392 BT_CI_COMPLIANCE_PRIMARY = 1,
393 BT_CI_COMPLIANCE_SECONDARY = 2,
394 BT_CI_COMPLIANCE_BOTH = 3,
395}; /* BT_COEX_CI_COMPLIENCE_E_VER_1 */
396
397#define IWL_COEX_IS_TTC_ON(_ttc_rrc_status, _phy_id) \
398 (_ttc_rrc_status & BIT(_phy_id))
399
400#define IWL_COEX_IS_RRC_ON(_ttc_rrc_status, _phy_id) \
401 ((_ttc_rrc_status >> 4) & BIT(_phy_id))
402
293/** 403/**
294 * struct iwl_bt_coex_profile_notif - notification about BT coex 404 * struct iwl_bt_coex_profile_notif - notification about BT coex
295 * @mbox_msg: message from BT to WiFi 405 * @mbox_msg: message from BT to WiFi
296 * @msg_idx: the index of the message 406 * @msg_idx: the index of the message
297 * @bt_status: 0 - off, 1 - on 407 * @bt_ci_compliance: enum %iwl_bt_ci_compliance
298 * @bt_open_conn: number of BT connections open 408 * @primary_ch_lut: LUT used for primary channel enum %iwl_bt_coex_lut_type
299 * @bt_traffic_load: load of BT traffic 409 * @secondary_ch_lut: LUT used for secondary channel enume %iwl_bt_coex_lut_type
300 * @bt_agg_traffic_load: aggregated load of BT traffic
301 * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
302 * @primary_ch_lut: LUT used for primary channel
303 * @secondary_ch_lut: LUT used for secondary channel
304 * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading 410 * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
411 * @ttc_rrc_status: is TTC or RRC enabled - one bit per PHY
305 */ 412 */
306struct iwl_bt_coex_profile_notif { 413struct iwl_bt_coex_profile_notif {
307 __le32 mbox_msg[4]; 414 __le32 mbox_msg[4];
308 __le32 msg_idx; 415 __le32 msg_idx;
309 u8 bt_status; 416 __le32 bt_ci_compliance;
310 u8 bt_open_conn;
311 u8 bt_traffic_load;
312 u8 bt_agg_traffic_load;
313 u8 bt_ci_compliance;
314 u8 reserved[3];
315 417
316 __le32 primary_ch_lut; 418 __le32 primary_ch_lut;
317 __le32 secondary_ch_lut; 419 __le32 secondary_ch_lut;
318 __le32 bt_activity_grading; 420 __le32 bt_activity_grading;
319} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */ 421 u8 ttc_rrc_status;
422 u8 reserved[3];
423} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_4 */
320 424
321enum iwl_bt_coex_prio_table_event { 425enum iwl_bt_coex_prio_table_event {
322 BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, 426 BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0,
@@ -355,4 +459,54 @@ struct iwl_bt_coex_prio_tbl_cmd {
355 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; 459 u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX];
356} __packed; 460} __packed;
357 461
462/**
463 * struct iwl_bt_coex_ci_cmd_old - bt coex channel inhibition command
464 * @bt_primary_ci:
465 * @bt_secondary_ci:
466 * @co_run_bw_primary:
467 * @co_run_bw_secondary:
468 * @primary_ch_phy_id:
469 * @secondary_ch_phy_id:
470 *
471 * Used for BT_COEX_CI command
472 */
473struct iwl_bt_coex_ci_cmd_old {
474 __le64 bt_primary_ci;
475 __le64 bt_secondary_ci;
476
477 u8 co_run_bw_primary;
478 u8 co_run_bw_secondary;
479 u8 primary_ch_phy_id;
480 u8 secondary_ch_phy_id;
481} __packed; /* BT_CI_MSG_API_S_VER_1 */
482
483/**
484 * struct iwl_bt_coex_profile_notif_old - notification about BT coex
485 * @mbox_msg: message from BT to WiFi
486 * @msg_idx: the index of the message
487 * @bt_status: 0 - off, 1 - on
488 * @bt_open_conn: number of BT connections open
489 * @bt_traffic_load: load of BT traffic
490 * @bt_agg_traffic_load: aggregated load of BT traffic
491 * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant
492 * @primary_ch_lut: LUT used for primary channel
493 * @secondary_ch_lut: LUT used for secondary channel
494 * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading
495 */
496struct iwl_bt_coex_profile_notif_old {
497 __le32 mbox_msg[4];
498 __le32 msg_idx;
499 u8 bt_status;
500 u8 bt_open_conn;
501 u8 bt_traffic_load;
502 u8 bt_agg_traffic_load;
503 u8 bt_ci_compliance;
504 u8 ttc_enabled;
505 __le16 reserved;
506
507 __le32 primary_ch_lut;
508 __le32 secondary_ch_lut;
509 __le32 bt_activity_grading;
510} __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_3 */
511
358#endif /* __fw_api_bt_coex_h__ */ 512#endif /* __fw_api_bt_coex_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index cbbcd8e284e4..c3a8c86b550d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -336,7 +336,7 @@ struct iwl_beacon_filter_cmd {
336#define IWL_BF_DEBUG_FLAG_D0I3 0 336#define IWL_BF_DEBUG_FLAG_D0I3 0
337 337
338#define IWL_BF_ESCAPE_TIMER_DEFAULT 50 338#define IWL_BF_ESCAPE_TIMER_DEFAULT 50
339#define IWL_BF_ESCAPE_TIMER_D0I3 1024 339#define IWL_BF_ESCAPE_TIMER_D0I3 0
340#define IWL_BF_ESCAPE_TIMER_MAX 1024 340#define IWL_BF_ESCAPE_TIMER_MAX 1024
341#define IWL_BF_ESCAPE_TIMER_MIN 0 341#define IWL_BF_ESCAPE_TIMER_MIN 0
342 342
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 6959fda3fe09..c02a9e45ec5e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -170,18 +170,12 @@ enum iwl_scan_type {
170}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */ 170}; /* SCAN_ACTIVITY_TYPE_E_VER_1 */
171 171
172/** 172/**
173 * Maximal number of channels to scan
174 * it should be equal to:
175 * max(IWL_NUM_CHANNELS, IWL_NUM_CHANNELS_FAMILY_8000)
176 */
177#define MAX_NUM_SCAN_CHANNELS 50
178
179/**
180 * struct iwl_scan_cmd - scan request command 173 * struct iwl_scan_cmd - scan request command
181 * ( SCAN_REQUEST_CMD = 0x80 ) 174 * ( SCAN_REQUEST_CMD = 0x80 )
182 * @len: command length in bytes 175 * @len: command length in bytes
183 * @scan_flags: scan flags from SCAN_FLAGS_* 176 * @scan_flags: scan flags from SCAN_FLAGS_*
184 * @channel_count: num of channels in channel list (1 - MAX_NUM_SCAN_CHANNELS) 177 * @channel_count: num of channels in channel list
178 * (1 - ucode_capa.n_scan_channels)
185 * @quiet_time: in msecs, dwell this time for active scan on quiet channels 179 * @quiet_time: in msecs, dwell this time for active scan on quiet channels
186 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than 180 * @quiet_plcp_th: quiet PLCP threshold (channel is quiet if less than
187 * this number of packets were received (typically 1) 181 * this number of packets were received (typically 1)
@@ -345,7 +339,7 @@ struct iwl_scan_results_notif {
345 * @last_channel: last channel that was scanned 339 * @last_channel: last channel that was scanned
346 * @tsf_low: TSF timer (lower half) in usecs 340 * @tsf_low: TSF timer (lower half) in usecs
347 * @tsf_high: TSF timer (higher half) in usecs 341 * @tsf_high: TSF timer (higher half) in usecs
348 * @results: all scan results, only "scanned_channels" of them are valid 342 * @results: array of scan results, only "scanned_channels" of them are valid
349 */ 343 */
350struct iwl_scan_complete_notif { 344struct iwl_scan_complete_notif {
351 u8 scanned_channels; 345 u8 scanned_channels;
@@ -354,11 +348,10 @@ struct iwl_scan_complete_notif {
354 u8 last_channel; 348 u8 last_channel;
355 __le32 tsf_low; 349 __le32 tsf_low;
356 __le32 tsf_high; 350 __le32 tsf_high;
357 struct iwl_scan_results_notif results[MAX_NUM_SCAN_CHANNELS]; 351 struct iwl_scan_results_notif results[];
358} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */ 352} __packed; /* SCAN_COMPLETE_NTF_API_S_VER_2 */
359 353
360/* scan offload */ 354/* scan offload */
361#define IWL_MAX_SCAN_CHANNELS 40
362#define IWL_SCAN_MAX_BLACKLIST_LEN 64 355#define IWL_SCAN_MAX_BLACKLIST_LEN 64
363#define IWL_SCAN_SHORT_BLACKLIST_LEN 16 356#define IWL_SCAN_SHORT_BLACKLIST_LEN 16
364#define IWL_SCAN_MAX_PROFILES 11 357#define IWL_SCAN_MAX_PROFILES 11
@@ -423,36 +416,24 @@ enum iwl_scan_offload_channel_flags {
423 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL = BIT(25), 416 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL = BIT(25),
424}; 417};
425 418
426/** 419/* channel configuration for struct iwl_scan_offload_cfg. Each channels needs:
427 * iwl_scan_channel_cfg - SCAN_CHANNEL_CFG_S 420 * __le32 type: bitmap; bits 1-20 are for directed scan to i'th ssid and
428 * @type: bitmap - see enum iwl_scan_offload_channel_flags. 421 * see enum iwl_scan_offload_channel_flags.
429 * 0: passive (0) or active (1) scan. 422 * __le16 channel_number: channel number 1-13 etc.
430 * 1-20: directed scan to i'th ssid. 423 * __le16 iter_count: repetition count for the channel.
431 * 22: channel width configuation - 1 for narrow. 424 * __le32 iter_interval: interval between two innteration on one channel.
432 * 24: full scan. 425 * u8 active_dwell.
433 * 25: partial scan. 426 * u8 passive_dwell.
434 * @channel_number: channel number 1-13 etc.
435 * @iter_count: repetition count for the channel.
436 * @iter_interval: interval between two innteration on one channel.
437 * @dwell_time: entry 0 - active scan, entry 1 - passive scan.
438 */ 427 */
439struct iwl_scan_channel_cfg { 428#define IWL_SCAN_CHAN_SIZE 14
440 __le32 type[IWL_MAX_SCAN_CHANNELS];
441 __le16 channel_number[IWL_MAX_SCAN_CHANNELS];
442 __le16 iter_count[IWL_MAX_SCAN_CHANNELS];
443 __le32 iter_interval[IWL_MAX_SCAN_CHANNELS];
444 u8 dwell_time[IWL_MAX_SCAN_CHANNELS][2];
445} __packed;
446 429
447/** 430/**
448 * iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S 431 * iwl_scan_offload_cfg - SCAN_OFFLOAD_CONFIG_API_S
449 * @scan_cmd: scan command fixed part 432 * @scan_cmd: scan command fixed part
450 * @channel_cfg: scan channel configuration 433 * @data: scan channel configuration and probe request frames
451 * @data: probe request frames (one per band)
452 */ 434 */
453struct iwl_scan_offload_cfg { 435struct iwl_scan_offload_cfg {
454 struct iwl_scan_offload_cmd scan_cmd; 436 struct iwl_scan_offload_cmd scan_cmd;
455 struct iwl_scan_channel_cfg channel_cfg;
456 u8 data[0]; 437 u8 data[0];
457} __packed; 438} __packed;
458 439
@@ -528,7 +509,7 @@ struct iwl_scan_offload_profile_cfg {
528 * @full_scan_mul: number of partial scans before each full scan 509 * @full_scan_mul: number of partial scans before each full scan
529 */ 510 */
530struct iwl_scan_offload_schedule { 511struct iwl_scan_offload_schedule {
531 u16 delay; 512 __le16 delay;
532 u8 iterations; 513 u8 iterations;
533 u8 full_scan_mul; 514 u8 full_scan_mul;
534} __packed; 515} __packed;
@@ -601,4 +582,211 @@ struct iwl_sched_scan_results {
601 u8 reserved; 582 u8 reserved;
602}; 583};
603 584
585/* Unified LMAC scan API */
586
587#define IWL_MVM_BASIC_PASSIVE_DWELL 110
588
589/**
590 * iwl_scan_req_tx_cmd - SCAN_REQ_TX_CMD_API_S
591 * @tx_flags: combination of TX_CMD_FLG_*
592 * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
593 * cleared. Combination of RATE_MCS_*
594 * @sta_id: index of destination station in FW station table
595 * @reserved: for alignment and future use
596 */
597struct iwl_scan_req_tx_cmd {
598 __le32 tx_flags;
599 __le32 rate_n_flags;
600 u8 sta_id;
601 u8 reserved[3];
602} __packed;
603
604enum iwl_scan_channel_flags_lmac {
605 IWL_UNIFIED_SCAN_CHANNEL_FULL = BIT(27),
606 IWL_UNIFIED_SCAN_CHANNEL_PARTIAL = BIT(28),
607};
608
609/**
610 * iwl_scan_channel_cfg_lmac - SCAN_CHANNEL_CFG_S_VER2
611 * @flags: bits 1-20: directed scan to i'th ssid
612 * other bits &enum iwl_scan_channel_flags_lmac
613 * @channel_number: channel number 1-13 etc
614 * @iter_count: scan iteration on this channel
615 * @iter_interval: interval in seconds between iterations on one channel
616 */
617struct iwl_scan_channel_cfg_lmac {
618 __le32 flags;
619 __le16 channel_num;
620 __le16 iter_count;
621 __le32 iter_interval;
622} __packed;
623
624/*
625 * iwl_scan_probe_segment - PROBE_SEGMENT_API_S_VER_1
626 * @offset: offset in the data block
627 * @len: length of the segment
628 */
629struct iwl_scan_probe_segment {
630 __le16 offset;
631 __le16 len;
632} __packed;
633
634/* iwl_scan_probe_req - PROBE_REQUEST_FRAME_API_S_VER_2
635 * @mac_header: first (and common) part of the probe
636 * @band_data: band specific data
637 * @common_data: last (and common) part of the probe
638 * @buf: raw data block
639 */
640struct iwl_scan_probe_req {
641 struct iwl_scan_probe_segment mac_header;
642 struct iwl_scan_probe_segment band_data[2];
643 struct iwl_scan_probe_segment common_data;
644 u8 buf[SCAN_OFFLOAD_PROBE_REQ_SIZE];
645} __packed;
646
647enum iwl_scan_channel_flags {
648 IWL_SCAN_CHANNEL_FLAG_EBS = BIT(0),
649 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE = BIT(1),
650 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD = BIT(2),
651};
652
653/* iwl_scan_channel_opt - CHANNEL_OPTIMIZATION_API_S
654 * @flags: enum iwl_scan_channel_flgs
655 * @non_ebs_ratio: how many regular scan iteration before EBS
656 */
657struct iwl_scan_channel_opt {
658 __le16 flags;
659 __le16 non_ebs_ratio;
660} __packed;
661
662/**
663 * iwl_mvm_lmac_scan_flags
664 * @IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL: pass all beacons and probe responses
665 * without filtering.
666 * @IWL_MVM_LMAC_SCAN_FLAG_PASSIVE: force passive scan on all channels
667 * @IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION: single channel scan
668 * @IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE: send iteration complete notification
669 * @IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS multiple SSID matching
670 * @IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED: all passive scans will be fragmented
671 */
672enum iwl_mvm_lmac_scan_flags {
673 IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL = BIT(0),
674 IWL_MVM_LMAC_SCAN_FLAG_PASSIVE = BIT(1),
675 IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION = BIT(2),
676 IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE = BIT(3),
677 IWL_MVM_LMAC_SCAN_FLAG_MULTIPLE_SSIDS = BIT(4),
678 IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED = BIT(5),
679};
680
681enum iwl_scan_priority {
682 IWL_SCAN_PRIORITY_LOW,
683 IWL_SCAN_PRIORITY_MEDIUM,
684 IWL_SCAN_PRIORITY_HIGH,
685};
686
687/**
688 * iwl_scan_req_unified_lmac - SCAN_REQUEST_CMD_API_S_VER_1
689 * @reserved1: for alignment and future use
690 * @channel_num: num of channels to scan
691 * @active-dwell: dwell time for active channels
692 * @passive-dwell: dwell time for passive channels
693 * @fragmented-dwell: dwell time for fragmented passive scan
694 * @reserved2: for alignment and future use
695 * @rx_chain_selct: PHY_RX_CHAIN_* flags
696 * @scan_flags: &enum iwl_mvm_lmac_scan_flags
697 * @max_out_time: max time (in TU) to be out of associated channel
698 * @suspend_time: pause scan this long (TUs) when returning to service channel
699 * @flags: RXON flags
700 * @filter_flags: RXON filter
701 * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz
702 * @direct_scan: list of SSIDs for directed active scan
703 * @scan_prio: enum iwl_scan_priority
704 * @iter_num: number of scan iterations
705 * @delay: delay in seconds before first iteration
706 * @schedule: two scheduling plans. The first one is finite, the second one can
707 * be infinite.
708 * @channel_opt: channel optimization options, for full and partial scan
709 * @data: channel configuration and probe request packet.
710 */
711struct iwl_scan_req_unified_lmac {
712 /* SCAN_REQUEST_FIXED_PART_API_S_VER_7 */
713 __le32 reserved1;
714 u8 n_channels;
715 u8 active_dwell;
716 u8 passive_dwell;
717 u8 fragmented_dwell;
718 __le16 reserved2;
719 __le16 rx_chain_select;
720 __le32 scan_flags;
721 __le32 max_out_time;
722 __le32 suspend_time;
723 /* RX_ON_FLAGS_API_S_VER_1 */
724 __le32 flags;
725 __le32 filter_flags;
726 struct iwl_scan_req_tx_cmd tx_cmd[2];
727 struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX];
728 __le32 scan_prio;
729 /* SCAN_REQ_PERIODIC_PARAMS_API_S */
730 __le32 iter_num;
731 __le32 delay;
732 struct iwl_scan_offload_schedule schedule[2];
733 struct iwl_scan_channel_opt channel_opt[2];
734 u8 data[];
735} __packed;
736
737/**
738 * struct iwl_lmac_scan_results_notif - scan results for one channel -
739 * SCAN_RESULT_NTF_API_S_VER_3
740 * @channel: which channel the results are from
741 * @band: 0 for 5.2 GHz, 1 for 2.4 GHz
742 * @probe_status: SCAN_PROBE_STATUS_*, indicates success of probe request
743 * @num_probe_not_sent: # of request that weren't sent due to not enough time
744 * @duration: duration spent in channel, in usecs
745 */
746struct iwl_lmac_scan_results_notif {
747 u8 channel;
748 u8 band;
749 u8 probe_status;
750 u8 num_probe_not_sent;
751 __le32 duration;
752} __packed;
753
754/**
755 * struct iwl_lmac_scan_complete_notif - notifies end of scanning (all channels)
756 * SCAN_COMPLETE_NTF_API_S_VER_3
757 * @scanned_channels: number of channels scanned (and number of valid results)
758 * @status: one of SCAN_COMP_STATUS_*
759 * @bt_status: BT on/off status
760 * @last_channel: last channel that was scanned
761 * @tsf_low: TSF timer (lower half) in usecs
762 * @tsf_high: TSF timer (higher half) in usecs
763 * @results: an array of scan results, only "scanned_channels" of them are valid
764 */
765struct iwl_lmac_scan_complete_notif {
766 u8 scanned_channels;
767 u8 status;
768 u8 bt_status;
769 u8 last_channel;
770 __le32 tsf_low;
771 __le32 tsf_high;
772 struct iwl_scan_results_notif results[];
773} __packed;
774
775/**
776 * iwl_scan_offload_complete - PERIODIC_SCAN_COMPLETE_NTF_API_S_VER_2
777 * @last_schedule_line: last schedule line executed (fast or regular)
778 * @last_schedule_iteration: last scan iteration executed before scan abort
779 * @status: enum iwl_scan_offload_complete_status
780 * @ebs_status: EBS success status &enum iwl_scan_ebs_status
781 * @time_after_last_iter; time in seconds elapsed after last iteration
782 */
783struct iwl_periodic_scan_complete {
784 u8 last_schedule_line;
785 u8 last_schedule_iteration;
786 u8 status;
787 u8 ebs_status;
788 __le32 time_after_last_iter;
789 __le32 reserved;
790} __packed;
791
604#endif 792#endif
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
index 39cebee8016f..47bd0406355d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h
@@ -67,7 +67,7 @@
67 * enum iwl_sta_flags - flags for the ADD_STA host command 67 * enum iwl_sta_flags - flags for the ADD_STA host command
68 * @STA_FLG_REDUCED_TX_PWR_CTRL: 68 * @STA_FLG_REDUCED_TX_PWR_CTRL:
69 * @STA_FLG_REDUCED_TX_PWR_DATA: 69 * @STA_FLG_REDUCED_TX_PWR_DATA:
70 * @STA_FLG_FLG_ANT_MSK: Antenna selection 70 * @STA_FLG_DISABLE_TX: set if TX should be disabled
71 * @STA_FLG_PS: set if STA is in Power Save 71 * @STA_FLG_PS: set if STA is in Power Save
72 * @STA_FLG_INVALID: set if STA is invalid 72 * @STA_FLG_INVALID: set if STA is invalid
73 * @STA_FLG_DLP_EN: Direct Link Protocol is enabled 73 * @STA_FLG_DLP_EN: Direct Link Protocol is enabled
@@ -91,10 +91,7 @@ enum iwl_sta_flags {
91 STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3), 91 STA_FLG_REDUCED_TX_PWR_CTRL = BIT(3),
92 STA_FLG_REDUCED_TX_PWR_DATA = BIT(6), 92 STA_FLG_REDUCED_TX_PWR_DATA = BIT(6),
93 93
94 STA_FLG_FLG_ANT_A = (1 << 4), 94 STA_FLG_DISABLE_TX = BIT(4),
95 STA_FLG_FLG_ANT_B = (2 << 4),
96 STA_FLG_FLG_ANT_MSK = (STA_FLG_FLG_ANT_A |
97 STA_FLG_FLG_ANT_B),
98 95
99 STA_FLG_PS = BIT(8), 96 STA_FLG_PS = BIT(8),
100 STA_FLG_DRAIN_FLOW = BIT(12), 97 STA_FLG_DRAIN_FLOW = BIT(12),
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
index 6cc5f52b807f..d6073f67b212 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-tx.h
@@ -69,10 +69,8 @@
69 * @TX_CMD_FLG_ACK: expect ACK from receiving station 69 * @TX_CMD_FLG_ACK: expect ACK from receiving station
70 * @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command. 70 * @TX_CMD_FLG_STA_RATE: use RS table with initial index from the TX command.
71 * Otherwise, use rate_n_flags from the TX command 71 * Otherwise, use rate_n_flags from the TX command
72 * @TX_CMD_FLG_BA: this frame is a block ack
73 * @TX_CMD_FLG_BAR: this frame is a BA request, immediate BAR is expected 72 * @TX_CMD_FLG_BAR: this frame is a BA request, immediate BAR is expected
74 * Must set TX_CMD_FLG_ACK with this flag. 73 * Must set TX_CMD_FLG_ACK with this flag.
75 * @TX_CMD_FLG_TXOP_PROT: protect frame with full TXOP protection
76 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence 74 * @TX_CMD_FLG_VHT_NDPA: mark frame is NDPA for VHT beamformer sequence
77 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence 75 * @TX_CMD_FLG_HT_NDPA: mark frame is NDPA for HT beamformer sequence
78 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC) 76 * @TX_CMD_FLG_CSI_FDBK2HOST: mark to send feedback to host (only if good CRC)
@@ -82,12 +80,10 @@
82 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control. 80 * @TX_CMD_FLG_SEQ_CTL: set if FW should override the sequence control.
83 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command 81 * Should be set for mgmt, non-QOS data, mcast, bcast and in scan command
84 * @TX_CMD_FLG_MORE_FRAG: this frame is non-last MPDU 82 * @TX_CMD_FLG_MORE_FRAG: this frame is non-last MPDU
85 * @TX_CMD_FLG_NEXT_FRAME: this frame includes information of the next frame
86 * @TX_CMD_FLG_TSF: FW should calculate and insert TSF in the frame 83 * @TX_CMD_FLG_TSF: FW should calculate and insert TSF in the frame
87 * Should be set for beacons and probe responses 84 * Should be set for beacons and probe responses
88 * @TX_CMD_FLG_CALIB: activate PA TX power calibrations 85 * @TX_CMD_FLG_CALIB: activate PA TX power calibrations
89 * @TX_CMD_FLG_KEEP_SEQ_CTL: if seq_ctl is set, don't increase inner seq count 86 * @TX_CMD_FLG_KEEP_SEQ_CTL: if seq_ctl is set, don't increase inner seq count
90 * @TX_CMD_FLG_AGG_START: allow this frame to start aggregation
91 * @TX_CMD_FLG_MH_PAD: driver inserted 2 byte padding after MAC header. 87 * @TX_CMD_FLG_MH_PAD: driver inserted 2 byte padding after MAC header.
92 * Should be set for 26/30 length MAC headers 88 * Should be set for 26/30 length MAC headers
93 * @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW 89 * @TX_CMD_FLG_RESP_TO_DRV: zero this if the response should go only to FW
@@ -103,7 +99,6 @@ enum iwl_tx_flags {
103 TX_CMD_FLG_PROT_REQUIRE = BIT(0), 99 TX_CMD_FLG_PROT_REQUIRE = BIT(0),
104 TX_CMD_FLG_ACK = BIT(3), 100 TX_CMD_FLG_ACK = BIT(3),
105 TX_CMD_FLG_STA_RATE = BIT(4), 101 TX_CMD_FLG_STA_RATE = BIT(4),
106 TX_CMD_FLG_BA = BIT(5),
107 TX_CMD_FLG_BAR = BIT(6), 102 TX_CMD_FLG_BAR = BIT(6),
108 TX_CMD_FLG_TXOP_PROT = BIT(7), 103 TX_CMD_FLG_TXOP_PROT = BIT(7),
109 TX_CMD_FLG_VHT_NDPA = BIT(8), 104 TX_CMD_FLG_VHT_NDPA = BIT(8),
@@ -113,11 +108,9 @@ enum iwl_tx_flags {
113 TX_CMD_FLG_BT_DIS = BIT(12), 108 TX_CMD_FLG_BT_DIS = BIT(12),
114 TX_CMD_FLG_SEQ_CTL = BIT(13), 109 TX_CMD_FLG_SEQ_CTL = BIT(13),
115 TX_CMD_FLG_MORE_FRAG = BIT(14), 110 TX_CMD_FLG_MORE_FRAG = BIT(14),
116 TX_CMD_FLG_NEXT_FRAME = BIT(15),
117 TX_CMD_FLG_TSF = BIT(16), 111 TX_CMD_FLG_TSF = BIT(16),
118 TX_CMD_FLG_CALIB = BIT(17), 112 TX_CMD_FLG_CALIB = BIT(17),
119 TX_CMD_FLG_KEEP_SEQ_CTL = BIT(18), 113 TX_CMD_FLG_KEEP_SEQ_CTL = BIT(18),
120 TX_CMD_FLG_AGG_START = BIT(19),
121 TX_CMD_FLG_MH_PAD = BIT(20), 114 TX_CMD_FLG_MH_PAD = BIT(20),
122 TX_CMD_FLG_RESP_TO_DRV = BIT(21), 115 TX_CMD_FLG_RESP_TO_DRV = BIT(21),
123 TX_CMD_FLG_CCMP_AGG = BIT(22), 116 TX_CMD_FLG_CCMP_AGG = BIT(22),
@@ -191,8 +184,6 @@ enum iwl_tx_flags {
191 * struct iwl_tx_cmd - TX command struct to FW 184 * struct iwl_tx_cmd - TX command struct to FW
192 * ( TX_CMD = 0x1c ) 185 * ( TX_CMD = 0x1c )
193 * @len: in bytes of the payload, see below for details 186 * @len: in bytes of the payload, see below for details
194 * @next_frame_len: same as len, but for next frame (0 if not applicable)
195 * Used for fragmentation and bursting, but not in 11n aggregation.
196 * @tx_flags: combination of TX_CMD_FLG_* 187 * @tx_flags: combination of TX_CMD_FLG_*
197 * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is 188 * @rate_n_flags: rate for *all* Tx attempts, if TX_CMD_FLG_STA_RATE_MSK is
198 * cleared. Combination of RATE_MCS_* 189 * cleared. Combination of RATE_MCS_*
@@ -210,8 +201,6 @@ enum iwl_tx_flags {
210 * @data_retry_limit: max attempts to send the data packet 201 * @data_retry_limit: max attempts to send the data packet
211 * @tid_spec: TID/tspec 202 * @tid_spec: TID/tspec
212 * @pm_frame_timeout: PM TX frame timeout 203 * @pm_frame_timeout: PM TX frame timeout
213 * @driver_txop: duration od EDCA TXOP, in 32-usec units. Set this if not
214 * specified by HCCA protocol
215 * 204 *
216 * The byte count (both len and next_frame_len) includes MAC header 205 * The byte count (both len and next_frame_len) includes MAC header
217 * (24/26/30/32 bytes) 206 * (24/26/30/32 bytes)
@@ -241,8 +230,7 @@ struct iwl_tx_cmd {
241 u8 initial_rate_index; 230 u8 initial_rate_index;
242 u8 reserved2; 231 u8 reserved2;
243 u8 key[16]; 232 u8 key[16];
244 __le16 next_frame_flags; 233 __le32 reserved3;
245 __le16 reserved3;
246 __le32 life_time; 234 __le32 life_time;
247 __le32 dram_lsb_ptr; 235 __le32 dram_lsb_ptr;
248 u8 dram_msb_ptr; 236 u8 dram_msb_ptr;
@@ -250,7 +238,7 @@ struct iwl_tx_cmd {
250 u8 data_retry_limit; 238 u8 data_retry_limit;
251 u8 tid_tspec; 239 u8 tid_tspec;
252 __le16 pm_frame_timeout; 240 __le16 pm_frame_timeout;
253 __le16 driver_txop; 241 __le16 reserved4;
254 u8 payload[0]; 242 u8 payload[0];
255 struct ieee80211_hdr hdr[0]; 243 struct ieee80211_hdr hdr[0];
256} __packed; /* TX_CMD_API_S_VER_3 */ 244} __packed; /* TX_CMD_API_S_VER_3 */
@@ -549,6 +537,20 @@ struct iwl_beacon_notif {
549} __packed; 537} __packed;
550 538
551/** 539/**
540 * struct iwl_extended_beacon_notif - notifies about beacon transmission
541 * @beacon_notify_hdr: tx response command associated with the beacon
542 * @tsf: last beacon tsf
543 * @ibss_mgr_status: whether IBSS is manager
544 * @gp2: last beacon time in gp2
545 */
546struct iwl_extended_beacon_notif {
547 struct iwl_mvm_tx_resp beacon_notify_hdr;
548 __le64 tsf;
549 __le32 ibss_mgr_status;
550 __le32 gp2;
551} __packed; /* BEACON_NTFY_API_S_VER_5 */
552
553/**
552 * enum iwl_dump_control - dump (flush) control flags 554 * enum iwl_dump_control - dump (flush) control flags
553 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty 555 * @DUMP_TX_FIFO_FLUSH: Dump MSDUs until the the FIFO is empty
554 * and the TFD queues are empty. 556 * and the TFD queues are empty.
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 309a9b9a94fe..b8e4e78d601b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -86,6 +86,8 @@ enum {
86 86
87#define IWL_MVM_STATION_COUNT 16 87#define IWL_MVM_STATION_COUNT 16
88 88
89#define IWL_MVM_TDLS_STA_COUNT 4
90
89/* commands */ 91/* commands */
90enum { 92enum {
91 MVM_ALIVE = 0x1, 93 MVM_ALIVE = 0x1,
@@ -135,6 +137,7 @@ enum {
135 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, 137 SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E,
136 SCAN_OFFLOAD_CONFIG_CMD = 0x6f, 138 SCAN_OFFLOAD_CONFIG_CMD = 0x6f,
137 MATCH_FOUND_NOTIFICATION = 0xd9, 139 MATCH_FOUND_NOTIFICATION = 0xd9,
140 SCAN_ITERATION_COMPLETE = 0xe7,
138 141
139 /* Phy */ 142 /* Phy */
140 PHY_CONFIGURATION_CMD = 0x6a, 143 PHY_CONFIGURATION_CMD = 0x6a,
@@ -163,7 +166,6 @@ enum {
163 BEACON_NOTIFICATION = 0x90, 166 BEACON_NOTIFICATION = 0x90,
164 BEACON_TEMPLATE_CMD = 0x91, 167 BEACON_TEMPLATE_CMD = 0x91,
165 TX_ANT_CONFIGURATION_CMD = 0x98, 168 TX_ANT_CONFIGURATION_CMD = 0x98,
166 BT_CONFIG = 0x9b,
167 STATISTICS_NOTIFICATION = 0x9d, 169 STATISTICS_NOTIFICATION = 0x9d,
168 EOSP_NOTIFICATION = 0x9e, 170 EOSP_NOTIFICATION = 0x9e,
169 REDUCE_TX_POWER_CMD = 0x9f, 171 REDUCE_TX_POWER_CMD = 0x9f,
@@ -185,6 +187,10 @@ enum {
185 BT_COEX_PRIO_TABLE = 0xcc, 187 BT_COEX_PRIO_TABLE = 0xcc,
186 BT_COEX_PROT_ENV = 0xcd, 188 BT_COEX_PROT_ENV = 0xcd,
187 BT_PROFILE_NOTIFICATION = 0xce, 189 BT_PROFILE_NOTIFICATION = 0xce,
190 BT_CONFIG = 0x9b,
191 BT_COEX_UPDATE_SW_BOOST = 0x5a,
192 BT_COEX_UPDATE_CORUN_LUT = 0x5b,
193 BT_COEX_UPDATE_REDUCED_TXP = 0x5c,
188 BT_COEX_CI = 0x5d, 194 BT_COEX_CI = 0x5d,
189 195
190 REPLY_SF_CFG_CMD = 0xd1, 196 REPLY_SF_CFG_CMD = 0xd1,
@@ -534,6 +540,9 @@ enum iwl_time_event_type {
534 /* WiDi Sync Events */ 540 /* WiDi Sync Events */
535 TE_WIDI_TX_SYNC, 541 TE_WIDI_TX_SYNC,
536 542
543 /* Channel Switch NoA */
544 TE_P2P_GO_CSA_NOA,
545
537 TE_MAX 546 TE_MAX
538}; /* MAC_EVENT_TYPE_API_E_VER_1 */ 547}; /* MAC_EVENT_TYPE_API_E_VER_1 */
539 548
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 8b5302777632..96b9cf8137e7 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -67,6 +67,7 @@
67#include "iwl-prph.h" 67#include "iwl-prph.h"
68#include "fw-api.h" 68#include "fw-api.h"
69#include "mvm.h" 69#include "mvm.h"
70#include "time-event.h"
70 71
71const u8 iwl_mvm_ac_to_tx_fifo[] = { 72const u8 iwl_mvm_ac_to_tx_fifo[] = {
72 IWL_MVM_TX_FIFO_VO, 73 IWL_MVM_TX_FIFO_VO,
@@ -667,10 +668,9 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
667 if (vif->bss_conf.qos) 668 if (vif->bss_conf.qos)
668 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); 669 cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA);
669 670
670 if (vif->bss_conf.use_cts_prot) { 671 if (vif->bss_conf.use_cts_prot)
671 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); 672 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT);
672 cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN); 673
673 }
674 IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n", 674 IWL_DEBUG_RATE(mvm, "use_cts_prot %d, ht_operation_mode %d\n",
675 vif->bss_conf.use_cts_prot, 675 vif->bss_conf.use_cts_prot,
676 vif->bss_conf.ht_operation_mode); 676 vif->bss_conf.ht_operation_mode);
@@ -904,7 +904,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
904 struct iwl_mac_beacon_cmd beacon_cmd = {}; 904 struct iwl_mac_beacon_cmd beacon_cmd = {};
905 struct ieee80211_tx_info *info; 905 struct ieee80211_tx_info *info;
906 u32 beacon_skb_len; 906 u32 beacon_skb_len;
907 u32 rate; 907 u32 rate, tx_flags;
908 908
909 if (WARN_ON(!beacon)) 909 if (WARN_ON(!beacon))
910 return -EINVAL; 910 return -EINVAL;
@@ -914,14 +914,17 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
914 /* TODO: for now the beacon template id is set to be the mac context id. 914 /* TODO: for now the beacon template id is set to be the mac context id.
915 * Might be better to handle it as another resource ... */ 915 * Might be better to handle it as another resource ... */
916 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id); 916 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id);
917 info = IEEE80211_SKB_CB(beacon);
917 918
918 /* Set up TX command fields */ 919 /* Set up TX command fields */
919 beacon_cmd.tx.len = cpu_to_le16((u16)beacon_skb_len); 920 beacon_cmd.tx.len = cpu_to_le16((u16)beacon_skb_len);
920 beacon_cmd.tx.sta_id = mvmvif->bcast_sta.sta_id; 921 beacon_cmd.tx.sta_id = mvmvif->bcast_sta.sta_id;
921 beacon_cmd.tx.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); 922 beacon_cmd.tx.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
922 beacon_cmd.tx.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | 923 tx_flags = TX_CMD_FLG_SEQ_CTL | TX_CMD_FLG_TSF;
923 TX_CMD_FLG_BT_DIS | 924 tx_flags |=
924 TX_CMD_FLG_TSF); 925 iwl_mvm_bt_coex_tx_prio(mvm, (void *)beacon->data, info, 0) <<
926 TX_CMD_FLG_BT_PRIO_POS;
927 beacon_cmd.tx.tx_flags = cpu_to_le32(tx_flags);
925 928
926 mvm->mgmt_last_antenna_idx = 929 mvm->mgmt_last_antenna_idx =
927 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 930 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
@@ -931,8 +934,6 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
931 cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) << 934 cpu_to_le32(BIT(mvm->mgmt_last_antenna_idx) <<
932 RATE_MCS_ANT_POS); 935 RATE_MCS_ANT_POS);
933 936
934 info = IEEE80211_SKB_CB(beacon);
935
936 if (info->band == IEEE80211_BAND_5GHZ || vif->p2p) { 937 if (info->band == IEEE80211_BAND_5GHZ || vif->p2p) {
937 rate = IWL_FIRST_OFDM_RATE; 938 rate = IWL_FIRST_OFDM_RATE;
938 } else { 939 } else {
@@ -969,7 +970,7 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
969 WARN_ON(vif->type != NL80211_IFTYPE_AP && 970 WARN_ON(vif->type != NL80211_IFTYPE_AP &&
970 vif->type != NL80211_IFTYPE_ADHOC); 971 vif->type != NL80211_IFTYPE_ADHOC);
971 972
972 beacon = ieee80211_beacon_get(mvm->hw, vif); 973 beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL);
973 if (!beacon) 974 if (!beacon)
974 return -ENOMEM; 975 return -ENOMEM;
975 976
@@ -1200,31 +1201,94 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1200 return 0; 1201 return 0;
1201} 1202}
1202 1203
1204static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm,
1205 struct ieee80211_vif *csa_vif, u32 gp2)
1206{
1207 struct iwl_mvm_vif *mvmvif =
1208 iwl_mvm_vif_from_mac80211(csa_vif);
1209
1210 if (!ieee80211_csa_is_complete(csa_vif)) {
1211 int c = ieee80211_csa_update_counter(csa_vif);
1212
1213 iwl_mvm_mac_ctxt_beacon_changed(mvm, csa_vif);
1214 if (csa_vif->p2p &&
1215 !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) {
1216 u32 rel_time = (c + 1) *
1217 csa_vif->bss_conf.beacon_int -
1218 IWL_MVM_CHANNEL_SWITCH_TIME;
1219 u32 apply_time = gp2 + rel_time * 1024;
1220
1221 iwl_mvm_schedule_csa_noa(mvm, csa_vif,
1222 IWL_MVM_CHANNEL_SWITCH_TIME -
1223 IWL_MVM_CHANNEL_SWITCH_MARGIN,
1224 apply_time);
1225 }
1226 } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) {
1227 /* we don't have CSA NoA scheduled yet, switch now */
1228 ieee80211_csa_finish(csa_vif);
1229 RCU_INIT_POINTER(mvm->csa_vif, NULL);
1230 }
1231}
1232
1203int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm, 1233int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1204 struct iwl_rx_cmd_buffer *rxb, 1234 struct iwl_rx_cmd_buffer *rxb,
1205 struct iwl_device_cmd *cmd) 1235 struct iwl_device_cmd *cmd)
1206{ 1236{
1207 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1237 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1208 struct iwl_beacon_notif *beacon = (void *)pkt->data; 1238 struct iwl_mvm_tx_resp *beacon_notify_hdr;
1209 u16 status __maybe_unused = 1239 struct ieee80211_vif *csa_vif;
1210 le16_to_cpu(beacon->beacon_notify_hdr.status.status); 1240 struct ieee80211_vif *tx_blocked_vif;
1211 u32 rate __maybe_unused = 1241 u64 tsf;
1212 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
1213 1242
1214 lockdep_assert_held(&mvm->mutex); 1243 lockdep_assert_held(&mvm->mutex);
1215 1244
1216 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n", 1245 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_CAPA_EXTENDED_BEACON) {
1217 status & TX_STATUS_MSK, 1246 struct iwl_extended_beacon_notif *beacon = (void *)pkt->data;
1218 beacon->beacon_notify_hdr.failure_frame,
1219 le64_to_cpu(beacon->tsf),
1220 rate);
1221 1247
1222 if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) { 1248 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1223 if (!ieee80211_csa_is_complete(mvm->csa_vif)) { 1249 tsf = le64_to_cpu(beacon->tsf);
1224 iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm->csa_vif); 1250 mvm->ap_last_beacon_gp2 = le32_to_cpu(beacon->gp2);
1225 } else { 1251 } else {
1226 ieee80211_csa_finish(mvm->csa_vif); 1252 struct iwl_beacon_notif *beacon = (void *)pkt->data;
1227 mvm->csa_vif = NULL; 1253
1254 beacon_notify_hdr = &beacon->beacon_notify_hdr;
1255 tsf = le64_to_cpu(beacon->tsf);
1256 }
1257
1258 IWL_DEBUG_RX(mvm,
1259 "beacon status %#x retries:%d tsf:0x%16llX gp2:0x%X rate:%d\n",
1260 le16_to_cpu(beacon_notify_hdr->status.status) &
1261 TX_STATUS_MSK,
1262 beacon_notify_hdr->failure_frame, tsf,
1263 mvm->ap_last_beacon_gp2,
1264 le32_to_cpu(beacon_notify_hdr->initial_rate));
1265
1266 csa_vif = rcu_dereference_protected(mvm->csa_vif,
1267 lockdep_is_held(&mvm->mutex));
1268 if (unlikely(csa_vif && csa_vif->csa_active))
1269 iwl_mvm_csa_count_down(mvm, csa_vif, mvm->ap_last_beacon_gp2);
1270
1271 tx_blocked_vif = rcu_dereference_protected(mvm->csa_tx_blocked_vif,
1272 lockdep_is_held(&mvm->mutex));
1273 if (unlikely(tx_blocked_vif)) {
1274 struct iwl_mvm_vif *mvmvif =
1275 iwl_mvm_vif_from_mac80211(tx_blocked_vif);
1276
1277 /*
1278 * The channel switch is started and we have blocked the
1279 * stations. If this is the first beacon (the timeout wasn't
1280 * set), set the unblock timeout, otherwise countdown
1281 */
1282 if (!mvm->csa_tx_block_bcn_timeout)
1283 mvm->csa_tx_block_bcn_timeout =
1284 IWL_MVM_CS_UNBLOCK_TX_TIMEOUT;
1285 else
1286 mvm->csa_tx_block_bcn_timeout--;
1287
1288 /* Check if the timeout is expired, and unblock tx */
1289 if (mvm->csa_tx_block_bcn_timeout == 0) {
1290 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, false);
1291 RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
1228 } 1292 }
1229 } 1293 }
1230 1294
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7215f5980186..2eb6ebee4467 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -80,6 +80,8 @@
80#include "fw-api-scan.h" 80#include "fw-api-scan.h"
81#include "iwl-phy-db.h" 81#include "iwl-phy-db.h"
82#include "testmode.h" 82#include "testmode.h"
83#include "iwl-fw-error-dump.h"
84#include "iwl-prph.h"
83 85
84static const struct ieee80211_iface_limit iwl_mvm_limits[] = { 86static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
85 { 87 {
@@ -241,6 +243,21 @@ iwl_mvm_unref_all_except(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref)
241 } 243 }
242} 244}
243 245
246static int iwl_mvm_ref_sync(struct iwl_mvm *mvm, enum iwl_mvm_ref_type ref_type)
247{
248 iwl_mvm_ref(mvm, ref_type);
249
250 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
251 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status),
252 HZ)) {
253 WARN_ON_ONCE(1);
254 iwl_mvm_unref(mvm, ref_type);
255 return -EIO;
256 }
257
258 return 0;
259}
260
244static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) 261static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
245{ 262{
246 int i; 263 int i;
@@ -276,6 +293,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
276 IEEE80211_HW_AMPDU_AGGREGATION | 293 IEEE80211_HW_AMPDU_AGGREGATION |
277 IEEE80211_HW_TIMING_BEACON_ONLY | 294 IEEE80211_HW_TIMING_BEACON_ONLY |
278 IEEE80211_HW_CONNECTION_MONITOR | 295 IEEE80211_HW_CONNECTION_MONITOR |
296 IEEE80211_HW_CHANCTX_STA_CSA |
279 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 297 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
280 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 298 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
281 299
@@ -303,6 +321,16 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
303 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; 321 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
304 } 322 }
305 323
324 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT &&
325 !iwlwifi_mod_params.uapsd_disable) {
326 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
327 hw->uapsd_queues = IWL_UAPSD_AC_INFO;
328 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
329 }
330
331 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
332 hw->flags |= IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS;
333
306 hw->sta_data_size = sizeof(struct iwl_mvm_sta); 334 hw->sta_data_size = sizeof(struct iwl_mvm_sta);
307 hw->vif_data_size = sizeof(struct iwl_mvm_vif); 335 hw->vif_data_size = sizeof(struct iwl_mvm_vif);
308 hw->chanctx_data_size = sizeof(u16); 336 hw->chanctx_data_size = sizeof(u16);
@@ -374,6 +402,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
374 hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2; 402 hw->wiphy->max_sched_scan_ie_len = SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2;
375 403
376 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 404 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
405 NL80211_FEATURE_LOW_PRIORITY_SCAN |
377 NL80211_FEATURE_P2P_GO_OPPPS; 406 NL80211_FEATURE_P2P_GO_OPPPS;
378 407
379 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 408 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
@@ -549,9 +578,6 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
549 case IEEE80211_AMPDU_TX_STOP_FLUSH: 578 case IEEE80211_AMPDU_TX_STOP_FLUSH:
550 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 579 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
551 case IEEE80211_AMPDU_TX_OPERATIONAL: 580 case IEEE80211_AMPDU_TX_OPERATIONAL:
552 iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
553 tx_agg_ref = true;
554
555 /* 581 /*
556 * for tx start, wait synchronously until D0i3 exit to 582 * for tx start, wait synchronously until D0i3 exit to
557 * get the correct sequence number for the tid. 583 * get the correct sequence number for the tid.
@@ -560,12 +586,11 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
560 * by the trans layer (unlike commands), so wait for 586 * by the trans layer (unlike commands), so wait for
561 * d0i3 exit in these cases as well. 587 * d0i3 exit in these cases as well.
562 */ 588 */
563 if (!wait_event_timeout(mvm->d0i3_exit_waitq, 589 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_TX_AGG);
564 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) { 590 if (ret)
565 WARN_ON_ONCE(1); 591 return ret;
566 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG); 592
567 return -EIO; 593 tx_agg_ref = true;
568 }
569 break; 594 break;
570 default: 595 default:
571 break; 596 break;
@@ -637,6 +662,104 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
637 mvmvif->phy_ctxt = NULL; 662 mvmvif->phy_ctxt = NULL;
638} 663}
639 664
665#ifdef CONFIG_IWLWIFI_DEBUGFS
666static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
667{
668 struct iwl_fw_error_dump_file *dump_file;
669 struct iwl_fw_error_dump_data *dump_data;
670 struct iwl_fw_error_dump_info *dump_info;
671 const struct fw_img *img;
672 u32 sram_len, sram_ofs;
673 u32 file_len, rxf_len;
674 unsigned long flags;
675 u32 trans_len;
676 int reg_val;
677
678 lockdep_assert_held(&mvm->mutex);
679
680 if (mvm->fw_error_dump)
681 return;
682
683 img = &mvm->fw->img[mvm->cur_ucode];
684 sram_ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
685 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
686
687 /* reading buffer size */
688 reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
689 rxf_len = (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
690
691 /* the register holds the value divided by 128 */
692 rxf_len = rxf_len << 7;
693
694 file_len = sizeof(*dump_file) +
695 sizeof(*dump_data) * 3 +
696 sram_len +
697 rxf_len +
698 sizeof(*dump_info);
699
700 trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
701 if (trans_len)
702 file_len += trans_len;
703
704 dump_file = vzalloc(file_len);
705 if (!dump_file)
706 return;
707
708 mvm->fw_error_dump = dump_file;
709
710 dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
711 dump_file->file_len = cpu_to_le32(file_len);
712 dump_data = (void *)dump_file->data;
713
714 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_DEV_FW_INFO);
715 dump_data->len = cpu_to_le32(sizeof(*dump_info));
716 dump_info = (void *) dump_data->data;
717 dump_info->device_family =
718 mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000 ?
719 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_7) :
720 cpu_to_le32(IWL_FW_ERROR_DUMP_FAMILY_8);
721 memcpy(dump_info->fw_human_readable, mvm->fw->human_readable,
722 sizeof(dump_info->fw_human_readable));
723 strncpy(dump_info->dev_human_readable, mvm->cfg->name,
724 sizeof(dump_info->dev_human_readable));
725 strncpy(dump_info->bus_human_readable, mvm->dev->bus->name,
726 sizeof(dump_info->bus_human_readable));
727
728 dump_data = iwl_fw_error_next_data(dump_data);
729 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
730 dump_data->len = cpu_to_le32(rxf_len);
731
732 if (iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
733 u32 *rxf = (void *)dump_data->data;
734 int i;
735
736 for (i = 0; i < (rxf_len / sizeof(u32)); i++) {
737 iwl_trans_write_prph(mvm->trans,
738 RXF_LD_FENCE_OFFSET_ADDR,
739 i * sizeof(u32));
740 rxf[i] = iwl_trans_read_prph(mvm->trans,
741 RXF_FIFO_RD_FENCE_ADDR);
742 }
743 iwl_trans_release_nic_access(mvm->trans, &flags);
744 }
745
746 dump_data = iwl_fw_error_next_data(dump_data);
747 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
748 dump_data->len = cpu_to_le32(sram_len);
749 iwl_trans_read_mem_bytes(mvm->trans, sram_ofs, dump_data->data,
750 sram_len);
751
752 if (trans_len) {
753 void *buf = iwl_fw_error_next_data(dump_data);
754 u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
755 trans_len);
756 dump_data = (void *)((u8 *)buf + real_trans_len);
757 dump_file->file_len =
758 cpu_to_le32(file_len - trans_len + real_trans_len);
759 }
760}
761#endif
762
640static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 763static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
641{ 764{
642#ifdef CONFIG_IWLWIFI_DEBUGFS 765#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -688,6 +811,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
688 iwl_mvm_restart_cleanup(mvm); 811 iwl_mvm_restart_cleanup(mvm);
689 812
690 ret = iwl_mvm_up(mvm); 813 ret = iwl_mvm_up(mvm);
814
815 if (ret && test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
816 /* Something went wrong - we need to finish some cleanup
817 * that normally iwl_mvm_mac_restart_complete() below
818 * would do.
819 */
820 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
821 iwl_mvm_d0i3_enable_tx(mvm, NULL);
822 }
823
691 mutex_unlock(&mvm->mutex); 824 mutex_unlock(&mvm->mutex);
692 825
693 return ret; 826 return ret;
@@ -786,6 +919,15 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
786 int ret; 919 int ret;
787 920
788 /* 921 /*
922 * make sure D0i3 exit is completed, otherwise a target access
923 * during tx queue configuration could be done when still in
924 * D0i3 state.
925 */
926 ret = iwl_mvm_ref_sync(mvm, IWL_MVM_REF_ADD_IF);
927 if (ret)
928 return ret;
929
930 /*
789 * Not much to do here. The stack will not allow interface 931 * Not much to do here. The stack will not allow interface
790 * types or combinations that we didn't advertise, so we 932 * types or combinations that we didn't advertise, so we
791 * don't really have to check the types. 933 * don't really have to check the types.
@@ -899,6 +1041,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
899 out_unlock: 1041 out_unlock:
900 mutex_unlock(&mvm->mutex); 1042 mutex_unlock(&mvm->mutex);
901 1043
1044 iwl_mvm_unref(mvm, IWL_MVM_REF_ADD_IF);
1045
902 return ret; 1046 return ret;
903} 1047}
904 1048
@@ -1159,8 +1303,12 @@ static void iwl_mvm_bcast_filter_iterator(void *_data, u8 *mac,
1159 1303
1160 bcast_mac = &cmd->macs[mvmvif->id]; 1304 bcast_mac = &cmd->macs[mvmvif->id];
1161 1305
1162 /* enable filtering only for associated stations */ 1306 /*
1163 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) 1307 * enable filtering only for associated stations, but not for P2P
1308 * Clients
1309 */
1310 if (vif->type != NL80211_IFTYPE_STATION || vif->p2p ||
1311 !vif->bss_conf.assoc)
1164 return; 1312 return;
1165 1313
1166 bcast_mac->default_discard = 1; 1314 bcast_mac->default_discard = 1;
@@ -1237,10 +1385,6 @@ static int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
1237 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING)) 1385 if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING))
1238 return 0; 1386 return 0;
1239 1387
1240 /* bcast filtering isn't supported for P2P client */
1241 if (vif->p2p)
1242 return 0;
1243
1244 if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) 1388 if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd))
1245 return 0; 1389 return 0;
1246 1390
@@ -1278,7 +1422,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1278 if (changes & BSS_CHANGED_ASSOC) { 1422 if (changes & BSS_CHANGED_ASSOC) {
1279 if (bss_conf->assoc) { 1423 if (bss_conf->assoc) {
1280 /* add quota for this interface */ 1424 /* add quota for this interface */
1281 ret = iwl_mvm_update_quotas(mvm, vif); 1425 ret = iwl_mvm_update_quotas(mvm, NULL);
1282 if (ret) { 1426 if (ret) {
1283 IWL_ERR(mvm, "failed to update quotas\n"); 1427 IWL_ERR(mvm, "failed to update quotas\n");
1284 return; 1428 return;
@@ -1425,7 +1569,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
1425 /* power updated needs to be done before quotas */ 1569 /* power updated needs to be done before quotas */
1426 iwl_mvm_power_update_mac(mvm); 1570 iwl_mvm_power_update_mac(mvm);
1427 1571
1428 ret = iwl_mvm_update_quotas(mvm, vif); 1572 ret = iwl_mvm_update_quotas(mvm, NULL);
1429 if (ret) 1573 if (ret)
1430 goto out_quota_failed; 1574 goto out_quota_failed;
1431 1575
@@ -1463,7 +1607,20 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
1463 1607
1464 mutex_lock(&mvm->mutex); 1608 mutex_lock(&mvm->mutex);
1465 1609
1610 /* Handle AP stop while in CSA */
1611 if (rcu_access_pointer(mvm->csa_vif) == vif) {
1612 iwl_mvm_remove_time_event(mvm, mvmvif,
1613 &mvmvif->time_event_data);
1614 RCU_INIT_POINTER(mvm->csa_vif, NULL);
1615 }
1616
1617 if (rcu_access_pointer(mvm->csa_tx_blocked_vif) == vif) {
1618 RCU_INIT_POINTER(mvm->csa_tx_blocked_vif, NULL);
1619 mvm->csa_tx_block_bcn_timeout = 0;
1620 }
1621
1466 mvmvif->ap_ibss_active = false; 1622 mvmvif->ap_ibss_active = false;
1623 mvm->ap_last_beacon_gp2 = 0;
1467 1624
1468 iwl_mvm_bt_coex_vif_change(mvm); 1625 iwl_mvm_bt_coex_vif_change(mvm);
1469 1626
@@ -1517,7 +1674,7 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
1517 mutex_lock(&mvm->mutex); 1674 mutex_lock(&mvm->mutex);
1518 1675
1519 if (changes & BSS_CHANGED_IDLE && !bss_conf->idle) 1676 if (changes & BSS_CHANGED_IDLE && !bss_conf->idle)
1520 iwl_mvm_sched_scan_stop(mvm, true); 1677 iwl_mvm_scan_offload_stop(mvm, true);
1521 1678
1522 switch (vif->type) { 1679 switch (vif->type) {
1523 case NL80211_IFTYPE_STATION: 1680 case NL80211_IFTYPE_STATION:
@@ -1537,19 +1694,21 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
1537 1694
1538static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw, 1695static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1539 struct ieee80211_vif *vif, 1696 struct ieee80211_vif *vif,
1540 struct cfg80211_scan_request *req) 1697 struct ieee80211_scan_request *hw_req)
1541{ 1698{
1542 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1699 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1700 struct cfg80211_scan_request *req = &hw_req->req;
1543 int ret; 1701 int ret;
1544 1702
1545 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS) 1703 if (req->n_channels == 0 ||
1704 req->n_channels > mvm->fw->ucode_capa.n_scan_channels)
1546 return -EINVAL; 1705 return -EINVAL;
1547 1706
1548 mutex_lock(&mvm->mutex); 1707 mutex_lock(&mvm->mutex);
1549 1708
1550 switch (mvm->scan_status) { 1709 switch (mvm->scan_status) {
1551 case IWL_MVM_SCAN_SCHED: 1710 case IWL_MVM_SCAN_SCHED:
1552 ret = iwl_mvm_sched_scan_stop(mvm, true); 1711 ret = iwl_mvm_scan_offload_stop(mvm, true);
1553 if (ret) { 1712 if (ret) {
1554 ret = -EBUSY; 1713 ret = -EBUSY;
1555 goto out; 1714 goto out;
@@ -1564,7 +1723,11 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1564 1723
1565 iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN); 1724 iwl_mvm_ref(mvm, IWL_MVM_REF_SCAN);
1566 1725
1567 ret = iwl_mvm_scan_request(mvm, vif, req); 1726 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
1727 ret = iwl_mvm_unified_scan_lmac(mvm, vif, hw_req);
1728 else
1729 ret = iwl_mvm_scan_request(mvm, vif, req);
1730
1568 if (ret) 1731 if (ret)
1569 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN); 1732 iwl_mvm_unref(mvm, IWL_MVM_REF_SCAN);
1570out: 1733out:
@@ -1680,6 +1843,70 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
1680 mutex_unlock(&mvm->mutex); 1843 mutex_unlock(&mvm->mutex);
1681} 1844}
1682 1845
1846int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1847{
1848 struct ieee80211_sta *sta;
1849 struct iwl_mvm_sta *mvmsta;
1850 int count = 0;
1851 int i;
1852
1853 lockdep_assert_held(&mvm->mutex);
1854
1855 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
1856 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
1857 lockdep_is_held(&mvm->mutex));
1858 if (!sta || IS_ERR(sta) || !sta->tdls)
1859 continue;
1860
1861 if (vif) {
1862 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1863 if (mvmsta->vif != vif)
1864 continue;
1865 }
1866
1867 count++;
1868 }
1869
1870 return count;
1871}
1872
1873static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm,
1874 struct ieee80211_vif *vif,
1875 bool sta_added)
1876{
1877 int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);
1878
1879 /*
1880 * Disable ps when the first TDLS sta is added and re-enable it
1881 * when the last TDLS sta is removed
1882 */
1883 if ((tdls_sta_cnt == 1 && sta_added) ||
1884 (tdls_sta_cnt == 0 && !sta_added))
1885 iwl_mvm_power_update_mac(mvm);
1886}
1887
1888static void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
1889{
1890 struct ieee80211_sta *sta;
1891 struct iwl_mvm_sta *mvmsta;
1892 int i;
1893
1894 lockdep_assert_held(&mvm->mutex);
1895
1896 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
1897 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
1898 lockdep_is_held(&mvm->mutex));
1899 if (!sta || IS_ERR(sta) || !sta->tdls)
1900 continue;
1901
1902 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1903 ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
1904 NL80211_TDLS_TEARDOWN,
1905 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
1906 GFP_KERNEL);
1907 }
1908}
1909
1683static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 1910static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1684 struct ieee80211_vif *vif, 1911 struct ieee80211_vif *vif,
1685 struct ieee80211_sta *sta, 1912 struct ieee80211_sta *sta,
@@ -1718,7 +1945,20 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1718 ret = -EINVAL; 1945 ret = -EINVAL;
1719 goto out_unlock; 1946 goto out_unlock;
1720 } 1947 }
1948
1949 if (sta->tdls &&
1950 (vif->p2p ||
1951 iwl_mvm_tdls_sta_count(mvm, NULL) ==
1952 IWL_MVM_TDLS_STA_COUNT ||
1953 iwl_mvm_phy_ctx_count(mvm) > 1)) {
1954 IWL_DEBUG_MAC80211(mvm, "refusing TDLS sta\n");
1955 ret = -EBUSY;
1956 goto out_unlock;
1957 }
1958
1721 ret = iwl_mvm_add_sta(mvm, vif, sta); 1959 ret = iwl_mvm_add_sta(mvm, vif, sta);
1960 if (sta->tdls && ret == 0)
1961 iwl_mvm_recalc_tdls_state(mvm, vif, true);
1722 } else if (old_state == IEEE80211_STA_NONE && 1962 } else if (old_state == IEEE80211_STA_NONE &&
1723 new_state == IEEE80211_STA_AUTH) { 1963 new_state == IEEE80211_STA_AUTH) {
1724 /* 1964 /*
@@ -1736,6 +1976,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1736 true); 1976 true);
1737 } else if (old_state == IEEE80211_STA_ASSOC && 1977 } else if (old_state == IEEE80211_STA_ASSOC &&
1738 new_state == IEEE80211_STA_AUTHORIZED) { 1978 new_state == IEEE80211_STA_AUTHORIZED) {
1979
1980 /* we don't support TDLS during DCM */
1981 if (iwl_mvm_phy_ctx_count(mvm) > 1)
1982 iwl_mvm_teardown_tdls_peers(mvm);
1983
1739 /* enable beacon filtering */ 1984 /* enable beacon filtering */
1740 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0)); 1985 WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
1741 ret = 0; 1986 ret = 0;
@@ -1753,6 +1998,8 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
1753 } else if (old_state == IEEE80211_STA_NONE && 1998 } else if (old_state == IEEE80211_STA_NONE &&
1754 new_state == IEEE80211_STA_NOTEXIST) { 1999 new_state == IEEE80211_STA_NOTEXIST) {
1755 ret = iwl_mvm_rm_sta(mvm, vif, sta); 2000 ret = iwl_mvm_rm_sta(mvm, vif, sta);
2001 if (sta->tdls)
2002 iwl_mvm_recalc_tdls_state(mvm, vif, false);
1756 } else { 2003 } else {
1757 ret = -EIO; 2004 ret = -EIO;
1758 } 2005 }
@@ -1824,10 +2071,22 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
1824 mutex_unlock(&mvm->mutex); 2071 mutex_unlock(&mvm->mutex);
1825} 2072}
1826 2073
2074static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
2075 struct ieee80211_vif *vif)
2076{
2077 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2078 u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
2079
2080 mutex_lock(&mvm->mutex);
2081 /* Protect the session to hear the TDLS setup response on the channel */
2082 iwl_mvm_protect_session(mvm, vif, duration, duration, 100);
2083 mutex_unlock(&mvm->mutex);
2084}
2085
1827static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, 2086static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1828 struct ieee80211_vif *vif, 2087 struct ieee80211_vif *vif,
1829 struct cfg80211_sched_scan_request *req, 2088 struct cfg80211_sched_scan_request *req,
1830 struct ieee80211_sched_scan_ies *ies) 2089 struct ieee80211_scan_ies *ies)
1831{ 2090{
1832 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2091 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1833 int ret; 2092 int ret;
@@ -1865,15 +2124,21 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1865 2124
1866 mvm->scan_status = IWL_MVM_SCAN_SCHED; 2125 mvm->scan_status = IWL_MVM_SCAN_SCHED;
1867 2126
1868 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); 2127 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
1869 if (ret) 2128 ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies);
1870 goto err; 2129 if (ret)
2130 goto err;
2131 }
1871 2132
1872 ret = iwl_mvm_config_sched_scan_profiles(mvm, req); 2133 ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
1873 if (ret) 2134 if (ret)
1874 goto err; 2135 goto err;
1875 2136
1876 ret = iwl_mvm_sched_scan_start(mvm, req); 2137 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
2138 ret = iwl_mvm_unified_sched_scan_lmac(mvm, vif, req, ies);
2139 else
2140 ret = iwl_mvm_sched_scan_start(mvm, req);
2141
1877 if (!ret) 2142 if (!ret)
1878 goto out; 2143 goto out;
1879err: 2144err:
@@ -1892,7 +2157,7 @@ static int iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw,
1892 int ret; 2157 int ret;
1893 2158
1894 mutex_lock(&mvm->mutex); 2159 mutex_lock(&mvm->mutex);
1895 ret = iwl_mvm_sched_scan_stop(mvm, false); 2160 ret = iwl_mvm_scan_offload_stop(mvm, false);
1896 mutex_unlock(&mvm->mutex); 2161 mutex_unlock(&mvm->mutex);
1897 iwl_mvm_wait_for_async_handlers(mvm); 2162 iwl_mvm_wait_for_async_handlers(mvm);
1898 2163
@@ -2126,17 +2391,17 @@ static int iwl_mvm_cancel_roc(struct ieee80211_hw *hw)
2126 return 0; 2391 return 0;
2127} 2392}
2128 2393
2129static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw, 2394static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
2130 struct ieee80211_chanctx_conf *ctx) 2395 struct ieee80211_chanctx_conf *ctx)
2131{ 2396{
2132 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2133 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 2397 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
2134 struct iwl_mvm_phy_ctxt *phy_ctxt; 2398 struct iwl_mvm_phy_ctxt *phy_ctxt;
2135 int ret; 2399 int ret;
2136 2400
2401 lockdep_assert_held(&mvm->mutex);
2402
2137 IWL_DEBUG_MAC80211(mvm, "Add channel context\n"); 2403 IWL_DEBUG_MAC80211(mvm, "Add channel context\n");
2138 2404
2139 mutex_lock(&mvm->mutex);
2140 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); 2405 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
2141 if (!phy_ctxt) { 2406 if (!phy_ctxt) {
2142 ret = -ENOSPC; 2407 ret = -ENOSPC;
@@ -2154,19 +2419,40 @@ static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
2154 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt); 2419 iwl_mvm_phy_ctxt_ref(mvm, phy_ctxt);
2155 *phy_ctxt_id = phy_ctxt->id; 2420 *phy_ctxt_id = phy_ctxt->id;
2156out: 2421out:
2422 return ret;
2423}
2424
2425static int iwl_mvm_add_chanctx(struct ieee80211_hw *hw,
2426 struct ieee80211_chanctx_conf *ctx)
2427{
2428 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2429 int ret;
2430
2431 mutex_lock(&mvm->mutex);
2432 ret = __iwl_mvm_add_chanctx(mvm, ctx);
2157 mutex_unlock(&mvm->mutex); 2433 mutex_unlock(&mvm->mutex);
2434
2158 return ret; 2435 return ret;
2159} 2436}
2160 2437
2438static void __iwl_mvm_remove_chanctx(struct iwl_mvm *mvm,
2439 struct ieee80211_chanctx_conf *ctx)
2440{
2441 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
2442 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
2443
2444 lockdep_assert_held(&mvm->mutex);
2445
2446 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt);
2447}
2448
2161static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw, 2449static void iwl_mvm_remove_chanctx(struct ieee80211_hw *hw,
2162 struct ieee80211_chanctx_conf *ctx) 2450 struct ieee80211_chanctx_conf *ctx)
2163{ 2451{
2164 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2452 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2165 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
2166 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
2167 2453
2168 mutex_lock(&mvm->mutex); 2454 mutex_lock(&mvm->mutex);
2169 iwl_mvm_phy_ctxt_unref(mvm, phy_ctxt); 2455 __iwl_mvm_remove_chanctx(mvm, ctx);
2170 mutex_unlock(&mvm->mutex); 2456 mutex_unlock(&mvm->mutex);
2171} 2457}
2172 2458
@@ -2195,17 +2481,17 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
2195 mutex_unlock(&mvm->mutex); 2481 mutex_unlock(&mvm->mutex);
2196} 2482}
2197 2483
2198static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, 2484static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
2199 struct ieee80211_vif *vif, 2485 struct ieee80211_vif *vif,
2200 struct ieee80211_chanctx_conf *ctx) 2486 struct ieee80211_chanctx_conf *ctx,
2487 bool switching_chanctx)
2201{ 2488{
2202 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2203 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv; 2489 u16 *phy_ctxt_id = (u16 *)ctx->drv_priv;
2204 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id]; 2490 struct iwl_mvm_phy_ctxt *phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
2205 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2491 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2206 int ret; 2492 int ret;
2207 2493
2208 mutex_lock(&mvm->mutex); 2494 lockdep_assert_held(&mvm->mutex);
2209 2495
2210 mvmvif->phy_ctxt = phy_ctxt; 2496 mvmvif->phy_ctxt = phy_ctxt;
2211 2497
@@ -2222,18 +2508,18 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2222 * (in bss_info_changed), similarly for IBSS. 2508 * (in bss_info_changed), similarly for IBSS.
2223 */ 2509 */
2224 ret = 0; 2510 ret = 0;
2225 goto out_unlock; 2511 goto out;
2226 case NL80211_IFTYPE_STATION: 2512 case NL80211_IFTYPE_STATION:
2227 case NL80211_IFTYPE_MONITOR: 2513 case NL80211_IFTYPE_MONITOR:
2228 break; 2514 break;
2229 default: 2515 default:
2230 ret = -EINVAL; 2516 ret = -EINVAL;
2231 goto out_unlock; 2517 goto out;
2232 } 2518 }
2233 2519
2234 ret = iwl_mvm_binding_add_vif(mvm, vif); 2520 ret = iwl_mvm_binding_add_vif(mvm, vif);
2235 if (ret) 2521 if (ret)
2236 goto out_unlock; 2522 goto out;
2237 2523
2238 /* 2524 /*
2239 * Power state must be updated before quotas, 2525 * Power state must be updated before quotas,
@@ -2247,65 +2533,162 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2247 */ 2533 */
2248 if (vif->type == NL80211_IFTYPE_MONITOR) { 2534 if (vif->type == NL80211_IFTYPE_MONITOR) {
2249 mvmvif->monitor_active = true; 2535 mvmvif->monitor_active = true;
2250 ret = iwl_mvm_update_quotas(mvm, vif); 2536 ret = iwl_mvm_update_quotas(mvm, NULL);
2251 if (ret) 2537 if (ret)
2252 goto out_remove_binding; 2538 goto out_remove_binding;
2253 } 2539 }
2254 2540
2255 /* Handle binding during CSA */ 2541 /* Handle binding during CSA */
2256 if (vif->type == NL80211_IFTYPE_AP) { 2542 if ((vif->type == NL80211_IFTYPE_AP) ||
2257 iwl_mvm_update_quotas(mvm, vif); 2543 (switching_chanctx && (vif->type == NL80211_IFTYPE_STATION))) {
2544 iwl_mvm_update_quotas(mvm, NULL);
2258 iwl_mvm_mac_ctxt_changed(mvm, vif, false); 2545 iwl_mvm_mac_ctxt_changed(mvm, vif, false);
2259 } 2546 }
2260 2547
2261 goto out_unlock; 2548 goto out;
2262 2549
2263 out_remove_binding: 2550out_remove_binding:
2264 iwl_mvm_binding_remove_vif(mvm, vif); 2551 iwl_mvm_binding_remove_vif(mvm, vif);
2265 iwl_mvm_power_update_mac(mvm); 2552 iwl_mvm_power_update_mac(mvm);
2266 out_unlock: 2553out:
2267 mutex_unlock(&mvm->mutex);
2268 if (ret) 2554 if (ret)
2269 mvmvif->phy_ctxt = NULL; 2555 mvmvif->phy_ctxt = NULL;
2270 return ret; 2556 return ret;
2271} 2557}
2272 2558static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2273static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, 2559 struct ieee80211_vif *vif,
2274 struct ieee80211_vif *vif, 2560 struct ieee80211_chanctx_conf *ctx)
2275 struct ieee80211_chanctx_conf *ctx)
2276{ 2561{
2277 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2562 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2278 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 2563 int ret;
2279 2564
2280 mutex_lock(&mvm->mutex); 2565 mutex_lock(&mvm->mutex);
2566 ret = __iwl_mvm_assign_vif_chanctx(mvm, vif, ctx, false);
2567 mutex_unlock(&mvm->mutex);
2568
2569 return ret;
2570}
2571
2572static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
2573 struct ieee80211_vif *vif,
2574 struct ieee80211_chanctx_conf *ctx,
2575 bool switching_chanctx)
2576{
2577 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
2578 struct ieee80211_vif *disabled_vif = NULL;
2579
2580 lockdep_assert_held(&mvm->mutex);
2281 2581
2282 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); 2582 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
2283 2583
2284 switch (vif->type) { 2584 switch (vif->type) {
2285 case NL80211_IFTYPE_ADHOC: 2585 case NL80211_IFTYPE_ADHOC:
2286 goto out_unlock; 2586 goto out;
2287 case NL80211_IFTYPE_MONITOR: 2587 case NL80211_IFTYPE_MONITOR:
2288 mvmvif->monitor_active = false; 2588 mvmvif->monitor_active = false;
2289 iwl_mvm_update_quotas(mvm, NULL);
2290 break; 2589 break;
2291 case NL80211_IFTYPE_AP: 2590 case NL80211_IFTYPE_AP:
2292 /* This part is triggered only during CSA */ 2591 /* This part is triggered only during CSA */
2293 if (!vif->csa_active || !mvmvif->ap_ibss_active) 2592 if (!vif->csa_active || !mvmvif->ap_ibss_active)
2294 goto out_unlock; 2593 goto out;
2594
2595 /* Set CS bit on all the stations */
2596 iwl_mvm_modify_all_sta_disable_tx(mvm, mvmvif, true);
2597
2598 /* Save blocked iface, the timeout is set on the next beacon */
2599 rcu_assign_pointer(mvm->csa_tx_blocked_vif, vif);
2295 2600
2296 mvmvif->ap_ibss_active = false; 2601 mvmvif->ap_ibss_active = false;
2297 iwl_mvm_update_quotas(mvm, NULL); 2602 break;
2298 /*TODO: bt_coex notification here? */ 2603 case NL80211_IFTYPE_STATION:
2604 if (!switching_chanctx)
2605 break;
2606
2607 disabled_vif = vif;
2608
2609 iwl_mvm_mac_ctxt_changed(mvm, vif, true);
2610 break;
2299 default: 2611 default:
2300 break; 2612 break;
2301 } 2613 }
2302 2614
2615 iwl_mvm_update_quotas(mvm, disabled_vif);
2303 iwl_mvm_binding_remove_vif(mvm, vif); 2616 iwl_mvm_binding_remove_vif(mvm, vif);
2304 2617
2305out_unlock: 2618out:
2306 mvmvif->phy_ctxt = NULL; 2619 mvmvif->phy_ctxt = NULL;
2307 iwl_mvm_power_update_mac(mvm); 2620 iwl_mvm_power_update_mac(mvm);
2621}
2622
2623static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
2624 struct ieee80211_vif *vif,
2625 struct ieee80211_chanctx_conf *ctx)
2626{
2627 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2628
2629 mutex_lock(&mvm->mutex);
2630 __iwl_mvm_unassign_vif_chanctx(mvm, vif, ctx, false);
2631 mutex_unlock(&mvm->mutex);
2632}
2633
2634static int iwl_mvm_switch_vif_chanctx(struct ieee80211_hw *hw,
2635 struct ieee80211_vif_chanctx_switch *vifs,
2636 int n_vifs,
2637 enum ieee80211_chanctx_switch_mode mode)
2638{
2639 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2640 int ret;
2641
2642 /* we only support SWAP_CONTEXTS and with a single-vif right now */
2643 if (mode != CHANCTX_SWMODE_SWAP_CONTEXTS || n_vifs > 1)
2644 return -EOPNOTSUPP;
2645
2646 mutex_lock(&mvm->mutex);
2647 __iwl_mvm_unassign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx, true);
2648 __iwl_mvm_remove_chanctx(mvm, vifs[0].old_ctx);
2649
2650 ret = __iwl_mvm_add_chanctx(mvm, vifs[0].new_ctx);
2651 if (ret) {
2652 IWL_ERR(mvm, "failed to add new_ctx during channel switch\n");
2653 goto out_reassign;
2654 }
2655
2656 ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].new_ctx,
2657 true);
2658 if (ret) {
2659 IWL_ERR(mvm,
2660 "failed to assign new_ctx during channel switch\n");
2661 goto out_remove;
2662 }
2663
2664 goto out;
2665
2666out_remove:
2667 __iwl_mvm_remove_chanctx(mvm, vifs[0].new_ctx);
2668
2669out_reassign:
2670 ret = __iwl_mvm_add_chanctx(mvm, vifs[0].old_ctx);
2671 if (ret) {
2672 IWL_ERR(mvm, "failed to add old_ctx back after failure.\n");
2673 goto out_restart;
2674 }
2675
2676 ret = __iwl_mvm_assign_vif_chanctx(mvm, vifs[0].vif, vifs[0].old_ctx,
2677 true);
2678 if (ret) {
2679 IWL_ERR(mvm, "failed to reassign old_ctx after failure.\n");
2680 goto out_restart;
2681 }
2682
2683 goto out;
2684
2685out_restart:
2686 /* things keep failing, better restart the hw */
2687 iwl_mvm_nic_restart(mvm, false);
2688
2689out:
2308 mutex_unlock(&mvm->mutex); 2690 mutex_unlock(&mvm->mutex);
2691 return ret;
2309} 2692}
2310 2693
2311static int iwl_mvm_set_tim(struct ieee80211_hw *hw, 2694static int iwl_mvm_set_tim(struct ieee80211_hw *hw,
@@ -2395,15 +2778,19 @@ static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw,
2395 struct cfg80211_chan_def *chandef) 2778 struct cfg80211_chan_def *chandef)
2396{ 2779{
2397 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2780 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2781 struct ieee80211_vif *csa_vif;
2398 2782
2399 mutex_lock(&mvm->mutex); 2783 mutex_lock(&mvm->mutex);
2400 if (WARN(mvm->csa_vif && mvm->csa_vif->csa_active, 2784
2785 csa_vif = rcu_dereference_protected(mvm->csa_vif,
2786 lockdep_is_held(&mvm->mutex));
2787 if (WARN(csa_vif && csa_vif->csa_active,
2401 "Another CSA is already in progress")) 2788 "Another CSA is already in progress"))
2402 goto out_unlock; 2789 goto out_unlock;
2403 2790
2404 IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n", 2791 IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n",
2405 chandef->center_freq1); 2792 chandef->center_freq1);
2406 mvm->csa_vif = vif; 2793 rcu_assign_pointer(mvm->csa_vif, vif);
2407 2794
2408out_unlock: 2795out_unlock:
2409 mutex_unlock(&mvm->mutex); 2796 mutex_unlock(&mvm->mutex);
@@ -2460,6 +2847,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
2460 .sta_rc_update = iwl_mvm_sta_rc_update, 2847 .sta_rc_update = iwl_mvm_sta_rc_update,
2461 .conf_tx = iwl_mvm_mac_conf_tx, 2848 .conf_tx = iwl_mvm_mac_conf_tx,
2462 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 2849 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
2850 .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover,
2463 .flush = iwl_mvm_mac_flush, 2851 .flush = iwl_mvm_mac_flush,
2464 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 2852 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
2465 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, 2853 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
@@ -2472,6 +2860,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
2472 .change_chanctx = iwl_mvm_change_chanctx, 2860 .change_chanctx = iwl_mvm_change_chanctx,
2473 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx, 2861 .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
2474 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx, 2862 .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
2863 .switch_vif_chanctx = iwl_mvm_switch_vif_chanctx,
2475 2864
2476 .start_ap = iwl_mvm_start_ap_ibss, 2865 .start_ap = iwl_mvm_start_ap_ibss,
2477 .stop_ap = iwl_mvm_stop_ap_ibss, 2866 .stop_ap = iwl_mvm_stop_ap_ibss,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index fcc6c29482d0..785e5232c757 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -83,6 +83,24 @@
83#define IWL_RSSI_OFFSET 50 83#define IWL_RSSI_OFFSET 50
84#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8 84#define IWL_MVM_MISSED_BEACONS_THRESHOLD 8
85 85
86/*
87 * The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0"
88 * TBTT. This value should be big enough to ensure that we switch in time.
89 */
90#define IWL_MVM_CHANNEL_SWITCH_TIME 40
91
92/*
93 * This value (in TUs) is used to fine tune the CSA NoA end time which should
94 * be just before "beacon 0" TBTT.
95 */
96#define IWL_MVM_CHANNEL_SWITCH_MARGIN 4
97
98/*
99 * Number of beacons to transmit on a new channel until we unblock tx to
100 * the stations, even if we didn't identify them on a new channel
101 */
102#define IWL_MVM_CS_UNBLOCK_TX_TIMEOUT 3
103
86enum iwl_mvm_tx_fifo { 104enum iwl_mvm_tx_fifo {
87 IWL_MVM_TX_FIFO_BK = 0, 105 IWL_MVM_TX_FIFO_BK = 0,
88 IWL_MVM_TX_FIFO_BE, 106 IWL_MVM_TX_FIFO_BE,
@@ -230,11 +248,21 @@ enum iwl_mvm_ref_type {
230 IWL_MVM_REF_USER, 248 IWL_MVM_REF_USER,
231 IWL_MVM_REF_TX, 249 IWL_MVM_REF_TX,
232 IWL_MVM_REF_TX_AGG, 250 IWL_MVM_REF_TX_AGG,
251 IWL_MVM_REF_ADD_IF,
233 IWL_MVM_REF_EXIT_WORK, 252 IWL_MVM_REF_EXIT_WORK,
234 253
235 IWL_MVM_REF_COUNT, 254 IWL_MVM_REF_COUNT,
236}; 255};
237 256
257enum iwl_bt_force_ant_mode {
258 BT_FORCE_ANT_DIS = 0,
259 BT_FORCE_ANT_AUTO,
260 BT_FORCE_ANT_BT,
261 BT_FORCE_ANT_WIFI,
262
263 BT_FORCE_ANT_MAX,
264};
265
238/** 266/**
239* struct iwl_mvm_vif_bf_data - beacon filtering related data 267* struct iwl_mvm_vif_bf_data - beacon filtering related data
240* @bf_enabled: indicates if beacon filtering is enabled 268* @bf_enabled: indicates if beacon filtering is enabled
@@ -523,7 +551,7 @@ struct iwl_mvm {
523 551
524 /* Scan status, cmd (pre-allocated) and auxiliary station */ 552 /* Scan status, cmd (pre-allocated) and auxiliary station */
525 enum iwl_scan_status scan_status; 553 enum iwl_scan_status scan_status;
526 struct iwl_scan_cmd *scan_cmd; 554 void *scan_cmd;
527 struct iwl_mcast_filter_cmd *mcast_filter_cmd; 555 struct iwl_mcast_filter_cmd *mcast_filter_cmd;
528 556
529 /* rx chain antennas set through debugfs for the scan command */ 557 /* rx chain antennas set through debugfs for the scan command */
@@ -586,10 +614,6 @@ struct iwl_mvm {
586 /* -1 for always, 0 for never, >0 for that many times */ 614 /* -1 for always, 0 for never, >0 for that many times */
587 s8 restart_fw; 615 s8 restart_fw;
588 void *fw_error_dump; 616 void *fw_error_dump;
589 void *fw_error_sram;
590 u32 fw_error_sram_len;
591 u32 *fw_error_rxf;
592 u32 fw_error_rxf_len;
593 617
594#ifdef CONFIG_IWLWIFI_LEDS 618#ifdef CONFIG_IWLWIFI_LEDS
595 struct led_classdev led; 619 struct led_classdev led;
@@ -624,11 +648,16 @@ struct iwl_mvm {
624 648
625 /* BT-Coex */ 649 /* BT-Coex */
626 u8 bt_kill_msk; 650 u8 bt_kill_msk;
651
652 struct iwl_bt_coex_profile_notif_old last_bt_notif_old;
653 struct iwl_bt_coex_ci_cmd_old last_bt_ci_cmd_old;
627 struct iwl_bt_coex_profile_notif last_bt_notif; 654 struct iwl_bt_coex_profile_notif last_bt_notif;
628 struct iwl_bt_coex_ci_cmd last_bt_ci_cmd; 655 struct iwl_bt_coex_ci_cmd last_bt_ci_cmd;
656
629 u32 last_ant_isol; 657 u32 last_ant_isol;
630 u8 last_corun_lut; 658 u8 last_corun_lut;
631 u8 bt_tx_prio; 659 u8 bt_tx_prio;
660 enum iwl_bt_force_ant_mode bt_force_ant_mode;
632 661
633 /* Thermal Throttling and CTkill */ 662 /* Thermal Throttling and CTkill */
634 struct iwl_mvm_tt_mgmt thermal_throttle; 663 struct iwl_mvm_tt_mgmt thermal_throttle;
@@ -647,7 +676,12 @@ struct iwl_mvm {
647 /* Indicate if device power save is allowed */ 676 /* Indicate if device power save is allowed */
648 bool ps_disabled; 677 bool ps_disabled;
649 678
650 struct ieee80211_vif *csa_vif; 679 struct ieee80211_vif __rcu *csa_vif;
680 struct ieee80211_vif __rcu *csa_tx_blocked_vif;
681 u8 csa_tx_block_bcn_timeout;
682
683 /* system time of last beacon (for AP/GO interface) */
684 u32 ap_last_beacon_gp2;
651}; 685};
652 686
653/* Extract MVM priv from op_mode and _hw */ 687/* Extract MVM priv from op_mode and _hw */
@@ -719,11 +753,6 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags,
719 struct ieee80211_tx_rate *r); 753 struct ieee80211_tx_rate *r);
720u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); 754u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx);
721void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); 755void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm);
722#ifdef CONFIG_IWLWIFI_DEBUGFS
723void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
724void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm);
725void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm);
726#endif
727u8 first_antenna(u8 mask); 756u8 first_antenna(u8 mask);
728u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx); 757u8 iwl_mvm_next_antenna(struct iwl_mvm *mvm, u8 valid, u8 last_idx);
729 758
@@ -809,6 +838,7 @@ void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
809 struct iwl_mvm_phy_ctxt *ctxt); 838 struct iwl_mvm_phy_ctxt *ctxt);
810void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, 839void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm,
811 struct iwl_mvm_phy_ctxt *ctxt); 840 struct iwl_mvm_phy_ctxt *ctxt);
841int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm);
812 842
813/* MAC (virtual interface) programming */ 843/* MAC (virtual interface) programming */
814int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 844int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -835,7 +865,8 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
835int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 865int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
836 866
837/* Quota management */ 867/* Quota management */
838int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif); 868int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
869 struct ieee80211_vif *disabled_vif);
839 870
840/* Scanning */ 871/* Scanning */
841int iwl_mvm_scan_request(struct iwl_mvm *mvm, 872int iwl_mvm_scan_request(struct iwl_mvm *mvm,
@@ -854,15 +885,24 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
854int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 885int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
855 struct ieee80211_vif *vif, 886 struct ieee80211_vif *vif,
856 struct cfg80211_sched_scan_request *req, 887 struct cfg80211_sched_scan_request *req,
857 struct ieee80211_sched_scan_ies *ies); 888 struct ieee80211_scan_ies *ies);
858int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, 889int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
859 struct cfg80211_sched_scan_request *req); 890 struct cfg80211_sched_scan_request *req);
860int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, 891int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
861 struct cfg80211_sched_scan_request *req); 892 struct cfg80211_sched_scan_request *req);
862int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify); 893int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify);
863int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm, 894int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
864 struct iwl_rx_cmd_buffer *rxb, 895 struct iwl_rx_cmd_buffer *rxb,
865 struct iwl_device_cmd *cmd); 896 struct iwl_device_cmd *cmd);
897
898/* Unified scan */
899int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
900 struct ieee80211_vif *vif,
901 struct ieee80211_scan_request *req);
902int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
903 struct ieee80211_vif *vif,
904 struct cfg80211_sched_scan_request *req,
905 struct ieee80211_scan_ies *ies);
866 906
867/* MVM debugfs */ 907/* MVM debugfs */
868#ifdef CONFIG_IWLWIFI_DEBUGFS 908#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -963,11 +1003,30 @@ u16 iwl_mvm_coex_agg_time_limit(struct iwl_mvm *mvm,
963 struct ieee80211_sta *sta); 1003 struct ieee80211_sta *sta);
964bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, 1004bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
965 struct ieee80211_sta *sta); 1005 struct ieee80211_sta *sta);
1006bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm);
966bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm, 1007bool iwl_mvm_bt_coex_is_tpc_allowed(struct iwl_mvm *mvm,
967 enum ieee80211_band band); 1008 enum ieee80211_band band);
968u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr, 1009u8 iwl_mvm_bt_coex_tx_prio(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
969 struct ieee80211_tx_info *info, u8 ac); 1010 struct ieee80211_tx_info *info, u8 ac);
970 1011
1012bool iwl_mvm_bt_coex_is_shared_ant_avail_old(struct iwl_mvm *mvm);
1013void iwl_mvm_bt_coex_vif_change_old(struct iwl_mvm *mvm);
1014int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm);
1015int iwl_mvm_rx_bt_coex_notif_old(struct iwl_mvm *mvm,
1016 struct iwl_rx_cmd_buffer *rxb,
1017 struct iwl_device_cmd *cmd);
1018void iwl_mvm_bt_rssi_event_old(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1019 enum ieee80211_rssi_event rssi_event);
1020u16 iwl_mvm_coex_agg_time_limit_old(struct iwl_mvm *mvm,
1021 struct ieee80211_sta *sta);
1022bool iwl_mvm_bt_coex_is_mimo_allowed_old(struct iwl_mvm *mvm,
1023 struct ieee80211_sta *sta);
1024bool iwl_mvm_bt_coex_is_tpc_allowed_old(struct iwl_mvm *mvm,
1025 enum ieee80211_band band);
1026int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
1027 struct iwl_rx_cmd_buffer *rxb,
1028 struct iwl_device_cmd *cmd);
1029
971enum iwl_bt_kill_msk { 1030enum iwl_bt_kill_msk {
972 BT_KILL_MSK_DEFAULT, 1031 BT_KILL_MSK_DEFAULT,
973 BT_KILL_MSK_SCO_HID_A2DP, 1032 BT_KILL_MSK_SCO_HID_A2DP,
@@ -1039,4 +1098,9 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
1039int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1098int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1040 bool added_vif); 1099 bool added_vif);
1041 1100
1101/* TDLS */
1102int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
1103
1104void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1105
1042#endif /* __IWL_MVM_H__ */ 1106#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 808f78f6fbf9..b04805ccb443 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -69,7 +69,9 @@
69 69
70/* Default NVM size to read */ 70/* Default NVM size to read */
71#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) 71#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
72#define IWL_MAX_NVM_SECTION_SIZE 7000 72#define IWL_MAX_NVM_SECTION_SIZE 0x1b58
73#define IWL_MAX_NVM_8000A_SECTION_SIZE 0xffc
74#define IWL_MAX_NVM_8000B_SECTION_SIZE 0x1ffc
73 75
74#define NVM_WRITE_OPCODE 1 76#define NVM_WRITE_OPCODE 1
75#define NVM_READ_OPCODE 0 77#define NVM_READ_OPCODE 0
@@ -219,7 +221,7 @@ static int iwl_nvm_write_section(struct iwl_mvm *mvm, u16 section,
219 * without overflowing, so no check is needed. 221 * without overflowing, so no check is needed.
220 */ 222 */
221static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section, 223static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
222 u8 *data) 224 u8 *data, u32 size_read)
223{ 225{
224 u16 length, offset = 0; 226 u16 length, offset = 0;
225 int ret; 227 int ret;
@@ -231,6 +233,13 @@ static int iwl_nvm_read_section(struct iwl_mvm *mvm, u16 section,
231 233
232 /* Read the NVM until exhausted (reading less than requested) */ 234 /* Read the NVM until exhausted (reading less than requested) */
233 while (ret == length) { 235 while (ret == length) {
236 /* Check no memory assumptions fail and cause an overflow */
237 if ((size_read + offset + length) >
238 mvm->cfg->base_params->eeprom_size) {
239 IWL_ERR(mvm, "EEPROM size is too small for NVM\n");
240 return -ENOBUFS;
241 }
242
234 ret = iwl_nvm_read_chunk(mvm, section, offset, length, data); 243 ret = iwl_nvm_read_chunk(mvm, section, offset, length, data);
235 if (ret < 0) { 244 if (ret < 0) {
236 IWL_DEBUG_EEPROM(mvm->trans->dev, 245 IWL_DEBUG_EEPROM(mvm->trans->dev,
@@ -326,6 +335,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
326 u8 data[]; 335 u8 data[];
327 } *file_sec; 336 } *file_sec;
328 const u8 *eof, *temp; 337 const u8 *eof, *temp;
338 int max_section_size;
329 339
330#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) 340#define NVM_WORD1_LEN(x) (8 * (x & 0x03FF))
331#define NVM_WORD2_ID(x) (x >> 12) 341#define NVM_WORD2_ID(x) (x >> 12)
@@ -334,6 +344,14 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
334 344
335 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 345 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
336 346
347 /* Maximal size depends on HW family and step */
348 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
349 max_section_size = IWL_MAX_NVM_SECTION_SIZE;
350 else if ((mvm->trans->hw_rev & 0xc) == 0) /* Family 8000 A-step */
351 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE;
352 else /* Family 8000 B-step */
353 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE;
354
337 /* 355 /*
338 * Obtain NVM image via request_firmware. Since we already used 356 * Obtain NVM image via request_firmware. Since we already used
339 * request_firmware_nowait() for the firmware binary load and only 357 * request_firmware_nowait() for the firmware binary load and only
@@ -392,7 +410,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
392 le16_to_cpu(file_sec->word1)); 410 le16_to_cpu(file_sec->word1));
393 } 411 }
394 412
395 if (section_size > IWL_MAX_NVM_SECTION_SIZE) { 413 if (section_size > max_section_size) {
396 IWL_ERR(mvm, "ERROR - section too large (%d)\n", 414 IWL_ERR(mvm, "ERROR - section too large (%d)\n",
397 section_size); 415 section_size);
398 ret = -EINVAL; 416 ret = -EINVAL;
@@ -459,6 +477,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
459int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic) 477int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
460{ 478{
461 int ret, section; 479 int ret, section;
480 u32 size_read = 0;
462 u8 *nvm_buffer, *temp; 481 u8 *nvm_buffer, *temp;
463 482
464 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) 483 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
@@ -475,9 +494,11 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
475 return -ENOMEM; 494 return -ENOMEM;
476 for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) { 495 for (section = 0; section < NVM_MAX_NUM_SECTIONS; section++) {
477 /* we override the constness for initial read */ 496 /* we override the constness for initial read */
478 ret = iwl_nvm_read_section(mvm, section, nvm_buffer); 497 ret = iwl_nvm_read_section(mvm, section, nvm_buffer,
498 size_read);
479 if (ret < 0) 499 if (ret < 0)
480 continue; 500 continue;
501 size_read += ret;
481 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); 502 temp = kmemdup(nvm_buffer, ret, GFP_KERNEL);
482 if (!temp) { 503 if (!temp) {
483 ret = -ENOMEM; 504 ret = -ENOMEM;
@@ -509,6 +530,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
509 } 530 }
510#endif 531#endif
511 } 532 }
533 if (!size_read)
534 IWL_ERR(mvm, "OTP is blank\n");
512 kfree(nvm_buffer); 535 kfree(nvm_buffer);
513 } 536 }
514 537
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index cc2f7de396de..7d7b2fbe7cd1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -166,8 +166,15 @@ static void iwl_mvm_nic_config(struct iwl_op_mode *op_mode)
166 WARN_ON((radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE) & 166 WARN_ON((radio_cfg_type << CSR_HW_IF_CONFIG_REG_POS_PHY_TYPE) &
167 ~CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE); 167 ~CSR_HW_IF_CONFIG_REG_MSK_PHY_TYPE);
168 168
169 /* silicon bits */ 169 /*
170 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI; 170 * TODO: Bits 7-8 of CSR in 8000 HW family set the ADC sampling, and
171 * shouldn't be set to any non-zero value. The same is supposed to be
172 * true of the other HW, but unsetting them (such as the 7260) causes
173 * automatic tests to fail on seemingly unrelated errors. Need to
174 * further investigate this, but for now we'll separate cases.
175 */
176 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
177 reg_val |= CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI;
171 178
172 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG, 179 iwl_trans_set_bits_mask(mvm->trans, CSR_HW_IF_CONFIG_REG,
173 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH | 180 CSR_HW_IF_CONFIG_REG_MSK_MAC_DASH |
@@ -233,7 +240,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
233 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true), 240 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, true),
234 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 241 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
235 iwl_mvm_rx_scan_offload_complete_notif, true), 242 iwl_mvm_rx_scan_offload_complete_notif, true),
236 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results, 243 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_scan_offload_results,
237 false), 244 false),
238 245
239 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 246 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
@@ -284,6 +291,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
284 CMD(SCAN_OFFLOAD_ABORT_CMD), 291 CMD(SCAN_OFFLOAD_ABORT_CMD),
285 CMD(SCAN_OFFLOAD_COMPLETE), 292 CMD(SCAN_OFFLOAD_COMPLETE),
286 CMD(SCAN_OFFLOAD_UPDATE_PROFILES_CMD), 293 CMD(SCAN_OFFLOAD_UPDATE_PROFILES_CMD),
294 CMD(SCAN_ITERATION_COMPLETE),
287 CMD(POWER_TABLE_CMD), 295 CMD(POWER_TABLE_CMD),
288 CMD(WEP_KEY), 296 CMD(WEP_KEY),
289 CMD(REPLY_RX_PHY_CMD), 297 CMD(REPLY_RX_PHY_CMD),
@@ -324,6 +332,9 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
324 CMD(REPLY_THERMAL_MNG_BACKOFF), 332 CMD(REPLY_THERMAL_MNG_BACKOFF),
325 CMD(MAC_PM_POWER_TABLE), 333 CMD(MAC_PM_POWER_TABLE),
326 CMD(BT_COEX_CI), 334 CMD(BT_COEX_CI),
335 CMD(BT_COEX_UPDATE_SW_BOOST),
336 CMD(BT_COEX_UPDATE_CORUN_LUT),
337 CMD(BT_COEX_UPDATE_REDUCED_TXP),
327 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION), 338 CMD(PSM_UAPSD_AP_MISBEHAVING_NOTIFICATION),
328 CMD(ANTENNA_COUPLING_NOTIFICATION), 339 CMD(ANTENNA_COUPLING_NOTIFICATION),
329}; 340};
@@ -502,9 +513,17 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
502 } 513 }
503 } 514 }
504 515
505 scan_size = sizeof(struct iwl_scan_cmd) + 516 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
506 mvm->fw->ucode_capa.max_probe_length + 517 scan_size = sizeof(struct iwl_scan_req_unified_lmac) +
507 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)); 518 sizeof(struct iwl_scan_channel_cfg_lmac) *
519 mvm->fw->ucode_capa.n_scan_channels +
520 sizeof(struct iwl_scan_probe_req);
521 else
522 scan_size = sizeof(struct iwl_scan_cmd) +
523 mvm->fw->ucode_capa.max_probe_length +
524 mvm->fw->ucode_capa.n_scan_channels *
525 sizeof(struct iwl_scan_channel);
526
508 mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL); 527 mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL);
509 if (!mvm->scan_cmd) 528 if (!mvm->scan_cmd)
510 goto out_free; 529 goto out_free;
@@ -549,8 +568,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
549 568
550 kfree(mvm->scan_cmd); 569 kfree(mvm->scan_cmd);
551 vfree(mvm->fw_error_dump); 570 vfree(mvm->fw_error_dump);
552 kfree(mvm->fw_error_sram);
553 kfree(mvm->fw_error_rxf);
554 kfree(mvm->mcast_filter_cmd); 571 kfree(mvm->mcast_filter_cmd);
555 mvm->mcast_filter_cmd = NULL; 572 mvm->mcast_filter_cmd = NULL;
556 573
@@ -754,7 +771,7 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
754 module_put(THIS_MODULE); 771 module_put(THIS_MODULE);
755} 772}
756 773
757static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) 774void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
758{ 775{
759 iwl_abort_notification_waits(&mvm->notif_wait); 776 iwl_abort_notification_waits(&mvm->notif_wait);
760 777
@@ -811,93 +828,24 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm)
811 reprobe->dev = mvm->trans->dev; 828 reprobe->dev = mvm->trans->dev;
812 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk); 829 INIT_WORK(&reprobe->work, iwl_mvm_reprobe_wk);
813 schedule_work(&reprobe->work); 830 schedule_work(&reprobe->work);
814 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR && mvm->restart_fw) { 831 } else if (mvm->cur_ucode == IWL_UCODE_REGULAR &&
832 (!fw_error || mvm->restart_fw)) {
815 /* don't let the transport/FW power down */ 833 /* don't let the transport/FW power down */
816 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 834 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
817 835
818 if (mvm->restart_fw > 0) 836 if (fw_error && mvm->restart_fw > 0)
819 mvm->restart_fw--; 837 mvm->restart_fw--;
820 ieee80211_restart_hw(mvm->hw); 838 ieee80211_restart_hw(mvm->hw);
821 } 839 }
822} 840}
823 841
824#ifdef CONFIG_IWLWIFI_DEBUGFS
825void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
826{
827 struct iwl_fw_error_dump_file *dump_file;
828 struct iwl_fw_error_dump_data *dump_data;
829 u32 file_len;
830 u32 trans_len;
831
832 lockdep_assert_held(&mvm->mutex);
833
834 if (mvm->fw_error_dump)
835 return;
836
837 file_len = mvm->fw_error_sram_len +
838 mvm->fw_error_rxf_len +
839 sizeof(*dump_file) +
840 sizeof(*dump_data) * 2;
841
842 trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
843 if (trans_len)
844 file_len += trans_len;
845
846 dump_file = vmalloc(file_len);
847 if (!dump_file)
848 return;
849
850 mvm->fw_error_dump = dump_file;
851
852 dump_file->barker = cpu_to_le32(IWL_FW_ERROR_DUMP_BARKER);
853 dump_file->file_len = cpu_to_le32(file_len);
854 dump_data = (void *)dump_file->data;
855 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_RXF);
856 dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
857 memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
858
859 dump_data = iwl_mvm_fw_error_next_data(dump_data);
860 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
861 dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
862
863 /*
864 * No need for lock since at the stage the FW isn't loaded. So it
865 * can't assert - we are the only one who can possibly be accessing
866 * mvm->fw_error_sram right now.
867 */
868 memcpy(dump_data->data, mvm->fw_error_sram, mvm->fw_error_sram_len);
869
870 kfree(mvm->fw_error_rxf);
871 mvm->fw_error_rxf = NULL;
872 mvm->fw_error_rxf_len = 0;
873
874 kfree(mvm->fw_error_sram);
875 mvm->fw_error_sram = NULL;
876 mvm->fw_error_sram_len = 0;
877
878 if (trans_len) {
879 void *buf = iwl_mvm_fw_error_next_data(dump_data);
880 u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
881 trans_len);
882 dump_data = (void *)((u8 *)buf + real_trans_len);
883 dump_file->file_len =
884 cpu_to_le32(file_len - trans_len + real_trans_len);
885 }
886}
887#endif
888
889static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) 842static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode)
890{ 843{
891 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 844 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
892 845
893 iwl_mvm_dump_nic_error_log(mvm); 846 iwl_mvm_dump_nic_error_log(mvm);
894 847
895#ifdef CONFIG_IWLWIFI_DEBUGFS 848 iwl_mvm_nic_restart(mvm, true);
896 iwl_mvm_fw_error_sram_dump(mvm);
897 iwl_mvm_fw_error_rxf_dump(mvm);
898#endif
899
900 iwl_mvm_nic_restart(mvm);
901} 849}
902 850
903static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) 851static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
@@ -905,7 +853,7 @@ static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode)
905 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); 853 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
906 854
907 WARN_ON(1); 855 WARN_ON(1);
908 iwl_mvm_nic_restart(mvm); 856 iwl_mvm_nic_restart(mvm, true);
909} 857}
910 858
911struct iwl_d0i3_iter_data { 859struct iwl_d0i3_iter_data {
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 539f3a942d43..6cc243f7cf60 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -261,3 +261,29 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
261 261
262 ctxt->ref--; 262 ctxt->ref--;
263} 263}
264
265static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
266 struct ieee80211_vif *vif)
267{
268 unsigned long *data = _data;
269 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
270
271 if (!mvmvif->phy_ctxt)
272 return;
273
274 if (vif->type == NL80211_IFTYPE_STATION ||
275 vif->type == NL80211_IFTYPE_AP)
276 __set_bit(mvmvif->phy_ctxt->id, data);
277}
278
279int iwl_mvm_phy_ctx_count(struct iwl_mvm *mvm)
280{
281 unsigned long phy_ctxt_counter = 0;
282
283 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
284 IEEE80211_IFACE_ITER_NORMAL,
285 iwl_mvm_binding_iterator,
286 &phy_ctxt_counter);
287
288 return hweight8(phy_ctxt_counter);
289}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index c182a8baf685..2b2d10800a55 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -246,30 +246,10 @@ static void iwl_mvm_power_configure_uapsd(struct iwl_mvm *mvm,
246 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT; 246 IWL_MVM_PS_HEAVY_RX_THLD_PERCENT;
247} 247}
248 248
249static void iwl_mvm_binding_iterator(void *_data, u8 *mac,
250 struct ieee80211_vif *vif)
251{
252 unsigned long *data = _data;
253 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
254
255 if (!mvmvif->phy_ctxt)
256 return;
257
258 if (vif->type == NL80211_IFTYPE_STATION ||
259 vif->type == NL80211_IFTYPE_AP)
260 __set_bit(mvmvif->phy_ctxt->id, data);
261}
262
263static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm, 249static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
264 struct ieee80211_vif *vif) 250 struct ieee80211_vif *vif)
265{ 251{
266 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 252 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
267 unsigned long phy_ctxt_counter = 0;
268
269 ieee80211_iterate_active_interfaces_atomic(mvm->hw,
270 IEEE80211_IFACE_ITER_NORMAL,
271 iwl_mvm_binding_iterator,
272 &phy_ctxt_counter);
273 253
274 if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid, 254 if (!memcmp(mvmvif->uapsd_misbehaving_bssid, vif->bss_conf.bssid,
275 ETH_ALEN)) 255 ETH_ALEN))
@@ -291,7 +271,7 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
291 * Avoid using uAPSD if client is in DCM - 271 * Avoid using uAPSD if client is in DCM -
292 * low latency issue in Miracast 272 * low latency issue in Miracast
293 */ 273 */
294 if (hweight8(phy_ctxt_counter) >= 2) 274 if (iwl_mvm_phy_ctx_count(mvm) >= 2)
295 return false; 275 return false;
296 276
297 return true; 277 return true;
@@ -503,6 +483,7 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
503} 483}
504 484
505struct iwl_power_vifs { 485struct iwl_power_vifs {
486 struct iwl_mvm *mvm;
506 struct ieee80211_vif *bf_vif; 487 struct ieee80211_vif *bf_vif;
507 struct ieee80211_vif *bss_vif; 488 struct ieee80211_vif *bss_vif;
508 struct ieee80211_vif *p2p_vif; 489 struct ieee80211_vif *p2p_vif;
@@ -512,6 +493,8 @@ struct iwl_power_vifs {
512 bool bss_active; 493 bool bss_active;
513 bool ap_active; 494 bool ap_active;
514 bool monitor_active; 495 bool monitor_active;
496 bool bss_tdls;
497 bool p2p_tdls;
515}; 498};
516 499
517static void iwl_mvm_power_iterator(void *_data, u8 *mac, 500static void iwl_mvm_power_iterator(void *_data, u8 *mac,
@@ -548,6 +531,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
548 /* only a single MAC of the same type */ 531 /* only a single MAC of the same type */
549 WARN_ON(power_iterator->p2p_vif); 532 WARN_ON(power_iterator->p2p_vif);
550 power_iterator->p2p_vif = vif; 533 power_iterator->p2p_vif = vif;
534 power_iterator->p2p_tdls =
535 !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
551 if (mvmvif->phy_ctxt) 536 if (mvmvif->phy_ctxt)
552 if (mvmvif->phy_ctxt->id < MAX_PHYS) 537 if (mvmvif->phy_ctxt->id < MAX_PHYS)
553 power_iterator->p2p_active = true; 538 power_iterator->p2p_active = true;
@@ -557,6 +542,8 @@ static void iwl_mvm_power_iterator(void *_data, u8 *mac,
557 /* only a single MAC of the same type */ 542 /* only a single MAC of the same type */
558 WARN_ON(power_iterator->bss_vif); 543 WARN_ON(power_iterator->bss_vif);
559 power_iterator->bss_vif = vif; 544 power_iterator->bss_vif = vif;
545 power_iterator->bss_tdls =
546 !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
560 if (mvmvif->phy_ctxt) 547 if (mvmvif->phy_ctxt)
561 if (mvmvif->phy_ctxt->id < MAX_PHYS) 548 if (mvmvif->phy_ctxt->id < MAX_PHYS)
562 power_iterator->bss_active = true; 549 power_iterator->bss_active = true;
@@ -599,13 +586,15 @@ iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
599 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif); 586 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
600 587
601 /* enable PM on bss if bss stand alone */ 588 /* enable PM on bss if bss stand alone */
602 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) { 589 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active &&
590 !vifs->bss_tdls) {
603 bss_mvmvif->pm_enabled = true; 591 bss_mvmvif->pm_enabled = true;
604 return; 592 return;
605 } 593 }
606 594
607 /* enable PM on p2p if p2p stand alone */ 595 /* enable PM on p2p if p2p stand alone */
608 if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) { 596 if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active &&
597 !vifs->p2p_tdls) {
609 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM) 598 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
610 p2p_mvmvif->pm_enabled = true; 599 p2p_mvmvif->pm_enabled = true;
611 return; 600 return;
@@ -831,7 +820,9 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
831int iwl_mvm_power_update_mac(struct iwl_mvm *mvm) 820int iwl_mvm_power_update_mac(struct iwl_mvm *mvm)
832{ 821{
833 struct iwl_mvm_vif *mvmvif; 822 struct iwl_mvm_vif *mvmvif;
834 struct iwl_power_vifs vifs = {}; 823 struct iwl_power_vifs vifs = {
824 .mvm = mvm,
825 };
835 bool ba_enable; 826 bool ba_enable;
836 int ret; 827 int ret;
837 828
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index ba68d7b84505..4e20b3ce2b6a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -73,7 +73,7 @@ struct iwl_mvm_quota_iterator_data {
73 int colors[MAX_BINDINGS]; 73 int colors[MAX_BINDINGS];
74 int low_latency[MAX_BINDINGS]; 74 int low_latency[MAX_BINDINGS];
75 int n_low_latency_bindings; 75 int n_low_latency_bindings;
76 struct ieee80211_vif *new_vif; 76 struct ieee80211_vif *disabled_vif;
77}; 77};
78 78
79static void iwl_mvm_quota_iterator(void *_data, u8 *mac, 79static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
@@ -83,13 +83,8 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
83 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 83 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
84 u16 id; 84 u16 id;
85 85
86 /* 86 /* skip disabled interfaces here immediately */
87 * We'll account for the new interface (if any) below, 87 if (vif == data->disabled_vif)
88 * skip it here in case we're not called from within
89 * the add_interface callback (otherwise it won't show
90 * up in iteration)
91 */
92 if (vif == data->new_vif)
93 return; 88 return;
94 89
95 if (!mvmvif->phy_ctxt) 90 if (!mvmvif->phy_ctxt)
@@ -104,11 +99,6 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
104 if (WARN_ON_ONCE(id >= MAX_BINDINGS)) 99 if (WARN_ON_ONCE(id >= MAX_BINDINGS))
105 return; 100 return;
106 101
107 if (data->colors[id] < 0)
108 data->colors[id] = mvmvif->phy_ctxt->color;
109 else
110 WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
111
112 switch (vif->type) { 102 switch (vif->type) {
113 case NL80211_IFTYPE_STATION: 103 case NL80211_IFTYPE_STATION:
114 if (vif->bss_conf.assoc) 104 if (vif->bss_conf.assoc)
@@ -130,6 +120,11 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac,
130 return; 120 return;
131 } 121 }
132 122
123 if (data->colors[id] < 0)
124 data->colors[id] = mvmvif->phy_ctxt->color;
125 else
126 WARN_ON_ONCE(data->colors[id] != mvmvif->phy_ctxt->color);
127
133 data->n_interfaces[id]++; 128 data->n_interfaces[id]++;
134 129
135 if (iwl_mvm_vif_low_latency(mvmvif) && !data->low_latency[id]) { 130 if (iwl_mvm_vif_low_latency(mvmvif) && !data->low_latency[id]) {
@@ -171,14 +166,15 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
171#endif 166#endif
172} 167}
173 168
174int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) 169int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
170 struct ieee80211_vif *disabled_vif)
175{ 171{
176 struct iwl_time_quota_cmd cmd = {}; 172 struct iwl_time_quota_cmd cmd = {};
177 int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat; 173 int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat;
178 struct iwl_mvm_quota_iterator_data data = { 174 struct iwl_mvm_quota_iterator_data data = {
179 .n_interfaces = {}, 175 .n_interfaces = {},
180 .colors = { -1, -1, -1, -1 }, 176 .colors = { -1, -1, -1, -1 },
181 .new_vif = newvif, 177 .disabled_vif = disabled_vif,
182 }; 178 };
183 179
184 lockdep_assert_held(&mvm->mutex); 180 lockdep_assert_held(&mvm->mutex);
@@ -193,10 +189,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
193 ieee80211_iterate_active_interfaces_atomic( 189 ieee80211_iterate_active_interfaces_atomic(
194 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 190 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
195 iwl_mvm_quota_iterator, &data); 191 iwl_mvm_quota_iterator, &data);
196 if (newvif) {
197 data.new_vif = NULL;
198 iwl_mvm_quota_iterator(&data, newvif->addr, newvif);
199 }
200 192
201 /* 193 /*
202 * The FW's scheduling session consists of 194 * The FW's scheduling session consists of
@@ -285,6 +277,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif)
285 277
286 iwl_mvm_adjust_quota_for_noa(mvm, &cmd); 278 iwl_mvm_adjust_quota_for_noa(mvm, &cmd);
287 279
280 /* check that we have non-zero quota for all valid bindings */
281 for (i = 0; i < MAX_BINDINGS; i++) {
282 if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
283 continue;
284 WARN_ONCE(cmd.quotas[i].quota == 0,
285 "zero quota on binding %d\n", i);
286 }
287
288 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, 288 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
289 sizeof(cmd), &cmd); 289 sizeof(cmd), &cmd);
290 if (ret) 290 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 306a6caa4868..c70e959bf0e3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -927,7 +927,7 @@ static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
927 u8 low; 927 u8 low;
928 u16 high_low; 928 u16 high_low;
929 u16 rate_mask; 929 u16 rate_mask;
930 struct iwl_mvm *mvm = lq_sta->drv; 930 struct iwl_mvm *mvm = lq_sta->pers.drv;
931 931
932 rate_mask = rs_get_supported_rates(lq_sta, rate); 932 rate_mask = rs_get_supported_rates(lq_sta, rate);
933 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask, 933 high_low = rs_get_adjacent_rate(mvm, rate->index, rate_mask,
@@ -946,7 +946,7 @@ static bool rs_get_lower_rate_in_column(struct iwl_lq_sta *lq_sta,
946static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, 946static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
947 struct rs_rate *rate) 947 struct rs_rate *rate)
948{ 948{
949 struct iwl_mvm *mvm = lq_sta->drv; 949 struct iwl_mvm *mvm = lq_sta->pers.drv;
950 950
951 if (is_legacy(rate)) { 951 if (is_legacy(rate)) {
952 /* No column to downgrade from Legacy */ 952 /* No column to downgrade from Legacy */
@@ -1026,14 +1026,14 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1026 if (!lq_sta) { 1026 if (!lq_sta) {
1027 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n"); 1027 IWL_DEBUG_RATE(mvm, "Station rate scaling not created yet.\n");
1028 return; 1028 return;
1029 } else if (!lq_sta->drv) { 1029 } else if (!lq_sta->pers.drv) {
1030 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); 1030 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
1031 return; 1031 return;
1032 } 1032 }
1033 1033
1034#ifdef CONFIG_MAC80211_DEBUGFS 1034#ifdef CONFIG_MAC80211_DEBUGFS
1035 /* Disable last tx check if we are debugging with fixed rate */ 1035 /* Disable last tx check if we are debugging with fixed rate */
1036 if (lq_sta->dbg_fixed_rate) { 1036 if (lq_sta->pers.dbg_fixed_rate) {
1037 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n"); 1037 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
1038 return; 1038 return;
1039 } 1039 }
@@ -1405,7 +1405,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
1405 int flush_interval_passed = 0; 1405 int flush_interval_passed = 0;
1406 struct iwl_mvm *mvm; 1406 struct iwl_mvm *mvm;
1407 1407
1408 mvm = lq_sta->drv; 1408 mvm = lq_sta->pers.drv;
1409 active_tbl = lq_sta->active_tbl; 1409 active_tbl = lq_sta->active_tbl;
1410 1410
1411 tbl = &(lq_sta->lq_info[active_tbl]); 1411 tbl = &(lq_sta->lq_info[active_tbl]);
@@ -1865,11 +1865,11 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
1865 int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE; 1865 int weak_tpt = IWL_INVALID_VALUE, strong_tpt = IWL_INVALID_VALUE;
1866 1866
1867#ifdef CONFIG_MAC80211_DEBUGFS 1867#ifdef CONFIG_MAC80211_DEBUGFS
1868 if (lq_sta->dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) { 1868 if (lq_sta->pers.dbg_fixed_txp_reduction <= TPC_MAX_REDUCTION) {
1869 IWL_DEBUG_RATE(mvm, "fixed tpc: %d\n", 1869 IWL_DEBUG_RATE(mvm, "fixed tpc: %d\n",
1870 lq_sta->dbg_fixed_txp_reduction); 1870 lq_sta->pers.dbg_fixed_txp_reduction);
1871 lq_sta->lq.reduced_tpc = lq_sta->dbg_fixed_txp_reduction; 1871 lq_sta->lq.reduced_tpc = lq_sta->pers.dbg_fixed_txp_reduction;
1872 return cur != lq_sta->dbg_fixed_txp_reduction; 1872 return cur != lq_sta->pers.dbg_fixed_txp_reduction;
1873 } 1873 }
1874#endif 1874#endif
1875 1875
@@ -2382,7 +2382,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2382 } 2382 }
2383 2383
2384 /* Treat uninitialized rate scaling data same as non-existing. */ 2384 /* Treat uninitialized rate scaling data same as non-existing. */
2385 if (lq_sta && !lq_sta->drv) { 2385 if (lq_sta && !lq_sta->pers.drv) {
2386 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n"); 2386 IWL_DEBUG_RATE(mvm, "Rate scaling not initialized yet.\n");
2387 mvm_sta = NULL; 2387 mvm_sta = NULL;
2388 } 2388 }
@@ -2401,12 +2401,18 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta,
2401 gfp_t gfp) 2401 gfp_t gfp)
2402{ 2402{
2403 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2403 struct iwl_mvm_sta *sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2404 struct iwl_op_mode *op_mode __maybe_unused = 2404 struct iwl_op_mode *op_mode = (struct iwl_op_mode *)mvm_rate;
2405 (struct iwl_op_mode *)mvm_rate; 2405 struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
2406 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); 2406 struct iwl_lq_sta *lq_sta = &sta_priv->lq_sta;
2407 2407
2408 IWL_DEBUG_RATE(mvm, "create station rate scale window\n"); 2408 IWL_DEBUG_RATE(mvm, "create station rate scale window\n");
2409 2409
2410 lq_sta->pers.drv = mvm;
2411#ifdef CONFIG_MAC80211_DEBUGFS
2412 lq_sta->pers.dbg_fixed_rate = 0;
2413 lq_sta->pers.dbg_fixed_txp_reduction = TPC_INVALID;
2414#endif
2415
2410 return &sta_priv->lq_sta; 2416 return &sta_priv->lq_sta;
2411} 2417}
2412 2418
@@ -2552,7 +2558,9 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2552 2558
2553 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv; 2559 sta_priv = (struct iwl_mvm_sta *)sta->drv_priv;
2554 lq_sta = &sta_priv->lq_sta; 2560 lq_sta = &sta_priv->lq_sta;
2555 memset(lq_sta, 0, sizeof(*lq_sta)); 2561
2562 /* clear all non-persistent lq data */
2563 memset(lq_sta, 0, offsetof(typeof(*lq_sta), pers));
2556 2564
2557 sband = hw->wiphy->bands[band]; 2565 sband = hw->wiphy->bands[band];
2558 2566
@@ -2630,17 +2638,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2630 2638
2631 /* as default allow aggregation for all tids */ 2639 /* as default allow aggregation for all tids */
2632 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2640 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2633 lq_sta->drv = mvm;
2634 2641
2635 /* Set last_txrate_idx to lowest rate */ 2642 /* Set last_txrate_idx to lowest rate */
2636 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta); 2643 lq_sta->last_txrate_idx = rate_lowest_index(sband, sta);
2637 if (sband->band == IEEE80211_BAND_5GHZ) 2644 if (sband->band == IEEE80211_BAND_5GHZ)
2638 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2645 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2639 lq_sta->is_agg = 0; 2646 lq_sta->is_agg = 0;
2640#ifdef CONFIG_MAC80211_DEBUGFS
2641 lq_sta->dbg_fixed_rate = 0;
2642 lq_sta->dbg_fixed_txp_reduction = TPC_INVALID;
2643#endif
2644#ifdef CONFIG_IWLWIFI_DEBUGFS 2647#ifdef CONFIG_IWLWIFI_DEBUGFS
2645 iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats); 2648 iwl_mvm_reset_frame_stats(mvm, &mvm->drv_rx_stats);
2646#endif 2649#endif
@@ -2811,12 +2814,12 @@ static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
2811 u8 ant = initial_rate->ant; 2814 u8 ant = initial_rate->ant;
2812 2815
2813#ifdef CONFIG_MAC80211_DEBUGFS 2816#ifdef CONFIG_MAC80211_DEBUGFS
2814 if (lq_sta->dbg_fixed_rate) { 2817 if (lq_sta->pers.dbg_fixed_rate) {
2815 rs_build_rates_table_from_fixed(mvm, lq_cmd, 2818 rs_build_rates_table_from_fixed(mvm, lq_cmd,
2816 lq_sta->band, 2819 lq_sta->band,
2817 lq_sta->dbg_fixed_rate); 2820 lq_sta->pers.dbg_fixed_rate);
2818 lq_cmd->reduced_tpc = 0; 2821 lq_cmd->reduced_tpc = 0;
2819 ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >> 2822 ant = (lq_sta->pers.dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
2820 RATE_MCS_ANT_POS; 2823 RATE_MCS_ANT_POS;
2821 } else 2824 } else
2822#endif 2825#endif
@@ -2926,14 +2929,14 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
2926 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2929 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2927 2930
2928 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n", 2931 IWL_DEBUG_RATE(mvm, "sta_id %d rate 0x%X\n",
2929 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 2932 lq_sta->lq.sta_id, lq_sta->pers.dbg_fixed_rate);
2930 2933
2931 if (lq_sta->dbg_fixed_rate) { 2934 if (lq_sta->pers.dbg_fixed_rate) {
2932 struct rs_rate rate; 2935 struct rs_rate rate;
2933 rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate, 2936 rs_rate_from_ucode_rate(lq_sta->pers.dbg_fixed_rate,
2934 lq_sta->band, &rate); 2937 lq_sta->band, &rate);
2935 rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate); 2938 rs_fill_lq_cmd(mvm, NULL, lq_sta, &rate);
2936 iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false); 2939 iwl_mvm_send_lq_cmd(lq_sta->pers.drv, &lq_sta->lq, false);
2937 } 2940 }
2938} 2941}
2939 2942
@@ -2946,16 +2949,16 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2946 size_t buf_size; 2949 size_t buf_size;
2947 u32 parsed_rate; 2950 u32 parsed_rate;
2948 2951
2949 mvm = lq_sta->drv; 2952 mvm = lq_sta->pers.drv;
2950 memset(buf, 0, sizeof(buf)); 2953 memset(buf, 0, sizeof(buf));
2951 buf_size = min(count, sizeof(buf) - 1); 2954 buf_size = min(count, sizeof(buf) - 1);
2952 if (copy_from_user(buf, user_buf, buf_size)) 2955 if (copy_from_user(buf, user_buf, buf_size))
2953 return -EFAULT; 2956 return -EFAULT;
2954 2957
2955 if (sscanf(buf, "%x", &parsed_rate) == 1) 2958 if (sscanf(buf, "%x", &parsed_rate) == 1)
2956 lq_sta->dbg_fixed_rate = parsed_rate; 2959 lq_sta->pers.dbg_fixed_rate = parsed_rate;
2957 else 2960 else
2958 lq_sta->dbg_fixed_rate = 0; 2961 lq_sta->pers.dbg_fixed_rate = 0;
2959 2962
2960 rs_program_fix_rate(mvm, lq_sta); 2963 rs_program_fix_rate(mvm, lq_sta);
2961 2964
@@ -2974,7 +2977,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2974 struct iwl_mvm *mvm; 2977 struct iwl_mvm *mvm;
2975 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2978 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2976 struct rs_rate *rate = &tbl->rate; 2979 struct rs_rate *rate = &tbl->rate;
2977 mvm = lq_sta->drv; 2980 mvm = lq_sta->pers.drv;
2978 buff = kmalloc(2048, GFP_KERNEL); 2981 buff = kmalloc(2048, GFP_KERNEL);
2979 if (!buff) 2982 if (!buff)
2980 return -ENOMEM; 2983 return -ENOMEM;
@@ -2984,7 +2987,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2984 lq_sta->total_failed, lq_sta->total_success, 2987 lq_sta->total_failed, lq_sta->total_success,
2985 lq_sta->active_legacy_rate); 2988 lq_sta->active_legacy_rate);
2986 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2989 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2987 lq_sta->dbg_fixed_rate); 2990 lq_sta->pers.dbg_fixed_rate);
2988 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 2991 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
2989 (mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "", 2992 (mvm->fw->valid_tx_ant & ANT_A) ? "ANT_A," : "",
2990 (mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "", 2993 (mvm->fw->valid_tx_ant & ANT_B) ? "ANT_B," : "",
@@ -3182,31 +3185,20 @@ static const struct file_operations rs_sta_dbgfs_drv_tx_stats_ops = {
3182static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir) 3185static void rs_add_debugfs(void *mvm, void *mvm_sta, struct dentry *dir)
3183{ 3186{
3184 struct iwl_lq_sta *lq_sta = mvm_sta; 3187 struct iwl_lq_sta *lq_sta = mvm_sta;
3185 lq_sta->rs_sta_dbgfs_scale_table_file = 3188 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir,
3186 debugfs_create_file("rate_scale_table", S_IRUSR | S_IWUSR, dir, 3189 lq_sta, &rs_sta_dbgfs_scale_table_ops);
3187 lq_sta, &rs_sta_dbgfs_scale_table_ops); 3190 debugfs_create_file("rate_stats_table", S_IRUSR, dir,
3188 lq_sta->rs_sta_dbgfs_stats_table_file = 3191 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3189 debugfs_create_file("rate_stats_table", S_IRUSR, dir, 3192 debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir,
3190 lq_sta, &rs_sta_dbgfs_stats_table_ops); 3193 lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops);
3191 lq_sta->rs_sta_dbgfs_drv_tx_stats_file = 3194 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
3192 debugfs_create_file("drv_tx_stats", S_IRUSR | S_IWUSR, dir, 3195 &lq_sta->tx_agg_tid_en);
3193 lq_sta, &rs_sta_dbgfs_drv_tx_stats_ops); 3196 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
3194 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = 3197 &lq_sta->pers.dbg_fixed_txp_reduction);
3195 debugfs_create_u8("tx_agg_tid_enable", S_IRUSR | S_IWUSR, dir,
3196 &lq_sta->tx_agg_tid_en);
3197 lq_sta->rs_sta_dbgfs_reduced_txp_file =
3198 debugfs_create_u8("reduced_tpc", S_IRUSR | S_IWUSR, dir,
3199 &lq_sta->dbg_fixed_txp_reduction);
3200} 3198}
3201 3199
3202static void rs_remove_debugfs(void *mvm, void *mvm_sta) 3200static void rs_remove_debugfs(void *mvm, void *mvm_sta)
3203{ 3201{
3204 struct iwl_lq_sta *lq_sta = mvm_sta;
3205 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
3206 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
3207 debugfs_remove(lq_sta->rs_sta_dbgfs_drv_tx_stats_file);
3208 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
3209 debugfs_remove(lq_sta->rs_sta_dbgfs_reduced_txp_file);
3210} 3202}
3211#endif 3203#endif
3212 3204
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index 374a83d7db25..f27b9d687a25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -349,16 +349,6 @@ struct iwl_lq_sta {
349 struct iwl_lq_cmd lq; 349 struct iwl_lq_cmd lq;
350 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ 350 struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
351 u8 tx_agg_tid_en; 351 u8 tx_agg_tid_en;
352#ifdef CONFIG_MAC80211_DEBUGFS
353 struct dentry *rs_sta_dbgfs_scale_table_file;
354 struct dentry *rs_sta_dbgfs_stats_table_file;
355 struct dentry *rs_sta_dbgfs_drv_tx_stats_file;
356 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
357 struct dentry *rs_sta_dbgfs_reduced_txp_file;
358 u32 dbg_fixed_rate;
359 u8 dbg_fixed_txp_reduction;
360#endif
361 struct iwl_mvm *drv;
362 352
363 /* used to be in sta_info */ 353 /* used to be in sta_info */
364 int last_txrate_idx; 354 int last_txrate_idx;
@@ -369,6 +359,15 @@ struct iwl_lq_sta {
369 359
370 /* tx power reduce for this sta */ 360 /* tx power reduce for this sta */
371 int tpc_reduce; 361 int tpc_reduce;
362
363 /* persistent fields - initialized only once - keep last! */
364 struct {
365#ifdef CONFIG_MAC80211_DEBUGFS
366 u32 dbg_fixed_rate;
367 u8 dbg_fixed_txp_reduction;
368#endif
369 struct iwl_mvm *drv;
370 } pers;
372}; 371};
373 372
374/* Initialize station's rate scaling information after adding station */ 373/* Initialize station's rate scaling information after adding station */
diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c
index cf7276967acd..4b98987fc413 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rx.c
@@ -259,6 +259,23 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
259 memset(&rx_status, 0, sizeof(rx_status)); 259 memset(&rx_status, 0, sizeof(rx_status));
260 260
261 /* 261 /*
262 * We have tx blocked stations (with CS bit). If we heard frames from
263 * a blocked station on a new channel we can TX to it again.
264 */
265 if (unlikely(mvm->csa_tx_block_bcn_timeout)) {
266 struct ieee80211_sta *sta;
267
268 rcu_read_lock();
269
270 sta = ieee80211_find_sta(
271 rcu_dereference(mvm->csa_tx_blocked_vif), hdr->addr2);
272 if (sta)
273 iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, false);
274
275 rcu_read_unlock();
276 }
277
278 /*
262 * drop the packet if it has failed being decrypted by HW 279 * drop the packet if it has failed being decrypted by HW
263 */ 280 */
264 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) { 281 if (iwl_mvm_set_mac80211_rx_flag(mvm, hdr, &rx_status, rx_pkt_status)) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 4b6c7d4bd199..004b1f5d0314 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -97,10 +97,9 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
97 return cpu_to_le16(rx_chain); 97 return cpu_to_le16(rx_chain);
98} 98}
99 99
100static inline __le32 100static __le32 iwl_mvm_scan_rxon_flags(enum ieee80211_band band)
101iwl_mvm_scan_rxon_flags(struct cfg80211_scan_request *req)
102{ 101{
103 if (req->channels[0]->band == IEEE80211_BAND_2GHZ) 102 if (band == IEEE80211_BAND_2GHZ)
104 return cpu_to_le32(PHY_BAND_24); 103 return cpu_to_le32(PHY_BAND_24);
105 else 104 else
106 return cpu_to_le32(PHY_BAND_5); 105 return cpu_to_le32(PHY_BAND_5);
@@ -130,19 +129,19 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band,
130 * request list, is not copied here, but inserted directly to the probe 129 * request list, is not copied here, but inserted directly to the probe
131 * request. 130 * request.
132 */ 131 */
133static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, 132static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
134 struct cfg80211_scan_request *req, 133 struct cfg80211_ssid *ssids,
135 int first) 134 int n_ssids, int first)
136{ 135{
137 int fw_idx, req_idx; 136 int fw_idx, req_idx;
138 137
139 for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first; 138 for (req_idx = n_ssids - 1, fw_idx = 0; req_idx >= first;
140 req_idx--, fw_idx++) { 139 req_idx--, fw_idx++) {
141 cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; 140 cmd_ssid[fw_idx].id = WLAN_EID_SSID;
142 cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; 141 cmd_ssid[fw_idx].len = ssids[req_idx].ssid_len;
143 memcpy(cmd->direct_scan[fw_idx].ssid, 142 memcpy(cmd_ssid[fw_idx].ssid,
144 req->ssids[req_idx].ssid, 143 ssids[req_idx].ssid,
145 req->ssids[req_idx].ssid_len); 144 ssids[req_idx].ssid_len);
146 } 145 }
147} 146}
148 147
@@ -204,7 +203,8 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
204 */ 203 */
205static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta, 204static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
206 int n_ssids, const u8 *ssid, int ssid_len, 205 int n_ssids, const u8 *ssid, int ssid_len,
207 const u8 *ie, int ie_len, 206 const u8 *band_ie, int band_ie_len,
207 const u8 *common_ie, int common_ie_len,
208 int left) 208 int left)
209{ 209{
210 int len = 0; 210 int len = 0;
@@ -244,12 +244,19 @@ static u16 iwl_mvm_fill_probe_req(struct ieee80211_mgmt *frame, const u8 *ta,
244 244
245 len += ssid_len + 2; 245 len += ssid_len + 2;
246 246
247 if (WARN_ON(left < ie_len)) 247 if (WARN_ON(left < band_ie_len + common_ie_len))
248 return len; 248 return len;
249 249
250 if (ie && ie_len) { 250 if (band_ie && band_ie_len) {
251 memcpy(pos, ie, ie_len); 251 memcpy(pos, band_ie, band_ie_len);
252 len += ie_len; 252 pos += band_ie_len;
253 len += band_ie_len;
254 }
255
256 if (common_ie && common_ie_len) {
257 memcpy(pos, common_ie, common_ie_len);
258 pos += common_ie_len;
259 len += common_ie_len;
253 } 260 }
254 261
255 return (u16)len; 262 return (u16)len;
@@ -267,7 +274,7 @@ static void iwl_mvm_scan_condition_iterator(void *data, u8 *mac,
267 274
268static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, 275static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
269 struct ieee80211_vif *vif, 276 struct ieee80211_vif *vif,
270 int n_ssids, 277 int n_ssids, u32 flags,
271 struct iwl_mvm_scan_params *params) 278 struct iwl_mvm_scan_params *params)
272{ 279{
273 bool global_bound = false; 280 bool global_bound = false;
@@ -289,6 +296,9 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
289 params->max_out_time = 250; 296 params->max_out_time = 250;
290 } 297 }
291 298
299 if (flags & NL80211_SCAN_FLAG_LOW_PRIORITY)
300 params->max_out_time = 200;
301
292not_bound: 302not_bound:
293 303
294 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 304 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
@@ -325,22 +335,20 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
325 335
326 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n"); 336 IWL_DEBUG_SCAN(mvm, "Handling mac80211 scan request\n");
327 mvm->scan_status = IWL_MVM_SCAN_OS; 337 mvm->scan_status = IWL_MVM_SCAN_OS;
328 memset(cmd, 0, sizeof(struct iwl_scan_cmd) + 338 memset(cmd, 0, ksize(cmd));
329 mvm->fw->ucode_capa.max_probe_length +
330 (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)));
331 339
332 cmd->channel_count = (u8)req->n_channels; 340 cmd->channel_count = (u8)req->n_channels;
333 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 341 cmd->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
334 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 342 cmd->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
335 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm); 343 cmd->rxchain_sel_flags = iwl_mvm_scan_rx_chain(mvm);
336 344
337 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params); 345 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, req->flags, &params);
338 cmd->max_out_time = cpu_to_le32(params.max_out_time); 346 cmd->max_out_time = cpu_to_le32(params.max_out_time);
339 cmd->suspend_time = cpu_to_le32(params.suspend_time); 347 cmd->suspend_time = cpu_to_le32(params.suspend_time);
340 if (params.passive_fragmented) 348 if (params.passive_fragmented)
341 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN; 349 cmd->scan_flags |= SCAN_FLAGS_FRAGMENTED_SCAN;
342 350
343 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req); 351 cmd->rxon_flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
344 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP | 352 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
345 MAC_FILTER_IN_BEACON); 353 MAC_FILTER_IN_BEACON);
346 354
@@ -367,7 +375,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
367 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; 375 cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE;
368 } 376 }
369 377
370 iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); 378 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->ssids, req->n_ssids,
379 basic_ssid ? 1 : 0);
371 380
372 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL | 381 cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
373 TX_CMD_FLG_BT_DIS); 382 TX_CMD_FLG_BT_DIS);
@@ -382,7 +391,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
382 (struct ieee80211_mgmt *)cmd->data, 391 (struct ieee80211_mgmt *)cmd->data,
383 vif->addr, 392 vif->addr,
384 req->n_ssids, ssid, ssid_len, 393 req->n_ssids, ssid, ssid_len,
385 req->ie, req->ie_len, 394 req->ie, req->ie_len, NULL, 0,
386 mvm->fw->ucode_capa.max_probe_length)); 395 mvm->fw->ucode_capa.max_probe_length));
387 396
388 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params); 397 iwl_mvm_scan_fill_channels(cmd, req, basic_ssid, &params);
@@ -441,16 +450,27 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
441 return 0; 450 return 0;
442} 451}
443 452
444int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm, 453int iwl_mvm_rx_scan_offload_results(struct iwl_mvm *mvm,
445 struct iwl_rx_cmd_buffer *rxb, 454 struct iwl_rx_cmd_buffer *rxb,
446 struct iwl_device_cmd *cmd) 455 struct iwl_device_cmd *cmd)
447{ 456{
448 struct iwl_rx_packet *pkt = rxb_addr(rxb); 457 struct iwl_rx_packet *pkt = rxb_addr(rxb);
449 struct iwl_sched_scan_results *notif = (void *)pkt->data; 458 u8 client_bitmap = 0;
450 459
451 if (notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN) { 460 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)) {
452 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); 461 struct iwl_sched_scan_results *notif = (void *)pkt->data;
453 ieee80211_sched_scan_results(mvm->hw); 462
463 client_bitmap = notif->client_bitmap;
464 }
465
466 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN ||
467 client_bitmap & SCAN_CLIENT_SCHED_SCAN) {
468 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
469 IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
470 ieee80211_sched_scan_results(mvm->hw);
471 } else {
472 IWL_DEBUG_SCAN(mvm, "Scan results\n");
473 }
454 } 474 }
455 475
456 return 0; 476 return 0;
@@ -494,7 +514,7 @@ static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait,
494 }; 514 };
495} 515}
496 516
497int iwl_mvm_cancel_scan(struct iwl_mvm *mvm) 517static int iwl_mvm_cancel_regular_scan(struct iwl_mvm *mvm)
498{ 518{
499 struct iwl_notification_wait wait_scan_abort; 519 struct iwl_notification_wait wait_scan_abort;
500 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD, 520 static const u8 scan_abort_notif[] = { SCAN_ABORT_CMD,
@@ -535,33 +555,52 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
535 struct iwl_device_cmd *cmd) 555 struct iwl_device_cmd *cmd)
536{ 556{
537 struct iwl_rx_packet *pkt = rxb_addr(rxb); 557 struct iwl_rx_packet *pkt = rxb_addr(rxb);
538 struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data; 558 u8 status, ebs_status;
559
560 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) {
561 struct iwl_periodic_scan_complete *scan_notif;
562
563 scan_notif = (void *)pkt->data;
564 status = scan_notif->status;
565 ebs_status = scan_notif->ebs_status;
566 } else {
567 struct iwl_scan_offload_complete *scan_notif;
539 568
569 scan_notif = (void *)pkt->data;
570 status = scan_notif->status;
571 ebs_status = scan_notif->ebs_status;
572 }
540 /* scan status must be locked for proper checking */ 573 /* scan status must be locked for proper checking */
541 lockdep_assert_held(&mvm->mutex); 574 lockdep_assert_held(&mvm->mutex);
542 575
543 IWL_DEBUG_SCAN(mvm, 576 IWL_DEBUG_SCAN(mvm,
544 "Scheduled scan completed, status %s EBS status %s:%d\n", 577 "%s completed, status %s, EBS status %s\n",
545 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? 578 mvm->scan_status == IWL_MVM_SCAN_SCHED ?
546 "completed" : "aborted", scan_notif->ebs_status == 579 "Scheduled scan" : "Scan",
547 IWL_SCAN_EBS_SUCCESS ? "success" : "failed", 580 status == IWL_SCAN_OFFLOAD_COMPLETED ?
548 scan_notif->ebs_status); 581 "completed" : "aborted",
582 ebs_status == IWL_SCAN_EBS_SUCCESS ?
583 "success" : "failed");
549 584
550 585
551 /* only call mac80211 completion if the stop was initiated by FW */ 586 /* only call mac80211 completion if the stop was initiated by FW */
552 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) { 587 if (mvm->scan_status == IWL_MVM_SCAN_SCHED) {
553 mvm->scan_status = IWL_MVM_SCAN_NONE; 588 mvm->scan_status = IWL_MVM_SCAN_NONE;
554 ieee80211_sched_scan_stopped(mvm->hw); 589 ieee80211_sched_scan_stopped(mvm->hw);
590 } else if (mvm->scan_status == IWL_MVM_SCAN_OS) {
591 mvm->scan_status = IWL_MVM_SCAN_NONE;
592 ieee80211_scan_completed(mvm->hw,
593 status == IWL_SCAN_OFFLOAD_ABORTED);
555 } 594 }
556 595
557 mvm->last_ebs_successful = !scan_notif->ebs_status; 596 mvm->last_ebs_successful = !ebs_status;
558 597
559 return 0; 598 return 0;
560} 599}
561 600
562static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm, 601static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
563 struct ieee80211_vif *vif, 602 struct ieee80211_vif *vif,
564 struct ieee80211_sched_scan_ies *ies, 603 struct ieee80211_scan_ies *ies,
565 enum ieee80211_band band, 604 enum ieee80211_band band,
566 struct iwl_tx_cmd *cmd, 605 struct iwl_tx_cmd *cmd,
567 u8 *data) 606 u8 *data)
@@ -577,7 +616,8 @@ static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm,
577 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data, 616 cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data,
578 vif->addr, 617 vif->addr,
579 1, NULL, 0, 618 1, NULL, 0,
580 ies->ie[band], ies->len[band], 619 ies->ies[band], ies->len[band],
620 ies->common_ies, ies->common_ie_len,
581 SCAN_OFFLOAD_PROBE_REQ_SIZE); 621 SCAN_OFFLOAD_PROBE_REQ_SIZE);
582 cmd->len = cpu_to_le16(cmd_len); 622 cmd->len = cpu_to_le16(cmd_len);
583} 623}
@@ -588,9 +628,7 @@ static void iwl_build_scan_cmd(struct iwl_mvm *mvm,
588 struct iwl_scan_offload_cmd *scan, 628 struct iwl_scan_offload_cmd *scan,
589 struct iwl_mvm_scan_params *params) 629 struct iwl_mvm_scan_params *params)
590{ 630{
591 scan->channel_count = 631 scan->channel_count = req->n_channels;
592 mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels +
593 mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
594 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); 632 scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME);
595 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); 633 scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH);
596 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; 634 scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT;
@@ -623,8 +661,8 @@ static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
623} 661}
624 662
625static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req, 663static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
626 struct iwl_scan_offload_cmd *scan, 664 struct iwl_ssid_ie *direct_scan,
627 u32 *ssid_bitmap) 665 u32 *ssid_bitmap, bool basic_ssid)
628{ 666{
629 int i, j; 667 int i, j;
630 int index; 668 int index;
@@ -638,10 +676,10 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
638 /* skip empty SSID matchsets */ 676 /* skip empty SSID matchsets */
639 if (!req->match_sets[i].ssid.ssid_len) 677 if (!req->match_sets[i].ssid.ssid_len)
640 continue; 678 continue;
641 scan->direct_scan[i].id = WLAN_EID_SSID; 679 direct_scan[i].id = WLAN_EID_SSID;
642 scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len; 680 direct_scan[i].len = req->match_sets[i].ssid.ssid_len;
643 memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid, 681 memcpy(direct_scan[i].ssid, req->match_sets[i].ssid.ssid,
644 scan->direct_scan[i].len); 682 direct_scan[i].len);
645 } 683 }
646 684
647 /* add SSIDs from scan SSID list */ 685 /* add SSIDs from scan SSID list */
@@ -649,14 +687,14 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
649 for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) { 687 for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) {
650 index = iwl_ssid_exist(req->ssids[j].ssid, 688 index = iwl_ssid_exist(req->ssids[j].ssid,
651 req->ssids[j].ssid_len, 689 req->ssids[j].ssid_len,
652 scan->direct_scan); 690 direct_scan);
653 if (index < 0) { 691 if (index < 0) {
654 if (!req->ssids[j].ssid_len) 692 if (!req->ssids[j].ssid_len && basic_ssid)
655 continue; 693 continue;
656 scan->direct_scan[i].id = WLAN_EID_SSID; 694 direct_scan[i].id = WLAN_EID_SSID;
657 scan->direct_scan[i].len = req->ssids[j].ssid_len; 695 direct_scan[i].len = req->ssids[j].ssid_len;
658 memcpy(scan->direct_scan[i].ssid, req->ssids[j].ssid, 696 memcpy(direct_scan[i].ssid, req->ssids[j].ssid,
659 scan->direct_scan[i].len); 697 direct_scan[i].len);
660 *ssid_bitmap |= BIT(i + 1); 698 *ssid_bitmap |= BIT(i + 1);
661 i++; 699 i++;
662 } else { 700 } else {
@@ -667,83 +705,67 @@ static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req,
667 705
668static void iwl_build_channel_cfg(struct iwl_mvm *mvm, 706static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
669 struct cfg80211_sched_scan_request *req, 707 struct cfg80211_sched_scan_request *req,
670 struct iwl_scan_channel_cfg *channels, 708 u8 *channels_buffer,
671 enum ieee80211_band band, 709 enum ieee80211_band band,
672 int *head, int *tail, 710 int *head,
673 u32 ssid_bitmap, 711 u32 ssid_bitmap,
674 struct iwl_mvm_scan_params *params) 712 struct iwl_mvm_scan_params *params)
675{ 713{
676 struct ieee80211_supported_band *s_band; 714 u32 n_channels = mvm->fw->ucode_capa.n_scan_channels;
677 int n_channels = req->n_channels; 715 __le32 *type = (__le32 *)channels_buffer;
678 int i, j, index = 0; 716 __le16 *channel_number = (__le16 *)(type + n_channels);
679 bool partial; 717 __le16 *iter_count = channel_number + n_channels;
718 __le32 *iter_interval = (__le32 *)(iter_count + n_channels);
719 u8 *active_dwell = (u8 *)(iter_interval + n_channels);
720 u8 *passive_dwell = active_dwell + n_channels;
721 int i, index = 0;
722
723 for (i = 0; i < req->n_channels; i++) {
724 struct ieee80211_channel *chan = req->channels[i];
725
726 if (chan->band != band)
727 continue;
680 728
681 /* 729 index = *head;
682 * We have to configure all supported channels, even if we don't want to 730 (*head)++;
683 * scan on them, but we have to send channels in the order that we want 731
684 * to scan. So add requested channels to head of the list and others to 732 channel_number[index] = cpu_to_le16(chan->hw_value);
685 * the end. 733 active_dwell[index] = params->dwell[band].active;
686 */ 734 passive_dwell[index] = params->dwell[band].passive;
687 s_band = &mvm->nvm_data->bands[band];
688
689 for (i = 0; i < s_band->n_channels && *head <= *tail; i++) {
690 partial = false;
691 for (j = 0; j < n_channels; j++)
692 if (s_band->channels[i].center_freq ==
693 req->channels[j]->center_freq) {
694 index = *head;
695 (*head)++;
696 /*
697 * Channels that came with the request will be
698 * in partial scan .
699 */
700 partial = true;
701 break;
702 }
703 if (!partial) {
704 index = *tail;
705 (*tail)--;
706 }
707 channels->channel_number[index] =
708 cpu_to_le16(ieee80211_frequency_to_channel(
709 s_band->channels[i].center_freq));
710 channels->dwell_time[index][0] = params->dwell[band].active;
711 channels->dwell_time[index][1] = params->dwell[band].passive;
712 735
713 channels->iter_count[index] = cpu_to_le16(1); 736 iter_count[index] = cpu_to_le16(1);
714 channels->iter_interval[index] = 0; 737 iter_interval[index] = 0;
715 738
716 if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR)) 739 if (!(chan->flags & IEEE80211_CHAN_NO_IR))
717 channels->type[index] |= 740 type[index] |=
718 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 741 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
719 742
720 channels->type[index] |= 743 type[index] |= cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL |
721 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL); 744 IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
722 if (partial)
723 channels->type[index] |=
724 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL);
725 745
726 if (s_band->channels[i].flags & IEEE80211_CHAN_NO_HT40) 746 if (chan->flags & IEEE80211_CHAN_NO_HT40)
727 channels->type[index] |= 747 type[index] |=
728 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW); 748 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW);
729 749
730 /* scan for all SSIDs from req->ssids */ 750 /* scan for all SSIDs from req->ssids */
731 channels->type[index] |= cpu_to_le32(ssid_bitmap); 751 type[index] |= cpu_to_le32(ssid_bitmap);
732 } 752 }
733} 753}
734 754
735int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, 755int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
736 struct ieee80211_vif *vif, 756 struct ieee80211_vif *vif,
737 struct cfg80211_sched_scan_request *req, 757 struct cfg80211_sched_scan_request *req,
738 struct ieee80211_sched_scan_ies *ies) 758 struct ieee80211_scan_ies *ies)
739{ 759{
740 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; 760 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
741 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 761 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
742 int head = 0; 762 int head = 0;
743 int tail = band_2ghz + band_5ghz - 1;
744 u32 ssid_bitmap; 763 u32 ssid_bitmap;
745 int cmd_len; 764 int cmd_len;
746 int ret; 765 int ret;
766 u8 *probes;
767 bool basic_ssid = !(mvm->fw->ucode_capa.flags &
768 IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID);
747 769
748 struct iwl_scan_offload_cfg *scan_cfg; 770 struct iwl_scan_offload_cfg *scan_cfg;
749 struct iwl_host_cmd cmd = { 771 struct iwl_host_cmd cmd = {
@@ -754,35 +776,40 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
754 lockdep_assert_held(&mvm->mutex); 776 lockdep_assert_held(&mvm->mutex);
755 777
756 cmd_len = sizeof(struct iwl_scan_offload_cfg) + 778 cmd_len = sizeof(struct iwl_scan_offload_cfg) +
779 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE +
757 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE; 780 2 * SCAN_OFFLOAD_PROBE_REQ_SIZE;
758 781
759 scan_cfg = kzalloc(cmd_len, GFP_KERNEL); 782 scan_cfg = kzalloc(cmd_len, GFP_KERNEL);
760 if (!scan_cfg) 783 if (!scan_cfg)
761 return -ENOMEM; 784 return -ENOMEM;
762 785
763 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, &params); 786 probes = scan_cfg->data +
787 mvm->fw->ucode_capa.n_scan_channels * IWL_SCAN_CHAN_SIZE;
788
789 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
764 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params); 790 iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd, &params);
765 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); 791 scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len);
766 792
767 iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap); 793 iwl_scan_offload_build_ssid(req, scan_cfg->scan_cmd.direct_scan,
794 &ssid_bitmap, basic_ssid);
768 /* build tx frames for supported bands */ 795 /* build tx frames for supported bands */
769 if (band_2ghz) { 796 if (band_2ghz) {
770 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 797 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
771 IEEE80211_BAND_2GHZ, 798 IEEE80211_BAND_2GHZ,
772 &scan_cfg->scan_cmd.tx_cmd[0], 799 &scan_cfg->scan_cmd.tx_cmd[0],
773 scan_cfg->data); 800 probes);
774 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 801 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
775 IEEE80211_BAND_2GHZ, &head, &tail, 802 IEEE80211_BAND_2GHZ, &head,
776 ssid_bitmap, &params); 803 ssid_bitmap, &params);
777 } 804 }
778 if (band_5ghz) { 805 if (band_5ghz) {
779 iwl_scan_offload_build_tx_cmd(mvm, vif, ies, 806 iwl_scan_offload_build_tx_cmd(mvm, vif, ies,
780 IEEE80211_BAND_5GHZ, 807 IEEE80211_BAND_5GHZ,
781 &scan_cfg->scan_cmd.tx_cmd[1], 808 &scan_cfg->scan_cmd.tx_cmd[1],
782 scan_cfg->data + 809 probes +
783 SCAN_OFFLOAD_PROBE_REQ_SIZE); 810 SCAN_OFFLOAD_PROBE_REQ_SIZE);
784 iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, 811 iwl_build_channel_cfg(mvm, req, scan_cfg->data,
785 IEEE80211_BAND_5GHZ, &head, &tail, 812 IEEE80211_BAND_5GHZ, &head,
786 ssid_bitmap, &params); 813 ssid_bitmap, &params);
787 } 814 }
788 815
@@ -872,11 +899,11 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
872 .watchdog = IWL_SCHED_SCAN_WATCHDOG, 899 .watchdog = IWL_SCHED_SCAN_WATCHDOG,
873 900
874 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS, 901 .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS,
875 .schedule_line[0].delay = req->interval / 1000, 902 .schedule_line[0].delay = cpu_to_le16(req->interval / 1000),
876 .schedule_line[0].full_scan_mul = 1, 903 .schedule_line[0].full_scan_mul = 1,
877 904
878 .schedule_line[1].iterations = 0xff, 905 .schedule_line[1].iterations = 0xff,
879 .schedule_line[1].delay = req->interval / 1000, 906 .schedule_line[1].delay = cpu_to_le16(req->interval / 1000),
880 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER, 907 .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER,
881 }; 908 };
882 909
@@ -899,7 +926,7 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
899 sizeof(scan_req), &scan_req); 926 sizeof(scan_req), &scan_req);
900} 927}
901 928
902static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm) 929static int iwl_mvm_send_scan_offload_abort(struct iwl_mvm *mvm)
903{ 930{
904 int ret; 931 int ret;
905 struct iwl_host_cmd cmd = { 932 struct iwl_host_cmd cmd = {
@@ -910,7 +937,9 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
910 /* Exit instantly with error when device is not ready 937 /* Exit instantly with error when device is not ready
911 * to receive scan abort command or it does not perform 938 * to receive scan abort command or it does not perform
912 * scheduled scan currently */ 939 * scheduled scan currently */
913 if (mvm->scan_status != IWL_MVM_SCAN_SCHED) 940 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
941 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
942 mvm->scan_status != IWL_MVM_SCAN_OS))
914 return -EIO; 943 return -EIO;
915 944
916 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); 945 ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
@@ -932,16 +961,19 @@ static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm)
932 return ret; 961 return ret;
933} 962}
934 963
935int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify) 964int iwl_mvm_scan_offload_stop(struct iwl_mvm *mvm, bool notify)
936{ 965{
937 int ret; 966 int ret;
938 struct iwl_notification_wait wait_scan_done; 967 struct iwl_notification_wait wait_scan_done;
939 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, }; 968 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, };
969 bool sched = mvm->scan_status == IWL_MVM_SCAN_SCHED;
940 970
941 lockdep_assert_held(&mvm->mutex); 971 lockdep_assert_held(&mvm->mutex);
942 972
943 if (mvm->scan_status != IWL_MVM_SCAN_SCHED) { 973 if (mvm->scan_status != IWL_MVM_SCAN_SCHED &&
944 IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n"); 974 (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN) ||
975 mvm->scan_status != IWL_MVM_SCAN_OS)) {
976 IWL_DEBUG_SCAN(mvm, "No scan to stop\n");
945 return 0; 977 return 0;
946 } 978 }
947 979
@@ -950,14 +982,16 @@ int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify)
950 ARRAY_SIZE(scan_done_notif), 982 ARRAY_SIZE(scan_done_notif),
951 NULL, NULL); 983 NULL, NULL);
952 984
953 ret = iwl_mvm_send_sched_scan_abort(mvm); 985 ret = iwl_mvm_send_scan_offload_abort(mvm);
954 if (ret) { 986 if (ret) {
955 IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret); 987 IWL_DEBUG_SCAN(mvm, "Send stop %sscan failed %d\n",
988 sched ? "offloaded " : "", ret);
956 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done); 989 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
957 return ret; 990 return ret;
958 } 991 }
959 992
960 IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n"); 993 IWL_DEBUG_SCAN(mvm, "Successfully sent stop %sscan\n",
994 sched ? "offloaded " : "");
961 995
962 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ); 996 ret = iwl_wait_notification(&mvm->notif_wait, &wait_scan_done, 1 * HZ);
963 if (ret) 997 if (ret)
@@ -970,8 +1004,317 @@ int iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm, bool notify)
970 */ 1004 */
971 mvm->scan_status = IWL_MVM_SCAN_NONE; 1005 mvm->scan_status = IWL_MVM_SCAN_NONE;
972 1006
973 if (notify) 1007 if (notify) {
974 ieee80211_sched_scan_stopped(mvm->hw); 1008 if (sched)
1009 ieee80211_sched_scan_stopped(mvm->hw);
1010 else
1011 ieee80211_scan_completed(mvm->hw, true);
1012 }
975 1013
976 return 0; 1014 return 0;
977} 1015}
1016
1017static void iwl_mvm_unified_scan_fill_tx_cmd(struct iwl_mvm *mvm,
1018 struct iwl_scan_req_tx_cmd *tx_cmd,
1019 bool no_cck)
1020{
1021 tx_cmd[0].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
1022 TX_CMD_FLG_BT_DIS);
1023 tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
1024 IEEE80211_BAND_2GHZ,
1025 no_cck);
1026 tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
1027
1028 tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
1029 TX_CMD_FLG_BT_DIS);
1030 tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
1031 IEEE80211_BAND_5GHZ,
1032 no_cck);
1033 tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
1034}
1035
1036static void
1037iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm,
1038 struct ieee80211_channel **channels,
1039 int n_channels, u32 ssid_bitmap,
1040 struct iwl_scan_req_unified_lmac *cmd)
1041{
1042 struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data;
1043 int i;
1044
1045 for (i = 0; i < n_channels; i++) {
1046 channel_cfg[i].channel_num =
1047 cpu_to_le16(channels[i]->hw_value);
1048 channel_cfg[i].iter_count = cpu_to_le16(1);
1049 channel_cfg[i].iter_interval = 0;
1050 channel_cfg[i].flags =
1051 cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL |
1052 ssid_bitmap);
1053 }
1054}
1055
1056static void
1057iwl_mvm_build_unified_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1058 struct ieee80211_scan_ies *ies,
1059 struct iwl_scan_req_unified_lmac *cmd)
1060{
1061 struct iwl_scan_probe_req *preq = (void *)(cmd->data +
1062 sizeof(struct iwl_scan_channel_cfg_lmac) *
1063 mvm->fw->ucode_capa.n_scan_channels);
1064 struct ieee80211_mgmt *frame = (struct ieee80211_mgmt *)preq->buf;
1065 u8 *pos;
1066
1067 frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
1068 eth_broadcast_addr(frame->da);
1069 memcpy(frame->sa, vif->addr, ETH_ALEN);
1070 eth_broadcast_addr(frame->bssid);
1071 frame->seq_ctrl = 0;
1072
1073 pos = frame->u.probe_req.variable;
1074 *pos++ = WLAN_EID_SSID;
1075 *pos++ = 0;
1076
1077 preq->mac_header.offset = 0;
1078 preq->mac_header.len = cpu_to_le16(24 + 2);
1079
1080 memcpy(pos, ies->ies[IEEE80211_BAND_2GHZ],
1081 ies->len[IEEE80211_BAND_2GHZ]);
1082 preq->band_data[0].offset = cpu_to_le16(pos - preq->buf);
1083 preq->band_data[0].len = cpu_to_le16(ies->len[IEEE80211_BAND_2GHZ]);
1084 pos += ies->len[IEEE80211_BAND_2GHZ];
1085
1086 memcpy(pos, ies->ies[IEEE80211_BAND_5GHZ],
1087 ies->len[IEEE80211_BAND_5GHZ]);
1088 preq->band_data[1].offset = cpu_to_le16(pos - preq->buf);
1089 preq->band_data[1].len = cpu_to_le16(ies->len[IEEE80211_BAND_5GHZ]);
1090 pos += ies->len[IEEE80211_BAND_5GHZ];
1091
1092 memcpy(pos, ies->common_ies, ies->common_ie_len);
1093 preq->common_data.offset = cpu_to_le16(pos - preq->buf);
1094 preq->common_data.len = cpu_to_le16(ies->common_ie_len);
1095}
1096
1097static void
1098iwl_mvm_build_generic_unified_scan_cmd(struct iwl_mvm *mvm,
1099 struct iwl_scan_req_unified_lmac *cmd,
1100 struct iwl_mvm_scan_params *params)
1101{
1102 memset(cmd, 0, ksize(cmd));
1103 cmd->active_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].active;
1104 cmd->passive_dwell = (u8)params->dwell[IEEE80211_BAND_2GHZ].passive;
1105 /* TODO: Use params; now fragmented isn't used. */
1106 cmd->fragmented_dwell = 0;
1107 cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
1108 cmd->max_out_time = cpu_to_le32(params->max_out_time);
1109 cmd->suspend_time = cpu_to_le32(params->suspend_time);
1110 cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_HIGH);
1111 cmd->iter_num = cpu_to_le32(1);
1112
1113 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT &&
1114 mvm->last_ebs_successful) {
1115 cmd->channel_opt[0].flags =
1116 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1117 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1118 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1119 cmd->channel_opt[1].flags =
1120 cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
1121 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
1122 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
1123 }
1124}
1125
1126int iwl_mvm_unified_scan_lmac(struct iwl_mvm *mvm,
1127 struct ieee80211_vif *vif,
1128 struct ieee80211_scan_request *req)
1129{
1130 struct iwl_host_cmd hcmd = {
1131 .id = SCAN_OFFLOAD_REQUEST_CMD,
1132 .len = { sizeof(struct iwl_scan_req_unified_lmac) +
1133 sizeof(struct iwl_scan_channel_cfg_lmac) *
1134 mvm->fw->ucode_capa.n_scan_channels +
1135 sizeof(struct iwl_scan_probe_req), },
1136 .data = { mvm->scan_cmd, },
1137 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1138 };
1139 struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd;
1140 struct iwl_mvm_scan_params params = {};
1141 u32 flags;
1142 int ssid_bitmap = 0;
1143 int ret, i;
1144
1145 lockdep_assert_held(&mvm->mutex);
1146
1147 /* we should have failed registration if scan_cmd was NULL */
1148 if (WARN_ON(mvm->scan_cmd == NULL))
1149 return -ENOMEM;
1150
1151 if (WARN_ON_ONCE(req->req.n_ssids > PROBE_OPTION_MAX ||
1152 req->ies.common_ie_len + req->ies.len[0] +
1153 req->ies.len[1] + 24 + 2 >
1154 SCAN_OFFLOAD_PROBE_REQ_SIZE ||
1155 req->req.n_channels >
1156 mvm->fw->ucode_capa.n_scan_channels))
1157 return -1;
1158
1159 mvm->scan_status = IWL_MVM_SCAN_OS;
1160
1161 iwl_mvm_scan_calc_params(mvm, vif, req->req.n_ssids, req->req.flags,
1162 &params);
1163
1164 iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, &params);
1165
1166 cmd->n_channels = (u8)req->req.n_channels;
1167
1168 flags = IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
1169
1170 if (req->req.n_ssids == 1 && req->req.ssids[0].ssid_len != 0)
1171 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
1172
1173 if (params.passive_fragmented)
1174 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
1175
1176 if (req->req.n_ssids == 0)
1177 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
1178
1179 cmd->scan_flags = cpu_to_le32(flags);
1180
1181 cmd->flags = iwl_mvm_scan_rxon_flags(req->req.channels[0]->band);
1182 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
1183 MAC_FILTER_IN_BEACON);
1184 iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, req->req.no_cck);
1185 iwl_mvm_scan_fill_ssids(cmd->direct_scan, req->req.ssids,
1186 req->req.n_ssids, 0);
1187
1188 cmd->schedule[0].delay = 0;
1189 cmd->schedule[0].iterations = 1;
1190 cmd->schedule[0].full_scan_mul = 0;
1191 cmd->schedule[1].delay = 0;
1192 cmd->schedule[1].iterations = 0;
1193 cmd->schedule[1].full_scan_mul = 0;
1194
1195 for (i = 1; i <= req->req.n_ssids; i++)
1196 ssid_bitmap |= BIT(i);
1197
1198 iwl_mvm_lmac_scan_cfg_channels(mvm, req->req.channels,
1199 req->req.n_channels, ssid_bitmap,
1200 cmd);
1201
1202 iwl_mvm_build_unified_scan_probe(mvm, vif, &req->ies, cmd);
1203
1204 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1205 if (!ret) {
1206 IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
1207 } else {
1208 /*
1209 * If the scan failed, it usually means that the FW was unable
1210 * to allocate the time events. Warn on it, but maybe we
1211 * should try to send the command again with different params.
1212 */
1213 IWL_ERR(mvm, "Scan failed! ret %d\n", ret);
1214 mvm->scan_status = IWL_MVM_SCAN_NONE;
1215 ret = -EIO;
1216 }
1217 return ret;
1218}
1219
1220int iwl_mvm_unified_sched_scan_lmac(struct iwl_mvm *mvm,
1221 struct ieee80211_vif *vif,
1222 struct cfg80211_sched_scan_request *req,
1223 struct ieee80211_scan_ies *ies)
1224{
1225 struct iwl_host_cmd hcmd = {
1226 .id = SCAN_OFFLOAD_REQUEST_CMD,
1227 .len = { sizeof(struct iwl_scan_req_unified_lmac) +
1228 sizeof(struct iwl_scan_channel_cfg_lmac) *
1229 mvm->fw->ucode_capa.n_scan_channels +
1230 sizeof(struct iwl_scan_probe_req), },
1231 .data = { mvm->scan_cmd, },
1232 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
1233 };
1234 struct iwl_scan_req_unified_lmac *cmd = mvm->scan_cmd;
1235 struct iwl_mvm_scan_params params = {};
1236 int ret;
1237 u32 flags = 0, ssid_bitmap = 0;
1238
1239 lockdep_assert_held(&mvm->mutex);
1240
1241 /* we should have failed registration if scan_cmd was NULL */
1242 if (WARN_ON(mvm->scan_cmd == NULL))
1243 return -ENOMEM;
1244
1245 if (WARN_ON_ONCE(req->n_ssids > PROBE_OPTION_MAX ||
1246 ies->common_ie_len + ies->len[0] + ies->len[1] + 24 + 2
1247 > SCAN_OFFLOAD_PROBE_REQ_SIZE ||
1248 req->n_channels > mvm->fw->ucode_capa.n_scan_channels))
1249 return -ENOBUFS;
1250
1251 iwl_mvm_scan_calc_params(mvm, vif, req->n_ssids, 0, &params);
1252
1253 iwl_mvm_build_generic_unified_scan_cmd(mvm, cmd, &params);
1254
1255 cmd->n_channels = (u8)req->n_channels;
1256
1257 if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
1258 IWL_DEBUG_SCAN(mvm,
1259 "Sending scheduled scan with filtering, n_match_sets %d\n",
1260 req->n_match_sets);
1261 } else {
1262 IWL_DEBUG_SCAN(mvm,
1263 "Sending Scheduled scan without filtering\n");
1264 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
1265 }
1266
1267 if (req->n_ssids == 1 && req->ssids[0].ssid_len != 0)
1268 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
1269
1270 if (params.passive_fragmented)
1271 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
1272
1273 if (req->n_ssids == 0)
1274 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
1275
1276 cmd->scan_flags = cpu_to_le32(flags);
1277
1278 cmd->flags = iwl_mvm_scan_rxon_flags(req->channels[0]->band);
1279 cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
1280 MAC_FILTER_IN_BEACON);
1281 iwl_mvm_unified_scan_fill_tx_cmd(mvm, cmd->tx_cmd, false);
1282 iwl_scan_offload_build_ssid(req, cmd->direct_scan, &ssid_bitmap, false);
1283
1284 cmd->schedule[0].delay = cpu_to_le16(req->interval / MSEC_PER_SEC);
1285 cmd->schedule[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS;
1286 cmd->schedule[0].full_scan_mul = 1;
1287
1288 cmd->schedule[1].delay = cpu_to_le16(req->interval / MSEC_PER_SEC);
1289 cmd->schedule[1].iterations = 0xff;
1290 cmd->schedule[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER;
1291
1292 iwl_mvm_lmac_scan_cfg_channels(mvm, req->channels, req->n_channels,
1293 ssid_bitmap, cmd);
1294
1295 iwl_mvm_build_unified_scan_probe(mvm, vif, ies, cmd);
1296
1297 ret = iwl_mvm_send_cmd(mvm, &hcmd);
1298 if (!ret) {
1299 IWL_DEBUG_SCAN(mvm,
1300 "Sched scan request was sent successfully\n");
1301 } else {
1302 /*
1303 * If the scan failed, it usually means that the FW was unable
1304 * to allocate the time events. Warn on it, but maybe we
1305 * should try to send the command again with different params.
1306 */
1307 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret);
1308 mvm->scan_status = IWL_MVM_SCAN_NONE;
1309 ret = -EIO;
1310 }
1311 return ret;
1312}
1313
1314
1315int iwl_mvm_cancel_scan(struct iwl_mvm *mvm)
1316{
1317 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_LMAC_SCAN)
1318 return iwl_mvm_scan_offload_stop(mvm, true);
1319 return iwl_mvm_cancel_regular_scan(mvm);
1320}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 1fb01ea2e704..812813964847 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -1448,3 +1448,77 @@ int iwl_mvm_rx_eosp_notif(struct iwl_mvm *mvm,
1448 1448
1449 return 0; 1449 return 0;
1450} 1450}
1451
1452void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
1453 struct iwl_mvm_sta *mvmsta, bool disable)
1454{
1455 struct iwl_mvm_add_sta_cmd cmd = {
1456 .add_modify = STA_MODE_MODIFY,
1457 .sta_id = mvmsta->sta_id,
1458 .station_flags = disable ? cpu_to_le32(STA_FLG_DISABLE_TX) : 0,
1459 .station_flags_msk = cpu_to_le32(STA_FLG_DISABLE_TX),
1460 .mac_id_n_color = cpu_to_le32(mvmsta->mac_id_n_color),
1461 };
1462 int ret;
1463
1464 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_DISABLE_STA_TX))
1465 return;
1466
1467 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1468 if (ret)
1469 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
1470}
1471
1472void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
1473 struct ieee80211_sta *sta,
1474 bool disable)
1475{
1476 struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1477
1478 spin_lock_bh(&mvm_sta->lock);
1479
1480 if (mvm_sta->disable_tx == disable) {
1481 spin_unlock_bh(&mvm_sta->lock);
1482 return;
1483 }
1484
1485 mvm_sta->disable_tx = disable;
1486
1487 /*
1488 * Tell mac80211 to start/stop queueing tx for this station,
1489 * but don't stop queueing if there are still pending frames
1490 * for this station.
1491 */
1492 if (disable || !atomic_read(&mvm->pending_frames[mvm_sta->sta_id]))
1493 ieee80211_sta_block_awake(mvm->hw, sta, disable);
1494
1495 iwl_mvm_sta_modify_disable_tx(mvm, mvm_sta, disable);
1496
1497 spin_unlock_bh(&mvm_sta->lock);
1498}
1499
1500void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
1501 struct iwl_mvm_vif *mvmvif,
1502 bool disable)
1503{
1504 struct ieee80211_sta *sta;
1505 struct iwl_mvm_sta *mvm_sta;
1506 int i;
1507
1508 lockdep_assert_held(&mvm->mutex);
1509
1510 /* Block/unblock all the stations of the given mvmvif */
1511 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
1512 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
1513 lockdep_is_held(&mvm->mutex));
1514 if (IS_ERR_OR_NULL(sta))
1515 continue;
1516
1517 mvm_sta = iwl_mvm_sta_from_mac80211(sta);
1518 if (mvm_sta->mac_id_n_color !=
1519 FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
1520 continue;
1521
1522 iwl_mvm_sta_modify_disable_tx_ap(mvm, sta, disable);
1523 }
1524}
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h
index d98e8a2142b8..3b1c8bd6cb54 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.h
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.h
@@ -73,6 +73,7 @@
73#include "rs.h" 73#include "rs.h"
74 74
75struct iwl_mvm; 75struct iwl_mvm;
76struct iwl_mvm_vif;
76 77
77/** 78/**
78 * DOC: station table - introduction 79 * DOC: station table - introduction
@@ -295,6 +296,7 @@ static inline u16 iwl_mvm_tid_queued(struct iwl_mvm_tid_data *tid_data)
295 * @tid_data: per tid data. Look at %iwl_mvm_tid_data. 296 * @tid_data: per tid data. Look at %iwl_mvm_tid_data.
296 * @tx_protection: reference counter for controlling the Tx protection. 297 * @tx_protection: reference counter for controlling the Tx protection.
297 * @tt_tx_protection: is thermal throttling enable Tx protection? 298 * @tt_tx_protection: is thermal throttling enable Tx protection?
299 * @disable_tx: is tx to this STA disabled?
298 * 300 *
299 * When mac80211 creates a station it reserves some space (hw->sta_data_size) 301 * When mac80211 creates a station it reserves some space (hw->sta_data_size)
300 * in the structure for use by driver. This structure is placed in that 302 * in the structure for use by driver. This structure is placed in that
@@ -317,6 +319,8 @@ struct iwl_mvm_sta {
317 /* Temporary, until the new TLC will control the Tx protection */ 319 /* Temporary, until the new TLC will control the Tx protection */
318 s8 tx_protection; 320 s8 tx_protection;
319 bool tt_tx_protection; 321 bool tt_tx_protection;
322
323 bool disable_tx;
320}; 324};
321 325
322static inline struct iwl_mvm_sta * 326static inline struct iwl_mvm_sta *
@@ -404,5 +408,13 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm,
404 bool agg); 408 bool agg);
405int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, 409int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta,
406 bool drain); 410 bool drain);
411void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
412 struct iwl_mvm_sta *mvmsta, bool disable);
413void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
414 struct ieee80211_sta *sta,
415 bool disable);
416void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
417 struct iwl_mvm_vif *mvmvif,
418 bool disable);
407 419
408#endif /* __sta_h__ */ 420#endif /* __sta_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 80100f6cc12a..ae52613b97f2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -138,6 +138,41 @@ static void iwl_mvm_roc_finished(struct iwl_mvm *mvm)
138 schedule_work(&mvm->roc_done_wk); 138 schedule_work(&mvm->roc_done_wk);
139} 139}
140 140
141static void iwl_mvm_csa_noa_start(struct iwl_mvm *mvm)
142{
143 struct ieee80211_vif *csa_vif;
144
145 rcu_read_lock();
146
147 csa_vif = rcu_dereference(mvm->csa_vif);
148 if (!csa_vif || !csa_vif->csa_active)
149 goto out_unlock;
150
151 IWL_DEBUG_TE(mvm, "CSA NOA started\n");
152
153 /*
154 * CSA NoA is started but we still have beacons to
155 * transmit on the current channel.
156 * So we just do nothing here and the switch
157 * will be performed on the last TBTT.
158 */
159 if (!ieee80211_csa_is_complete(csa_vif)) {
160 IWL_WARN(mvm, "CSA NOA started too early\n");
161 goto out_unlock;
162 }
163
164 ieee80211_csa_finish(csa_vif);
165
166 rcu_read_unlock();
167
168 RCU_INIT_POINTER(mvm->csa_vif, NULL);
169
170 return;
171
172out_unlock:
173 rcu_read_unlock();
174}
175
141static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm, 176static bool iwl_mvm_te_check_disconnect(struct iwl_mvm *mvm,
142 struct ieee80211_vif *vif, 177 struct ieee80211_vif *vif,
143 const char *errmsg) 178 const char *errmsg)
@@ -213,6 +248,14 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
213 set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); 248 set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
214 iwl_mvm_ref(mvm, IWL_MVM_REF_ROC); 249 iwl_mvm_ref(mvm, IWL_MVM_REF_ROC);
215 ieee80211_ready_on_channel(mvm->hw); 250 ieee80211_ready_on_channel(mvm->hw);
251 } else if (te_data->vif->type == NL80211_IFTYPE_AP) {
252 if (le32_to_cpu(notif->status))
253 iwl_mvm_csa_noa_start(mvm);
254 else
255 IWL_DEBUG_TE(mvm, "CSA NOA failed to start\n");
256
257 /* we don't need it anymore */
258 iwl_mvm_te_clear_data(mvm, te_data);
216 } 259 }
217 } else { 260 } else {
218 IWL_WARN(mvm, "Got TE with unknown action\n"); 261 IWL_WARN(mvm, "Got TE with unknown action\n");
@@ -538,3 +581,33 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
538 581
539 iwl_mvm_roc_finished(mvm); 582 iwl_mvm_roc_finished(mvm);
540} 583}
584
585int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
586 struct ieee80211_vif *vif,
587 u32 duration, u32 apply_time)
588{
589 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
590 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
591 struct iwl_time_event_cmd time_cmd = {};
592
593 lockdep_assert_held(&mvm->mutex);
594
595 if (te_data->running) {
596 IWL_DEBUG_TE(mvm, "CS NOA is already scheduled\n");
597 return -EBUSY;
598 }
599
600 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
601 time_cmd.id_and_color =
602 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
603 time_cmd.id = cpu_to_le32(TE_P2P_GO_CSA_NOA);
604 time_cmd.apply_time = cpu_to_le32(apply_time);
605 time_cmd.max_frags = TE_V2_FRAG_NONE;
606 time_cmd.duration = cpu_to_le32(duration);
607 time_cmd.repeat = 1;
608 time_cmd.interval = cpu_to_le32(1);
609 time_cmd.policy = cpu_to_le16(TE_V2_NOTIF_HOST_EVENT_START |
610 TE_V2_ABSENCE);
611
612 return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
613}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index 4a61c8c02372..2f48a90d4ad3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -214,4 +214,33 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
214 214
215void iwl_mvm_roc_done_wk(struct work_struct *wk); 215void iwl_mvm_roc_done_wk(struct work_struct *wk);
216 216
217/**
218 * iwl_mvm_schedule_csa_noa - request NoA for channel switch
219 * @mvm: the mvm component
220 * @vif: the virtual interface for which the channel switch is issued
221 * @duration: the duration of the NoA in TU.
222 * @apply_time: NoA start time in GP2.
223 *
224 * This function is used to schedule NoA time event and is used to perform
225 * the channel switch flow.
226 */
227int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
228 struct ieee80211_vif *vif,
229 u32 duration, u32 apply_time);
230
231/**
232 * iwl_mvm_te_scheduled - check if the fw received the TE cmd
233 * @te_data: the time event data that corresponds to that time event
234 *
235 * This function returns true iff this TE is added to the fw.
236 */
237static inline bool
238iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
239{
240 if (!te_data)
241 return false;
242
243 return !!te_data->uid;
244}
245
217#endif /* __time_event_h__ */ 246#endif /* __time_event_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index 3846a6c41eb1..e9ff38635c21 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -131,7 +131,6 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
131 !is_multicast_ether_addr(ieee80211_get_DA(hdr))) 131 !is_multicast_ether_addr(ieee80211_get_DA(hdr)))
132 tx_flags |= TX_CMD_FLG_PROT_REQUIRE; 132 tx_flags |= TX_CMD_FLG_PROT_REQUIRE;
133 133
134 tx_cmd->driver_txop = 0;
135 tx_cmd->tx_flags = cpu_to_le32(tx_flags); 134 tx_cmd->tx_flags = cpu_to_le32(tx_flags);
136 /* Total # bytes to be transmitted */ 135 /* Total # bytes to be transmitted */
137 tx_cmd->len = cpu_to_le16((u16)skb->len); 136 tx_cmd->len = cpu_to_le16((u16)skb->len);
@@ -205,7 +204,13 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
205 mvm->mgmt_last_antenna_idx = 204 mvm->mgmt_last_antenna_idx =
206 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant, 205 iwl_mvm_next_antenna(mvm, mvm->fw->valid_tx_ant,
207 mvm->mgmt_last_antenna_idx); 206 mvm->mgmt_last_antenna_idx);
208 rate_flags = BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; 207
208 if (info->band == IEEE80211_BAND_2GHZ &&
209 !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
210 rate_flags = BIT(ANT_A) << RATE_MCS_ANT_POS;
211 else
212 rate_flags =
213 BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
209 214
210 /* Set CCK flag as needed */ 215 /* Set CCK flag as needed */
211 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) 216 if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
@@ -717,18 +722,26 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
717 /* We can't free more than one frame at once on a shared queue */ 722 /* We can't free more than one frame at once on a shared queue */
718 WARN_ON(skb_freed > 1); 723 WARN_ON(skb_freed > 1);
719 724
720 /* If we have still frames from this STA nothing to do here */ 725 /* If we have still frames for this STA nothing to do here */
721 if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) 726 if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id]))
722 goto out; 727 goto out;
723 728
724 if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) { 729 if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) {
730
725 /* 731 /*
726 * If there are no pending frames for this STA, notify 732 * If there are no pending frames for this STA and
727 * mac80211 that this station can go to sleep in its 733 * the tx to this station is not disabled, notify
734 * mac80211 that this station can now wake up in its
728 * STA table. 735 * STA table.
729 * If mvmsta is not NULL, sta is valid. 736 * If mvmsta is not NULL, sta is valid.
730 */ 737 */
731 ieee80211_sta_block_awake(mvm->hw, sta, false); 738
739 spin_lock_bh(&mvmsta->lock);
740
741 if (!mvmsta->disable_tx)
742 ieee80211_sta_block_awake(mvm->hw, sta, false);
743
744 spin_unlock_bh(&mvmsta->lock);
732 } 745 }
733 746
734 if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) { 747 if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) {
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index aa9fc77e8413..ac249da8a22b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -519,71 +519,6 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
519 iwl_mvm_dump_umac_error_log(mvm); 519 iwl_mvm_dump_umac_error_log(mvm);
520} 520}
521 521
522#ifdef CONFIG_IWLWIFI_DEBUGFS
523void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
524{
525 const struct fw_img *img;
526 u32 ofs, sram_len;
527 void *sram;
528
529 if (!mvm->ucode_loaded || mvm->fw_error_sram || mvm->fw_error_dump)
530 return;
531
532 img = &mvm->fw->img[mvm->cur_ucode];
533 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset;
534 sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
535
536 sram = kzalloc(sram_len, GFP_ATOMIC);
537 if (!sram)
538 return;
539
540 iwl_trans_read_mem_bytes(mvm->trans, ofs, sram, sram_len);
541 mvm->fw_error_sram = sram;
542 mvm->fw_error_sram_len = sram_len;
543}
544
545void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
546{
547 int i, reg_val;
548 unsigned long flags;
549
550 if (!mvm->ucode_loaded || mvm->fw_error_rxf || mvm->fw_error_dump)
551 return;
552
553 /* reading buffer size */
554 reg_val = iwl_trans_read_prph(mvm->trans, RXF_SIZE_ADDR);
555 mvm->fw_error_rxf_len =
556 (reg_val & RXF_SIZE_BYTE_CNT_MSK) >> RXF_SIZE_BYTE_CND_POS;
557
558 /* the register holds the value divided by 128 */
559 mvm->fw_error_rxf_len = mvm->fw_error_rxf_len << 7;
560
561 if (!mvm->fw_error_rxf_len)
562 return;
563
564 mvm->fw_error_rxf = kzalloc(mvm->fw_error_rxf_len, GFP_ATOMIC);
565 if (!mvm->fw_error_rxf) {
566 mvm->fw_error_rxf_len = 0;
567 return;
568 }
569
570 if (!iwl_trans_grab_nic_access(mvm->trans, false, &flags)) {
571 kfree(mvm->fw_error_rxf);
572 mvm->fw_error_rxf = NULL;
573 mvm->fw_error_rxf_len = 0;
574 return;
575 }
576
577 for (i = 0; i < (mvm->fw_error_rxf_len / sizeof(u32)); i++) {
578 iwl_trans_write_prph(mvm->trans, RXF_LD_FENCE_OFFSET_ADDR,
579 i * sizeof(u32));
580 mvm->fw_error_rxf[i] =
581 iwl_trans_read_prph(mvm->trans, RXF_FIFO_RD_FENCE_ADDR);
582 }
583 iwl_trans_release_nic_access(mvm->trans, &flags);
584}
585#endif
586
587/** 522/**
588 * iwl_mvm_send_lq_cmd() - Send link quality command 523 * iwl_mvm_send_lq_cmd() - Send link quality command
589 * @init: This command is sent as part of station initialization right 524 * @init: This command is sent as part of station initialization right
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 7091a18d5a72..98950e45c7b0 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -367,6 +367,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
367 {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)}, 367 {IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
368 {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)}, 368 {IWL_PCI_DEVICE(0x095A, 0x5412, iwl7265_2ac_cfg)},
369 {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)}, 369 {IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
370 {IWL_PCI_DEVICE(0x095A, 0x5510, iwl7265_2ac_cfg)},
370 {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)}, 371 {IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
371 {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)}, 372 {IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
372 {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)}, 373 {IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
@@ -380,7 +381,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
380 {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, 381 {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
381 {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, 382 {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
382 {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, 383 {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
383 {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)}, 384 {IWL_PCI_DEVICE(0x095B, 0x9200, iwl7265_2ac_cfg)},
384 {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, 385 {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
385 {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, 386 {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
386 {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, 387 {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 6c22b23a2845..78f72c34438a 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -260,6 +260,9 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
260 * @wd_timeout: queue watchdog timeout (jiffies) 260 * @wd_timeout: queue watchdog timeout (jiffies)
261 * @reg_lock: protect hw register access 261 * @reg_lock: protect hw register access
262 * @cmd_in_flight: true when we have a host command in flight 262 * @cmd_in_flight: true when we have a host command in flight
263 * @fw_mon_phys: physical address of the buffer for the firmware monitor
264 * @fw_mon_page: points to the first page of the buffer for the firmware monitor
265 * @fw_mon_size: size of the buffer for the firmware monitor
263 */ 266 */
264struct iwl_trans_pcie { 267struct iwl_trans_pcie {
265 struct iwl_rxq rxq; 268 struct iwl_rxq rxq;
@@ -312,6 +315,10 @@ struct iwl_trans_pcie {
312 /*protect hw register */ 315 /*protect hw register */
313 spinlock_t reg_lock; 316 spinlock_t reg_lock;
314 bool cmd_in_flight; 317 bool cmd_in_flight;
318
319 dma_addr_t fw_mon_phys;
320 struct page *fw_mon_page;
321 u32 fw_mon_size;
315}; 322};
316 323
317#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ 324#define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 788085bc65d7..5b5b0d8c6f60 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -76,6 +76,68 @@
76#include "iwl-fw-error-dump.h" 76#include "iwl-fw-error-dump.h"
77#include "internal.h" 77#include "internal.h"
78 78
79static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
80{
81 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
82
83 if (!trans_pcie->fw_mon_page)
84 return;
85
86 dma_unmap_page(trans->dev, trans_pcie->fw_mon_phys,
87 trans_pcie->fw_mon_size, DMA_FROM_DEVICE);
88 __free_pages(trans_pcie->fw_mon_page,
89 get_order(trans_pcie->fw_mon_size));
90 trans_pcie->fw_mon_page = NULL;
91 trans_pcie->fw_mon_phys = 0;
92 trans_pcie->fw_mon_size = 0;
93}
94
95static void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans)
96{
97 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
98 struct page *page;
99 dma_addr_t phys;
100 u32 size;
101 u8 power;
102
103 if (trans_pcie->fw_mon_page) {
104 dma_sync_single_for_device(trans->dev, trans_pcie->fw_mon_phys,
105 trans_pcie->fw_mon_size,
106 DMA_FROM_DEVICE);
107 return;
108 }
109
110 phys = 0;
111 for (power = 26; power >= 11; power--) {
112 int order;
113
114 size = BIT(power);
115 order = get_order(size);
116 page = alloc_pages(__GFP_COMP | __GFP_NOWARN | __GFP_ZERO,
117 order);
118 if (!page)
119 continue;
120
121 phys = dma_map_page(trans->dev, page, 0, PAGE_SIZE << order,
122 DMA_FROM_DEVICE);
123 if (dma_mapping_error(trans->dev, phys)) {
124 __free_pages(page, order);
125 continue;
126 }
127 IWL_INFO(trans,
128 "Allocated 0x%08x bytes (order %d) for firmware monitor.\n",
129 size, order);
130 break;
131 }
132
133 if (!page)
134 return;
135
136 trans_pcie->fw_mon_page = page;
137 trans_pcie->fw_mon_phys = phys;
138 trans_pcie->fw_mon_size = size;
139}
140
79static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg) 141static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg)
80{ 142{
81 iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG, 143 iwl_write32(trans, HEEP_CTRL_WRD_PCIEX_CTRL_REG,
@@ -675,6 +737,7 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans,
675static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, 737static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
676 const struct fw_img *image) 738 const struct fw_img *image)
677{ 739{
740 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
678 int ret = 0; 741 int ret = 0;
679 int first_ucode_section; 742 int first_ucode_section;
680 743
@@ -733,6 +796,20 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
733 return ret; 796 return ret;
734 } 797 }
735 798
799 /* supported for 7000 only for the moment */
800 if (iwlwifi_mod_params.fw_monitor &&
801 trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
802 iwl_pcie_alloc_fw_monitor(trans);
803
804 if (trans_pcie->fw_mon_size) {
805 iwl_write_prph(trans, MON_BUFF_BASE_ADDR,
806 trans_pcie->fw_mon_phys >> 4);
807 iwl_write_prph(trans, MON_BUFF_END_ADDR,
808 (trans_pcie->fw_mon_phys +
809 trans_pcie->fw_mon_size) >> 4);
810 }
811 }
812
736 /* release CPU reset */ 813 /* release CPU reset */
737 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) 814 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
738 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); 815 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -1126,6 +1203,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
1126 if (trans_pcie->napi.poll) 1203 if (trans_pcie->napi.poll)
1127 netif_napi_del(&trans_pcie->napi); 1204 netif_napi_del(&trans_pcie->napi);
1128 1205
1206 iwl_pcie_free_fw_monitor(trans);
1207
1129 kfree(trans); 1208 kfree(trans);
1130} 1209}
1131 1210
@@ -1494,10 +1573,12 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
1494 txq = &trans_pcie->txq[cnt]; 1573 txq = &trans_pcie->txq[cnt];
1495 q = &txq->q; 1574 q = &txq->q;
1496 pos += scnprintf(buf + pos, bufsz - pos, 1575 pos += scnprintf(buf + pos, bufsz - pos,
1497 "hwq %.2d: read=%u write=%u use=%d stop=%d\n", 1576 "hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d%s\n",
1498 cnt, q->read_ptr, q->write_ptr, 1577 cnt, q->read_ptr, q->write_ptr,
1499 !!test_bit(cnt, trans_pcie->queue_used), 1578 !!test_bit(cnt, trans_pcie->queue_used),
1500 !!test_bit(cnt, trans_pcie->queue_stopped)); 1579 !!test_bit(cnt, trans_pcie->queue_stopped),
1580 txq->need_update,
1581 (cnt == trans_pcie->cmd_queue ? " HCMD" : ""));
1501 } 1582 }
1502 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1583 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1503 kfree(buf); 1584 kfree(buf);
@@ -1519,6 +1600,10 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1519 rxq->read); 1600 rxq->read);
1520 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", 1601 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n",
1521 rxq->write); 1602 rxq->write);
1603 pos += scnprintf(buf + pos, bufsz - pos, "write_actual: %u\n",
1604 rxq->write_actual);
1605 pos += scnprintf(buf + pos, bufsz - pos, "need_update: %d\n",
1606 rxq->need_update);
1522 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1607 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",
1523 rxq->free_count); 1608 rxq->free_count);
1524 if (rxq->rb_stts) { 1609 if (rxq->rb_stts) {
@@ -1698,10 +1783,15 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
1698 u32 len; 1783 u32 len;
1699 int i, ptr; 1784 int i, ptr;
1700 1785
1786 len = sizeof(*data) +
1787 cmdq->q.n_window * (sizeof(*txcmd) + TFD_MAX_PAYLOAD_SIZE);
1788
1789 if (trans_pcie->fw_mon_page)
1790 len += sizeof(*data) + sizeof(struct iwl_fw_error_dump_fw_mon) +
1791 trans_pcie->fw_mon_size;
1792
1701 if (!buf) 1793 if (!buf)
1702 return sizeof(*data) + 1794 return len;
1703 cmdq->q.n_window * (sizeof(*txcmd) +
1704 TFD_MAX_PAYLOAD_SIZE);
1705 1795
1706 len = 0; 1796 len = 0;
1707 data = buf; 1797 data = buf;
@@ -1729,7 +1819,40 @@ static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
1729 spin_unlock_bh(&cmdq->lock); 1819 spin_unlock_bh(&cmdq->lock);
1730 1820
1731 data->len = cpu_to_le32(len); 1821 data->len = cpu_to_le32(len);
1732 return sizeof(*data) + len; 1822 len += sizeof(*data);
1823
1824 if (trans_pcie->fw_mon_page) {
1825 struct iwl_fw_error_dump_fw_mon *fw_mon_data;
1826
1827 data = iwl_fw_error_next_data(data);
1828 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_FW_MONITOR);
1829 data->len = cpu_to_le32(trans_pcie->fw_mon_size +
1830 sizeof(*fw_mon_data));
1831 fw_mon_data = (void *)data->data;
1832 fw_mon_data->fw_mon_wr_ptr =
1833 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_WRPTR));
1834 fw_mon_data->fw_mon_cycle_cnt =
1835 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_CYCLE_CNT));
1836 fw_mon_data->fw_mon_base_ptr =
1837 cpu_to_le32(iwl_read_prph(trans, MON_BUFF_BASE_ADDR));
1838
1839 /*
1840 * The firmware is now asserted, it won't write anything to
1841 * the buffer. CPU can take ownership to fetch the data.
1842 * The buffer will be handed back to the device before the
1843 * firmware will be restarted.
1844 */
1845 dma_sync_single_for_cpu(trans->dev, trans_pcie->fw_mon_phys,
1846 trans_pcie->fw_mon_size,
1847 DMA_FROM_DEVICE);
1848 memcpy(fw_mon_data->data, page_address(trans_pcie->fw_mon_page),
1849 trans_pcie->fw_mon_size);
1850
1851 len += sizeof(*data) + sizeof(*fw_mon_data) +
1852 trans_pcie->fw_mon_size;
1853 }
1854
1855 return len;
1733} 1856}
1734#else 1857#else
1735static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, 1858static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
@@ -1870,6 +1993,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1870 } 1993 }
1871 1994
1872 trans->hw_rev = iwl_read32(trans, CSR_HW_REV); 1995 trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
1996 /*
1997 * In the 8000 HW family the format of the 4 bytes of CSR_HW_REV have
1998 * changed, and now the revision step also includes bit 0-1 (no more
1999 * "dash" value). To keep hw_rev backwards compatible - we'll store it
2000 * in the old format.
2001 */
2002 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
2003 trans->hw_rev = (trans->hw_rev & 0xfff0) |
2004 ((trans->hw_rev << 2) & 0xc);
2005
1873 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; 2006 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
1874 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 2007 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
1875 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); 2008 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index 038940afbdc5..6acccb19c4f3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -1438,6 +1438,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1438 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 1438 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1439 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1439 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
1440 trans_pcie->cmd_in_flight = false; 1440 trans_pcie->cmd_in_flight = false;
1441 IWL_ERR(trans, "Failed to wake NIC for hcmd\n");
1441 idx = -EIO; 1442 idx = -EIO;
1442 goto out; 1443 goto out;
1443 } 1444 }
diff --git a/drivers/net/wireless/libertas/Kconfig b/drivers/net/wireless/libertas/Kconfig
index 0485c9957575..e6268ceacbf1 100644
--- a/drivers/net/wireless/libertas/Kconfig
+++ b/drivers/net/wireless/libertas/Kconfig
@@ -16,7 +16,7 @@ config LIBERTAS_USB
16 16
17config LIBERTAS_CS 17config LIBERTAS_CS
18 tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards" 18 tristate "Marvell Libertas 8385 CompactFlash 802.11b/g cards"
19 depends on LIBERTAS && PCMCIA 19 depends on LIBERTAS && PCMCIA && HAS_IOPORT_MAP
20 ---help--- 20 ---help---
21 A driver for Marvell Libertas 8385 CompactFlash devices. 21 A driver for Marvell Libertas 8385 CompactFlash devices.
22 22
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index aaa297315c47..0387a5b380c8 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1111,6 +1111,7 @@ int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1111 1111
1112 cmd.hdr.size = cpu_to_le16(sizeof(cmd)); 1112 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1113 cmd.action = cpu_to_le16(CMD_ACT_SET); 1113 cmd.action = cpu_to_le16(CMD_ACT_SET);
1114 cmd.control = 0;
1114 1115
1115 /* Only v8 and below support setting the preamble */ 1116 /* Only v8 and below support setting the preamble */
1116 if (priv->fwrelease < 0x09000000) { 1117 if (priv->fwrelease < 0x09000000) {
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index a312c653d116..eba51460a5de 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -781,6 +781,36 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan,
781 netif_rx(skb); 781 netif_rx(skb);
782} 782}
783 783
784struct mac80211_hwsim_addr_match_data {
785 u8 addr[ETH_ALEN];
786 bool ret;
787};
788
789static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
790 struct ieee80211_vif *vif)
791{
792 struct mac80211_hwsim_addr_match_data *md = data;
793
794 if (memcmp(mac, md->addr, ETH_ALEN) == 0)
795 md->ret = true;
796}
797
798static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
799 const u8 *addr)
800{
801 struct mac80211_hwsim_addr_match_data md = {
802 .ret = false,
803 };
804
805 memcpy(md.addr, addr, ETH_ALEN);
806
807 ieee80211_iterate_active_interfaces_atomic(data->hw,
808 IEEE80211_IFACE_ITER_NORMAL,
809 mac80211_hwsim_addr_iter,
810 &md);
811
812 return md.ret;
813}
784 814
785static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data, 815static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
786 struct sk_buff *skb) 816 struct sk_buff *skb)
@@ -798,8 +828,7 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
798 /* Allow unicast frames to own address if there is a pending 828 /* Allow unicast frames to own address if there is a pending
799 * PS-Poll */ 829 * PS-Poll */
800 if (data->ps_poll_pending && 830 if (data->ps_poll_pending &&
801 memcmp(data->hw->wiphy->perm_addr, skb->data + 4, 831 mac80211_hwsim_addr_match(data, skb->data + 4)) {
802 ETH_ALEN) == 0) {
803 data->ps_poll_pending = false; 832 data->ps_poll_pending = false;
804 return true; 833 return true;
805 } 834 }
@@ -809,39 +838,6 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data,
809 return true; 838 return true;
810} 839}
811 840
812
813struct mac80211_hwsim_addr_match_data {
814 bool ret;
815 const u8 *addr;
816};
817
818static void mac80211_hwsim_addr_iter(void *data, u8 *mac,
819 struct ieee80211_vif *vif)
820{
821 struct mac80211_hwsim_addr_match_data *md = data;
822 if (memcmp(mac, md->addr, ETH_ALEN) == 0)
823 md->ret = true;
824}
825
826
827static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data,
828 const u8 *addr)
829{
830 struct mac80211_hwsim_addr_match_data md;
831
832 if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0)
833 return true;
834
835 md.ret = false;
836 md.addr = addr;
837 ieee80211_iterate_active_interfaces_atomic(data->hw,
838 IEEE80211_IFACE_ITER_NORMAL,
839 mac80211_hwsim_addr_iter,
840 &md);
841
842 return md.ret;
843}
844
845static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, 841static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
846 struct sk_buff *my_skb, 842 struct sk_buff *my_skb,
847 int dst_portid) 843 int dst_portid)
@@ -1740,9 +1736,10 @@ static void hw_scan_work(struct work_struct *work)
1740 1736
1741static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, 1737static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw,
1742 struct ieee80211_vif *vif, 1738 struct ieee80211_vif *vif,
1743 struct cfg80211_scan_request *req) 1739 struct ieee80211_scan_request *hw_req)
1744{ 1740{
1745 struct mac80211_hwsim_data *hwsim = hw->priv; 1741 struct mac80211_hwsim_data *hwsim = hw->priv;
1742 struct cfg80211_scan_request *req = &hw_req->req;
1746 1743
1747 mutex_lock(&hwsim->mutex); 1744 mutex_lock(&hwsim->mutex);
1748 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { 1745 if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) {
diff --git a/drivers/net/wireless/mwifiex/11ac.c b/drivers/net/wireless/mwifiex/11ac.c
index 706831df1fa2..59d23fb2365f 100644
--- a/drivers/net/wireless/mwifiex/11ac.c
+++ b/drivers/net/wireless/mwifiex/11ac.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11ac 2 * Marvell Wireless LAN device driver: 802.11ac
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11ac.h b/drivers/net/wireless/mwifiex/11ac.h
index 0b02cb6cfcb4..1ca92c7a8a4a 100644
--- a/drivers/net/wireless/mwifiex/11ac.h
+++ b/drivers/net/wireless/mwifiex/11ac.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11ac 2 * Marvell Wireless LAN device driver: 802.11ac
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11h.c b/drivers/net/wireless/mwifiex/11h.c
index e76b0db4e3e6..2668e83afbb6 100644
--- a/drivers/net/wireless/mwifiex/11h.c
+++ b/drivers/net/wireless/mwifiex/11h.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11h 2 * Marvell Wireless LAN device driver: 802.11h
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index e1c2f67ae85e..9d6d8d9f01e3 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n 2 * Marvell Wireless LAN device driver: 802.11n
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 0b73fa08f5d4..2ee268b632be 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n 2 * Marvell Wireless LAN device driver: 802.11n
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 5b32106182f8..b4c14b0fd3cb 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation 2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.h b/drivers/net/wireless/mwifiex/11n_aggr.h
index 892098d6a696..0cd2a3eb6c17 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.h
+++ b/drivers/net/wireless/mwifiex/11n_aggr.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n Aggregation 2 * Marvell Wireless LAN device driver: 802.11n Aggregation
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 0c3571f830b0..b22bae3d1205 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering 2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h
index 0fc76e4a60f8..3a87bb0e3a62 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.h
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering 2 * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/Makefile b/drivers/net/wireless/mwifiex/Makefile
index 2aa208ffbe23..9487d728ac20 100644
--- a/drivers/net/wireless/mwifiex/Makefile
+++ b/drivers/net/wireless/mwifiex/Makefile
@@ -1,5 +1,5 @@
1# 1#
2# Copyright (C) 2011, Marvell International Ltd. 2# Copyright (C) 2011-2014, Marvell International Ltd.
3# 3#
4# This software file (the "File") is distributed by Marvell International 4# This software file (the "File") is distributed by Marvell International
5# Ltd. under the terms of the GNU General Public License Version 2, June 1991 5# Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/README b/drivers/net/wireless/mwifiex/README
index 3b55ce5690a5..31928caeeed2 100644
--- a/drivers/net/wireless/mwifiex/README
+++ b/drivers/net/wireless/mwifiex/README
@@ -1,4 +1,4 @@
1# Copyright (C) 2011, Marvell International Ltd. 1# Copyright (C) 2011-2014, Marvell International Ltd.
2# 2#
3# This software file (the "File") is distributed by Marvell International 3# This software file (the "File") is distributed by Marvell International
4# Ltd. under the terms of the GNU General Public License Version 2, June 1991 4# Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -194,6 +194,36 @@ rdeeprom
194 Example: 194 Example:
195 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0 195 echo "0 20" > rdeeprom : Read 20 bytes of EEPROM data from offset 0
196 196
197hscfg
198 This command is used to debug/simulate host sleep feature using
199 different configuration parameters.
200
201 Usage:
202 echo "<condition> [GPIO# [gap]]]" > hscfg
203 cat hscfg
204
205 where the parameters are,
206 <condition>: bit 0 = 1 -- broadcast data
207 bit 1 = 1 -- unicast data
208 bit 2 = 1 -- mac event
209 bit 3 = 1 -- multicast data
210 [GPIO#]: pin number of GPIO used to wakeup the host.
211 GPIO pin# (e.g. 0-7) or 0xff (interface, e.g. SDIO
212 will be used instead).
213 [gap]: the gap in milliseconds between wakeup signal and
214 wakeup event or 0xff for special setting (host
215 acknowledge required) when GPIO is used to wakeup host.
216
217 Examples:
218 echo "-1" > hscfg : Cancel host sleep mode
219 echo "3" > hscfg : Broadcast and unicast data;
220 Use GPIO and gap set previously
221 echo "2 3" > hscfg : Unicast data and GPIO 3;
222 Use gap set previously
223 echo "2 1 160" > hscfg : Unicast data, GPIO 1 and gap 160 ms
224 echo "2 1 0xff" > hscfg : Unicast data, GPIO 1; Wait for host
225 to ack before sending wakeup event
226
197getlog 227getlog
198 This command is used to get the statistics available in the station. 228 This command is used to get the statistics available in the station.
199 Usage: 229 Usage:
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e95dec91a561..15fa7b453372 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: CFG80211 2 * Marvell Wireless LAN device driver: CFG80211
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -42,36 +42,6 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
42 .beacon_int_infra_match = true, 42 .beacon_int_infra_match = true,
43}; 43};
44 44
45static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
46 .n_reg_rules = 7,
47 .alpha2 = "99",
48 .reg_rules = {
49 /* Channel 1 - 11 */
50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
51 /* Channel 12 - 13 */
52 REG_RULE(2467-10, 2472+10, 20, 3, 20,
53 NL80211_RRF_NO_IR),
54 /* Channel 14 */
55 REG_RULE(2484-10, 2484+10, 20, 3, 20,
56 NL80211_RRF_NO_IR |
57 NL80211_RRF_NO_OFDM),
58 /* Channel 36 - 48 */
59 REG_RULE(5180-10, 5240+10, 40, 3, 20,
60 NL80211_RRF_NO_IR),
61 /* Channel 149 - 165 */
62 REG_RULE(5745-10, 5825+10, 40, 3, 20,
63 NL80211_RRF_NO_IR),
64 /* Channel 52 - 64 */
65 REG_RULE(5260-10, 5320+10, 40, 3, 30,
66 NL80211_RRF_NO_IR |
67 NL80211_RRF_DFS),
68 /* Channel 100 - 140 */
69 REG_RULE(5500-10, 5700+10, 40, 3, 30,
70 NL80211_RRF_NO_IR |
71 NL80211_RRF_DFS),
72 }
73};
74
75/* 45/*
76 * This function maps the nl802.11 channel type into driver channel type. 46 * This function maps the nl802.11 channel type into driver channel type.
77 * 47 *
@@ -151,7 +121,6 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
151 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 121 u8 addr[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
152 u16 pkt_len; 122 u16 pkt_len;
153 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT; 123 u32 tx_control = 0, pkt_type = PKT_TYPE_MGMT;
154 struct timeval tv;
155 124
156 pkt_len = len + ETH_ALEN; 125 pkt_len = len + ETH_ALEN;
157 126
@@ -173,8 +142,7 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
173 len - sizeof(struct ieee80211_hdr_3addr)); 142 len - sizeof(struct ieee80211_hdr_3addr));
174 143
175 skb->priority = LOW_PRIO_TID; 144 skb->priority = LOW_PRIO_TID;
176 do_gettimeofday(&tv); 145 __net_timestamp(skb);
177 skb->tstamp = timeval_to_ktime(tv);
178 146
179 return 0; 147 return 0;
180} 148}
@@ -2483,6 +2451,16 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2483 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2451 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2484 if (filt_num) 2452 if (filt_num)
2485 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2453 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2454
2455 filt_num++;
2456 mef_entry->filter[filt_num].repeat = 16;
2457 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2458 ETH_ALEN);
2459 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2460 ETH_ALEN;
2461 mef_entry->filter[filt_num].offset = 56;
2462 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2463 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2486 } 2464 }
2487 2465
2488 if (!mef_cfg.criteria) 2466 if (!mef_cfg.criteria)
@@ -2631,7 +2609,8 @@ static int
2631mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 2609mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
2632 const u8 *peer, u8 action_code, u8 dialog_token, 2610 const u8 *peer, u8 action_code, u8 dialog_token,
2633 u16 status_code, u32 peer_capability, 2611 u16 status_code, u32 peer_capability,
2634 const u8 *extra_ies, size_t extra_ies_len) 2612 bool initiator, const u8 *extra_ies,
2613 size_t extra_ies_len)
2635{ 2614{
2636 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 2615 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
2637 int ret; 2616 int ret;
@@ -2916,12 +2895,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2916 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 2895 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |
2917 WIPHY_FLAG_TDLS_EXTERNAL_SETUP; 2896 WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
2918 2897
2919 wiphy->regulatory_flags |=
2920 REGULATORY_CUSTOM_REG |
2921 REGULATORY_STRICT_REG;
2922
2923 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2924
2925#ifdef CONFIG_PM 2898#ifdef CONFIG_PM
2926 wiphy->wowlan = &mwifiex_wowlan_support; 2899 wiphy->wowlan = &mwifiex_wowlan_support;
2927#endif 2900#endif
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index c5848934f111..908367857d58 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: CFG80211 2 * Marvell Wireless LAN device driver: CFG80211
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c
index 0ddec3d4b059..b8242eb2be6f 100644
--- a/drivers/net/wireless/mwifiex/cfp.c
+++ b/drivers/net/wireless/mwifiex/cfp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: Channel, Frequence and Power 2 * Marvell Wireless LAN device driver: Channel, Frequence and Power
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 8dee6c86f4f1..df42f066d70c 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: commands and events 2 * Marvell Wireless LAN device driver: commands and events
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -273,6 +273,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
273 (struct mwifiex_opt_sleep_confirm *) 273 (struct mwifiex_opt_sleep_confirm *)
274 adapter->sleep_cfm->data; 274 adapter->sleep_cfm->data;
275 struct sk_buff *sleep_cfm_tmp; 275 struct sk_buff *sleep_cfm_tmp;
276 struct timeval ts;
276 __le32 tmp; 277 __le32 tmp;
277 278
278 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); 279 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
@@ -283,6 +284,14 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
283 (adapter->seq_num, priv->bss_num, 284 (adapter->seq_num, priv->bss_num,
284 priv->bss_type))); 285 priv->bss_type)));
285 286
287 do_gettimeofday(&ts);
288 dev_dbg(adapter->dev,
289 "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d, seqno %#x\n",
290 ts.tv_sec, ts.tv_usec, le16_to_cpu(sleep_cfm_buf->command),
291 le16_to_cpu(sleep_cfm_buf->action),
292 le16_to_cpu(sleep_cfm_buf->size),
293 le16_to_cpu(sleep_cfm_buf->seq_num));
294
286 if (adapter->iface_type == MWIFIEX_USB) { 295 if (adapter->iface_type == MWIFIEX_USB) {
287 sleep_cfm_tmp = 296 sleep_cfm_tmp =
288 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm) 297 dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
@@ -457,11 +466,10 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
457 rx_info->bss_type = priv->bss_type; 466 rx_info->bss_type = priv->bss_type;
458 } 467 }
459 468
460 if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { 469 do_gettimeofday(&tstamp);
461 do_gettimeofday(&tstamp); 470 dev_dbg(adapter->dev, "EVENT: %lu.%lu: cause: %#x\n",
462 dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n", 471 tstamp.tv_sec, tstamp.tv_usec, eventcause);
463 tstamp.tv_sec, tstamp.tv_usec, eventcause); 472 if (eventcause == EVENT_PS_SLEEP || eventcause == EVENT_PS_AWAKE) {
464 } else {
465 /* Handle PS_SLEEP/AWAKE events on STA */ 473 /* Handle PS_SLEEP/AWAKE events on STA */
466 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 474 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
467 if (!priv) 475 if (!priv)
@@ -960,6 +968,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
960 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 968 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
961 mwifiex_init_fw_complete(adapter); 969 mwifiex_init_fw_complete(adapter);
962 970
971 if (adapter->if_ops.fw_dump)
972 adapter->if_ops.fw_dump(adapter);
973
963 if (adapter->if_ops.card_reset) 974 if (adapter->if_ops.card_reset)
964 adapter->if_ops.card_reset(adapter); 975 adapter->if_ops.card_reset(adapter);
965} 976}
@@ -1225,12 +1236,19 @@ mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
1225 uint16_t result = le16_to_cpu(cmd->result); 1236 uint16_t result = le16_to_cpu(cmd->result);
1226 uint16_t command = le16_to_cpu(cmd->command); 1237 uint16_t command = le16_to_cpu(cmd->command);
1227 uint16_t seq_num = le16_to_cpu(cmd->seq_num); 1238 uint16_t seq_num = le16_to_cpu(cmd->seq_num);
1239 struct timeval ts;
1228 1240
1229 if (!upld_len) { 1241 if (!upld_len) {
1230 dev_err(adapter->dev, "%s: cmd size is 0\n", __func__); 1242 dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
1231 return; 1243 return;
1232 } 1244 }
1233 1245
1246 do_gettimeofday(&ts);
1247 dev_dbg(adapter->dev,
1248 "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d, len %d, seqno 0x%x\n",
1249 ts.tv_sec, ts.tv_usec, command, result, le16_to_cpu(cmd->size),
1250 seq_num);
1251
1234 /* Get BSS number and corresponding priv */ 1252 /* Get BSS number and corresponding priv */
1235 priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num), 1253 priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
1236 HostCmd_GET_BSS_TYPE(seq_num)); 1254 HostCmd_GET_BSS_TYPE(seq_num));
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c
index 7b419bbcd544..2713f7acd35e 100644
--- a/drivers/net/wireless/mwifiex/debugfs.c
+++ b/drivers/net/wireless/mwifiex/debugfs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: debugfs 2 * Marvell Wireless LAN device driver: debugfs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -692,6 +692,97 @@ done:
692 return ret; 692 return ret;
693} 693}
694 694
695/* Proc hscfg file write handler
696 * This function can be used to configure the host sleep parameters.
697 */
698static ssize_t
699mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
700 size_t count, loff_t *ppos)
701{
702 struct mwifiex_private *priv = (void *)file->private_data;
703 unsigned long addr = get_zeroed_page(GFP_KERNEL);
704 char *buf = (char *)addr;
705 size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
706 int ret, arg_num;
707 struct mwifiex_ds_hs_cfg hscfg;
708 int conditions = HS_CFG_COND_DEF;
709 u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
710
711 if (!buf)
712 return -ENOMEM;
713
714 if (copy_from_user(buf, ubuf, buf_size)) {
715 ret = -EFAULT;
716 goto done;
717 }
718
719 arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
720
721 memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
722
723 if (arg_num > 3) {
724 dev_err(priv->adapter->dev, "Too many arguments\n");
725 ret = -EINVAL;
726 goto done;
727 }
728
729 if (arg_num >= 1 && arg_num < 3)
730 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
731 MWIFIEX_SYNC_CMD, &hscfg);
732
733 if (arg_num) {
734 if (conditions == HS_CFG_CANCEL) {
735 mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
736 ret = count;
737 goto done;
738 }
739 hscfg.conditions = conditions;
740 }
741 if (arg_num >= 2)
742 hscfg.gpio = gpio;
743 if (arg_num == 3)
744 hscfg.gap = gap;
745
746 hscfg.is_invoke_hostcmd = false;
747 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
748 MWIFIEX_SYNC_CMD, &hscfg);
749
750 mwifiex_enable_hs(priv->adapter);
751 priv->adapter->hs_enabling = false;
752 ret = count;
753done:
754 free_page(addr);
755 return ret;
756}
757
758/* Proc hscfg file read handler
759 * This function can be used to read host sleep configuration
760 * parameters from driver.
761 */
762static ssize_t
763mwifiex_hscfg_read(struct file *file, char __user *ubuf,
764 size_t count, loff_t *ppos)
765{
766 struct mwifiex_private *priv = (void *)file->private_data;
767 unsigned long addr = get_zeroed_page(GFP_KERNEL);
768 char *buf = (char *)addr;
769 int pos, ret;
770 struct mwifiex_ds_hs_cfg hscfg;
771
772 if (!buf)
773 return -ENOMEM;
774
775 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
776 MWIFIEX_SYNC_CMD, &hscfg);
777
778 pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
779 hscfg.gpio, hscfg.gap);
780
781 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
782
783 free_page(addr);
784 return ret;
785}
695 786
696#define MWIFIEX_DFS_ADD_FILE(name) do { \ 787#define MWIFIEX_DFS_ADD_FILE(name) do { \
697 if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \ 788 if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir, \
@@ -725,6 +816,7 @@ MWIFIEX_DFS_FILE_READ_OPS(getlog);
725MWIFIEX_DFS_FILE_READ_OPS(fw_dump); 816MWIFIEX_DFS_FILE_READ_OPS(fw_dump);
726MWIFIEX_DFS_FILE_OPS(regrdwr); 817MWIFIEX_DFS_FILE_OPS(regrdwr);
727MWIFIEX_DFS_FILE_OPS(rdeeprom); 818MWIFIEX_DFS_FILE_OPS(rdeeprom);
819MWIFIEX_DFS_FILE_OPS(hscfg);
728 820
729/* 821/*
730 * This function creates the debug FS directory structure and the files. 822 * This function creates the debug FS directory structure and the files.
@@ -747,6 +839,7 @@ mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
747 MWIFIEX_DFS_ADD_FILE(regrdwr); 839 MWIFIEX_DFS_ADD_FILE(regrdwr);
748 MWIFIEX_DFS_ADD_FILE(rdeeprom); 840 MWIFIEX_DFS_ADD_FILE(rdeeprom);
749 MWIFIEX_DFS_ADD_FILE(fw_dump); 841 MWIFIEX_DFS_ADD_FILE(fw_dump);
842 MWIFIEX_DFS_ADD_FILE(hscfg);
750} 843}
751 844
752/* 845/*
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 38da6ff6f416..0e03fe39fc35 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: generic data structures and APIs 2 * Marvell Wireless LAN device driver: generic data structures and APIs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/ethtool.c b/drivers/net/wireless/mwifiex/ethtool.c
index bfb39908b2c6..04e56b5fc535 100644
--- a/drivers/net/wireless/mwifiex/ethtool.c
+++ b/drivers/net/wireless/mwifiex/ethtool.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: ethtool 2 * Marvell Wireless LAN device driver: ethtool
3 * 3 *
4 * Copyright (C) 2013, Marvell International Ltd. 4 * Copyright (C) 2013-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -64,7 +64,90 @@ static int mwifiex_ethtool_set_wol(struct net_device *dev,
64 return 0; 64 return 0;
65} 65}
66 66
67static int
68mwifiex_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump)
69{
70 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
71 struct mwifiex_adapter *adapter = priv->adapter;
72 struct memory_type_mapping *entry;
73
74 if (!adapter->if_ops.fw_dump)
75 return -ENOTSUPP;
76
77 dump->flag = adapter->curr_mem_idx;
78 dump->version = 1;
79 if (adapter->curr_mem_idx != MWIFIEX_FW_DUMP_IDX) {
80 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
81 dump->len = entry->mem_size;
82 } else {
83 dump->len = 0;
84 }
85
86 return 0;
87}
88
89static int
90mwifiex_get_dump_data(struct net_device *dev, struct ethtool_dump *dump,
91 void *buffer)
92{
93 u8 *p = buffer;
94 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
95 struct mwifiex_adapter *adapter = priv->adapter;
96 struct memory_type_mapping *entry;
97
98 if (!adapter->if_ops.fw_dump)
99 return -ENOTSUPP;
100
101 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
102 dev_err(adapter->dev, "firmware dump in progress!!\n");
103 return -EBUSY;
104 }
105
106 entry = &adapter->mem_type_mapping_tbl[adapter->curr_mem_idx];
107
108 if (!entry->mem_ptr)
109 return -EFAULT;
110
111 memcpy(p, entry->mem_ptr, entry->mem_size);
112
113 entry->mem_size = 0;
114 vfree(entry->mem_ptr);
115 entry->mem_ptr = NULL;
116
117 return 0;
118}
119
120static int mwifiex_set_dump(struct net_device *dev, struct ethtool_dump *val)
121{
122 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
123 struct mwifiex_adapter *adapter = priv->adapter;
124
125 if (!adapter->if_ops.fw_dump)
126 return -ENOTSUPP;
127
128 if (adapter->curr_mem_idx == MWIFIEX_FW_DUMP_IDX) {
129 dev_err(adapter->dev, "firmware dump in progress!!\n");
130 return -EBUSY;
131 }
132
133 if (val->flag == MWIFIEX_FW_DUMP_IDX) {
134 adapter->curr_mem_idx = val->flag;
135 adapter->if_ops.fw_dump(adapter);
136 return 0;
137 }
138
139 if (val->flag < 0 || val->flag >= adapter->num_mem_types)
140 return -EINVAL;
141
142 adapter->curr_mem_idx = val->flag;
143
144 return 0;
145}
146
67const struct ethtool_ops mwifiex_ethtool_ops = { 147const struct ethtool_ops mwifiex_ethtool_ops = {
68 .get_wol = mwifiex_ethtool_get_wol, 148 .get_wol = mwifiex_ethtool_get_wol,
69 .set_wol = mwifiex_ethtool_set_wol, 149 .set_wol = mwifiex_ethtool_set_wol,
150 .get_dump_flag = mwifiex_get_dump_flag,
151 .get_dump_data = mwifiex_get_dump_data,
152 .set_dump = mwifiex_set_dump,
70}; 153};
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 3175dd04834b..5561573452bb 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: Firmware specific macros & structures 2 * Marvell Wireless LAN device driver: Firmware specific macros & structures
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c
index 3bf3d58bbc02..b933794758b7 100644
--- a/drivers/net/wireless/mwifiex/ie.c
+++ b/drivers/net/wireless/mwifiex/ie.c
@@ -2,7 +2,7 @@
2 * Marvell Wireless LAN device driver: management IE handling- setting and 2 * Marvell Wireless LAN device driver: management IE handling- setting and
3 * deleting IE. 3 * deleting IE.
4 * 4 *
5 * Copyright (C) 2012, Marvell International Ltd. 5 * Copyright (C) 2012-2014, Marvell International Ltd.
6 * 6 *
7 * This software file (the "File") is distributed by Marvell International 7 * This software file (the "File") is distributed by Marvell International
8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 8 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 4ecd0b208ac6..269a277d0a2e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: HW/FW Initialization 2 * Marvell Wireless LAN device driver: HW/FW Initialization
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -382,6 +382,8 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
382static void 382static void
383mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) 383mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
384{ 384{
385 int idx;
386
385 if (!adapter) { 387 if (!adapter) {
386 pr_err("%s: adapter is NULL\n", __func__); 388 pr_err("%s: adapter is NULL\n", __func__);
387 return; 389 return;
@@ -396,7 +398,16 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
396 dev_dbg(adapter->dev, "info: free cmd buffer\n"); 398 dev_dbg(adapter->dev, "info: free cmd buffer\n");
397 mwifiex_free_cmd_buffer(adapter); 399 mwifiex_free_cmd_buffer(adapter);
398 400
399 dev_dbg(adapter->dev, "info: free scan table\n"); 401 for (idx = 0; idx < adapter->num_mem_types; idx++) {
402 struct memory_type_mapping *entry =
403 &adapter->mem_type_mapping_tbl[idx];
404
405 if (entry->mem_ptr) {
406 vfree(entry->mem_ptr);
407 entry->mem_ptr = NULL;
408 }
409 entry->mem_size = 0;
410 }
400 411
401 if (adapter->sleep_cfm) 412 if (adapter->sleep_cfm)
402 dev_kfree_skb_any(adapter->sleep_cfm); 413 dev_kfree_skb_any(adapter->sleep_cfm);
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h
index 1b576722671d..0847f3e07ab7 100644
--- a/drivers/net/wireless/mwifiex/ioctl.h
+++ b/drivers/net/wireless/mwifiex/ioctl.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: ioctl data structures & APIs 2 * Marvell Wireless LAN device driver: ioctl data structures & APIs
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 89dc62a467f4..fc135649b85f 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: association and ad-hoc start/join 2 * Marvell Wireless LAN device driver: association and ad-hoc start/join
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index cbabc12fbda3..657504c3c79d 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: major functions 2 * Marvell Wireless LAN device driver: major functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -609,7 +609,6 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
609 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 609 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
610 struct sk_buff *new_skb; 610 struct sk_buff *new_skb;
611 struct mwifiex_txinfo *tx_info; 611 struct mwifiex_txinfo *tx_info;
612 struct timeval tv;
613 612
614 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", 613 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
615 jiffies, priv->bss_type, priv->bss_num); 614 jiffies, priv->bss_type, priv->bss_num);
@@ -656,8 +655,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
656 * firmware for aggregate delay calculation for stats and 655 * firmware for aggregate delay calculation for stats and
657 * MSDU lifetime expiry. 656 * MSDU lifetime expiry.
658 */ 657 */
659 do_gettimeofday(&tv); 658 __net_timestamp(skb);
660 skb->tstamp = timeval_to_ktime(tv);
661 659
662 mwifiex_queue_tx_pkt(priv, skb); 660 mwifiex_queue_tx_pkt(priv, skb);
663 661
@@ -881,6 +879,8 @@ mwifiex_add_card(void *card, struct semaphore *sem,
881 goto err_kmalloc; 879 goto err_kmalloc;
882 880
883 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); 881 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
882 if (adapter->if_ops.iface_work)
883 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
884 884
885 /* Register the device. Fill up the private data structure with relevant 885 /* Register the device. Fill up the private data structure with relevant
886 information from the card. */ 886 information from the card. */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1398afa84064..a2733b1e63f9 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: major data structures and prototypes 2 * Marvell Wireless LAN device driver: major data structures and prototypes
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -30,6 +30,7 @@
30#include <linux/etherdevice.h> 30#include <linux/etherdevice.h>
31#include <net/sock.h> 31#include <net/sock.h>
32#include <net/lib80211.h> 32#include <net/lib80211.h>
33#include <linux/vmalloc.h>
33#include <linux/firmware.h> 34#include <linux/firmware.h>
34#include <linux/ctype.h> 35#include <linux/ctype.h>
35#include <linux/of.h> 36#include <linux/of.h>
@@ -410,6 +411,29 @@ struct mwifiex_roc_cfg {
410 struct ieee80211_channel chan; 411 struct ieee80211_channel chan;
411}; 412};
412 413
414#define MWIFIEX_FW_DUMP_IDX 0xff
415#define FW_DUMP_MAX_NAME_LEN 8
416#define FW_DUMP_HOST_READY 0xEE
417#define FW_DUMP_DONE 0xFF
418
419struct memory_type_mapping {
420 u8 mem_name[FW_DUMP_MAX_NAME_LEN];
421 u8 *mem_ptr;
422 u32 mem_size;
423 u8 done_flag;
424};
425
426enum rdwr_status {
427 RDWR_STATUS_SUCCESS = 0,
428 RDWR_STATUS_FAILURE = 1,
429 RDWR_STATUS_DONE = 2
430};
431
432enum mwifiex_iface_work_flags {
433 MWIFIEX_IFACE_WORK_FW_DUMP,
434 MWIFIEX_IFACE_WORK_CARD_RESET,
435};
436
413struct mwifiex_adapter; 437struct mwifiex_adapter;
414struct mwifiex_private; 438struct mwifiex_private;
415 439
@@ -674,6 +698,7 @@ struct mwifiex_if_ops {
674 void (*card_reset) (struct mwifiex_adapter *); 698 void (*card_reset) (struct mwifiex_adapter *);
675 void (*fw_dump)(struct mwifiex_adapter *); 699 void (*fw_dump)(struct mwifiex_adapter *);
676 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 700 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
701 void (*iface_work)(struct work_struct *work);
677}; 702};
678 703
679struct mwifiex_adapter { 704struct mwifiex_adapter {
@@ -809,6 +834,11 @@ struct mwifiex_adapter {
809 bool ext_scan; 834 bool ext_scan;
810 u8 fw_api_ver; 835 u8 fw_api_ver;
811 u8 fw_key_api_major_ver, fw_key_api_minor_ver; 836 u8 fw_key_api_major_ver, fw_key_api_minor_ver;
837 struct work_struct iface_work;
838 unsigned long iface_work_flags;
839 struct memory_type_mapping *mem_type_mapping_tbl;
840 u8 num_mem_types;
841 u8 curr_mem_idx;
812}; 842};
813 843
814int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 844int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -890,6 +920,8 @@ int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
890void mwifiex_process_hs_config(struct mwifiex_adapter *adapter); 920void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
891void mwifiex_hs_activated_event(struct mwifiex_private *priv, 921void mwifiex_hs_activated_event(struct mwifiex_private *priv,
892 u8 activated); 922 u8 activated);
923int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
924 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg);
893int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, 925int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
894 struct host_cmd_ds_command *resp); 926 struct host_cmd_ds_command *resp);
895int mwifiex_process_rx_packet(struct mwifiex_private *priv, 927int mwifiex_process_rx_packet(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 2cc9b6fca490..5f7afffdd34e 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: PCIE specific handling 2 * Marvell Wireless LAN device driver: PCIE specific handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -37,6 +37,13 @@ static struct mwifiex_if_ops pcie_ops;
37 37
38static struct semaphore add_remove_card_sem; 38static struct semaphore add_remove_card_sem;
39 39
40static struct memory_type_mapping mem_type_mapping_tbl[] = {
41 {"ITCM", NULL, 0, 0xF0},
42 {"DTCM", NULL, 0, 0xF1},
43 {"SQRAM", NULL, 0, 0xF2},
44 {"IRAM", NULL, 0, 0xF3},
45};
46
40static int 47static int
41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, 48mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
42 size_t size, int flags) 49 size_t size, int flags)
@@ -192,6 +199,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev,
192 card->pcie.reg = data->reg; 199 card->pcie.reg = data->reg;
193 card->pcie.blksz_fw_dl = data->blksz_fw_dl; 200 card->pcie.blksz_fw_dl = data->blksz_fw_dl;
194 card->pcie.tx_buf_size = data->tx_buf_size; 201 card->pcie.tx_buf_size = data->tx_buf_size;
202 card->pcie.supports_fw_dump = data->supports_fw_dump;
195 } 203 }
196 204
197 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, 205 if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops,
@@ -221,6 +229,8 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
221 if (!adapter || !adapter->priv_num) 229 if (!adapter || !adapter->priv_num)
222 return; 230 return;
223 231
232 cancel_work_sync(&adapter->iface_work);
233
224 if (user_rmmod) { 234 if (user_rmmod) {
225#ifdef CONFIG_PM_SLEEP 235#ifdef CONFIG_PM_SLEEP
226 if (adapter->is_suspended) 236 if (adapter->is_suspended)
@@ -307,6 +317,17 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
307 return 0; 317 return 0;
308} 318}
309 319
320/* This function reads u8 data from PCIE card register. */
321static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
322 int reg, u8 *data)
323{
324 struct pcie_service_card *card = adapter->card;
325
326 *data = ioread8(card->pci_mmap1 + reg);
327
328 return 0;
329}
330
310/* 331/*
311 * This function adds delay loop to ensure FW is awake before proceeding. 332 * This function adds delay loop to ensure FW is awake before proceeding.
312 */ 333 */
@@ -2173,6 +2194,174 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2173 return 0; 2194 return 0;
2174} 2195}
2175 2196
2197/* This function read/write firmware */
2198static enum rdwr_status
2199mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2200{
2201 int ret, tries;
2202 u8 ctrl_data;
2203 struct pcie_service_card *card = adapter->card;
2204 const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
2205
2206 ret = mwifiex_write_reg(adapter, reg->fw_dump_ctrl, FW_DUMP_HOST_READY);
2207 if (ret) {
2208 dev_err(adapter->dev, "PCIE write err\n");
2209 return RDWR_STATUS_FAILURE;
2210 }
2211
2212 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2213 mwifiex_read_reg_byte(adapter, reg->fw_dump_ctrl, &ctrl_data);
2214 if (ctrl_data == FW_DUMP_DONE)
2215 return RDWR_STATUS_SUCCESS;
2216 if (doneflag && ctrl_data == doneflag)
2217 return RDWR_STATUS_DONE;
2218 if (ctrl_data != FW_DUMP_HOST_READY) {
2219 dev_info(adapter->dev,
2220 "The ctrl reg was changed, re-try again!\n");
2221 mwifiex_write_reg(adapter, reg->fw_dump_ctrl,
2222 FW_DUMP_HOST_READY);
2223 if (ret) {
2224 dev_err(adapter->dev, "PCIE write err\n");
2225 return RDWR_STATUS_FAILURE;
2226 }
2227 }
2228 usleep_range(100, 200);
2229 }
2230
2231 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2232 return RDWR_STATUS_FAILURE;
2233}
2234
2235/* This function dump firmware memory to file */
2236static void mwifiex_pcie_fw_dump_work(struct mwifiex_adapter *adapter)
2237{
2238 struct pcie_service_card *card = adapter->card;
2239 const struct mwifiex_pcie_card_reg *creg = card->pcie.reg;
2240 unsigned int reg, reg_start, reg_end;
2241 struct timeval t;
2242 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2243 enum rdwr_status stat;
2244 u32 memory_size;
2245 static char *env[] = { "DRIVER=mwifiex_pcie", "EVENT=fw_dump", NULL };
2246
2247 if (!card->pcie.supports_fw_dump)
2248 return;
2249
2250 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2251 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2252
2253 if (entry->mem_ptr) {
2254 vfree(entry->mem_ptr);
2255 entry->mem_ptr = NULL;
2256 }
2257 entry->mem_size = 0;
2258 }
2259
2260 do_gettimeofday(&t);
2261 dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
2262 (u32)t.tv_sec, (u32)t.tv_usec);
2263
2264 /* Read the number of the memories which will dump */
2265 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2266 if (stat == RDWR_STATUS_FAILURE)
2267 goto done;
2268
2269 reg = creg->fw_dump_start;
2270 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2271
2272 /* Read the length of every memory which will dump */
2273 for (idx = 0; idx < dump_num; idx++) {
2274 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2275
2276 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2277 if (stat == RDWR_STATUS_FAILURE)
2278 goto done;
2279
2280 memory_size = 0;
2281 reg = creg->fw_dump_start;
2282 for (i = 0; i < 4; i++) {
2283 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2284 memory_size |= (read_reg << (i * 8));
2285 reg++;
2286 }
2287
2288 if (memory_size == 0) {
2289 dev_info(adapter->dev, "Firmware dump Finished!\n");
2290 break;
2291 }
2292
2293 dev_info(adapter->dev,
2294 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2295 entry->mem_ptr = vmalloc(memory_size + 1);
2296 entry->mem_size = memory_size;
2297 if (!entry->mem_ptr) {
2298 dev_err(adapter->dev,
2299 "Vmalloc %s failed\n", entry->mem_name);
2300 goto done;
2301 }
2302 dbg_ptr = entry->mem_ptr;
2303 end_ptr = dbg_ptr + memory_size;
2304
2305 doneflag = entry->done_flag;
2306 do_gettimeofday(&t);
2307 dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
2308 entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
2309
2310 do {
2311 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2312 if (RDWR_STATUS_FAILURE == stat)
2313 goto done;
2314
2315 reg_start = creg->fw_dump_start;
2316 reg_end = creg->fw_dump_end;
2317 for (reg = reg_start; reg <= reg_end; reg++) {
2318 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
2319 if (dbg_ptr < end_ptr)
2320 dbg_ptr++;
2321 else
2322 dev_err(adapter->dev,
2323 "Allocated buf not enough\n");
2324 }
2325
2326 if (stat != RDWR_STATUS_DONE)
2327 continue;
2328
2329 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2330 entry->mem_name, dbg_ptr - entry->mem_ptr);
2331 break;
2332 } while (true);
2333 }
2334 do_gettimeofday(&t);
2335 dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
2336 (u32)t.tv_sec, (u32)t.tv_usec);
2337
2338 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2339
2340done:
2341 adapter->curr_mem_idx = 0;
2342}
2343
2344static void mwifiex_pcie_work(struct work_struct *work)
2345{
2346 struct mwifiex_adapter *adapter =
2347 container_of(work, struct mwifiex_adapter, iface_work);
2348
2349 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2350 &adapter->iface_work_flags))
2351 mwifiex_pcie_fw_dump_work(adapter);
2352}
2353
2354/* This function dumps FW information */
2355static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2356{
2357 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2358 return;
2359
2360 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
2361
2362 schedule_work(&adapter->iface_work);
2363}
2364
2176/* 2365/*
2177 * This function initializes the PCI-E host memory space, WCB rings, etc. 2366 * This function initializes the PCI-E host memory space, WCB rings, etc.
2178 * 2367 *
@@ -2342,6 +2531,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
2342 2531
2343 adapter->dev = &pdev->dev; 2532 adapter->dev = &pdev->dev;
2344 adapter->tx_buf_size = card->pcie.tx_buf_size; 2533 adapter->tx_buf_size = card->pcie.tx_buf_size;
2534 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
2535 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
2345 strcpy(adapter->fw_name, card->pcie.firmware); 2536 strcpy(adapter->fw_name, card->pcie.firmware);
2346 2537
2347 return 0; 2538 return 0;
@@ -2394,6 +2585,8 @@ static struct mwifiex_if_ops pcie_ops = {
2394 .cleanup_mpa_buf = NULL, 2585 .cleanup_mpa_buf = NULL,
2395 .init_fw_port = mwifiex_pcie_init_fw_port, 2586 .init_fw_port = mwifiex_pcie_init_fw_port,
2396 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2587 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2588 .fw_dump = mwifiex_pcie_fw_dump,
2589 .iface_work = mwifiex_pcie_work,
2397}; 2590};
2398 2591
2399/* 2592/*
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index e8ec561f8a64..a1a8fd3bc1be 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -3,7 +3,7 @@
3 * @brief This file contains definitions for PCI-E interface. 3 * @brief This file contains definitions for PCI-E interface.
4 * driver. 4 * driver.
5 * 5 *
6 * Copyright (C) 2011, Marvell International Ltd. 6 * Copyright (C) 2011-2014, Marvell International Ltd.
7 * 7 *
8 * This software file (the "File") is distributed by Marvell International 8 * This software file (the "File") is distributed by Marvell International
9 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 9 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -129,6 +129,9 @@ struct mwifiex_pcie_card_reg {
129 u32 ring_tx_start_ptr; 129 u32 ring_tx_start_ptr;
130 u8 pfu_enabled; 130 u8 pfu_enabled;
131 u8 sleep_cookie; 131 u8 sleep_cookie;
132 u16 fw_dump_ctrl;
133 u16 fw_dump_start;
134 u16 fw_dump_end;
132}; 135};
133 136
134static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { 137static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = {
@@ -191,6 +194,9 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = {
191 .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR, 194 .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR,
192 .pfu_enabled = 1, 195 .pfu_enabled = 1,
193 .sleep_cookie = 0, 196 .sleep_cookie = 0,
197 .fw_dump_ctrl = 0xcf4,
198 .fw_dump_start = 0xcf8,
199 .fw_dump_end = 0xcff
194}; 200};
195 201
196struct mwifiex_pcie_device { 202struct mwifiex_pcie_device {
@@ -198,6 +204,7 @@ struct mwifiex_pcie_device {
198 const struct mwifiex_pcie_card_reg *reg; 204 const struct mwifiex_pcie_card_reg *reg;
199 u16 blksz_fw_dl; 205 u16 blksz_fw_dl;
200 u16 tx_buf_size; 206 u16 tx_buf_size;
207 bool supports_fw_dump;
201}; 208};
202 209
203static const struct mwifiex_pcie_device mwifiex_pcie8766 = { 210static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
@@ -205,6 +212,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = {
205 .reg = &mwifiex_reg_8766, 212 .reg = &mwifiex_reg_8766,
206 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 213 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
207 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 214 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
215 .supports_fw_dump = false,
208}; 216};
209 217
210static const struct mwifiex_pcie_device mwifiex_pcie8897 = { 218static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
@@ -212,6 +220,7 @@ static const struct mwifiex_pcie_device mwifiex_pcie8897 = {
212 .reg = &mwifiex_reg_8897, 220 .reg = &mwifiex_reg_8897,
213 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, 221 .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD,
214 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 222 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
223 .supports_fw_dump = true,
215}; 224};
216 225
217struct mwifiex_evt_buf_desc { 226struct mwifiex_evt_buf_desc {
@@ -322,4 +331,5 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
322 331
323 return 0; 332 return 0;
324} 333}
334
325#endif /* _MWIFIEX_PCIE_H */ 335#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 45c5b3450cf5..dee717a19ddb 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: scan ioctl and command handling 2 * Marvell Wireless LAN device driver: scan ioctl and command handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 4ce3d7b33991..1da04a086bd9 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: SDIO specific handling 2 * Marvell Wireless LAN device driver: SDIO specific handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -50,6 +50,24 @@ static struct mwifiex_if_ops sdio_ops;
50 50
51static struct semaphore add_remove_card_sem; 51static struct semaphore add_remove_card_sem;
52 52
53static struct memory_type_mapping mem_type_mapping_tbl[] = {
54 {"ITCM", NULL, 0, 0xF0},
55 {"DTCM", NULL, 0, 0xF1},
56 {"SQRAM", NULL, 0, 0xF2},
57 {"APU", NULL, 0, 0xF3},
58 {"CIU", NULL, 0, 0xF4},
59 {"ICU", NULL, 0, 0xF5},
60 {"MAC", NULL, 0, 0xF6},
61 {"EXT7", NULL, 0, 0xF7},
62 {"EXT8", NULL, 0, 0xF8},
63 {"EXT9", NULL, 0, 0xF9},
64 {"EXT10", NULL, 0, 0xFA},
65 {"EXT11", NULL, 0, 0xFB},
66 {"EXT12", NULL, 0, 0xFC},
67 {"EXT13", NULL, 0, 0xFD},
68 {"EXTLAST", NULL, 0, 0xFE},
69};
70
53/* 71/*
54 * SDIO probe. 72 * SDIO probe.
55 * 73 *
@@ -87,6 +105,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
87 card->tx_buf_size = data->tx_buf_size; 105 card->tx_buf_size = data->tx_buf_size;
88 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size; 106 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;
89 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;
90 } 109 }
91 110
92 sdio_claim_host(func); 111 sdio_claim_host(func);
@@ -179,6 +198,8 @@ mwifiex_sdio_remove(struct sdio_func *func)
179 if (!adapter || !adapter->priv_num) 198 if (!adapter || !adapter->priv_num)
180 return; 199 return;
181 200
201 cancel_work_sync(&adapter->iface_work);
202
182 if (user_rmmod) { 203 if (user_rmmod) {
183 if (adapter->is_suspended) 204 if (adapter->is_suspended)
184 mwifiex_sdio_resume(adapter->dev); 205 mwifiex_sdio_resume(adapter->dev);
@@ -1777,6 +1798,8 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1777 adapter->dev = &func->dev; 1798 adapter->dev = &func->dev;
1778 1799
1779 strcpy(adapter->fw_name, card->firmware); 1800 strcpy(adapter->fw_name, card->firmware);
1801 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;
1802 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);
1780 1803
1781 return 0; 1804 return 0;
1782} 1805}
@@ -1914,10 +1937,10 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1914 port, card->mp_data_port_mask); 1937 port, card->mp_data_port_mask);
1915} 1938}
1916 1939
1917static struct mmc_host *reset_host; 1940static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1918static void sdio_card_reset_worker(struct work_struct *work)
1919{ 1941{
1920 struct mmc_host *target = reset_host; 1942 struct sdio_mmc_card *card = adapter->card;
1943 struct mmc_host *target = card->func->card->host;
1921 1944
1922 /* The actual reset operation must be run outside of driver thread. 1945 /* The actual reset operation must be run outside of driver thread.
1923 * This is because mmc_remove_host() will cause the device to be 1946 * This is because mmc_remove_host() will cause the device to be
@@ -1933,15 +1956,213 @@ static void sdio_card_reset_worker(struct work_struct *work)
1933 mdelay(20); 1956 mdelay(20);
1934 mmc_add_host(target); 1957 mmc_add_host(target);
1935} 1958}
1936static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); 1959
1960/* This function read/write firmware */
1961static enum
1962rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
1963 u8 doneflag)
1964{
1965 struct sdio_mmc_card *card = adapter->card;
1966 int ret, tries;
1967 u8 ctrl_data = 0;
1968
1969 sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl,
1970 &ret);
1971 if (ret) {
1972 dev_err(adapter->dev, "SDIO Write ERR\n");
1973 return RDWR_STATUS_FAILURE;
1974 }
1975 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
1976 ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,
1977 &ret);
1978 if (ret) {
1979 dev_err(adapter->dev, "SDIO read err\n");
1980 return RDWR_STATUS_FAILURE;
1981 }
1982 if (ctrl_data == FW_DUMP_DONE)
1983 break;
1984 if (doneflag && ctrl_data == doneflag)
1985 return RDWR_STATUS_DONE;
1986 if (ctrl_data != FW_DUMP_HOST_READY) {
1987 dev_info(adapter->dev,
1988 "The ctrl reg was changed, re-try again!\n");
1989 sdio_writeb(card->func, FW_DUMP_HOST_READY,
1990 card->reg->fw_dump_ctrl, &ret);
1991 if (ret) {
1992 dev_err(adapter->dev, "SDIO write err\n");
1993 return RDWR_STATUS_FAILURE;
1994 }
1995 }
1996 usleep_range(100, 200);
1997 }
1998 if (ctrl_data == FW_DUMP_HOST_READY) {
1999 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2000 return RDWR_STATUS_FAILURE;
2001 }
2002
2003 return RDWR_STATUS_SUCCESS;
2004}
2005
2006/* This function dump firmware memory to file */
2007static void mwifiex_sdio_fw_dump_work(struct work_struct *work)
2008{
2009 struct mwifiex_adapter *adapter =
2010 container_of(work, struct mwifiex_adapter, iface_work);
2011 struct sdio_mmc_card *card = adapter->card;
2012 int ret = 0;
2013 unsigned int reg, reg_start, reg_end;
2014 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;
2015 struct timeval t;
2016 enum rdwr_status stat;
2017 u32 memory_size;
2018 static char *env[] = { "DRIVER=mwifiex_sdio", "EVENT=fw_dump", NULL };
2019
2020 if (!card->supports_fw_dump)
2021 return;
2022
2023 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2024 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2025
2026 if (entry->mem_ptr) {
2027 vfree(entry->mem_ptr);
2028 entry->mem_ptr = NULL;
2029 }
2030 entry->mem_size = 0;
2031 }
2032
2033 mwifiex_pm_wakeup_card(adapter);
2034 sdio_claim_host(card->func);
2035
2036 do_gettimeofday(&t);
2037 dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
2038 (u32)t.tv_sec, (u32)t.tv_usec);
2039
2040 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2041 if (stat == RDWR_STATUS_FAILURE)
2042 goto done;
2043
2044 reg = card->reg->fw_dump_start;
2045 /* Read the number of the memories which will dump */
2046 dump_num = sdio_readb(card->func, reg, &ret);
2047 if (ret) {
2048 dev_err(adapter->dev, "SDIO read memory length err\n");
2049 goto done;
2050 }
2051
2052 /* Read the length of every memory which will dump */
2053 for (idx = 0; idx < dump_num; idx++) {
2054 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2055
2056 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2057 if (stat == RDWR_STATUS_FAILURE)
2058 goto done;
2059
2060 memory_size = 0;
2061 reg = card->reg->fw_dump_start;
2062 for (i = 0; i < 4; i++) {
2063 read_reg = sdio_readb(card->func, reg, &ret);
2064 if (ret) {
2065 dev_err(adapter->dev, "SDIO read err\n");
2066 goto done;
2067 }
2068 memory_size |= (read_reg << i*8);
2069 reg++;
2070 }
2071
2072 if (memory_size == 0) {
2073 dev_info(adapter->dev, "Firmware dump Finished!\n");
2074 break;
2075 }
2076
2077 dev_info(adapter->dev,
2078 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2079 entry->mem_ptr = vmalloc(memory_size + 1);
2080 entry->mem_size = memory_size;
2081 if (!entry->mem_ptr) {
2082 dev_err(adapter->dev, "Vmalloc %s failed\n",
2083 entry->mem_name);
2084 goto done;
2085 }
2086 dbg_ptr = entry->mem_ptr;
2087 end_ptr = dbg_ptr + memory_size;
2088
2089 doneflag = entry->done_flag;
2090 do_gettimeofday(&t);
2091 dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
2092 entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
2093
2094 do {
2095 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);
2096 if (stat == RDWR_STATUS_FAILURE)
2097 goto done;
2098
2099 reg_start = card->reg->fw_dump_start;
2100 reg_end = card->reg->fw_dump_end;
2101 for (reg = reg_start; reg <= reg_end; reg++) {
2102 *dbg_ptr = sdio_readb(card->func, reg, &ret);
2103 if (ret) {
2104 dev_err(adapter->dev,
2105 "SDIO read err\n");
2106 goto done;
2107 }
2108 if (dbg_ptr < end_ptr)
2109 dbg_ptr++;
2110 else
2111 dev_err(adapter->dev,
2112 "Allocated buf not enough\n");
2113 }
2114
2115 if (stat != RDWR_STATUS_DONE)
2116 continue;
2117
2118 dev_info(adapter->dev, "%s done: size=0x%tx\n",
2119 entry->mem_name, dbg_ptr - entry->mem_ptr);
2120 break;
2121 } while (1);
2122 }
2123 do_gettimeofday(&t);
2124 dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
2125 (u32)t.tv_sec, (u32)t.tv_usec);
2126
2127 kobject_uevent_env(&adapter->wiphy->dev.kobj, KOBJ_CHANGE, env);
2128
2129done:
2130 sdio_release_host(card->func);
2131 adapter->curr_mem_idx = 0;
2132}
2133
2134static void mwifiex_sdio_work(struct work_struct *work)
2135{
2136 struct mwifiex_adapter *adapter =
2137 container_of(work, struct mwifiex_adapter, iface_work);
2138
2139 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2140 &adapter->iface_work_flags))
2141 mwifiex_sdio_card_reset_work(adapter);
2142 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2143 &adapter->iface_work_flags))
2144 mwifiex_sdio_fw_dump_work(work);
2145}
1937 2146
1938/* This function resets the card */ 2147/* This function resets the card */
1939static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) 2148static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
1940{ 2149{
1941 struct sdio_mmc_card *card = adapter->card; 2150 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags))
2151 return;
2152
2153 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags);
2154
2155 schedule_work(&adapter->iface_work);
2156}
2157
2158/* This function dumps FW information */
2159static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2160{
2161 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags))
2162 return;
1942 2163
1943 reset_host = card->func->card->host; 2164 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags);
1944 schedule_work(&card_reset_work); 2165 schedule_work(&adapter->iface_work);
1945} 2166}
1946 2167
1947static struct mwifiex_if_ops sdio_ops = { 2168static struct mwifiex_if_ops sdio_ops = {
@@ -1964,6 +2185,8 @@ static struct mwifiex_if_ops sdio_ops = {
1964 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 2185 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
1965 .event_complete = mwifiex_sdio_event_complete, 2186 .event_complete = mwifiex_sdio_event_complete,
1966 .card_reset = mwifiex_sdio_card_reset, 2187 .card_reset = mwifiex_sdio_card_reset,
2188 .iface_work = mwifiex_sdio_work,
2189 .fw_dump = mwifiex_sdio_fw_dump,
1967}; 2190};
1968 2191
1969/* 2192/*
@@ -2001,7 +2224,6 @@ mwifiex_sdio_cleanup_module(void)
2001 /* Set the flag as user is removing this module. */ 2224 /* Set the flag as user is removing this module. */
2002 user_rmmod = 1; 2225 user_rmmod = 1;
2003 2226
2004 cancel_work_sync(&card_reset_work);
2005 sdio_unregister_driver(&mwifiex_sdio); 2227 sdio_unregister_driver(&mwifiex_sdio);
2006} 2228}
2007 2229
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 6eea30b43ed7..6b8835ec88f1 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: SDIO specific definitions 2 * Marvell Wireless LAN device driver: SDIO specific definitions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -219,6 +219,9 @@ struct mwifiex_sdio_card_reg {
219 u8 rd_len_p0_l; 219 u8 rd_len_p0_l;
220 u8 rd_len_p0_u; 220 u8 rd_len_p0_u;
221 u8 card_misc_cfg_reg; 221 u8 card_misc_cfg_reg;
222 u8 fw_dump_ctrl;
223 u8 fw_dump_start;
224 u8 fw_dump_end;
222}; 225};
223 226
224struct sdio_mmc_card { 227struct sdio_mmc_card {
@@ -231,6 +234,7 @@ struct sdio_mmc_card {
231 u8 mp_agg_pkt_limit; 234 u8 mp_agg_pkt_limit;
232 bool supports_sdio_new_mode; 235 bool supports_sdio_new_mode;
233 bool has_control_mask; 236 bool has_control_mask;
237 bool supports_fw_dump;
234 u16 tx_buf_size; 238 u16 tx_buf_size;
235 u32 mp_tx_agg_buf_size; 239 u32 mp_tx_agg_buf_size;
236 u32 mp_rx_agg_buf_size; 240 u32 mp_rx_agg_buf_size;
@@ -257,6 +261,7 @@ struct mwifiex_sdio_device {
257 u8 mp_agg_pkt_limit; 261 u8 mp_agg_pkt_limit;
258 bool supports_sdio_new_mode; 262 bool supports_sdio_new_mode;
259 bool has_control_mask; 263 bool has_control_mask;
264 bool supports_fw_dump;
260 u16 tx_buf_size; 265 u16 tx_buf_size;
261 u32 mp_tx_agg_buf_size; 266 u32 mp_tx_agg_buf_size;
262 u32 mp_rx_agg_buf_size; 267 u32 mp_rx_agg_buf_size;
@@ -307,6 +312,9 @@ static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {
307 .rd_len_p0_l = 0x0c, 312 .rd_len_p0_l = 0x0c,
308 .rd_len_p0_u = 0x0d, 313 .rd_len_p0_u = 0x0d,
309 .card_misc_cfg_reg = 0xcc, 314 .card_misc_cfg_reg = 0xcc,
315 .fw_dump_ctrl = 0xe2,
316 .fw_dump_start = 0xe3,
317 .fw_dump_end = 0xea,
310}; 318};
311 319
312static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = { 320static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
@@ -319,6 +327,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {
319 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 327 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
320 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 328 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
321 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 329 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
330 .supports_fw_dump = false,
322}; 331};
323 332
324static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { 333static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
@@ -331,6 +340,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
331 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 340 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
332 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 341 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
333 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 342 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
343 .supports_fw_dump = false,
334}; 344};
335 345
336static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { 346static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
@@ -343,6 +353,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
343 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K, 353 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,
344 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 354 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
345 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K, 355 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,
356 .supports_fw_dump = false,
346}; 357};
347 358
348static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { 359static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
@@ -355,6 +366,7 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
355 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 366 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
356 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 367 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
357 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 368 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,
369 .supports_fw_dump = true,
358}; 370};
359 371
360/* 372/*
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 88202ce0c139..0f077aaadab6 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station command handling 2 * Marvell Wireless LAN device driver: station command handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 577f2979ed8f..822357b7b0bb 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station command response handling 2 * Marvell Wireless LAN device driver: station command response handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index f6395ef11a72..f1c240eca0cd 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station event handling 2 * Marvell Wireless LAN device driver: station event handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 536c14aa71f3..1a03d4d8b418 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: functions for station ioctl 2 * Marvell Wireless LAN device driver: functions for station ioctl
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -26,7 +26,7 @@
26#include "11n.h" 26#include "11n.h"
27#include "cfg80211.h" 27#include "cfg80211.h"
28 28
29static int disconnect_on_suspend = 1; 29static int disconnect_on_suspend;
30module_param(disconnect_on_suspend, int, 0644); 30module_param(disconnect_on_suspend, int, 0644);
31 31
32/* 32/*
@@ -389,8 +389,8 @@ done:
389 * This function prepares the correct firmware command and 389 * This function prepares the correct firmware command and
390 * issues it. 390 * issues it.
391 */ 391 */
392static int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action, 392int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
393 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg) 393 int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
394 394
395{ 395{
396 struct mwifiex_adapter *adapter = priv->adapter; 396 struct mwifiex_adapter *adapter = priv->adapter;
diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c
index 8b639d7fe6df..9ceb1dbe34c5 100644
--- a/drivers/net/wireless/mwifiex/sta_rx.c
+++ b/drivers/net/wireless/mwifiex/sta_rx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station RX data handling 2 * Marvell Wireless LAN device driver: station RX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c
index 5fce7e78a36e..cf330ba951cd 100644
--- a/drivers/net/wireless/mwifiex/sta_tx.c
+++ b/drivers/net/wireless/mwifiex/sta_tx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: station TX data handling 2 * Marvell Wireless LAN device driver: station TX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index e73034fbbde9..3efbcbe7e891 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -530,7 +530,6 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
530{ 530{
531 struct sk_buff *skb; 531 struct sk_buff *skb;
532 struct mwifiex_txinfo *tx_info; 532 struct mwifiex_txinfo *tx_info;
533 struct timeval tv;
534 int ret; 533 int ret;
535 u16 skb_len; 534 u16 skb_len;
536 535
@@ -608,8 +607,7 @@ int mwifiex_send_tdls_data_frame(struct mwifiex_private *priv, const u8 *peer,
608 tx_info->bss_num = priv->bss_num; 607 tx_info->bss_num = priv->bss_num;
609 tx_info->bss_type = priv->bss_type; 608 tx_info->bss_type = priv->bss_type;
610 609
611 do_gettimeofday(&tv); 610 __net_timestamp(skb);
612 skb->tstamp = timeval_to_ktime(tv);
613 mwifiex_queue_tx_pkt(priv, skb); 611 mwifiex_queue_tx_pkt(priv, skb);
614 612
615 return 0; 613 return 0;
@@ -702,7 +700,6 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
702{ 700{
703 struct sk_buff *skb; 701 struct sk_buff *skb;
704 struct mwifiex_txinfo *tx_info; 702 struct mwifiex_txinfo *tx_info;
705 struct timeval tv;
706 u8 *pos; 703 u8 *pos;
707 u32 pkt_type, tx_control; 704 u32 pkt_type, tx_control;
708 u16 pkt_len, skb_len; 705 u16 pkt_len, skb_len;
@@ -767,8 +764,7 @@ int mwifiex_send_tdls_action_frame(struct mwifiex_private *priv, const u8 *peer,
767 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len); 764 pkt_len = skb->len - MWIFIEX_MGMT_FRAME_HEADER_SIZE - sizeof(pkt_len);
768 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len, 765 memcpy(skb->data + MWIFIEX_MGMT_FRAME_HEADER_SIZE, &pkt_len,
769 sizeof(pkt_len)); 766 sizeof(pkt_len));
770 do_gettimeofday(&tv); 767 __net_timestamp(skb);
771 skb->tstamp = timeval_to_ktime(tv);
772 mwifiex_queue_tx_pkt(priv, skb); 768 mwifiex_queue_tx_pkt(priv, skb);
773 769
774 return 0; 770 return 0;
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 37f26afd4314..08205683f877 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: generic TX/RX data handling 2 * Marvell Wireless LAN device driver: generic TX/RX data handling
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 32643555dd2a..300bab438011 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP specific command handling 2 * Marvell Wireless LAN device driver: AP specific command handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c
index 92e77a398ecf..7c2b97660a03 100644
--- a/drivers/net/wireless/mwifiex/uap_event.c
+++ b/drivers/net/wireless/mwifiex/uap_event.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP event handling 2 * Marvell Wireless LAN device driver: AP event handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c
index 9a56bc61cb1d..ddfc3c6c1e78 100644
--- a/drivers/net/wireless/mwifiex/uap_txrx.c
+++ b/drivers/net/wireless/mwifiex/uap_txrx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: AP TX and RX data handling 2 * Marvell Wireless LAN device driver: AP TX and RX data handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -96,7 +96,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
96 struct sk_buff *new_skb; 96 struct sk_buff *new_skb;
97 struct mwifiex_txinfo *tx_info; 97 struct mwifiex_txinfo *tx_info;
98 int hdr_chop; 98 int hdr_chop;
99 struct timeval tv;
100 struct ethhdr *p_ethhdr; 99 struct ethhdr *p_ethhdr;
101 100
102 uap_rx_pd = (struct uap_rxpd *)(skb->data); 101 uap_rx_pd = (struct uap_rxpd *)(skb->data);
@@ -192,8 +191,7 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv,
192 tx_info->pkt_len = skb->len; 191 tx_info->pkt_len = skb->len;
193 } 192 }
194 193
195 do_gettimeofday(&tv); 194 __net_timestamp(skb);
196 skb->tstamp = timeval_to_ktime(tv);
197 mwifiex_wmm_add_buf_txqueue(priv, skb); 195 mwifiex_wmm_add_buf_txqueue(priv, skb);
198 atomic_inc(&adapter->tx_pending); 196 atomic_inc(&adapter->tx_pending);
199 atomic_inc(&adapter->pending_bridged_pkts); 197 atomic_inc(&adapter->pending_bridged_pkts);
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index a8ce8130cfae..7118a18b91ba 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: USB specific handling 2 * Marvell Wireless LAN device driver: USB specific handling
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/usb.h b/drivers/net/wireless/mwifiex/usb.h
index 15b73d12e998..4c41c2a193c5 100644
--- a/drivers/net/wireless/mwifiex/usb.h
+++ b/drivers/net/wireless/mwifiex/usb.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * This file contains definitions for mwifiex USB interface driver. 2 * This file contains definitions for mwifiex USB interface driver.
3 * 3 *
4 * Copyright (C) 2012, Marvell International Ltd. 4 * Copyright (C) 2012-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 6da5abf52e61..cee028321a9a 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: utility functions 2 * Marvell Wireless LAN device driver: utility functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/util.h b/drivers/net/wireless/mwifiex/util.h
index caadb3737b9e..40296cb4a3f1 100644
--- a/drivers/net/wireless/mwifiex/util.h
+++ b/drivers/net/wireless/mwifiex/util.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: utility functions 2 * Marvell Wireless LAN device driver: utility functions
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index d3671d009f6c..94c98a86ebbe 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: WMM 2 * Marvell Wireless LAN device driver: WMM
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -878,15 +878,8 @@ u8
878mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, 878mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
879 const struct sk_buff *skb) 879 const struct sk_buff *skb)
880{ 880{
881 u32 queue_delay = ktime_to_ms(net_timedelta(skb->tstamp));
881 u8 ret_val; 882 u8 ret_val;
882 struct timeval out_tstamp, in_tstamp;
883 u32 queue_delay;
884
885 do_gettimeofday(&out_tstamp);
886 in_tstamp = ktime_to_timeval(skb->tstamp);
887
888 queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
889 queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
890 883
891 /* 884 /*
892 * Queue delay is passed as a uint8 in units of 2ms (ms shifted 885 * Queue delay is passed as a uint8 in units of 2ms (ms shifted
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index eca56e371a57..569bd73f33c5 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Marvell Wireless LAN device driver: WMM 2 * Marvell Wireless LAN device driver: WMM
3 * 3 *
4 * Copyright (C) 2011, Marvell International Ltd. 4 * Copyright (C) 2011-2014, Marvell International Ltd.
5 * 5 *
6 * This software file (the "File") is distributed by Marvell International 6 * This software file (the "File") is distributed by Marvell International
7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991 7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index 60819bcf4377..60698b020851 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -107,7 +107,7 @@ config PCI_HERMES
107 107
108config PCMCIA_HERMES 108config PCMCIA_HERMES
109 tristate "Hermes PCMCIA card support" 109 tristate "Hermes PCMCIA card support"
110 depends on PCMCIA && HERMES 110 depends on PCMCIA && HERMES && HAS_IOPORT_MAP
111 ---help--- 111 ---help---
112 A driver for "Hermes" chipset based PCMCIA wireless adaptors, such 112 A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
113 as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ 113 as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -122,7 +122,7 @@ config PCMCIA_HERMES
122 122
123config PCMCIA_SPECTRUM 123config PCMCIA_SPECTRUM
124 tristate "Symbol Spectrum24 Trilogy PCMCIA card support" 124 tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
125 depends on PCMCIA && HERMES 125 depends on PCMCIA && HERMES && HAS_IOPORT_MAP
126 ---help--- 126 ---help---
127 127
128 This is a driver for 802.11b cards using RAM-loadable Symbol 128 This is a driver for 802.11b cards using RAM-loadable Symbol
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index de15171e2cd8..63de5eed25cf 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -193,7 +193,7 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
193 /* allow users to customize their eeprom. 193 /* allow users to customize their eeprom.
194 */ 194 */
195 195
196 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); 196 ret = request_firmware_direct(&eeprom, "3826.eeprom", &priv->spi->dev);
197 if (ret < 0) { 197 if (ret < 0) {
198#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM 198#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
199 dev_info(&priv->spi->dev, "loading default eeprom...\n"); 199 dev_info(&priv->spi->dev, "loading default eeprom...\n");
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index cf61d6e3eaa7..f3d3995d8f6b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -77,6 +77,52 @@ static bool rsi_recalculate_weights(struct rsi_common *common)
77} 77}
78 78
79/** 79/**
80 * rsi_get_num_pkts_dequeue() - This function determines the number of
81 * packets to be dequeued based on the number
82 * of bytes calculated using txop.
83 *
84 * @common: Pointer to the driver private structure.
85 * @q_num: the queue from which pkts have to be dequeued
86 *
87 * Return: pkt_num: Number of pkts to be dequeued.
88 */
89static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num)
90{
91 struct rsi_hw *adapter = common->priv;
92 struct sk_buff *skb;
93 u32 pkt_cnt = 0;
94 s16 txop = common->tx_qinfo[q_num].txop * 32;
95 __le16 r_txop;
96 struct ieee80211_rate rate;
97
98 rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */
99 if (q_num == VI_Q)
100 txop = ((txop << 5) / 80);
101
102 if (skb_queue_len(&common->tx_queue[q_num]))
103 skb = skb_peek(&common->tx_queue[q_num]);
104 else
105 return 0;
106
107 do {
108 r_txop = ieee80211_generic_frame_duration(adapter->hw,
109 adapter->vifs[0],
110 common->band,
111 skb->len, &rate);
112 txop -= le16_to_cpu(r_txop);
113 pkt_cnt += 1;
114 /*checking if pkts are still there*/
115 if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt)
116 skb = skb->next;
117 else
118 break;
119
120 } while (txop > 0);
121
122 return pkt_cnt;
123}
124
125/**
80 * rsi_core_determine_hal_queue() - This function determines the queue from 126 * rsi_core_determine_hal_queue() - This function determines the queue from
81 * which packet has to be dequeued. 127 * which packet has to be dequeued.
82 * @common: Pointer to the driver private structure. 128 * @common: Pointer to the driver private structure.
@@ -88,7 +134,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
88 bool recontend_queue = false; 134 bool recontend_queue = false;
89 u32 q_len = 0; 135 u32 q_len = 0;
90 u8 q_num = INVALID_QUEUE; 136 u8 q_num = INVALID_QUEUE;
91 u8 ii = 0, min = 0; 137 u8 ii = 0;
92 138
93 if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { 139 if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
94 if (!common->mgmt_q_block) 140 if (!common->mgmt_q_block)
@@ -96,6 +142,9 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
96 return q_num; 142 return q_num;
97 } 143 }
98 144
145 if (common->hw_data_qs_blocked)
146 return q_num;
147
99 if (common->pkt_cnt != 0) { 148 if (common->pkt_cnt != 0) {
100 --common->pkt_cnt; 149 --common->pkt_cnt;
101 return common->selected_qnum; 150 return common->selected_qnum;
@@ -106,14 +155,15 @@ get_queue_num:
106 155
107 q_num = rsi_determine_min_weight_queue(common); 156 q_num = rsi_determine_min_weight_queue(common);
108 157
109 q_len = skb_queue_len(&common->tx_queue[ii]);
110 ii = q_num; 158 ii = q_num;
111 159
112 /* Selecting the queue with least back off */ 160 /* Selecting the queue with least back off */
113 for (; ii < NUM_EDCA_QUEUES; ii++) { 161 for (; ii < NUM_EDCA_QUEUES; ii++) {
162 q_len = skb_queue_len(&common->tx_queue[ii]);
114 if (((common->tx_qinfo[ii].pkt_contended) && 163 if (((common->tx_qinfo[ii].pkt_contended) &&
115 (common->tx_qinfo[ii].weight < min)) && q_len) { 164 (common->tx_qinfo[ii].weight < common->min_weight)) &&
116 min = common->tx_qinfo[ii].weight; 165 q_len) {
166 common->min_weight = common->tx_qinfo[ii].weight;
117 q_num = ii; 167 q_num = ii;
118 } 168 }
119 } 169 }
@@ -140,25 +190,9 @@ get_queue_num:
140 common->selected_qnum = q_num; 190 common->selected_qnum = q_num;
141 q_len = skb_queue_len(&common->tx_queue[q_num]); 191 q_len = skb_queue_len(&common->tx_queue[q_num]);
142 192
143 switch (common->selected_qnum) { 193 if (q_num == VO_Q || q_num == VI_Q) {
144 case VO_Q: 194 common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num);
145 if (q_len > MAX_CONTINUOUS_VO_PKTS) 195 common->pkt_cnt -= 1;
146 common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1);
147 else
148 common->pkt_cnt = --q_len;
149 break;
150
151 case VI_Q:
152 if (q_len > MAX_CONTINUOUS_VI_PKTS)
153 common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1);
154 else
155 common->pkt_cnt = --q_len;
156
157 break;
158
159 default:
160 common->pkt_cnt = 0;
161 break;
162 } 196 }
163 197
164 return q_num; 198 return q_num;
@@ -252,6 +286,7 @@ void rsi_core_qos_processor(struct rsi_common *common)
252 286
253 skb = rsi_core_dequeue_pkt(common, q_num); 287 skb = rsi_core_dequeue_pkt(common, q_num);
254 if (skb == NULL) { 288 if (skb == NULL) {
289 rsi_dbg(ERR_ZONE, "skb null\n");
255 mutex_unlock(&common->tx_rxlock); 290 mutex_unlock(&common->tx_rxlock);
256 break; 291 break;
257 } 292 }
@@ -306,7 +341,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
306 } 341 }
307 342
308 if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) || 343 if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) ||
309 (ieee80211_is_ctl(tmp_hdr->frame_control))) { 344 (ieee80211_is_ctl(tmp_hdr->frame_control)) ||
345 (ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) {
310 q_num = MGMT_SOFT_Q; 346 q_num = MGMT_SOFT_Q;
311 skb->priority = q_num; 347 skb->priority = q_num;
312 } else { 348 } else {
@@ -325,6 +361,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
325 if ((q_num != MGMT_SOFT_Q) && 361 if ((q_num != MGMT_SOFT_Q) &&
326 ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= 362 ((skb_queue_len(&common->tx_queue[q_num]) + 1) >=
327 DATA_QUEUE_WATER_MARK)) { 363 DATA_QUEUE_WATER_MARK)) {
364 rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__);
328 if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) 365 if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num)))
329 ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); 366 ieee80211_stop_queue(adapter->hw, WME_AC(q_num));
330 rsi_set_event(&common->tx_thread.event); 367 rsi_set_event(&common->tx_thread.event);
diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
index c466246a323f..828a042f903f 100644
--- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c
+++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c
@@ -145,7 +145,7 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
145 seq_printf(seq, "total_mgmt_pkt_send : %d\n", 145 seq_printf(seq, "total_mgmt_pkt_send : %d\n",
146 common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]); 146 common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]);
147 seq_printf(seq, "total_mgmt_pkt_queued : %d\n", 147 seq_printf(seq, "total_mgmt_pkt_queued : %d\n",
148 skb_queue_len(&common->tx_queue[4])); 148 skb_queue_len(&common->tx_queue[MGMT_SOFT_Q]));
149 seq_printf(seq, "total_mgmt_pkt_freed : %d\n", 149 seq_printf(seq, "total_mgmt_pkt_freed : %d\n",
150 common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]); 150 common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]);
151 151
@@ -153,25 +153,25 @@ static int rsi_stats_read(struct seq_file *seq, void *data)
153 seq_printf(seq, "total_data_vo_pkt_send: %8d\t", 153 seq_printf(seq, "total_data_vo_pkt_send: %8d\t",
154 common->tx_stats.total_tx_pkt_send[VO_Q]); 154 common->tx_stats.total_tx_pkt_send[VO_Q]);
155 seq_printf(seq, "total_data_vo_pkt_queued: %8d\t", 155 seq_printf(seq, "total_data_vo_pkt_queued: %8d\t",
156 skb_queue_len(&common->tx_queue[0])); 156 skb_queue_len(&common->tx_queue[VO_Q]));
157 seq_printf(seq, "total_vo_pkt_freed: %8d\n", 157 seq_printf(seq, "total_vo_pkt_freed: %8d\n",
158 common->tx_stats.total_tx_pkt_freed[VO_Q]); 158 common->tx_stats.total_tx_pkt_freed[VO_Q]);
159 seq_printf(seq, "total_data_vi_pkt_send: %8d\t", 159 seq_printf(seq, "total_data_vi_pkt_send: %8d\t",
160 common->tx_stats.total_tx_pkt_send[VI_Q]); 160 common->tx_stats.total_tx_pkt_send[VI_Q]);
161 seq_printf(seq, "total_data_vi_pkt_queued: %8d\t", 161 seq_printf(seq, "total_data_vi_pkt_queued: %8d\t",
162 skb_queue_len(&common->tx_queue[1])); 162 skb_queue_len(&common->tx_queue[VI_Q]));
163 seq_printf(seq, "total_vi_pkt_freed: %8d\n", 163 seq_printf(seq, "total_vi_pkt_freed: %8d\n",
164 common->tx_stats.total_tx_pkt_freed[VI_Q]); 164 common->tx_stats.total_tx_pkt_freed[VI_Q]);
165 seq_printf(seq, "total_data_be_pkt_send: %8d\t", 165 seq_printf(seq, "total_data_be_pkt_send: %8d\t",
166 common->tx_stats.total_tx_pkt_send[BE_Q]); 166 common->tx_stats.total_tx_pkt_send[BE_Q]);
167 seq_printf(seq, "total_data_be_pkt_queued: %8d\t", 167 seq_printf(seq, "total_data_be_pkt_queued: %8d\t",
168 skb_queue_len(&common->tx_queue[2])); 168 skb_queue_len(&common->tx_queue[BE_Q]));
169 seq_printf(seq, "total_be_pkt_freed: %8d\n", 169 seq_printf(seq, "total_be_pkt_freed: %8d\n",
170 common->tx_stats.total_tx_pkt_freed[BE_Q]); 170 common->tx_stats.total_tx_pkt_freed[BE_Q]);
171 seq_printf(seq, "total_data_bk_pkt_send: %8d\t", 171 seq_printf(seq, "total_data_bk_pkt_send: %8d\t",
172 common->tx_stats.total_tx_pkt_send[BK_Q]); 172 common->tx_stats.total_tx_pkt_send[BK_Q]);
173 seq_printf(seq, "total_data_bk_pkt_queued: %8d\t", 173 seq_printf(seq, "total_data_bk_pkt_queued: %8d\t",
174 skb_queue_len(&common->tx_queue[3])); 174 skb_queue_len(&common->tx_queue[BK_Q]));
175 seq_printf(seq, "total_bk_pkt_freed: %8d\n", 175 seq_printf(seq, "total_bk_pkt_freed: %8d\n",
176 common->tx_stats.total_tx_pkt_freed[BK_Q]); 176 common->tx_stats.total_tx_pkt_freed[BK_Q]);
177 177
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 54aaeb09debf..aeaf87bb5518 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -177,7 +177,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
177 sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 177 sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
178 IEEE80211_HT_CAP_SGI_20 | 178 IEEE80211_HT_CAP_SGI_20 |
179 IEEE80211_HT_CAP_SGI_40); 179 IEEE80211_HT_CAP_SGI_40);
180 sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K; 180 sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
181 sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; 181 sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
182 sbands->ht_cap.mcs.rx_mask[0] = 0xff; 182 sbands->ht_cap.mcs.rx_mask[0] = 0xff;
183 sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 183 sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
@@ -185,7 +185,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band)
185} 185}
186 186
187/** 187/**
188 * rsi_mac80211_attach() - This function is used to de-initialize the 188 * rsi_mac80211_detach() - This function is used to de-initialize the
189 * Mac80211 stack. 189 * Mac80211 stack.
190 * @adapter: Pointer to the adapter structure. 190 * @adapter: Pointer to the adapter structure.
191 * 191 *
@@ -341,6 +341,59 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
341} 341}
342 342
343/** 343/**
344 * rsi_channel_change() - This function is a performs the checks
345 * required for changing a channel and sets
346 * the channel accordingly.
347 * @hw: Pointer to the ieee80211_hw structure.
348 *
349 * Return: 0 on success, negative error code on failure.
350 */
351static int rsi_channel_change(struct ieee80211_hw *hw)
352{
353 struct rsi_hw *adapter = hw->priv;
354 struct rsi_common *common = adapter->priv;
355 int status = -EOPNOTSUPP;
356 struct ieee80211_channel *curchan = hw->conf.chandef.chan;
357 u16 channel = curchan->hw_value;
358 struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf;
359
360 rsi_dbg(INFO_ZONE,
361 "%s: Set channel: %d MHz type: %d channel_no %d\n",
362 __func__, curchan->center_freq,
363 curchan->flags, channel);
364
365 if (bss->assoc) {
366 if (!common->hw_data_qs_blocked &&
367 (rsi_get_connected_channel(adapter) != channel)) {
368 rsi_dbg(INFO_ZONE, "blk data q %d\n", channel);
369 if (!rsi_send_block_unblock_frame(common, true))
370 common->hw_data_qs_blocked = true;
371 }
372 }
373
374 status = rsi_band_check(common);
375 if (!status)
376 status = rsi_set_channel(adapter->priv, channel);
377
378 if (bss->assoc) {
379 if (common->hw_data_qs_blocked &&
380 (rsi_get_connected_channel(adapter) == channel)) {
381 rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
382 if (!rsi_send_block_unblock_frame(common, false))
383 common->hw_data_qs_blocked = false;
384 }
385 } else {
386 if (common->hw_data_qs_blocked) {
387 rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel);
388 if (!rsi_send_block_unblock_frame(common, false))
389 common->hw_data_qs_blocked = false;
390 }
391 }
392
393 return status;
394}
395
396/**
344 * rsi_mac80211_config() - This function is a handler for configuration 397 * rsi_mac80211_config() - This function is a handler for configuration
345 * requests. The stack calls this function to 398 * requests. The stack calls this function to
346 * change hardware configuration, e.g., channel. 399 * change hardware configuration, e.g., channel.
@@ -357,17 +410,10 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw,
357 int status = -EOPNOTSUPP; 410 int status = -EOPNOTSUPP;
358 411
359 mutex_lock(&common->mutex); 412 mutex_lock(&common->mutex);
360 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 413
361 struct ieee80211_channel *curchan = hw->conf.chandef.chan; 414 if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
362 u16 channel = curchan->hw_value; 415 status = rsi_channel_change(hw);
363 416
364 rsi_dbg(INFO_ZONE,
365 "%s: Set channel: %d MHz type: %d channel_no %d\n",
366 __func__, curchan->center_freq,
367 curchan->flags, channel);
368 common->band = curchan->band;
369 status = rsi_set_channel(adapter->priv, channel);
370 }
371 mutex_unlock(&common->mutex); 417 mutex_unlock(&common->mutex);
372 418
373 return status; 419 return status;
@@ -421,6 +467,15 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
421 bss_conf->qos, 467 bss_conf->qos,
422 bss_conf->aid); 468 bss_conf->aid);
423 } 469 }
470
471 if (changed & BSS_CHANGED_CQM) {
472 common->cqm_info.last_cqm_event_rssi = 0;
473 common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold;
474 common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst;
475 rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n",
476 common->cqm_info.rssi_thold,
477 common->cqm_info.rssi_hyst);
478 }
424 mutex_unlock(&common->mutex); 479 mutex_unlock(&common->mutex);
425} 480}
426 481
@@ -723,17 +778,17 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
723{ 778{
724 struct rsi_hw *adapter = hw->priv; 779 struct rsi_hw *adapter = hw->priv;
725 struct rsi_common *common = adapter->priv; 780 struct rsi_common *common = adapter->priv;
781 enum ieee80211_band band = hw->conf.chandef.chan->band;
726 782
727 mutex_lock(&common->mutex); 783 mutex_lock(&common->mutex);
784 common->fixedrate_mask[band] = 0;
728 785
729 common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 0; 786 if (mask->control[band].legacy == 0xfff) {
730 787 common->fixedrate_mask[band] =
731 if (mask->control[IEEE80211_BAND_2GHZ].legacy == 0xfff) { 788 (mask->control[band].ht_mcs[0] << 12);
732 common->fixedrate_mask[IEEE80211_BAND_2GHZ] =
733 (mask->control[IEEE80211_BAND_2GHZ].ht_mcs[0] << 12);
734 } else { 789 } else {
735 common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 790 common->fixedrate_mask[band] =
736 mask->control[IEEE80211_BAND_2GHZ].legacy; 791 mask->control[band].legacy;
737 } 792 }
738 mutex_unlock(&common->mutex); 793 mutex_unlock(&common->mutex);
739 794
@@ -741,6 +796,37 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw,
741} 796}
742 797
743/** 798/**
799 * rsi_perform_cqm() - This function performs cqm.
800 * @common: Pointer to the driver private structure.
801 * @bssid: pointer to the bssid.
802 * @rssi: RSSI value.
803 */
804static void rsi_perform_cqm(struct rsi_common *common,
805 u8 *bssid,
806 s8 rssi)
807{
808 struct rsi_hw *adapter = common->priv;
809 s8 last_event = common->cqm_info.last_cqm_event_rssi;
810 int thold = common->cqm_info.rssi_thold;
811 u32 hyst = common->cqm_info.rssi_hyst;
812 enum nl80211_cqm_rssi_threshold_event event;
813
814 if (rssi < thold && (last_event == 0 || rssi < (last_event - hyst)))
815 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW;
816 else if (rssi > thold &&
817 (last_event == 0 || rssi > (last_event + hyst)))
818 event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
819 else
820 return;
821
822 common->cqm_info.last_cqm_event_rssi = rssi;
823 rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event);
824 ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL);
825
826 return;
827}
828
829/**
744 * rsi_fill_rx_status() - This function fills rx status in 830 * rsi_fill_rx_status() - This function fills rx status in
745 * ieee80211_rx_status structure. 831 * ieee80211_rx_status structure.
746 * @hw: Pointer to the ieee80211_hw structure. 832 * @hw: Pointer to the ieee80211_hw structure.
@@ -755,6 +841,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
755 struct rsi_common *common, 841 struct rsi_common *common,
756 struct ieee80211_rx_status *rxs) 842 struct ieee80211_rx_status *rxs)
757{ 843{
844 struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf;
758 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 845 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
759 struct skb_info *rx_params = (struct skb_info *)info->driver_data; 846 struct skb_info *rx_params = (struct skb_info *)info->driver_data;
760 struct ieee80211_hdr *hdr; 847 struct ieee80211_hdr *hdr;
@@ -770,10 +857,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
770 857
771 rxs->signal = -(rssi); 858 rxs->signal = -(rssi);
772 859
773 if (channel <= 14) 860 rxs->band = common->band;
774 rxs->band = IEEE80211_BAND_2GHZ;
775 else
776 rxs->band = IEEE80211_BAND_5GHZ;
777 861
778 freq = ieee80211_channel_to_frequency(channel, rxs->band); 862 freq = ieee80211_channel_to_frequency(channel, rxs->band);
779 863
@@ -792,6 +876,14 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw,
792 rxs->flag |= RX_FLAG_DECRYPTED; 876 rxs->flag |= RX_FLAG_DECRYPTED;
793 rxs->flag |= RX_FLAG_IV_STRIPPED; 877 rxs->flag |= RX_FLAG_IV_STRIPPED;
794 } 878 }
879
880 /* CQM only for connected AP beacons, the RSSI is a weighted avg */
881 if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) {
882 if (ieee80211_is_beacon(hdr->frame_control))
883 rsi_perform_cqm(common, hdr->addr2, rxs->signal);
884 }
885
886 return;
795} 887}
796 888
797/** 889/**
@@ -983,6 +1075,7 @@ int rsi_mac80211_attach(struct rsi_common *common)
983 1075
984 hw->max_tx_aggregation_subframes = 6; 1076 hw->max_tx_aggregation_subframes = 6;
985 rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ); 1077 rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ);
1078 rsi_register_rates_channels(adapter, IEEE80211_BAND_5GHZ);
986 hw->rate_control_algorithm = "AARF"; 1079 hw->rate_control_algorithm = "AARF";
987 1080
988 SET_IEEE80211_PERM_ADDR(hw, common->mac_addr); 1081 SET_IEEE80211_PERM_ADDR(hw, common->mac_addr);
@@ -1000,6 +1093,8 @@ int rsi_mac80211_attach(struct rsi_common *common)
1000 wiphy->available_antennas_tx = 1; 1093 wiphy->available_antennas_tx = 1;
1001 wiphy->bands[IEEE80211_BAND_2GHZ] = 1094 wiphy->bands[IEEE80211_BAND_2GHZ] =
1002 &adapter->sbands[IEEE80211_BAND_2GHZ]; 1095 &adapter->sbands[IEEE80211_BAND_2GHZ];
1096 wiphy->bands[IEEE80211_BAND_5GHZ] =
1097 &adapter->sbands[IEEE80211_BAND_5GHZ];
1003 1098
1004 status = ieee80211_register_hw(hw); 1099 status = ieee80211_register_hw(hw);
1005 if (status) 1100 if (status)
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 2eefbf159bc0..8d110fd9eba1 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -217,6 +217,7 @@ static void rsi_set_default_parameters(struct rsi_common *common)
217 common->min_rate = 0xffff; 217 common->min_rate = 0xffff;
218 common->fsm_state = FSM_CARD_NOT_READY; 218 common->fsm_state = FSM_CARD_NOT_READY;
219 common->iface_down = true; 219 common->iface_down = true;
220 common->endpoint = EP_2GHZ_20MHZ;
220} 221}
221 222
222/** 223/**
@@ -276,7 +277,6 @@ static int rsi_load_radio_caps(struct rsi_common *common)
276{ 277{
277 struct rsi_radio_caps *radio_caps; 278 struct rsi_radio_caps *radio_caps;
278 struct rsi_hw *adapter = common->priv; 279 struct rsi_hw *adapter = common->priv;
279 struct ieee80211_hw *hw = adapter->hw;
280 u16 inx = 0; 280 u16 inx = 0;
281 u8 ii; 281 u8 ii;
282 u8 radio_id = 0; 282 u8 radio_id = 0;
@@ -285,7 +285,6 @@ static int rsi_load_radio_caps(struct rsi_common *common)
285 0xf0, 0xf0, 0xf0, 0xf0, 285 0xf0, 0xf0, 0xf0, 0xf0,
286 0xf0, 0xf0, 0xf0, 0xf0, 286 0xf0, 0xf0, 0xf0, 0xf0,
287 0xf0, 0xf0, 0xf0, 0xf0}; 287 0xf0, 0xf0, 0xf0, 0xf0};
288 struct ieee80211_conf *conf = &hw->conf;
289 struct sk_buff *skb; 288 struct sk_buff *skb;
290 289
291 rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__); 290 rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__);
@@ -307,29 +306,36 @@ static int rsi_load_radio_caps(struct rsi_common *common)
307 if (common->channel_width == BW_40MHZ) { 306 if (common->channel_width == BW_40MHZ) {
308 radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ); 307 radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ);
309 radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ); 308 radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ);
310 if (common->channel_width) {
311 radio_caps->desc_word[5] =
312 cpu_to_le16(common->channel_width << 12);
313 radio_caps->desc_word[5] |= cpu_to_le16(FULL40M_ENABLE);
314 }
315 309
316 if (conf_is_ht40_minus(conf)) { 310 if (common->fsm_state == FSM_MAC_INIT_DONE) {
317 radio_caps->desc_word[5] = 0; 311 struct ieee80211_hw *hw = adapter->hw;
318 radio_caps->desc_word[5] |= 312 struct ieee80211_conf *conf = &hw->conf;
319 cpu_to_le16(LOWER_20_ENABLE); 313 if (conf_is_ht40_plus(conf)) {
320 radio_caps->desc_word[5] |= 314 radio_caps->desc_word[5] =
321 cpu_to_le16(LOWER_20_ENABLE >> 12); 315 cpu_to_le16(LOWER_20_ENABLE);
322 } 316 radio_caps->desc_word[5] |=
323 317 cpu_to_le16(LOWER_20_ENABLE >> 12);
324 if (conf_is_ht40_plus(conf)) { 318 } else if (conf_is_ht40_minus(conf)) {
325 radio_caps->desc_word[5] = 0; 319 radio_caps->desc_word[5] =
326 radio_caps->desc_word[5] |= 320 cpu_to_le16(UPPER_20_ENABLE);
327 cpu_to_le16(UPPER_20_ENABLE); 321 radio_caps->desc_word[5] |=
328 radio_caps->desc_word[5] |= 322 cpu_to_le16(UPPER_20_ENABLE >> 12);
329 cpu_to_le16(UPPER_20_ENABLE >> 12); 323 } else {
324 radio_caps->desc_word[5] =
325 cpu_to_le16(BW_40MHZ << 12);
326 radio_caps->desc_word[5] |=
327 cpu_to_le16(FULL40M_ENABLE);
328 }
330 } 329 }
331 } 330 }
332 331
332 radio_caps->sifs_tx_11n = cpu_to_le16(SIFS_TX_11N_VALUE);
333 radio_caps->sifs_tx_11b = cpu_to_le16(SIFS_TX_11B_VALUE);
334 radio_caps->slot_rx_11n = cpu_to_le16(SHORT_SLOT_VALUE);
335 radio_caps->ofdm_ack_tout = cpu_to_le16(OFDM_ACK_TOUT_VALUE);
336 radio_caps->cck_ack_tout = cpu_to_le16(CCK_ACK_TOUT_VALUE);
337 radio_caps->preamble_type = cpu_to_le16(LONG_PREAMBLE);
338
333 radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8); 339 radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8);
334 340
335 for (ii = 0; ii < MAX_HW_QUEUES; ii++) { 341 for (ii = 0; ii < MAX_HW_QUEUES; ii++) {
@@ -588,7 +594,7 @@ static int rsi_program_bb_rf(struct rsi_common *common)
588 594
589 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 595 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
590 mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA); 596 mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA);
591 mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint << 8); 597 mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint);
592 598
593 if (common->rf_reset) { 599 if (common->rf_reset) {
594 mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE); 600 mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE);
@@ -615,6 +621,9 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode)
615{ 621{
616 struct sk_buff *skb = NULL; 622 struct sk_buff *skb = NULL;
617 struct rsi_vap_caps *vap_caps; 623 struct rsi_vap_caps *vap_caps;
624 struct rsi_hw *adapter = common->priv;
625 struct ieee80211_hw *hw = adapter->hw;
626 struct ieee80211_conf *conf = &hw->conf;
618 u16 vap_id = 0; 627 u16 vap_id = 0;
619 628
620 rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__); 629 rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__);
@@ -644,13 +653,24 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode)
644 vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD); 653 vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD);
645 654
646 vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold); 655 vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold);
647 vap_caps->default_mgmt_rate = 0; 656 vap_caps->default_mgmt_rate = cpu_to_le32(RSI_RATE_6);
648 if (conf_is_ht40(&common->priv->hw->conf)) { 657
649 vap_caps->default_ctrl_rate = 658 if (common->band == IEEE80211_BAND_5GHZ) {
650 cpu_to_le32(RSI_RATE_6 | FULL40M_ENABLE << 16);
651 } else {
652 vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6); 659 vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6);
660 if (conf_is_ht40(&common->priv->hw->conf)) {
661 vap_caps->default_ctrl_rate |=
662 cpu_to_le32(FULL40M_ENABLE << 16);
663 }
664 } else {
665 vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_1);
666 if (conf_is_ht40_minus(conf))
667 vap_caps->default_ctrl_rate |=
668 cpu_to_le32(UPPER_20_ENABLE << 16);
669 else if (conf_is_ht40_plus(conf))
670 vap_caps->default_ctrl_rate |=
671 cpu_to_le32(LOWER_20_ENABLE << 16);
653 } 672 }
673
654 vap_caps->default_data_rate = 0; 674 vap_caps->default_data_rate = 0;
655 vap_caps->beacon_interval = cpu_to_le16(200); 675 vap_caps->beacon_interval = cpu_to_le16(200);
656 vap_caps->dtim_period = cpu_to_le16(4); 676 vap_caps->dtim_period = cpu_to_le16(4);
@@ -827,6 +847,63 @@ static int rsi_send_reset_mac(struct rsi_common *common)
827} 847}
828 848
829/** 849/**
850 * rsi_band_check() - This function programs the band
851 * @common: Pointer to the driver private structure.
852 *
853 * Return: 0 on success, corresponding error code on failure.
854 */
855int rsi_band_check(struct rsi_common *common)
856{
857 struct rsi_hw *adapter = common->priv;
858 struct ieee80211_hw *hw = adapter->hw;
859 u8 prev_bw = common->channel_width;
860 u8 prev_ep = common->endpoint;
861 struct ieee80211_channel *curchan = hw->conf.chandef.chan;
862 int status = 0;
863
864 if (common->band != curchan->band) {
865 common->rf_reset = 1;
866 common->band = curchan->band;
867 }
868
869 if ((hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) ||
870 (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20))
871 common->channel_width = BW_20MHZ;
872 else
873 common->channel_width = BW_40MHZ;
874
875 if (common->band == IEEE80211_BAND_2GHZ) {
876 if (common->channel_width)
877 common->endpoint = EP_2GHZ_40MHZ;
878 else
879 common->endpoint = EP_2GHZ_20MHZ;
880 } else {
881 if (common->channel_width)
882 common->endpoint = EP_5GHZ_40MHZ;
883 else
884 common->endpoint = EP_5GHZ_20MHZ;
885 }
886
887 if (common->endpoint != prev_ep) {
888 status = rsi_program_bb_rf(common);
889 if (status)
890 return status;
891 }
892
893 if (common->channel_width != prev_bw) {
894 status = rsi_load_bootup_params(common);
895 if (status)
896 return status;
897
898 status = rsi_load_radio_caps(common);
899 if (status)
900 return status;
901 }
902
903 return status;
904}
905
906/**
830 * rsi_set_channel() - This function programs the channel. 907 * rsi_set_channel() - This function programs the channel.
831 * @common: Pointer to the driver private structure. 908 * @common: Pointer to the driver private structure.
832 * @channel: Channel value to be set. 909 * @channel: Channel value to be set.
@@ -841,23 +918,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
841 rsi_dbg(MGMT_TX_ZONE, 918 rsi_dbg(MGMT_TX_ZONE,
842 "%s: Sending scan req frame\n", __func__); 919 "%s: Sending scan req frame\n", __func__);
843 920
844 if (common->band == IEEE80211_BAND_5GHZ) {
845 if ((channel >= 36) && (channel <= 64))
846 channel = ((channel - 32) / 4);
847 else if ((channel > 64) && (channel <= 140))
848 channel = ((channel - 102) / 4) + 8;
849 else if (channel >= 149)
850 channel = ((channel - 151) / 4) + 18;
851 else
852 return -EINVAL;
853 } else {
854 if (channel > 14) {
855 rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n",
856 __func__, channel, common->band);
857 return -EINVAL;
858 }
859 }
860
861 skb = dev_alloc_skb(FRAME_DESC_SZ); 921 skb = dev_alloc_skb(FRAME_DESC_SZ);
862 if (!skb) { 922 if (!skb) {
863 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 923 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
@@ -877,6 +937,7 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
877 (RSI_RF_TYPE << 4)); 937 (RSI_RF_TYPE << 4));
878 938
879 mgmt_frame->desc_word[5] = cpu_to_le16(0x01); 939 mgmt_frame->desc_word[5] = cpu_to_le16(0x01);
940 mgmt_frame->desc_word[6] = cpu_to_le16(0x12);
880 941
881 if (common->channel_width == BW_40MHZ) 942 if (common->channel_width == BW_40MHZ)
882 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8); 943 mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8);
@@ -950,7 +1011,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
950 struct ieee80211_hw *hw = common->priv->hw; 1011 struct ieee80211_hw *hw = common->priv->hw;
951 u8 band = hw->conf.chandef.chan->band; 1012 u8 band = hw->conf.chandef.chan->band;
952 u8 num_supported_rates = 0; 1013 u8 num_supported_rates = 0;
953 u8 rate_offset = 0; 1014 u8 rate_table_offset, rate_offset = 0;
954 u32 rate_bitmap = common->bitrate_mask[band]; 1015 u32 rate_bitmap = common->bitrate_mask[band];
955 1016
956 u16 *selected_rates, min_rate; 1017 u16 *selected_rates, min_rate;
@@ -986,14 +1047,19 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
986 if (common->channel_width == BW_40MHZ) 1047 if (common->channel_width == BW_40MHZ)
987 auto_rate->desc_word[7] |= cpu_to_le16(1); 1048 auto_rate->desc_word[7] |= cpu_to_le16(1);
988 1049
989 if (band == IEEE80211_BAND_2GHZ) 1050 if (band == IEEE80211_BAND_2GHZ) {
990 min_rate = STD_RATE_01; 1051 min_rate = RSI_RATE_1;
991 else 1052 rate_table_offset = 0;
992 min_rate = STD_RATE_06; 1053 } else {
1054 min_rate = RSI_RATE_6;
1055 rate_table_offset = 4;
1056 }
993 1057
994 for (ii = 0, jj = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { 1058 for (ii = 0, jj = 0;
1059 ii < (ARRAY_SIZE(rsi_rates) - rate_table_offset); ii++) {
995 if (rate_bitmap & BIT(ii)) { 1060 if (rate_bitmap & BIT(ii)) {
996 selected_rates[jj++] = (rsi_rates[ii].bitrate / 5); 1061 selected_rates[jj++] =
1062 (rsi_rates[ii + rate_table_offset].bitrate / 5);
997 rate_offset++; 1063 rate_offset++;
998 } 1064 }
999 } 1065 }
@@ -1006,13 +1072,6 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
1006 rate_offset += ARRAY_SIZE(mcs); 1072 rate_offset += ARRAY_SIZE(mcs);
1007 } 1073 }
1008 1074
1009 if (rate_offset < (RSI_TBL_SZ / 2) - 1) {
1010 for (ii = jj; ii < (RSI_TBL_SZ / 2); ii++) {
1011 selected_rates[jj++] = min_rate;
1012 rate_offset++;
1013 }
1014 }
1015
1016 sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL); 1075 sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL);
1017 1076
1018 /* mapping the rates to RSI rates */ 1077 /* mapping the rates to RSI rates */
@@ -1028,25 +1087,25 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
1028 1087
1029 /* loading HT rates in the bottom half of the auto rate table */ 1088 /* loading HT rates in the bottom half of the auto rate table */
1030 if (common->vif_info[0].is_ht) { 1089 if (common->vif_info[0].is_ht) {
1031 if (common->vif_info[0].sgi)
1032 auto_rate->supported_rates[rate_offset++] =
1033 cpu_to_le16(RSI_RATE_MCS7_SG);
1034
1035 for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1; 1090 for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1;
1036 ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) { 1091 ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) {
1037 if (common->vif_info[0].sgi) 1092 if (common->vif_info[0].sgi ||
1093 conf_is_ht40(&common->priv->hw->conf))
1038 auto_rate->supported_rates[ii++] = 1094 auto_rate->supported_rates[ii++] =
1039 cpu_to_le16(rsi_mcsrates[kk] | BIT(9)); 1095 cpu_to_le16(rsi_mcsrates[kk] | BIT(9));
1040 auto_rate->supported_rates[ii] = 1096 auto_rate->supported_rates[ii] =
1041 cpu_to_le16(rsi_mcsrates[kk--]); 1097 cpu_to_le16(rsi_mcsrates[kk--]);
1042 } 1098 }
1043 1099
1044 for (; ii < RSI_TBL_SZ; ii++) { 1100 for (; ii < (RSI_TBL_SZ - 1); ii++) {
1045 auto_rate->supported_rates[ii] = 1101 auto_rate->supported_rates[ii] =
1046 cpu_to_le16(rsi_mcsrates[0]); 1102 cpu_to_le16(rsi_mcsrates[0]);
1047 } 1103 }
1048 } 1104 }
1049 1105
1106 for (; ii < RSI_TBL_SZ; ii++)
1107 auto_rate->supported_rates[ii] = cpu_to_le16(min_rate);
1108
1050 auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2); 1109 auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2);
1051 auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2); 1110 auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2);
1052 auto_rate->desc_word[7] |= cpu_to_le16(0 << 8); 1111 auto_rate->desc_word[7] |= cpu_to_le16(0 << 8);
@@ -1141,6 +1200,49 @@ static int rsi_eeprom_read(struct rsi_common *common)
1141} 1200}
1142 1201
1143/** 1202/**
1203 * This function sends a frame to block/unblock
1204 * data queues in the firmware
1205 *
1206 * @param common Pointer to the driver private structure.
1207 * @param block event - block if true, unblock if false
1208 * @return 0 on success, -1 on failure.
1209 */
1210int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event)
1211{
1212 struct rsi_mac_frame *mgmt_frame;
1213 struct sk_buff *skb;
1214
1215 rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__);
1216
1217 skb = dev_alloc_skb(FRAME_DESC_SZ);
1218 if (!skb) {
1219 rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
1220 __func__);
1221 return -ENOMEM;
1222 }
1223
1224 memset(skb->data, 0, FRAME_DESC_SZ);
1225 mgmt_frame = (struct rsi_mac_frame *)skb->data;
1226
1227 mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
1228 mgmt_frame->desc_word[1] = cpu_to_le16(BLOCK_HW_QUEUE);
1229
1230 if (block_event == true) {
1231 rsi_dbg(INFO_ZONE, "blocking the data qs\n");
1232 mgmt_frame->desc_word[4] = cpu_to_le16(0xf);
1233 } else {
1234 rsi_dbg(INFO_ZONE, "unblocking the data qs\n");
1235 mgmt_frame->desc_word[5] = cpu_to_le16(0xf);
1236 }
1237
1238 skb_put(skb, FRAME_DESC_SZ);
1239
1240 return rsi_send_internal_mgmt_frame(common, skb);
1241
1242}
1243
1244
1245/**
1144 * rsi_handle_ta_confirm_type() - This function handles the confirm frames. 1246 * rsi_handle_ta_confirm_type() - This function handles the confirm frames.
1145 * @common: Pointer to the driver private structure. 1247 * @common: Pointer to the driver private structure.
1146 * @msg: Pointer to received packet. 1248 * @msg: Pointer to received packet.
@@ -1164,7 +1266,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
1164 common->fsm_state = FSM_EEPROM_READ_MAC_ADDR; 1266 common->fsm_state = FSM_EEPROM_READ_MAC_ADDR;
1165 } 1267 }
1166 } else { 1268 } else {
1167 rsi_dbg(ERR_ZONE, 1269 rsi_dbg(INFO_ZONE,
1168 "%s: Received bootup params cfm in %d state\n", 1270 "%s: Received bootup params cfm in %d state\n",
1169 __func__, common->fsm_state); 1271 __func__, common->fsm_state);
1170 return 0; 1272 return 0;
@@ -1227,7 +1329,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
1227 __func__); 1329 __func__);
1228 } 1330 }
1229 } else { 1331 } else {
1230 rsi_dbg(ERR_ZONE, 1332 rsi_dbg(INFO_ZONE,
1231 "%s: Received radio caps cfm in %d state\n", 1333 "%s: Received radio caps cfm in %d state\n",
1232 __func__, common->fsm_state); 1334 __func__, common->fsm_state);
1233 return 0; 1335 return 0;
@@ -1245,7 +1347,10 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common,
1245 return rsi_mac80211_attach(common); 1347 return rsi_mac80211_attach(common);
1246 } 1348 }
1247 } else { 1349 } else {
1248 goto out; 1350 rsi_dbg(INFO_ZONE,
1351 "%s: Received bbb_rf cfm in %d state\n",
1352 __func__, common->fsm_state);
1353 return 0;
1249 } 1354 }
1250 break; 1355 break;
1251 1356
diff --git a/drivers/net/wireless/rsi/rsi_91x_pkt.c b/drivers/net/wireless/rsi/rsi_91x_pkt.c
index 8e48e72bae20..702593f19997 100644
--- a/drivers/net/wireless/rsi/rsi_91x_pkt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_pkt.c
@@ -81,6 +81,16 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb)
81 /* Send fixed rate */ 81 /* Send fixed rate */
82 frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE); 82 frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE);
83 frame_desc[4] = cpu_to_le16(common->min_rate); 83 frame_desc[4] = cpu_to_le16(common->min_rate);
84
85 if (conf_is_ht40(&common->priv->hw->conf))
86 frame_desc[5] = cpu_to_le16(FULL40M_ENABLE);
87
88 if (common->vif_info[0].sgi) {
89 if (common->min_rate & 0x100) /* Only MCS rates */
90 frame_desc[4] |=
91 cpu_to_le16(ENABLE_SHORTGI_RATE);
92 }
93
84 } 94 }
85 95
86 frame_desc[6] |= cpu_to_le16(seq_num & 0xfff); 96 frame_desc[6] |= cpu_to_le16(seq_num & 0xfff);
@@ -116,6 +126,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
116 struct ieee80211_hdr *wh = NULL; 126 struct ieee80211_hdr *wh = NULL;
117 struct ieee80211_tx_info *info; 127 struct ieee80211_tx_info *info;
118 struct ieee80211_bss_conf *bss = NULL; 128 struct ieee80211_bss_conf *bss = NULL;
129 struct ieee80211_hw *hw = adapter->hw;
130 struct ieee80211_conf *conf = &hw->conf;
119 struct skb_info *tx_params; 131 struct skb_info *tx_params;
120 int status = -E2BIG; 132 int status = -E2BIG;
121 __le16 *msg = NULL; 133 __le16 *msg = NULL;
@@ -175,6 +187,11 @@ int rsi_send_mgmt_pkt(struct rsi_common *common,
175 else 187 else
176 msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE); 188 msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE);
177 189
190 if (conf_is_ht40(conf)) {
191 msg[4] = cpu_to_le16(0xB | RSI_11G_MODE);
192 msg[5] = cpu_to_le16(0x6);
193 }
194
178 /* Indicate to firmware to give cfm */ 195 /* Indicate to firmware to give cfm */
179 if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) { 196 if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) {
180 msg[1] |= cpu_to_le16(BIT(10)); 197 msg[1] |= cpu_to_le16(BIT(10));
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 46e7af446f01..8428858204a6 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -820,9 +820,11 @@ static struct sdio_driver rsi_driver = {
820 */ 820 */
821static int rsi_module_init(void) 821static int rsi_module_init(void)
822{ 822{
823 sdio_register_driver(&rsi_driver); 823 int ret;
824
825 ret = sdio_register_driver(&rsi_driver);
824 rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__); 826 rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
825 return 0; 827 return ret;
826} 828}
827 829
828/** 830/**
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
index 20d11ccfffe3..4834a9abc171 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
@@ -401,14 +401,16 @@ void rsi_interrupt_handler(struct rsi_hw *adapter)
401 case BUFFER_AVAILABLE: 401 case BUFFER_AVAILABLE:
402 dev->rx_info.watch_bufferfull_count = 0; 402 dev->rx_info.watch_bufferfull_count = 0;
403 dev->rx_info.buffer_full = false; 403 dev->rx_info.buffer_full = false;
404 dev->rx_info.semi_buffer_full = false;
404 dev->rx_info.mgmt_buffer_full = false; 405 dev->rx_info.mgmt_buffer_full = false;
405 rsi_sdio_ack_intr(common->priv, 406 rsi_sdio_ack_intr(common->priv,
406 (1 << PKT_BUFF_AVAILABLE)); 407 (1 << PKT_BUFF_AVAILABLE));
407 rsi_set_event((&common->tx_thread.event)); 408 rsi_set_event(&common->tx_thread.event);
409
408 rsi_dbg(ISR_ZONE, 410 rsi_dbg(ISR_ZONE,
409 "%s: ==> BUFFER_AVILABLE <==\n", 411 "%s: ==> BUFFER_AVAILABLE <==\n",
410 __func__); 412 __func__);
411 dev->rx_info.buf_avilable_counter++; 413 dev->rx_info.buf_available_counter++;
412 break; 414 break;
413 415
414 case FIRMWARE_ASSERT_IND: 416 case FIRMWARE_ASSERT_IND:
diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c
index 4c46e5631e2f..ef5d394f185b 100644
--- a/drivers/net/wireless/rsi/rsi_91x_usb.c
+++ b/drivers/net/wireless/rsi/rsi_91x_usb.c
@@ -25,7 +25,7 @@
25 * @len: Length to be written. 25 * @len: Length to be written.
26 * @endpoint: Type of endpoint. 26 * @endpoint: Type of endpoint.
27 * 27 *
28 * Return: status: 0 on success, -1 on failure. 28 * Return: status: 0 on success, a negative error code on failure.
29 */ 29 */
30static int rsi_usb_card_write(struct rsi_hw *adapter, 30static int rsi_usb_card_write(struct rsi_hw *adapter,
31 void *buf, 31 void *buf,
@@ -60,7 +60,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
60 * @data: Pointer to the data that has to be written. 60 * @data: Pointer to the data that has to be written.
61 * @count: Number of multiple bytes to be written. 61 * @count: Number of multiple bytes to be written.
62 * 62 *
63 * Return: 0 on success, -1 on failure. 63 * Return: 0 on success, a negative error code on failure.
64 */ 64 */
65static int rsi_write_multiple(struct rsi_hw *adapter, 65static int rsi_write_multiple(struct rsi_hw *adapter,
66 u8 endpoint, 66 u8 endpoint,
@@ -147,7 +147,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface,
147 * @value: Value to be read. 147 * @value: Value to be read.
148 * @len: length of data to be read. 148 * @len: length of data to be read.
149 * 149 *
150 * Return: status: 0 on success, -1 on failure. 150 * Return: status: 0 on success, a negative error code on failure.
151 */ 151 */
152static int rsi_usb_reg_read(struct usb_device *usbdev, 152static int rsi_usb_reg_read(struct usb_device *usbdev,
153 u32 reg, 153 u32 reg,
@@ -189,7 +189,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev,
189 * @value: Value to write. 189 * @value: Value to write.
190 * @len: Length of data to be written. 190 * @len: Length of data to be written.
191 * 191 *
192 * Return: status: 0 on success, -1 on failure. 192 * Return: status: 0 on success, a negative error code on failure.
193 */ 193 */
194static int rsi_usb_reg_write(struct usb_device *usbdev, 194static int rsi_usb_reg_write(struct usb_device *usbdev,
195 u32 reg, 195 u32 reg,
@@ -249,7 +249,7 @@ static void rsi_rx_done_handler(struct urb *urb)
249 * rsi_rx_urb_submit() - This function submits the given URB to the USB stack. 249 * rsi_rx_urb_submit() - This function submits the given URB to the USB stack.
250 * @adapter: Pointer to the adapter structure. 250 * @adapter: Pointer to the adapter structure.
251 * 251 *
252 * Return: 0 on success, -1 on failure. 252 * Return: 0 on success, a negative error code on failure.
253 */ 253 */
254static int rsi_rx_urb_submit(struct rsi_hw *adapter) 254static int rsi_rx_urb_submit(struct rsi_hw *adapter)
255{ 255{
@@ -281,7 +281,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter)
281 * @data: Pointer to the data that has to be written. 281 * @data: Pointer to the data that has to be written.
282 * @count: Number of multiple bytes to be written on to the registers. 282 * @count: Number of multiple bytes to be written on to the registers.
283 * 283 *
284 * Return: status: 0 on success, -1 on failure. 284 * Return: status: 0 on success, a negative error code on failure.
285 */ 285 */
286int rsi_usb_write_register_multiple(struct rsi_hw *adapter, 286int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
287 u32 addr, 287 u32 addr,
@@ -331,7 +331,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
331 * @pkt: Pointer to the data to be written on to the card. 331 * @pkt: Pointer to the data to be written on to the card.
332 * @len: Length of the data to be written on to the card. 332 * @len: Length of the data to be written on to the card.
333 * 333 *
334 * Return: 0 on success, -1 on failure. 334 * Return: 0 on success, a negative error code on failure.
335 */ 335 */
336static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, 336static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
337 u8 *pkt, 337 u8 *pkt,
@@ -359,6 +359,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
359 struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 359 struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
360 360
361 rsi_kill_thread(&dev->rx_thread); 361 rsi_kill_thread(&dev->rx_thread);
362 usb_free_urb(dev->rx_usb_urb[0]);
362 kfree(adapter->priv->rx_data_pkt); 363 kfree(adapter->priv->rx_data_pkt);
363 kfree(dev->tx_buffer); 364 kfree(dev->tx_buffer);
364} 365}
@@ -368,7 +369,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
368 * @adapter: Pointer to the adapter structure. 369 * @adapter: Pointer to the adapter structure.
369 * @pfunction: Pointer to USB interface structure. 370 * @pfunction: Pointer to USB interface structure.
370 * 371 *
371 * Return: 0 on success, -1 on failure. 372 * Return: 0 on success, a negative error code on failure.
372 */ 373 */
373static int rsi_init_usb_interface(struct rsi_hw *adapter, 374static int rsi_init_usb_interface(struct rsi_hw *adapter,
374 struct usb_interface *pfunction) 375 struct usb_interface *pfunction)
@@ -397,8 +398,16 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
397 return -ENOMEM; 398 return -ENOMEM;
398 } 399 }
399 400
400 rsi_dev->tx_buffer = kmalloc(2048, GFP_ATOMIC); 401 rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL);
402 if (!rsi_dev->tx_buffer) {
403 status = -ENOMEM;
404 goto fail_tx;
405 }
401 rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL); 406 rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL);
407 if (!rsi_dev->rx_usb_urb[0]) {
408 status = -ENOMEM;
409 goto fail_rx;
410 }
402 rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; 411 rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt;
403 rsi_dev->tx_blk_size = 252; 412 rsi_dev->tx_blk_size = 252;
404 413
@@ -413,7 +422,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
413 rsi_usb_rx_thread, "RX-Thread"); 422 rsi_usb_rx_thread, "RX-Thread");
414 if (status) { 423 if (status) {
415 rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); 424 rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
416 goto fail; 425 goto fail_thread;
417 } 426 }
418 427
419#ifdef CONFIG_RSI_DEBUGFS 428#ifdef CONFIG_RSI_DEBUGFS
@@ -424,8 +433,11 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
424 rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); 433 rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
425 return 0; 434 return 0;
426 435
427fail: 436fail_thread:
437 usb_free_urb(rsi_dev->rx_usb_urb[0]);
438fail_rx:
428 kfree(rsi_dev->tx_buffer); 439 kfree(rsi_dev->tx_buffer);
440fail_tx:
429 kfree(common->rx_data_pkt); 441 kfree(common->rx_data_pkt);
430 return status; 442 return status;
431} 443}
@@ -437,7 +449,7 @@ fail:
437 * @pfunction: Pointer to the USB interface structure. 449 * @pfunction: Pointer to the USB interface structure.
438 * @id: Pointer to the usb_device_id structure. 450 * @id: Pointer to the usb_device_id structure.
439 * 451 *
440 * Return: 0 on success, -1 on failure. 452 * Return: 0 on success, a negative error code on failure.
441 */ 453 */
442static int rsi_probe(struct usb_interface *pfunction, 454static int rsi_probe(struct usb_interface *pfunction,
443 const struct usb_device_id *id) 455 const struct usb_device_id *id)
@@ -445,6 +457,7 @@ static int rsi_probe(struct usb_interface *pfunction,
445 struct rsi_hw *adapter; 457 struct rsi_hw *adapter;
446 struct rsi_91x_usbdev *dev; 458 struct rsi_91x_usbdev *dev;
447 u16 fw_status; 459 u16 fw_status;
460 int status;
448 461
449 rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); 462 rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
450 463
@@ -452,10 +465,11 @@ static int rsi_probe(struct usb_interface *pfunction,
452 if (!adapter) { 465 if (!adapter) {
453 rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n", 466 rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
454 __func__); 467 __func__);
455 return 1; 468 return -ENOMEM;
456 } 469 }
457 470
458 if (rsi_init_usb_interface(adapter, pfunction)) { 471 status = rsi_init_usb_interface(adapter, pfunction);
472 if (status) {
459 rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n", 473 rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
460 __func__); 474 __func__);
461 goto err; 475 goto err;
@@ -465,26 +479,30 @@ static int rsi_probe(struct usb_interface *pfunction,
465 479
466 dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 480 dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
467 481
468 if (rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2) < 0) 482 status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2);
483 if (status)
469 goto err1; 484 goto err1;
470 else 485 else
471 fw_status &= 1; 486 fw_status &= 1;
472 487
473 if (!fw_status) { 488 if (!fw_status) {
474 if (rsi_usb_device_init(adapter->priv)) { 489 status = rsi_usb_device_init(adapter->priv);
490 if (status) {
475 rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", 491 rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
476 __func__); 492 __func__);
477 goto err1; 493 goto err1;
478 } 494 }
479 495
480 if (rsi_usb_reg_write(dev->usbdev, 496 status = rsi_usb_reg_write(dev->usbdev,
481 USB_INTERNAL_REG_1, 497 USB_INTERNAL_REG_1,
482 RSI_USB_READY_MAGIC_NUM, 1) < 0) 498 RSI_USB_READY_MAGIC_NUM, 1);
499 if (status)
483 goto err1; 500 goto err1;
484 rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__); 501 rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__);
485 } 502 }
486 503
487 if (rsi_rx_urb_submit(adapter)) 504 status = rsi_rx_urb_submit(adapter);
505 if (status)
488 goto err1; 506 goto err1;
489 507
490 return 0; 508 return 0;
@@ -493,7 +511,7 @@ err1:
493err: 511err:
494 rsi_91x_deinit(adapter); 512 rsi_91x_deinit(adapter);
495 rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); 513 rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
496 return 1; 514 return status;
497} 515}
498 516
499/** 517/**
@@ -550,33 +568,7 @@ static struct usb_driver rsi_driver = {
550#endif 568#endif
551}; 569};
552 570
553/** 571module_usb_driver(rsi_driver);
554 * rsi_module_init() - This function registers the client driver.
555 * @void: Void.
556 *
557 * Return: 0 on success.
558 */
559static int rsi_module_init(void)
560{
561 usb_register(&rsi_driver);
562 rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
563 return 0;
564}
565
566/**
567 * rsi_module_exit() - This function unregisters the client driver.
568 * @void: Void.
569 *
570 * Return: None.
571 */
572static void rsi_module_exit(void)
573{
574 usb_deregister(&rsi_driver);
575 rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
576}
577
578module_init(rsi_module_init);
579module_exit(rsi_module_exit);
580 572
581MODULE_AUTHOR("Redpine Signals Inc"); 573MODULE_AUTHOR("Redpine Signals Inc");
582MODULE_DESCRIPTION("Common USB layer for RSI drivers"); 574MODULE_DESCRIPTION("Common USB layer for RSI drivers");
diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h
index 2cb73e7edb98..5baed945f60e 100644
--- a/drivers/net/wireless/rsi/rsi_main.h
+++ b/drivers/net/wireless/rsi/rsi_main.h
@@ -115,6 +115,7 @@ struct wmm_qinfo {
115 s32 weight; 115 s32 weight;
116 s32 wme_params; 116 s32 wme_params;
117 s32 pkt_contended; 117 s32 pkt_contended;
118 s32 txop;
118}; 119};
119 120
120struct transmit_q_stats { 121struct transmit_q_stats {
@@ -141,6 +142,12 @@ struct rsi_thread {
141 atomic_t thread_done; 142 atomic_t thread_done;
142}; 143};
143 144
145struct cqm_info {
146 s8 last_cqm_event_rssi;
147 int rssi_thold;
148 u32 rssi_hyst;
149};
150
144struct rsi_hw; 151struct rsi_hw;
145 152
146struct rsi_common { 153struct rsi_common {
@@ -192,6 +199,11 @@ struct rsi_common {
192 u8 selected_qnum; 199 u8 selected_qnum;
193 u32 pkt_cnt; 200 u32 pkt_cnt;
194 u8 min_weight; 201 u8 min_weight;
202
203 /* bgscan related */
204 struct cqm_info cqm_info;
205
206 bool hw_data_qs_blocked;
195}; 207};
196 208
197struct rsi_hw { 209struct rsi_hw {
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index 225215a3b8bb..3741173fd3ac 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -69,6 +69,7 @@
69 69
70#define RSI_LMAC_CLOCK_80MHZ 0x1 70#define RSI_LMAC_CLOCK_80MHZ 0x1
71#define RSI_ENABLE_40MHZ (0x1 << 3) 71#define RSI_ENABLE_40MHZ (0x1 << 3)
72#define ENABLE_SHORTGI_RATE BIT(9)
72 73
73#define RX_BA_INDICATION 1 74#define RX_BA_INDICATION 1
74#define RSI_TBL_SZ 40 75#define RSI_TBL_SZ 40
@@ -123,6 +124,20 @@
123#define BW_20MHZ 0 124#define BW_20MHZ 0
124#define BW_40MHZ 1 125#define BW_40MHZ 1
125 126
127#define EP_2GHZ_20MHZ 0
128#define EP_2GHZ_40MHZ 1
129#define EP_5GHZ_20MHZ 2
130#define EP_5GHZ_40MHZ 3
131
132#define SIFS_TX_11N_VALUE 580
133#define SIFS_TX_11B_VALUE 346
134#define SHORT_SLOT_VALUE 360
135#define LONG_SLOT_VALUE 640
136#define OFDM_ACK_TOUT_VALUE 2720
137#define CCK_ACK_TOUT_VALUE 9440
138#define LONG_PREAMBLE 0x0000
139#define SHORT_PREAMBLE 0x0001
140
126#define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\ 141#define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\
127 FIF_BCN_PRBRESP_PROMISC) 142 FIF_BCN_PRBRESP_PROMISC)
128enum opmode { 143enum opmode {
@@ -153,7 +168,7 @@ enum cmd_frame_type {
153 SCAN_REQUEST, 168 SCAN_REQUEST,
154 TSF_UPDATE, 169 TSF_UPDATE,
155 PEER_NOTIFY, 170 PEER_NOTIFY,
156 BLOCK_UNBLOCK, 171 BLOCK_HW_QUEUE,
157 SET_KEY_REQ, 172 SET_KEY_REQ,
158 AUTO_RATE_IND, 173 AUTO_RATE_IND,
159 BOOTUP_PARAMS_REQUEST, 174 BOOTUP_PARAMS_REQUEST,
@@ -238,6 +253,12 @@ struct rsi_radio_caps {
238 u8 num_11n_rates; 253 u8 num_11n_rates;
239 u8 num_11ac_rates; 254 u8 num_11ac_rates;
240 __le16 gcpd_per_rate[20]; 255 __le16 gcpd_per_rate[20];
256 __le16 sifs_tx_11n;
257 __le16 sifs_tx_11b;
258 __le16 slot_rx_11n;
259 __le16 ofdm_ack_tout;
260 __le16 cck_ack_tout;
261 __le16 preamble_type;
241} __packed; 262} __packed;
242 263
243static inline u32 rsi_get_queueno(u8 *addr, u16 offset) 264static inline u32 rsi_get_queueno(u8 *addr, u16 offset)
@@ -272,6 +293,7 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid,
272int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len, 293int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len,
273 u8 key_type, u8 key_id, u32 cipher); 294 u8 key_type, u8 key_id, u32 cipher);
274int rsi_set_channel(struct rsi_common *common, u16 chno); 295int rsi_set_channel(struct rsi_common *common, u16 chno);
296int rsi_send_block_unblock_frame(struct rsi_common *common, bool event);
275void rsi_inform_bss_status(struct rsi_common *common, u8 status, 297void rsi_inform_bss_status(struct rsi_common *common, u8 status,
276 const u8 *bssid, u8 qos_enable, u16 aid); 298 const u8 *bssid, u8 qos_enable, u16 aid);
277void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb); 299void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb);
@@ -283,4 +305,5 @@ void rsi_core_qos_processor(struct rsi_common *common);
283void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb); 305void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb);
284int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb); 306int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb);
285int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb); 307int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb);
308int rsi_band_check(struct rsi_common *common);
286#endif 309#endif
diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h
index df4b5e20e05f..c7e8f2be7901 100644
--- a/drivers/net/wireless/rsi/rsi_sdio.h
+++ b/drivers/net/wireless/rsi/rsi_sdio.h
@@ -30,7 +30,7 @@
30 30
31enum sdio_interrupt_type { 31enum sdio_interrupt_type {
32 BUFFER_FULL = 0x0, 32 BUFFER_FULL = 0x0,
33 BUFFER_AVAILABLE = 0x1, 33 BUFFER_AVAILABLE = 0x2,
34 FIRMWARE_ASSERT_IND = 0x3, 34 FIRMWARE_ASSERT_IND = 0x3,
35 MSDU_PACKET_PENDING = 0x4, 35 MSDU_PACKET_PENDING = 0x4,
36 UNKNOWN_INT = 0XE 36 UNKNOWN_INT = 0XE
@@ -42,7 +42,7 @@ enum sdio_interrupt_type {
42#define PKT_MGMT_BUFF_FULL 2 42#define PKT_MGMT_BUFF_FULL 2
43#define MSDU_PKT_PENDING 3 43#define MSDU_PKT_PENDING 3
44/* Interrupt Bit Related Macros */ 44/* Interrupt Bit Related Macros */
45#define PKT_BUFF_AVAILABLE 0 45#define PKT_BUFF_AVAILABLE 1
46#define FW_ASSERT_IND 2 46#define FW_ASSERT_IND 2
47 47
48#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3 48#define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3
@@ -84,7 +84,7 @@ enum sdio_interrupt_type {
84#define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF) 84#define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF)
85#define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF) 85#define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF)
86#define TA_BASE_ADDR 0x2200 86#define TA_BASE_ADDR 0x2200
87#define MISC_CFG_BASE_ADDR 0x4150 87#define MISC_CFG_BASE_ADDR 0x4105
88 88
89struct receive_info { 89struct receive_info {
90 bool buffer_full; 90 bool buffer_full;
@@ -98,7 +98,7 @@ struct receive_info {
98 u32 total_sdio_msdu_pending_intr; 98 u32 total_sdio_msdu_pending_intr;
99 u32 total_sdio_unknown_intr; 99 u32 total_sdio_unknown_intr;
100 u32 buf_full_counter; 100 u32 buf_full_counter;
101 u32 buf_avilable_counter; 101 u32 buf_available_counter;
102}; 102};
103 103
104struct rsi_91x_sdiodev { 104struct rsi_91x_sdiodev {
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c17fcf272728..893c9d5f3d6f 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -947,6 +947,40 @@ static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
947 return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index)); 947 return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
948} 948}
949 949
950static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev)
951{
952 struct data_queue *queue = rt2x00dev->bcn;
953 struct queue_entry *entry;
954 int i, bcn_num = 0;
955 u64 off, reg = 0;
956 u32 bssid_dw1;
957
958 /*
959 * Setup offsets of all active beacons in BCN_OFFSET{0,1} registers.
960 */
961 for (i = 0; i < queue->limit; i++) {
962 entry = &queue->entries[i];
963 if (!test_bit(ENTRY_BCN_ENABLED, &entry->flags))
964 continue;
965 off = rt2800_get_beacon_offset(rt2x00dev, entry->entry_idx);
966 reg |= off << (8 * bcn_num);
967 bcn_num++;
968 }
969
970 WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing);
971
972 rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg);
973 rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32));
974
975 /*
976 * H/W sends up to MAC_BSSID_DW1_BSS_BCN_NUM + 1 consecutive beacons.
977 */
978 rt2800_register_read(rt2x00dev, MAC_BSSID_DW1, &bssid_dw1);
979 rt2x00_set_field32(&bssid_dw1, MAC_BSSID_DW1_BSS_BCN_NUM,
980 bcn_num > 0 ? bcn_num - 1 : 0);
981 rt2800_register_write(rt2x00dev, MAC_BSSID_DW1, bssid_dw1);
982}
983
950void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) 984void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
951{ 985{
952 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; 986 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -1003,6 +1037,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
1003 1037
1004 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, 1038 rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
1005 entry->skb->len + padding_len); 1039 entry->skb->len + padding_len);
1040 __set_bit(ENTRY_BCN_ENABLED, &entry->flags);
1041
1042 /*
1043 * Change global beacons settings.
1044 */
1045 rt2800_update_beacons_setup(rt2x00dev);
1006 1046
1007 /* 1047 /*
1008 * Restore beaconing state. 1048 * Restore beaconing state.
@@ -1053,8 +1093,13 @@ void rt2800_clear_beacon(struct queue_entry *entry)
1053 * Clear beacon. 1093 * Clear beacon.
1054 */ 1094 */
1055 rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx); 1095 rt2800_clear_beacon_register(rt2x00dev, entry->entry_idx);
1096 __clear_bit(ENTRY_BCN_ENABLED, &entry->flags);
1056 1097
1057 /* 1098 /*
1099 * Change global beacons settings.
1100 */
1101 rt2800_update_beacons_setup(rt2x00dev);
1102 /*
1058 * Restore beaconing state. 1103 * Restore beaconing state.
1059 */ 1104 */
1060 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); 1105 rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg);
@@ -1556,7 +1601,7 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
1556 if (!is_zero_ether_addr((const u8 *)conf->bssid)) { 1601 if (!is_zero_ether_addr((const u8 *)conf->bssid)) {
1557 reg = le32_to_cpu(conf->bssid[1]); 1602 reg = le32_to_cpu(conf->bssid[1]);
1558 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3); 1603 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 3);
1559 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 7); 1604 rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
1560 conf->bssid[1] = cpu_to_le32(reg); 1605 conf->bssid[1] = cpu_to_le32(reg);
1561 } 1606 }
1562 1607
@@ -4517,28 +4562,6 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
4517 if (ret) 4562 if (ret)
4518 return ret; 4563 return ret;
4519 4564
4520 rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
4521 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
4522 rt2800_get_beacon_offset(rt2x00dev, 0));
4523 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
4524 rt2800_get_beacon_offset(rt2x00dev, 1));
4525 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
4526 rt2800_get_beacon_offset(rt2x00dev, 2));
4527 rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
4528 rt2800_get_beacon_offset(rt2x00dev, 3));
4529 rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
4530
4531 rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
4532 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
4533 rt2800_get_beacon_offset(rt2x00dev, 4));
4534 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
4535 rt2800_get_beacon_offset(rt2x00dev, 5));
4536 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
4537 rt2800_get_beacon_offset(rt2x00dev, 6));
4538 rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
4539 rt2800_get_beacon_offset(rt2x00dev, 7));
4540 rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
4541
4542 rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f); 4565 rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
4543 rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); 4566 rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
4544 4567
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 4fa43a2eeb73..9967a1d9f0ec 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -141,8 +141,11 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
141 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 141 if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
142 return; 142 return;
143 143
144 if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) 144 if (test_and_clear_bit(DELAYED_UPDATE_BEACON, &intf->delayed_flags)) {
145 mutex_lock(&intf->beacon_skb_mutex);
145 rt2x00queue_update_beacon(rt2x00dev, vif); 146 rt2x00queue_update_beacon(rt2x00dev, vif);
147 mutex_unlock(&intf->beacon_skb_mutex);
148 }
146} 149}
147 150
148static void rt2x00lib_intf_scheduled(struct work_struct *work) 151static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -216,7 +219,7 @@ static void rt2x00lib_beaconupdate_iter(void *data, u8 *mac,
216 * never be called for USB devices. 219 * never be called for USB devices.
217 */ 220 */
218 WARN_ON(rt2x00_is_usb(rt2x00dev)); 221 WARN_ON(rt2x00_is_usb(rt2x00dev));
219 rt2x00queue_update_beacon_locked(rt2x00dev, vif); 222 rt2x00queue_update_beacon(rt2x00dev, vif);
220} 223}
221 224
222void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) 225void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
@@ -1470,8 +1473,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1470 /* 1473 /*
1471 * Free the driver data. 1474 * Free the driver data.
1472 */ 1475 */
1473 if (rt2x00dev->drv_data) 1476 kfree(rt2x00dev->drv_data);
1474 kfree(rt2x00dev->drv_data);
1475} 1477}
1476EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev); 1478EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
1477 1479
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 004dff9b962d..ad6e5a8d1e10 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -626,25 +626,24 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
626 * Start/stop beaconing. 626 * Start/stop beaconing.
627 */ 627 */
628 if (changes & BSS_CHANGED_BEACON_ENABLED) { 628 if (changes & BSS_CHANGED_BEACON_ENABLED) {
629 mutex_lock(&intf->beacon_skb_mutex);
629 if (!bss_conf->enable_beacon && intf->enable_beacon) { 630 if (!bss_conf->enable_beacon && intf->enable_beacon) {
630 rt2x00dev->intf_beaconing--; 631 rt2x00dev->intf_beaconing--;
631 intf->enable_beacon = false; 632 intf->enable_beacon = false;
632 /*
633 * Clear beacon in the H/W for this vif. This is needed
634 * to disable beaconing on this particular interface
635 * and keep it running on other interfaces.
636 */
637 rt2x00queue_clear_beacon(rt2x00dev, vif);
638 633
639 if (rt2x00dev->intf_beaconing == 0) { 634 if (rt2x00dev->intf_beaconing == 0) {
640 /* 635 /*
641 * Last beaconing interface disabled 636 * Last beaconing interface disabled
642 * -> stop beacon queue. 637 * -> stop beacon queue.
643 */ 638 */
644 mutex_lock(&intf->beacon_skb_mutex);
645 rt2x00queue_stop_queue(rt2x00dev->bcn); 639 rt2x00queue_stop_queue(rt2x00dev->bcn);
646 mutex_unlock(&intf->beacon_skb_mutex);
647 } 640 }
641 /*
642 * Clear beacon in the H/W for this vif. This is needed
643 * to disable beaconing on this particular interface
644 * and keep it running on other interfaces.
645 */
646 rt2x00queue_clear_beacon(rt2x00dev, vif);
648 } else if (bss_conf->enable_beacon && !intf->enable_beacon) { 647 } else if (bss_conf->enable_beacon && !intf->enable_beacon) {
649 rt2x00dev->intf_beaconing++; 648 rt2x00dev->intf_beaconing++;
650 intf->enable_beacon = true; 649 intf->enable_beacon = true;
@@ -660,11 +659,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
660 * First beaconing interface enabled 659 * First beaconing interface enabled
661 * -> start beacon queue. 660 * -> start beacon queue.
662 */ 661 */
663 mutex_lock(&intf->beacon_skb_mutex);
664 rt2x00queue_start_queue(rt2x00dev->bcn); 662 rt2x00queue_start_queue(rt2x00dev->bcn);
665 mutex_unlock(&intf->beacon_skb_mutex);
666 } 663 }
667 } 664 }
665 mutex_unlock(&intf->beacon_skb_mutex);
668 } 666 }
669 667
670 /* 668 /*
@@ -801,6 +799,8 @@ int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
801 799
802 setup.tx = tx_ant; 800 setup.tx = tx_ant;
803 setup.rx = rx_ant; 801 setup.rx = rx_ant;
802 setup.rx_chain_num = 0;
803 setup.tx_chain_num = 0;
804 804
805 rt2x00lib_config_antenna(rt2x00dev, setup); 805 rt2x00lib_config_antenna(rt2x00dev, setup);
806 806
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
index 6f236ea180aa..f0178fd4fe5f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mmio.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -119,14 +119,12 @@ static int rt2x00mmio_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
119 /* 119 /*
120 * Allocate DMA memory for descriptor and buffer. 120 * Allocate DMA memory for descriptor and buffer.
121 */ 121 */
122 addr = dma_alloc_coherent(rt2x00dev->dev, 122 addr = dma_zalloc_coherent(rt2x00dev->dev,
123 queue->limit * queue->desc_size, 123 queue->limit * queue->desc_size, &dma,
124 &dma, GFP_KERNEL); 124 GFP_KERNEL);
125 if (!addr) 125 if (!addr)
126 return -ENOMEM; 126 return -ENOMEM;
127 127
128 memset(addr, 0, queue->limit * queue->desc_size);
129
130 /* 128 /*
131 * Initialize all queue entries to contain valid addresses. 129 * Initialize all queue entries to contain valid addresses.
132 */ 130 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 5642ccceca7c..8e68f87ab13c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -754,8 +754,6 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
754 if (unlikely(!intf->beacon)) 754 if (unlikely(!intf->beacon))
755 return -ENOBUFS; 755 return -ENOBUFS;
756 756
757 mutex_lock(&intf->beacon_skb_mutex);
758
759 /* 757 /*
760 * Clean up the beacon skb. 758 * Clean up the beacon skb.
761 */ 759 */
@@ -768,13 +766,11 @@ int rt2x00queue_clear_beacon(struct rt2x00_dev *rt2x00dev,
768 if (rt2x00dev->ops->lib->clear_beacon) 766 if (rt2x00dev->ops->lib->clear_beacon)
769 rt2x00dev->ops->lib->clear_beacon(intf->beacon); 767 rt2x00dev->ops->lib->clear_beacon(intf->beacon);
770 768
771 mutex_unlock(&intf->beacon_skb_mutex);
772
773 return 0; 769 return 0;
774} 770}
775 771
776int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev, 772int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
777 struct ieee80211_vif *vif) 773 struct ieee80211_vif *vif)
778{ 774{
779 struct rt2x00_intf *intf = vif_to_intf(vif); 775 struct rt2x00_intf *intf = vif_to_intf(vif);
780 struct skb_frame_desc *skbdesc; 776 struct skb_frame_desc *skbdesc;
@@ -815,19 +811,6 @@ int rt2x00queue_update_beacon_locked(struct rt2x00_dev *rt2x00dev,
815 811
816} 812}
817 813
818int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
819 struct ieee80211_vif *vif)
820{
821 struct rt2x00_intf *intf = vif_to_intf(vif);
822 int ret;
823
824 mutex_lock(&intf->beacon_skb_mutex);
825 ret = rt2x00queue_update_beacon_locked(rt2x00dev, vif);
826 mutex_unlock(&intf->beacon_skb_mutex);
827
828 return ret;
829}
830
831bool rt2x00queue_for_each_entry(struct data_queue *queue, 814bool rt2x00queue_for_each_entry(struct data_queue *queue,
832 enum queue_index start, 815 enum queue_index start,
833 enum queue_index end, 816 enum queue_index end,
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index c48125be0e34..2233b911a1d7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -353,6 +353,7 @@ struct txentry_desc {
353 */ 353 */
354enum queue_entry_flags { 354enum queue_entry_flags {
355 ENTRY_BCN_ASSIGNED, 355 ENTRY_BCN_ASSIGNED,
356 ENTRY_BCN_ENABLED,
356 ENTRY_OWNER_DEVICE_DATA, 357 ENTRY_OWNER_DEVICE_DATA,
357 ENTRY_DATA_PENDING, 358 ENTRY_DATA_PENDING,
358 ENTRY_DATA_IO_FAILED, 359 ENTRY_DATA_IO_FAILED,
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 2c1c02bafa10..4b904f708184 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -16,6 +16,7 @@
16 * 16 *
17 * based also on: 17 * based also on:
18 * - portions of rtl8187se Linux staging driver, Copyright Realtek corp. 18 * - portions of rtl8187se Linux staging driver, Copyright Realtek corp.
19 * (available in drivers/staging/rtl8187se directory of Linux 3.14)
19 * - other GPL, unpublished (until now), Linux driver code, 20 * - other GPL, unpublished (until now), Linux driver code,
20 * Copyright Larry Finger <Larry.Finger@lwfinger.net> 21 * Copyright Larry Finger <Larry.Finger@lwfinger.net>
21 * 22 *
@@ -209,7 +210,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
209 struct rtl8180_priv *priv = dev->priv; 210 struct rtl8180_priv *priv = dev->priv;
210 struct rtl818x_rx_cmd_desc *cmd_desc; 211 struct rtl818x_rx_cmd_desc *cmd_desc;
211 unsigned int count = 32; 212 unsigned int count = 32;
212 u8 signal, agc, sq; 213 u8 agc, sq, signal = 1;
213 dma_addr_t mapping; 214 dma_addr_t mapping;
214 215
215 while (count--) { 216 while (count--) {
@@ -222,12 +223,20 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
222 struct rtl8187se_rx_desc *desc = entry; 223 struct rtl8187se_rx_desc *desc = entry;
223 224
224 flags = le32_to_cpu(desc->flags); 225 flags = le32_to_cpu(desc->flags);
226 /* if ownership flag is set, then we can trust the
227 * HW has written other fields. We must not trust
228 * other descriptor data read before we checked (read)
229 * the ownership flag
230 */
231 rmb();
225 flags2 = le32_to_cpu(desc->flags2); 232 flags2 = le32_to_cpu(desc->flags2);
226 tsft = le64_to_cpu(desc->tsft); 233 tsft = le64_to_cpu(desc->tsft);
227 } else { 234 } else {
228 struct rtl8180_rx_desc *desc = entry; 235 struct rtl8180_rx_desc *desc = entry;
229 236
230 flags = le32_to_cpu(desc->flags); 237 flags = le32_to_cpu(desc->flags);
238 /* same as above */
239 rmb();
231 flags2 = le32_to_cpu(desc->flags2); 240 flags2 = le32_to_cpu(desc->flags2);
232 tsft = le64_to_cpu(desc->tsft); 241 tsft = le64_to_cpu(desc->tsft);
233 } 242 }
@@ -266,18 +275,21 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
266 rx_status.rate_idx = (flags >> 20) & 0xF; 275 rx_status.rate_idx = (flags >> 20) & 0xF;
267 agc = (flags2 >> 17) & 0x7F; 276 agc = (flags2 >> 17) & 0x7F;
268 277
269 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) { 278 switch (priv->chip_family) {
279 case RTL818X_CHIP_FAMILY_RTL8185:
270 if (rx_status.rate_idx > 3) 280 if (rx_status.rate_idx > 3)
271 signal = 90 - clamp_t(u8, agc, 25, 90); 281 signal = -clamp_t(u8, agc, 25, 90) - 9;
272 else 282 else
273 signal = 95 - clamp_t(u8, agc, 30, 95); 283 signal = -clamp_t(u8, agc, 30, 95);
274 } else if (priv->chip_family == 284 break;
275 RTL818X_CHIP_FAMILY_RTL8180) { 285 case RTL818X_CHIP_FAMILY_RTL8180:
276 sq = flags2 & 0xff; 286 sq = flags2 & 0xff;
277 signal = priv->rf->calc_rssi(agc, sq); 287 signal = priv->rf->calc_rssi(agc, sq);
278 } else { 288 break;
289 case RTL818X_CHIP_FAMILY_RTL8187SE:
279 /* TODO: rtl8187se rssi */ 290 /* TODO: rtl8187se rssi */
280 signal = 10; 291 signal = 10;
292 break;
281 } 293 }
282 rx_status.signal = signal; 294 rx_status.signal = signal;
283 rx_status.freq = dev->conf.chandef.chan->center_freq; 295 rx_status.freq = dev->conf.chandef.chan->center_freq;
@@ -336,7 +348,6 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
336 info->flags |= IEEE80211_TX_STAT_ACK; 348 info->flags |= IEEE80211_TX_STAT_ACK;
337 349
338 info->status.rates[0].count = (flags & 0xFF) + 1; 350 info->status.rates[0].count = (flags & 0xFF) + 1;
339 info->status.rates[1].idx = -1;
340 351
341 ieee80211_tx_status_irqsafe(dev, skb); 352 ieee80211_tx_status_irqsafe(dev, skb);
342 if (ring->entries - skb_queue_len(&ring->queue) == 2) 353 if (ring->entries - skb_queue_len(&ring->queue) == 2)
@@ -528,9 +539,7 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
528 entry->plcp_len = cpu_to_le16(plcp_len); 539 entry->plcp_len = cpu_to_le16(plcp_len);
529 entry->tx_buf = cpu_to_le32(mapping); 540 entry->tx_buf = cpu_to_le32(mapping);
530 541
531 entry->flags2 = info->control.rates[1].idx >= 0 ? 542 entry->retry_limit = info->control.rates[0].count - 1;
532 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
533 entry->retry_limit = info->control.rates[0].count;
534 543
535 /* We must be sure that tx_flags is written last because the HW 544 /* We must be sure that tx_flags is written last because the HW
536 * looks at it to check if the rest of data is valid or not 545 * looks at it to check if the rest of data is valid or not
@@ -852,7 +861,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
852 861
853 if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) { 862 if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
854 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); 863 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
855 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); 864 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
856 } else { 865 } else {
857 rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); 866 rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
858 867
@@ -868,6 +877,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
868 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 877 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
869 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); 878 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
870 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 879 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
880 /* fix eccessive IFS after CTS-to-self */
881 if (priv->map_pio) {
882 u8 reg;
883
884 reg = rtl818x_ioread8(priv, &priv->map->PGSELECT);
885 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
886 rtl818x_iowrite8(priv, REG_ADDR1(0xff), 0x35);
887 rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
888 } else
889 rtl818x_iowrite8(priv, REG_ADDR1(0x1ff), 0x35);
871 } 890 }
872 891
873 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) { 892 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
@@ -1450,9 +1469,10 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
1450 vif_priv = (struct rtl8180_vif *)&vif->drv_priv; 1469 vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
1451 1470
1452 if (changed & BSS_CHANGED_BSSID) { 1471 if (changed & BSS_CHANGED_BSSID) {
1453 for (i = 0; i < ETH_ALEN; i++) 1472 rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->BSSID[0],
1454 rtl818x_iowrite8(priv, &priv->map->BSSID[i], 1473 le16_to_cpu(*(__le16 *)info->bssid));
1455 info->bssid[i]); 1474 rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->BSSID[2],
1475 le32_to_cpu(*(__le32 *)(info->bssid + 2)));
1456 1476
1457 if (is_valid_ether_addr(info->bssid)) { 1477 if (is_valid_ether_addr(info->bssid)) {
1458 if (vif->type == NL80211_IFTYPE_ADHOC) 1478 if (vif->type == NL80211_IFTYPE_ADHOC)
@@ -1723,17 +1743,20 @@ static int rtl8180_probe(struct pci_dev *pdev,
1723 priv = dev->priv; 1743 priv = dev->priv;
1724 priv->pdev = pdev; 1744 priv->pdev = pdev;
1725 1745
1726 dev->max_rates = 2; 1746 dev->max_rates = 1;
1727 SET_IEEE80211_DEV(dev, &pdev->dev); 1747 SET_IEEE80211_DEV(dev, &pdev->dev);
1728 pci_set_drvdata(pdev, dev); 1748 pci_set_drvdata(pdev, dev);
1729 1749
1750 priv->map_pio = false;
1730 priv->map = pci_iomap(pdev, 1, mem_len); 1751 priv->map = pci_iomap(pdev, 1, mem_len);
1731 if (!priv->map) 1752 if (!priv->map) {
1732 priv->map = pci_iomap(pdev, 0, io_len); 1753 priv->map = pci_iomap(pdev, 0, io_len);
1754 priv->map_pio = true;
1755 }
1733 1756
1734 if (!priv->map) { 1757 if (!priv->map) {
1735 printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n", 1758 dev_err(&pdev->dev, "Cannot map device memory/PIO\n");
1736 pci_name(pdev)); 1759 err = -ENOMEM;
1737 goto err_free_dev; 1760 goto err_free_dev;
1738 } 1761 }
1739 1762
@@ -1751,8 +1774,7 @@ static int rtl8180_probe(struct pci_dev *pdev,
1751 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; 1774 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
1752 1775
1753 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 1776 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1754 IEEE80211_HW_RX_INCLUDES_FCS | 1777 IEEE80211_HW_RX_INCLUDES_FCS;
1755 IEEE80211_HW_SIGNAL_UNSPEC;
1756 dev->vif_data_size = sizeof(struct rtl8180_vif); 1778 dev->vif_data_size = sizeof(struct rtl8180_vif);
1757 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 1779 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1758 BIT(NL80211_IFTYPE_ADHOC); 1780 BIT(NL80211_IFTYPE_ADHOC);
@@ -1783,12 +1805,19 @@ static int rtl8180_probe(struct pci_dev *pdev,
1783 1805
1784 case RTL818X_TX_CONF_RTL8187SE: 1806 case RTL818X_TX_CONF_RTL8187SE:
1785 chip_name = "RTL8187SE"; 1807 chip_name = "RTL8187SE";
1808 if (priv->map_pio) {
1809 dev_err(&pdev->dev,
1810 "MMIO failed. PIO not supported on RTL8187SE\n");
1811 err = -ENOMEM;
1812 goto err_iounmap;
1813 }
1786 priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE; 1814 priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE;
1787 break; 1815 break;
1788 1816
1789 default: 1817 default:
1790 printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", 1818 printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
1791 pci_name(pdev), reg >> 25); 1819 pci_name(pdev), reg >> 25);
1820 err = -ENODEV;
1792 goto err_iounmap; 1821 goto err_iounmap;
1793 } 1822 }
1794 1823
@@ -1809,6 +1838,11 @@ static int rtl8180_probe(struct pci_dev *pdev,
1809 pci_try_set_mwi(pdev); 1838 pci_try_set_mwi(pdev);
1810 } 1839 }
1811 1840
1841 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185)
1842 dev->flags |= IEEE80211_HW_SIGNAL_DBM;
1843 else
1844 dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;
1845
1812 rtl8180_eeprom_read(priv); 1846 rtl8180_eeprom_read(priv);
1813 1847
1814 switch (priv->rf_type) { 1848 switch (priv->rf_type) {
@@ -1834,12 +1868,14 @@ static int rtl8180_probe(struct pci_dev *pdev,
1834 default: 1868 default:
1835 printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", 1869 printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
1836 pci_name(pdev), priv->rf_type); 1870 pci_name(pdev), priv->rf_type);
1871 err = -ENODEV;
1837 goto err_iounmap; 1872 goto err_iounmap;
1838 } 1873 }
1839 1874
1840 if (!priv->rf) { 1875 if (!priv->rf) {
1841 printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n", 1876 printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
1842 pci_name(pdev), rf_name); 1877 pci_name(pdev), rf_name);
1878 err = -ENODEV;
1843 goto err_iounmap; 1879 goto err_iounmap;
1844 } 1880 }
1845 1881
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
index 291a55970d1a..e8243a44d6b6 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
@@ -107,6 +107,7 @@ struct rtl8180_priv {
107 struct ieee80211_vif *vif; 107 struct ieee80211_vif *vif;
108 108
109 /* rtl8180 driver specific */ 109 /* rtl8180 driver specific */
110 bool map_pio;
110 spinlock_t lock; 111 spinlock_t lock;
111 void *rx_ring; 112 void *rx_ring;
112 u8 rx_ring_sz; 113 u8 rx_ring_sz;
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
index 871fc3c6d559..049f4c8d98a8 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -114,7 +114,7 @@ extern u32 btc_dbg_type[];
114 114
115 115
116#define CL_SPRINTF snprintf 116#define CL_SPRINTF snprintf
117#define CL_PRINTF printk 117#define CL_PRINTF(buf) printk("%s", buf)
118 118
119#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \ 119#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
120 do { \ 120 do { \
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index b14cf5a10f44..d840ad7bdf65 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -1231,7 +1231,7 @@ static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
1231 1231
1232 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1232 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1233 rtlpriv->cfg->ops->led_control(hw, ledaction); 1233 rtlpriv->cfg->ops->led_control(hw, ledaction);
1234 if ((bt_msr & 0xfc) == MSR_AP) 1234 if ((bt_msr & MSR_MASK) == MSR_AP)
1235 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1235 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1236 else 1236 else
1237 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1237 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
index 7af85cfa8f87..cd7e7a527133 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/reg.h
@@ -411,6 +411,7 @@
411#define MSR_ADHOC 0x01 411#define MSR_ADHOC 0x01
412#define MSR_INFRA 0x02 412#define MSR_INFRA 0x02
413#define MSR_AP 0x03 413#define MSR_AP 0x03
414#define MSR_MASK 0x03
414 415
415#define RRSR_RSC_OFFSET 21 416#define RRSR_RSC_OFFSET 21
416#define RRSR_SHORT_OFFSET 23 417#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
index cdecb0fd4d8e..e2736929b5d0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -1206,7 +1206,7 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw,
1206 1206
1207 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1207 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1208 rtlpriv->cfg->ops->led_control(hw, ledaction); 1208 rtlpriv->cfg->ops->led_control(hw, ledaction);
1209 if ((bt_msr & 0xfc) == MSR_AP) 1209 if ((bt_msr & MSR_MASK) == MSR_AP)
1210 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1210 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1211 else 1211 else
1212 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1212 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
index ed703a1b3b7c..dc8460c0b32f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
@@ -375,6 +375,7 @@
375#define MSR_ADHOC 0x01 375#define MSR_ADHOC 0x01
376#define MSR_INFRA 0x02 376#define MSR_INFRA 0x02
377#define MSR_AP 0x03 377#define MSR_AP 0x03
378#define MSR_MASK 0x03
378 379
379#define RRSR_RSC_OFFSET 21 380#define RRSR_RSC_OFFSET 21
380#define RRSR_SHORT_OFFSET 23 381#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index a903c2671b4d..270cbffcac70 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1360,7 +1360,7 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
1360 } 1360 }
1361 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1361 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1362 rtlpriv->cfg->ops->led_control(hw, ledaction); 1362 rtlpriv->cfg->ops->led_control(hw, ledaction);
1363 if ((bt_msr & 0xfc) == MSR_AP) 1363 if ((bt_msr & MSR_MASK) == MSR_AP)
1364 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1364 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1365 else 1365 else
1366 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1366 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 2b08671004a0..280c3da42993 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1128,7 +1128,7 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
1128 } 1128 }
1129 rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr); 1129 rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr);
1130 rtlpriv->cfg->ops->led_control(hw, ledaction); 1130 rtlpriv->cfg->ops->led_control(hw, ledaction);
1131 if ((bt_msr & 0xfc) == MSR_AP) 1131 if ((bt_msr & MSR_MASK) == MSR_AP)
1132 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1132 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1133 else 1133 else
1134 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1134 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 3d1f0dd4e52d..592125a5f19c 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -203,11 +203,12 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
203 struct rtl_priv *rtlpriv = rtl_priv(hw); 203 struct rtl_priv *rtlpriv = rtl_priv(hw);
204 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 204 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
205 u32 returnvalue, originalvalue, bitshift; 205 u32 returnvalue, originalvalue, bitshift;
206 u8 dbi_direct;
207 206
208 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", 207 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
209 regaddr, bitmask); 208 regaddr, bitmask);
210 if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { 209 if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) {
210 u8 dbi_direct = 0;
211
211 /* mac1 use phy0 read radio_b. */ 212 /* mac1 use phy0 read radio_b. */
212 /* mac0 use phy1 read radio_b. */ 213 /* mac0 use phy1 read radio_b. */
213 if (rtlhal->during_mac1init_radioa) 214 if (rtlhal->during_mac1init_radioa)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
index 7f29b8d765b3..315a298bab06 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h
@@ -369,6 +369,7 @@
369#define MSR_ADHOC 0x01 369#define MSR_ADHOC 0x01
370#define MSR_INFRA 0x02 370#define MSR_INFRA 0x02
371#define MSR_AP 0x03 371#define MSR_AP 0x03
372#define MSR_MASK 0x03
372 373
373/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */ 374/* 6. Adaptive Control Registers (Offset: 0x0160 - 0x01CF) */
374/* ----------------------------------------------------- */ 375/* ----------------------------------------------------- */
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index 87f69166a7ed..539e53987372 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -1109,7 +1109,7 @@ static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw,
1109 1109
1110 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1110 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1111 rtlpriv->cfg->ops->led_control(hw, ledaction); 1111 rtlpriv->cfg->ops->led_control(hw, ledaction);
1112 if ((bt_msr & 0x03) == MSR_AP) 1112 if ((bt_msr & MSR_MASK) == MSR_AP)
1113 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1113 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1114 else 1114 else
1115 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1115 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
index 64376b38708b..ce2c66fd9eee 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h
@@ -361,6 +361,7 @@
361#define MSR_ADHOC 0x01 361#define MSR_ADHOC 0x01
362#define MSR_INFRA 0x02 362#define MSR_INFRA 0x02
363#define MSR_AP 0x03 363#define MSR_AP 0x03
364#define MSR_MASK 0x03
364 365
365#define RRSR_RSC_OFFSET 21 366#define RRSR_RSC_OFFSET 21
366#define RRSR_SHORT_OFFSET 23 367#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
index 3d555495b453..3cd286930fe0 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -1197,7 +1197,7 @@ static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1197 } 1197 }
1198 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1198 rtl_write_byte(rtlpriv, (MSR), bt_msr);
1199 rtlpriv->cfg->ops->led_control(hw, ledaction); 1199 rtlpriv->cfg->ops->led_control(hw, ledaction);
1200 if ((bt_msr & 0x03) == MSR_AP) 1200 if ((bt_msr & MSR_MASK) == MSR_AP)
1201 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1201 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1202 else 1202 else
1203 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 1203 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
index 4c653fab8795..3006849ed439 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/reg.h
@@ -412,6 +412,7 @@
412#define MSR_ADHOC 0x01 412#define MSR_ADHOC 0x01
413#define MSR_INFRA 0x02 413#define MSR_INFRA 0x02
414#define MSR_AP 0x03 414#define MSR_AP 0x03
415#define MSR_MASK 0x03
415 416
416#define RRSR_RSC_OFFSET 21 417#define RRSR_RSC_OFFSET 21
417#define RRSR_SHORT_OFFSET 23 418#define RRSR_SHORT_OFFSET 23
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 4e782f18ae34..38234851457e 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -991,8 +991,9 @@ out:
991 991
992static int wl1251_op_hw_scan(struct ieee80211_hw *hw, 992static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
993 struct ieee80211_vif *vif, 993 struct ieee80211_vif *vif,
994 struct cfg80211_scan_request *req) 994 struct ieee80211_scan_request *hw_req)
995{ 995{
996 struct cfg80211_scan_request *req = &hw_req->req;
996 struct wl1251 *wl = hw->priv; 997 struct wl1251 *wl = hw->priv;
997 struct sk_buff *skb; 998 struct sk_buff *skb;
998 size_t ssid_len = 0; 999 size_t ssid_len = 0;
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index 7541bd1a4a4b..0c0d5cd98514 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -156,7 +156,7 @@ static int wl1271_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
156 cmd->params.role_id, band, 156 cmd->params.role_id, band,
157 wl->scan.ssid, wl->scan.ssid_len, 157 wl->scan.ssid, wl->scan.ssid_len,
158 wl->scan.req->ie, 158 wl->scan.req->ie,
159 wl->scan.req->ie_len, false); 159 wl->scan.req->ie_len, NULL, 0, false);
160 if (ret < 0) { 160 if (ret < 0) {
161 wl1271_error("PROBE request template failed"); 161 wl1271_error("PROBE request template failed");
162 goto out; 162 goto out;
@@ -317,7 +317,7 @@ static void wl12xx_adjust_channels(struct wl1271_cmd_sched_scan_config *cmd,
317int wl1271_scan_sched_scan_config(struct wl1271 *wl, 317int wl1271_scan_sched_scan_config(struct wl1271 *wl,
318 struct wl12xx_vif *wlvif, 318 struct wl12xx_vif *wlvif,
319 struct cfg80211_sched_scan_request *req, 319 struct cfg80211_sched_scan_request *req,
320 struct ieee80211_sched_scan_ies *ies) 320 struct ieee80211_scan_ies *ies)
321{ 321{
322 struct wl1271_cmd_sched_scan_config *cfg = NULL; 322 struct wl1271_cmd_sched_scan_config *cfg = NULL;
323 struct wlcore_scan_channels *cfg_channels = NULL; 323 struct wlcore_scan_channels *cfg_channels = NULL;
@@ -378,8 +378,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
378 wlvif->role_id, band, 378 wlvif->role_id, band,
379 req->ssids[0].ssid, 379 req->ssids[0].ssid,
380 req->ssids[0].ssid_len, 380 req->ssids[0].ssid_len,
381 ies->ie[band], 381 ies->ies[band],
382 ies->len[band], true); 382 ies->len[band],
383 ies->common_ies,
384 ies->common_ie_len,
385 true);
383 if (ret < 0) { 386 if (ret < 0) {
384 wl1271_error("2.4GHz PROBE request template failed"); 387 wl1271_error("2.4GHz PROBE request template failed");
385 goto out; 388 goto out;
@@ -392,8 +395,11 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
392 wlvif->role_id, band, 395 wlvif->role_id, band,
393 req->ssids[0].ssid, 396 req->ssids[0].ssid,
394 req->ssids[0].ssid_len, 397 req->ssids[0].ssid_len,
395 ies->ie[band], 398 ies->ies[band],
396 ies->len[band], true); 399 ies->len[band],
400 ies->common_ies,
401 ies->common_ie_len,
402 true);
397 if (ret < 0) { 403 if (ret < 0) {
398 wl1271_error("5GHz PROBE request template failed"); 404 wl1271_error("5GHz PROBE request template failed");
399 goto out; 405 goto out;
@@ -449,7 +455,7 @@ out_free:
449 455
450int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 456int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
451 struct cfg80211_sched_scan_request *req, 457 struct cfg80211_sched_scan_request *req,
452 struct ieee80211_sched_scan_ies *ies) 458 struct ieee80211_scan_ies *ies)
453{ 459{
454 int ret; 460 int ret;
455 461
diff --git a/drivers/net/wireless/ti/wl12xx/scan.h b/drivers/net/wireless/ti/wl12xx/scan.h
index 264af7ac2785..427f9af85a00 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.h
+++ b/drivers/net/wireless/ti/wl12xx/scan.h
@@ -135,6 +135,6 @@ int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
135void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif); 135void wl12xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
136int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 136int wl12xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
137 struct cfg80211_sched_scan_request *req, 137 struct cfg80211_sched_scan_request *req,
138 struct ieee80211_sched_scan_ies *ies); 138 struct ieee80211_scan_ies *ies);
139void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); 139void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
140#endif 140#endif
diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c
index 2b642f8c9266..98666f235a12 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.c
+++ b/drivers/net/wireless/ti/wl18xx/scan.c
@@ -113,6 +113,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
113 req->ssids ? req->ssids[0].ssid_len : 0, 113 req->ssids ? req->ssids[0].ssid_len : 0,
114 req->ie, 114 req->ie,
115 req->ie_len, 115 req->ie_len,
116 NULL,
117 0,
116 false); 118 false);
117 if (ret < 0) { 119 if (ret < 0) {
118 wl1271_error("2.4GHz PROBE request template failed"); 120 wl1271_error("2.4GHz PROBE request template failed");
@@ -128,6 +130,8 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif,
128 req->ssids ? req->ssids[0].ssid_len : 0, 130 req->ssids ? req->ssids[0].ssid_len : 0,
129 req->ie, 131 req->ie,
130 req->ie_len, 132 req->ie_len,
133 NULL,
134 0,
131 false); 135 false);
132 if (ret < 0) { 136 if (ret < 0) {
133 wl1271_error("5GHz PROBE request template failed"); 137 wl1271_error("5GHz PROBE request template failed");
@@ -161,7 +165,7 @@ static
161int wl18xx_scan_sched_scan_config(struct wl1271 *wl, 165int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
162 struct wl12xx_vif *wlvif, 166 struct wl12xx_vif *wlvif,
163 struct cfg80211_sched_scan_request *req, 167 struct cfg80211_sched_scan_request *req,
164 struct ieee80211_sched_scan_ies *ies) 168 struct ieee80211_scan_ies *ies)
165{ 169{
166 struct wl18xx_cmd_scan_params *cmd; 170 struct wl18xx_cmd_scan_params *cmd;
167 struct wlcore_scan_channels *cmd_channels = NULL; 171 struct wlcore_scan_channels *cmd_channels = NULL;
@@ -237,8 +241,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
237 cmd->role_id, band, 241 cmd->role_id, band,
238 req->ssids ? req->ssids[0].ssid : NULL, 242 req->ssids ? req->ssids[0].ssid : NULL,
239 req->ssids ? req->ssids[0].ssid_len : 0, 243 req->ssids ? req->ssids[0].ssid_len : 0,
240 ies->ie[band], 244 ies->ies[band],
241 ies->len[band], 245 ies->len[band],
246 ies->common_ies,
247 ies->common_ie_len,
242 true); 248 true);
243 if (ret < 0) { 249 if (ret < 0) {
244 wl1271_error("2.4GHz PROBE request template failed"); 250 wl1271_error("2.4GHz PROBE request template failed");
@@ -252,8 +258,10 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl,
252 cmd->role_id, band, 258 cmd->role_id, band,
253 req->ssids ? req->ssids[0].ssid : NULL, 259 req->ssids ? req->ssids[0].ssid : NULL,
254 req->ssids ? req->ssids[0].ssid_len : 0, 260 req->ssids ? req->ssids[0].ssid_len : 0,
255 ies->ie[band], 261 ies->ies[band],
256 ies->len[band], 262 ies->len[band],
263 ies->common_ies,
264 ies->common_ie_len,
257 true); 265 true);
258 if (ret < 0) { 266 if (ret < 0) {
259 wl1271_error("5GHz PROBE request template failed"); 267 wl1271_error("5GHz PROBE request template failed");
@@ -277,7 +285,7 @@ out:
277 285
278int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 286int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
279 struct cfg80211_sched_scan_request *req, 287 struct cfg80211_sched_scan_request *req,
280 struct ieee80211_sched_scan_ies *ies) 288 struct ieee80211_scan_ies *ies)
281{ 289{
282 return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies); 290 return wl18xx_scan_sched_scan_config(wl, wlvif, req, ies);
283} 291}
diff --git a/drivers/net/wireless/ti/wl18xx/scan.h b/drivers/net/wireless/ti/wl18xx/scan.h
index eadee42689d1..2e636aa5dba9 100644
--- a/drivers/net/wireless/ti/wl18xx/scan.h
+++ b/drivers/net/wireless/ti/wl18xx/scan.h
@@ -122,6 +122,6 @@ int wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
122void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif); 122void wl18xx_scan_completed(struct wl1271 *wl, struct wl12xx_vif *wlvif);
123int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif, 123int wl18xx_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif,
124 struct cfg80211_sched_scan_request *req, 124 struct cfg80211_sched_scan_request *req,
125 struct ieee80211_sched_scan_ies *ies); 125 struct ieee80211_scan_ies *ies);
126void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif); 126void wl18xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif);
127#endif 127#endif
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 40dc30f4faaa..e269c0a57017 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1124,7 +1124,8 @@ out:
1124int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, 1124int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1125 u8 role_id, u8 band, 1125 u8 role_id, u8 band,
1126 const u8 *ssid, size_t ssid_len, 1126 const u8 *ssid, size_t ssid_len,
1127 const u8 *ie, size_t ie_len, bool sched_scan) 1127 const u8 *ie0, size_t ie0_len, const u8 *ie1,
1128 size_t ie1_len, bool sched_scan)
1128{ 1129{
1129 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); 1130 struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1130 struct sk_buff *skb; 1131 struct sk_buff *skb;
@@ -1136,13 +1137,15 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1136 wl1271_debug(DEBUG_SCAN, "build probe request band %d", band); 1137 wl1271_debug(DEBUG_SCAN, "build probe request band %d", band);
1137 1138
1138 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1139 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1139 ie_len); 1140 ie0_len + ie1_len);
1140 if (!skb) { 1141 if (!skb) {
1141 ret = -ENOMEM; 1142 ret = -ENOMEM;
1142 goto out; 1143 goto out;
1143 } 1144 }
1144 if (ie_len) 1145 if (ie0_len)
1145 memcpy(skb_put(skb, ie_len), ie, ie_len); 1146 memcpy(skb_put(skb, ie0_len), ie0, ie0_len);
1147 if (ie1_len)
1148 memcpy(skb_put(skb, ie1_len), ie1, ie1_len);
1146 1149
1147 if (sched_scan && 1150 if (sched_scan &&
1148 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { 1151 (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) {
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h
index b084830a61cf..6788d7356ca5 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.h
+++ b/drivers/net/wireless/ti/wlcore/cmd.h
@@ -64,7 +64,8 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
64int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, 64int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
65 u8 role_id, u8 band, 65 u8 role_id, u8 band,
66 const u8 *ssid, size_t ssid_len, 66 const u8 *ssid, size_t ssid_len,
67 const u8 *ie, size_t ie_len, bool sched_scan); 67 const u8 *ie, size_t ie_len, const u8 *common_ie,
68 size_t common_ie_len, bool sched_scan);
68struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, 69struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
69 struct wl12xx_vif *wlvif, 70 struct wl12xx_vif *wlvif,
70 struct sk_buff *skb); 71 struct sk_buff *skb);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 3d6028e62750..48f83868f9cb 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3540,8 +3540,9 @@ out:
3540 3540
3541static int wl1271_op_hw_scan(struct ieee80211_hw *hw, 3541static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
3542 struct ieee80211_vif *vif, 3542 struct ieee80211_vif *vif,
3543 struct cfg80211_scan_request *req) 3543 struct ieee80211_scan_request *hw_req)
3544{ 3544{
3545 struct cfg80211_scan_request *req = &hw_req->req;
3545 struct wl1271 *wl = hw->priv; 3546 struct wl1271 *wl = hw->priv;
3546 int ret; 3547 int ret;
3547 u8 *ssid = NULL; 3548 u8 *ssid = NULL;
@@ -3636,7 +3637,7 @@ out:
3636static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, 3637static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
3637 struct ieee80211_vif *vif, 3638 struct ieee80211_vif *vif,
3638 struct cfg80211_sched_scan_request *req, 3639 struct cfg80211_sched_scan_request *req,
3639 struct ieee80211_sched_scan_ies *ies) 3640 struct ieee80211_scan_ies *ies)
3640{ 3641{
3641 struct wl1271 *wl = hw->priv; 3642 struct wl1271 *wl = hw->priv;
3642 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); 3643 struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
diff --git a/drivers/net/wireless/ti/wlcore/scan.h b/drivers/net/wireless/ti/wlcore/scan.h
index a6ab24b5c0f9..4dadd0c62cde 100644
--- a/drivers/net/wireless/ti/wlcore/scan.h
+++ b/drivers/net/wireless/ti/wlcore/scan.h
@@ -37,7 +37,7 @@ void wl1271_scan_complete_work(struct work_struct *work);
37int wl1271_scan_sched_scan_config(struct wl1271 *wl, 37int wl1271_scan_sched_scan_config(struct wl1271 *wl,
38 struct wl12xx_vif *wlvif, 38 struct wl12xx_vif *wlvif,
39 struct cfg80211_sched_scan_request *req, 39 struct cfg80211_sched_scan_request *req,
40 struct ieee80211_sched_scan_ies *ies); 40 struct ieee80211_scan_ies *ies);
41int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif); 41int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif);
42void wlcore_scan_sched_scan_results(struct wl1271 *wl); 42void wlcore_scan_sched_scan_results(struct wl1271 *wl);
43 43
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 95a54504f0cc..71320509b56d 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -95,7 +95,7 @@ struct wlcore_ops {
95 int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); 95 int (*scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
96 int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif, 96 int (*sched_scan_start)(struct wl1271 *wl, struct wl12xx_vif *wlvif,
97 struct cfg80211_sched_scan_request *req, 97 struct cfg80211_sched_scan_request *req,
98 struct ieee80211_sched_scan_ies *ies); 98 struct ieee80211_scan_ies *ies);
99 void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif); 99 void (*sched_scan_stop)(struct wl1271 *wl, struct wl12xx_vif *wlvif);
100 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem); 100 int (*get_spare_blocks)(struct wl1271 *wl, bool is_gem);
101 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd, 101 int (*set_key)(struct wl1271 *wl, enum set_key_cmd cmd,
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 0b3bb16c705a..452286a38b2b 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/bcma/bcma_driver_chipcommon.h> 7#include <linux/bcma/bcma_driver_chipcommon.h>
8#include <linux/bcma/bcma_driver_pci.h> 8#include <linux/bcma/bcma_driver_pci.h>
9#include <linux/bcma/bcma_driver_pcie2.h>
9#include <linux/bcma/bcma_driver_mips.h> 10#include <linux/bcma/bcma_driver_mips.h>
10#include <linux/bcma/bcma_driver_gmac_cmn.h> 11#include <linux/bcma/bcma_driver_gmac_cmn.h>
11#include <linux/ssb/ssb.h> /* SPROM sharing */ 12#include <linux/ssb/ssb.h> /* SPROM sharing */
@@ -333,6 +334,7 @@ struct bcma_bus {
333 334
334 struct bcma_drv_cc drv_cc; 335 struct bcma_drv_cc drv_cc;
335 struct bcma_drv_pci drv_pci[2]; 336 struct bcma_drv_pci drv_pci[2];
337 struct bcma_drv_pcie2 drv_pcie2;
336 struct bcma_drv_mips drv_mips; 338 struct bcma_drv_mips drv_mips;
337 struct bcma_drv_gmac_cmn drv_gmac_cmn; 339 struct bcma_drv_gmac_cmn drv_gmac_cmn;
338 340
diff --git a/include/linux/bcma/bcma_driver_pcie2.h b/include/linux/bcma/bcma_driver_pcie2.h
new file mode 100644
index 000000000000..5988b05781c3
--- /dev/null
+++ b/include/linux/bcma/bcma_driver_pcie2.h
@@ -0,0 +1,158 @@
1#ifndef LINUX_BCMA_DRIVER_PCIE2_H_
2#define LINUX_BCMA_DRIVER_PCIE2_H_
3
4#define BCMA_CORE_PCIE2_CLK_CONTROL 0x0000
5#define PCIE2_CLKC_RST_OE 0x0001 /* When set, drives PCI_RESET out to pin */
6#define PCIE2_CLKC_RST 0x0002 /* Value driven out to pin */
7#define PCIE2_CLKC_SPERST 0x0004 /* SurvivePeRst */
8#define PCIE2_CLKC_DISABLE_L1CLK_GATING 0x0010
9#define PCIE2_CLKC_DLYPERST 0x0100 /* Delay PeRst to CoE Core */
10#define PCIE2_CLKC_DISSPROMLD 0x0200 /* DisableSpromLoadOnPerst */
11#define PCIE2_CLKC_WAKE_MODE_L2 0x1000 /* Wake on L2 */
12#define BCMA_CORE_PCIE2_RC_PM_CONTROL 0x0004
13#define BCMA_CORE_PCIE2_RC_PM_STATUS 0x0008
14#define BCMA_CORE_PCIE2_EP_PM_CONTROL 0x000C
15#define BCMA_CORE_PCIE2_EP_PM_STATUS 0x0010
16#define BCMA_CORE_PCIE2_EP_LTR_CONTROL 0x0014
17#define BCMA_CORE_PCIE2_EP_LTR_STATUS 0x0018
18#define BCMA_CORE_PCIE2_EP_OBFF_STATUS 0x001C
19#define BCMA_CORE_PCIE2_PCIE_ERR_STATUS 0x0020
20#define BCMA_CORE_PCIE2_RC_AXI_CONFIG 0x0100
21#define BCMA_CORE_PCIE2_EP_AXI_CONFIG 0x0104
22#define BCMA_CORE_PCIE2_RXDEBUG_STATUS0 0x0108
23#define BCMA_CORE_PCIE2_RXDEBUG_CONTROL0 0x010C
24#define BCMA_CORE_PCIE2_CONFIGINDADDR 0x0120
25#define BCMA_CORE_PCIE2_CONFIGINDDATA 0x0124
26#define BCMA_CORE_PCIE2_MDIOCONTROL 0x0128
27#define BCMA_CORE_PCIE2_MDIOWRDATA 0x012C
28#define BCMA_CORE_PCIE2_MDIORDDATA 0x0130
29#define BCMA_CORE_PCIE2_DATAINTF 0x0180
30#define BCMA_CORE_PCIE2_D2H_INTRLAZY_0 0x0188
31#define BCMA_CORE_PCIE2_H2D_INTRLAZY_0 0x018c
32#define BCMA_CORE_PCIE2_H2D_INTSTAT_0 0x0190
33#define BCMA_CORE_PCIE2_H2D_INTMASK_0 0x0194
34#define BCMA_CORE_PCIE2_D2H_INTSTAT_0 0x0198
35#define BCMA_CORE_PCIE2_D2H_INTMASK_0 0x019c
36#define BCMA_CORE_PCIE2_LTR_STATE 0x01A0 /* Latency Tolerance Reporting */
37#define PCIE2_LTR_ACTIVE 2
38#define PCIE2_LTR_ACTIVE_IDLE 1
39#define PCIE2_LTR_SLEEP 0
40#define PCIE2_LTR_FINAL_MASK 0x300
41#define PCIE2_LTR_FINAL_SHIFT 8
42#define BCMA_CORE_PCIE2_PWR_INT_STATUS 0x01A4
43#define BCMA_CORE_PCIE2_PWR_INT_MASK 0x01A8
44#define BCMA_CORE_PCIE2_CFG_ADDR 0x01F8
45#define BCMA_CORE_PCIE2_CFG_DATA 0x01FC
46#define BCMA_CORE_PCIE2_SYS_EQ_PAGE 0x0200
47#define BCMA_CORE_PCIE2_SYS_MSI_PAGE 0x0204
48#define BCMA_CORE_PCIE2_SYS_MSI_INTREN 0x0208
49#define BCMA_CORE_PCIE2_SYS_MSI_CTRL0 0x0210
50#define BCMA_CORE_PCIE2_SYS_MSI_CTRL1 0x0214
51#define BCMA_CORE_PCIE2_SYS_MSI_CTRL2 0x0218
52#define BCMA_CORE_PCIE2_SYS_MSI_CTRL3 0x021C
53#define BCMA_CORE_PCIE2_SYS_MSI_CTRL4 0x0220
54#define BCMA_CORE_PCIE2_SYS_MSI_CTRL5 0x0224
55#define BCMA_CORE_PCIE2_SYS_EQ_HEAD0 0x0250
56#define BCMA_CORE_PCIE2_SYS_EQ_TAIL0 0x0254
57#define BCMA_CORE_PCIE2_SYS_EQ_HEAD1 0x0258
58#define BCMA_CORE_PCIE2_SYS_EQ_TAIL1 0x025C
59#define BCMA_CORE_PCIE2_SYS_EQ_HEAD2 0x0260
60#define BCMA_CORE_PCIE2_SYS_EQ_TAIL2 0x0264
61#define BCMA_CORE_PCIE2_SYS_EQ_HEAD3 0x0268
62#define BCMA_CORE_PCIE2_SYS_EQ_TAIL3 0x026C
63#define BCMA_CORE_PCIE2_SYS_EQ_HEAD4 0x0270
64#define BCMA_CORE_PCIE2_SYS_EQ_TAIL4 0x0274
65#define BCMA_CORE_PCIE2_SYS_EQ_HEAD5 0x0278
66#define BCMA_CORE_PCIE2_SYS_EQ_TAIL5 0x027C
67#define BCMA_CORE_PCIE2_SYS_RC_INTX_EN 0x0330
68#define BCMA_CORE_PCIE2_SYS_RC_INTX_CSR 0x0334
69#define BCMA_CORE_PCIE2_SYS_MSI_REQ 0x0340
70#define BCMA_CORE_PCIE2_SYS_HOST_INTR_EN 0x0344
71#define BCMA_CORE_PCIE2_SYS_HOST_INTR_CSR 0x0348
72#define BCMA_CORE_PCIE2_SYS_HOST_INTR0 0x0350
73#define BCMA_CORE_PCIE2_SYS_HOST_INTR1 0x0354
74#define BCMA_CORE_PCIE2_SYS_HOST_INTR2 0x0358
75#define BCMA_CORE_PCIE2_SYS_HOST_INTR3 0x035C
76#define BCMA_CORE_PCIE2_SYS_EP_INT_EN0 0x0360
77#define BCMA_CORE_PCIE2_SYS_EP_INT_EN1 0x0364
78#define BCMA_CORE_PCIE2_SYS_EP_INT_CSR0 0x0370
79#define BCMA_CORE_PCIE2_SYS_EP_INT_CSR1 0x0374
80#define BCMA_CORE_PCIE2_SPROM(wordoffset) (0x0800 + ((wordoffset) * 2))
81#define BCMA_CORE_PCIE2_FUNC0_IMAP0_0 0x0C00
82#define BCMA_CORE_PCIE2_FUNC0_IMAP0_1 0x0C04
83#define BCMA_CORE_PCIE2_FUNC0_IMAP0_2 0x0C08
84#define BCMA_CORE_PCIE2_FUNC0_IMAP0_3 0x0C0C
85#define BCMA_CORE_PCIE2_FUNC0_IMAP0_4 0x0C10
86#define BCMA_CORE_PCIE2_FUNC0_IMAP0_5 0x0C14
87#define BCMA_CORE_PCIE2_FUNC0_IMAP0_6 0x0C18
88#define BCMA_CORE_PCIE2_FUNC0_IMAP0_7 0x0C1C
89#define BCMA_CORE_PCIE2_FUNC1_IMAP0_0 0x0C20
90#define BCMA_CORE_PCIE2_FUNC1_IMAP0_1 0x0C24
91#define BCMA_CORE_PCIE2_FUNC1_IMAP0_2 0x0C28
92#define BCMA_CORE_PCIE2_FUNC1_IMAP0_3 0x0C2C
93#define BCMA_CORE_PCIE2_FUNC1_IMAP0_4 0x0C30
94#define BCMA_CORE_PCIE2_FUNC1_IMAP0_5 0x0C34
95#define BCMA_CORE_PCIE2_FUNC1_IMAP0_6 0x0C38
96#define BCMA_CORE_PCIE2_FUNC1_IMAP0_7 0x0C3C
97#define BCMA_CORE_PCIE2_FUNC0_IMAP1 0x0C80
98#define BCMA_CORE_PCIE2_FUNC1_IMAP1 0x0C88
99#define BCMA_CORE_PCIE2_FUNC0_IMAP2 0x0CC0
100#define BCMA_CORE_PCIE2_FUNC1_IMAP2 0x0CC8
101#define BCMA_CORE_PCIE2_IARR0_LOWER 0x0D00
102#define BCMA_CORE_PCIE2_IARR0_UPPER 0x0D04
103#define BCMA_CORE_PCIE2_IARR1_LOWER 0x0D08
104#define BCMA_CORE_PCIE2_IARR1_UPPER 0x0D0C
105#define BCMA_CORE_PCIE2_IARR2_LOWER 0x0D10
106#define BCMA_CORE_PCIE2_IARR2_UPPER 0x0D14
107#define BCMA_CORE_PCIE2_OARR0 0x0D20
108#define BCMA_CORE_PCIE2_OARR1 0x0D28
109#define BCMA_CORE_PCIE2_OARR2 0x0D30
110#define BCMA_CORE_PCIE2_OMAP0_LOWER 0x0D40
111#define BCMA_CORE_PCIE2_OMAP0_UPPER 0x0D44
112#define BCMA_CORE_PCIE2_OMAP1_LOWER 0x0D48
113#define BCMA_CORE_PCIE2_OMAP1_UPPER 0x0D4C
114#define BCMA_CORE_PCIE2_OMAP2_LOWER 0x0D50
115#define BCMA_CORE_PCIE2_OMAP2_UPPER 0x0D54
116#define BCMA_CORE_PCIE2_FUNC1_IARR1_SIZE 0x0D58
117#define BCMA_CORE_PCIE2_FUNC1_IARR2_SIZE 0x0D5C
118#define BCMA_CORE_PCIE2_MEM_CONTROL 0x0F00
119#define BCMA_CORE_PCIE2_MEM_ECC_ERRLOG0 0x0F04
120#define BCMA_CORE_PCIE2_MEM_ECC_ERRLOG1 0x0F08
121#define BCMA_CORE_PCIE2_LINK_STATUS 0x0F0C
122#define BCMA_CORE_PCIE2_STRAP_STATUS 0x0F10
123#define BCMA_CORE_PCIE2_RESET_STATUS 0x0F14
124#define BCMA_CORE_PCIE2_RESETEN_IN_LINKDOWN 0x0F18
125#define BCMA_CORE_PCIE2_MISC_INTR_EN 0x0F1C
126#define BCMA_CORE_PCIE2_TX_DEBUG_CFG 0x0F20
127#define BCMA_CORE_PCIE2_MISC_CONFIG 0x0F24
128#define BCMA_CORE_PCIE2_MISC_STATUS 0x0F28
129#define BCMA_CORE_PCIE2_INTR_EN 0x0F30
130#define BCMA_CORE_PCIE2_INTR_CLEAR 0x0F34
131#define BCMA_CORE_PCIE2_INTR_STATUS 0x0F38
132
133/* PCIE gen2 config regs */
134#define PCIE2_INTSTATUS 0x090
135#define PCIE2_INTMASK 0x094
136#define PCIE2_SBMBX 0x098
137
138#define PCIE2_PMCR_REFUP 0x1814 /* Trefup time */
139
140#define PCIE2_CAP_DEVSTSCTRL2_OFFSET 0xD4
141#define PCIE2_CAP_DEVSTSCTRL2_LTRENAB 0x400
142#define PCIE2_PVT_REG_PM_CLK_PERIOD 0x184c
143
144struct bcma_drv_pcie2 {
145 struct bcma_device *core;
146};
147
148#define pcie2_read16(pcie2, offset) bcma_read16((pcie2)->core, offset)
149#define pcie2_read32(pcie2, offset) bcma_read32((pcie2)->core, offset)
150#define pcie2_write16(pcie2, offset, val) bcma_write16((pcie2)->core, offset, val)
151#define pcie2_write32(pcie2, offset, val) bcma_write32((pcie2)->core, offset, val)
152
153#define pcie2_set32(pcie2, offset, set) bcma_set32((pcie2)->core, offset, set)
154#define pcie2_mask32(pcie2, offset, mask) bcma_mask32((pcie2)->core, offset, mask)
155
156void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2);
157
158#endif /* LINUX_BCMA_DRIVER_PCIE2_H_ */
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 6bff13f74050..75d17e15da33 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1621,6 +1621,9 @@ enum ieee80211_reasoncode {
1621 WLAN_REASON_INVALID_RSN_IE_CAP = 22, 1621 WLAN_REASON_INVALID_RSN_IE_CAP = 22,
1622 WLAN_REASON_IEEE8021X_FAILED = 23, 1622 WLAN_REASON_IEEE8021X_FAILED = 23,
1623 WLAN_REASON_CIPHER_SUITE_REJECTED = 24, 1623 WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
1624 /* TDLS (802.11z) */
1625 WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE = 25,
1626 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED = 26,
1624 /* 802.11e */ 1627 /* 802.11e */
1625 WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32, 1628 WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32,
1626 WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33, 1629 WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e46c437944f7..0a080c4de275 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2266,10 +2266,6 @@ struct cfg80211_qos_map {
2266 * 2266 *
2267 * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). 2267 * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
2268 * 2268 *
2269 * @set_ringparam: Set tx and rx ring sizes.
2270 *
2271 * @get_ringparam: Get tx and rx ring current and maximum sizes.
2272 *
2273 * @tdls_mgmt: Transmit a TDLS management frame. 2269 * @tdls_mgmt: Transmit a TDLS management frame.
2274 * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). 2270 * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup).
2275 * 2271 *
@@ -2278,16 +2274,6 @@ struct cfg80211_qos_map {
2278 * 2274 *
2279 * @set_noack_map: Set the NoAck Map for the TIDs. 2275 * @set_noack_map: Set the NoAck Map for the TIDs.
2280 * 2276 *
2281 * @get_et_sset_count: Ethtool API to get string-set count.
2282 * See @ethtool_ops.get_sset_count
2283 *
2284 * @get_et_stats: Ethtool API to get a set of u64 stats.
2285 * See @ethtool_ops.get_ethtool_stats
2286 *
2287 * @get_et_strings: Ethtool API to get a set of strings to describe stats
2288 * and perhaps other supported types of ethtool data-sets.
2289 * See @ethtool_ops.get_strings
2290 *
2291 * @get_channel: Get the current operating channel for the virtual interface. 2277 * @get_channel: Get the current operating channel for the virtual interface.
2292 * For monitor interfaces, it should return %NULL unless there's a single 2278 * For monitor interfaces, it should return %NULL unless there's a single
2293 * current monitoring channel. 2279 * current monitoring channel.
@@ -2315,7 +2301,12 @@ struct cfg80211_qos_map {
2315 * reliability. This operation can not fail. 2301 * reliability. This operation can not fail.
2316 * @set_coalesce: Set coalesce parameters. 2302 * @set_coalesce: Set coalesce parameters.
2317 * 2303 *
2318 * @channel_switch: initiate channel-switch procedure (with CSA) 2304 * @channel_switch: initiate channel-switch procedure (with CSA). Driver is
2305 * responsible for veryfing if the switch is possible. Since this is
2306 * inherently tricky driver may decide to disconnect an interface later
2307 * with cfg80211_stop_iface(). This doesn't mean driver can accept
2308 * everything. It should do it's best to verify requests and reject them
2309 * as soon as possible.
2319 * 2310 *
2320 * @set_qos_map: Set QoS mapping information to the driver 2311 * @set_qos_map: Set QoS mapping information to the driver
2321 * 2312 *
@@ -2503,10 +2494,6 @@ struct cfg80211_ops {
2503 int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); 2494 int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
2504 int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); 2495 int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
2505 2496
2506 int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx);
2507 void (*get_ringparam)(struct wiphy *wiphy,
2508 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
2509
2510 int (*sched_scan_start)(struct wiphy *wiphy, 2497 int (*sched_scan_start)(struct wiphy *wiphy,
2511 struct net_device *dev, 2498 struct net_device *dev,
2512 struct cfg80211_sched_scan_request *request); 2499 struct cfg80211_sched_scan_request *request);
@@ -2518,7 +2505,7 @@ struct cfg80211_ops {
2518 int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, 2505 int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
2519 const u8 *peer, u8 action_code, u8 dialog_token, 2506 const u8 *peer, u8 action_code, u8 dialog_token,
2520 u16 status_code, u32 peer_capability, 2507 u16 status_code, u32 peer_capability,
2521 const u8 *buf, size_t len); 2508 bool initiator, const u8 *buf, size_t len);
2522 int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, 2509 int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
2523 const u8 *peer, enum nl80211_tdls_operation oper); 2510 const u8 *peer, enum nl80211_tdls_operation oper);
2524 2511
@@ -2529,13 +2516,6 @@ struct cfg80211_ops {
2529 struct net_device *dev, 2516 struct net_device *dev,
2530 u16 noack_map); 2517 u16 noack_map);
2531 2518
2532 int (*get_et_sset_count)(struct wiphy *wiphy,
2533 struct net_device *dev, int sset);
2534 void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev,
2535 struct ethtool_stats *stats, u64 *data);
2536 void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
2537 u32 sset, u8 *data);
2538
2539 int (*get_channel)(struct wiphy *wiphy, 2519 int (*get_channel)(struct wiphy *wiphy,
2540 struct wireless_dev *wdev, 2520 struct wireless_dev *wdev,
2541 struct cfg80211_chan_def *chandef); 2521 struct cfg80211_chan_def *chandef);
@@ -4843,6 +4823,10 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
4843 */ 4823 */
4844void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy); 4824void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy);
4845 4825
4826
4827/* ethtool helper */
4828void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
4829
4846/* Logging, debugging and troubleshooting/diagnostic helpers. */ 4830/* Logging, debugging and troubleshooting/diagnostic helpers. */
4847 4831
4848/* wiphy_printk helpers, similar to dev_printk */ 4832/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 421b6ecb4b2c..9ce5cb17ed82 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -754,20 +754,25 @@ struct ieee80211_tx_info {
754}; 754};
755 755
756/** 756/**
757 * struct ieee80211_sched_scan_ies - scheduled scan IEs 757 * struct ieee80211_scan_ies - descriptors for different blocks of IEs
758 * 758 *
759 * This structure is used to pass the appropriate IEs to be used in scheduled 759 * This structure is used to point to different blocks of IEs in HW scan
760 * scans for all bands. It contains both the IEs passed from the userspace 760 * and scheduled scan. These blocks contain the IEs passed by userspace
761 * and the ones generated by mac80211. 761 * and the ones generated by mac80211.
762 * 762 *
763 * @ie: array with the IEs for each supported band 763 * @ies: pointers to band specific IEs.
764 * @len: array with the total length of the IEs for each band 764 * @len: lengths of band_specific IEs.
765 * @common_ies: IEs for all bands (especially vendor specific ones)
766 * @common_ie_len: length of the common_ies
765 */ 767 */
766struct ieee80211_sched_scan_ies { 768struct ieee80211_scan_ies {
767 u8 *ie[IEEE80211_NUM_BANDS]; 769 const u8 *ies[IEEE80211_NUM_BANDS];
768 size_t len[IEEE80211_NUM_BANDS]; 770 size_t len[IEEE80211_NUM_BANDS];
771 const u8 *common_ies;
772 size_t common_ie_len;
769}; 773};
770 774
775
771static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb) 776static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
772{ 777{
773 return (struct ieee80211_tx_info *)skb->cb; 778 return (struct ieee80211_tx_info *)skb->cb;
@@ -1601,11 +1606,8 @@ struct ieee80211_tx_control {
1601 * is not enabled the default action is to disconnect when getting the 1606 * is not enabled the default action is to disconnect when getting the
1602 * CSA frame. 1607 * CSA frame.
1603 * 1608 *
1604 * @IEEE80211_HW_CHANGE_RUNNING_CHANCTX: The hardware can change a 1609 * @IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS: The HW supports scanning on all bands
1605 * channel context on-the-fly. This is needed for channel switch 1610 * in one command, mac80211 doesn't have to run separate scans per band.
1606 * on single-channel hardware. It can also be used as an
1607 * optimization in certain channel switch cases with
1608 * multi-channel.
1609 */ 1611 */
1610enum ieee80211_hw_flags { 1612enum ieee80211_hw_flags {
1611 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 1613 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1637,7 +1639,8 @@ enum ieee80211_hw_flags {
1637 IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26, 1639 IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26,
1638 IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27, 1640 IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27,
1639 IEEE80211_HW_CHANCTX_STA_CSA = 1<<28, 1641 IEEE80211_HW_CHANCTX_STA_CSA = 1<<28,
1640 IEEE80211_HW_CHANGE_RUNNING_CHANCTX = 1<<29, 1642 /* bit 29 unused */
1643 IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS = 1<<30,
1641}; 1644};
1642 1645
1643/** 1646/**
@@ -1764,6 +1767,19 @@ struct ieee80211_hw {
1764}; 1767};
1765 1768
1766/** 1769/**
1770 * struct ieee80211_scan_request - hw scan request
1771 *
1772 * @ies: pointers different parts of IEs (in req.ie)
1773 * @req: cfg80211 request.
1774 */
1775struct ieee80211_scan_request {
1776 struct ieee80211_scan_ies ies;
1777
1778 /* Keep last */
1779 struct cfg80211_scan_request req;
1780};
1781
1782/**
1767 * wiphy_to_ieee80211_hw - return a mac80211 driver hw struct from a wiphy 1783 * wiphy_to_ieee80211_hw - return a mac80211 driver hw struct from a wiphy
1768 * 1784 *
1769 * @wiphy: the &struct wiphy which we want to query 1785 * @wiphy: the &struct wiphy which we want to query
@@ -2764,6 +2780,15 @@ enum ieee80211_roc_type {
2764 * mac80211 will transmit the frame right away. 2780 * mac80211 will transmit the frame right away.
2765 * The callback is optional and can (should!) sleep. 2781 * The callback is optional and can (should!) sleep.
2766 * 2782 *
2783 * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending
2784 * a TDLS discovery-request, we expect a reply to arrive on the AP's
2785 * channel. We must stay on the channel (no PSM, scan, etc.), since a TDLS
2786 * setup-response is a direct packet not buffered by the AP.
2787 * mac80211 will call this function just before the transmission of a TDLS
2788 * discovery-request. The recommended period of protection is at least
2789 * 2 * (DTIM period).
2790 * The callback is optional and can sleep.
2791 *
2767 * @add_chanctx: Notifies device driver about new channel context creation. 2792 * @add_chanctx: Notifies device driver about new channel context creation.
2768 * @remove_chanctx: Notifies device driver about channel context destruction. 2793 * @remove_chanctx: Notifies device driver about channel context destruction.
2769 * @change_chanctx: Notifies device driver about channel context changes that 2794 * @change_chanctx: Notifies device driver about channel context changes that
@@ -2865,13 +2890,13 @@ struct ieee80211_ops {
2865 void (*set_default_unicast_key)(struct ieee80211_hw *hw, 2890 void (*set_default_unicast_key)(struct ieee80211_hw *hw,
2866 struct ieee80211_vif *vif, int idx); 2891 struct ieee80211_vif *vif, int idx);
2867 int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2892 int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2868 struct cfg80211_scan_request *req); 2893 struct ieee80211_scan_request *req);
2869 void (*cancel_hw_scan)(struct ieee80211_hw *hw, 2894 void (*cancel_hw_scan)(struct ieee80211_hw *hw,
2870 struct ieee80211_vif *vif); 2895 struct ieee80211_vif *vif);
2871 int (*sched_scan_start)(struct ieee80211_hw *hw, 2896 int (*sched_scan_start)(struct ieee80211_hw *hw,
2872 struct ieee80211_vif *vif, 2897 struct ieee80211_vif *vif,
2873 struct cfg80211_sched_scan_request *req, 2898 struct cfg80211_sched_scan_request *req,
2874 struct ieee80211_sched_scan_ies *ies); 2899 struct ieee80211_scan_ies *ies);
2875 int (*sched_scan_stop)(struct ieee80211_hw *hw, 2900 int (*sched_scan_stop)(struct ieee80211_hw *hw,
2876 struct ieee80211_vif *vif); 2901 struct ieee80211_vif *vif);
2877 void (*sw_scan_start)(struct ieee80211_hw *hw); 2902 void (*sw_scan_start)(struct ieee80211_hw *hw);
@@ -2981,6 +3006,9 @@ struct ieee80211_ops {
2981 void (*mgd_prepare_tx)(struct ieee80211_hw *hw, 3006 void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
2982 struct ieee80211_vif *vif); 3007 struct ieee80211_vif *vif);
2983 3008
3009 void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
3010 struct ieee80211_vif *vif);
3011
2984 int (*add_chanctx)(struct ieee80211_hw *hw, 3012 int (*add_chanctx)(struct ieee80211_hw *hw,
2985 struct ieee80211_chanctx_conf *ctx); 3013 struct ieee80211_chanctx_conf *ctx);
2986 void (*remove_chanctx)(struct ieee80211_hw *hw, 3014 void (*remove_chanctx)(struct ieee80211_hw *hw,
@@ -4815,4 +4843,17 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
4815 */ 4843 */
4816void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf); 4844void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf);
4817 4845
4846/**
4847 * ieee80211_tdls_oper - request userspace to perform a TDLS operation
4848 * @vif: virtual interface
4849 * @peer: the peer's destination address
4850 * @oper: the requested TDLS operation
4851 * @reason_code: reason code for the operation, valid for TDLS teardown
4852 * @gfp: allocation flags
4853 *
4854 * See cfg80211_tdls_oper_request().
4855 */
4856void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
4857 enum nl80211_tdls_operation oper,
4858 u16 reason_code, gfp_t gfp);
4818#endif /* MAC80211_H */ 4859#endif /* MAC80211_H */
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index be9519b52bb1..f1db15b9c041 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1591,6 +1591,9 @@ enum nl80211_commands {
1591 * creation then the new interface will be owned by the netlink socket 1591 * creation then the new interface will be owned by the netlink socket
1592 * that created it and will be destroyed when the socket is closed 1592 * that created it and will be destroyed when the socket is closed
1593 * 1593 *
1594 * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is
1595 * the TDLS link initiator.
1596 *
1594 * @NL80211_ATTR_MAX: highest attribute number currently defined 1597 * @NL80211_ATTR_MAX: highest attribute number currently defined
1595 * @__NL80211_ATTR_AFTER_LAST: internal use 1598 * @__NL80211_ATTR_AFTER_LAST: internal use
1596 */ 1599 */
@@ -1931,6 +1934,8 @@ enum nl80211_attrs {
1931 NL80211_ATTR_CSA_C_OFFSETS_TX, 1934 NL80211_ATTR_CSA_C_OFFSETS_TX,
1932 NL80211_ATTR_MAX_CSA_COUNTERS, 1935 NL80211_ATTR_MAX_CSA_COUNTERS,
1933 1936
1937 NL80211_ATTR_TDLS_INITIATOR,
1938
1934 /* add attributes here, update the policy in nl80211.c */ 1939 /* add attributes here, update the policy in nl80211.c */
1935 1940
1936 __NL80211_ATTR_AFTER_LAST, 1941 __NL80211_ATTR_AFTER_LAST,
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 97b5dcad5025..aeb6a483b3bc 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -19,14 +19,6 @@ if MAC80211 != n
19config MAC80211_HAS_RC 19config MAC80211_HAS_RC
20 bool 20 bool
21 21
22config MAC80211_RC_PID
23 bool "PID controller based rate control algorithm" if EXPERT
24 select MAC80211_HAS_RC
25 ---help---
26 This option enables a TX rate control algorithm for
27 mac80211 that uses a PID controller to select the TX
28 rate.
29
30config MAC80211_RC_MINSTREL 22config MAC80211_RC_MINSTREL
31 bool "Minstrel" if EXPERT 23 bool "Minstrel" if EXPERT
32 select MAC80211_HAS_RC 24 select MAC80211_HAS_RC
@@ -51,14 +43,6 @@ choice
51 overridden through the ieee80211_default_rc_algo module 43 overridden through the ieee80211_default_rc_algo module
52 parameter if different algorithms are available. 44 parameter if different algorithms are available.
53 45
54config MAC80211_RC_DEFAULT_PID
55 bool "PID controller based rate control algorithm"
56 depends on MAC80211_RC_PID
57 ---help---
58 Select the PID controller based rate control as the
59 default rate control algorithm. You should choose
60 this unless you know what you are doing.
61
62config MAC80211_RC_DEFAULT_MINSTREL 46config MAC80211_RC_DEFAULT_MINSTREL
63 bool "Minstrel" 47 bool "Minstrel"
64 depends on MAC80211_RC_MINSTREL 48 depends on MAC80211_RC_MINSTREL
@@ -72,7 +56,6 @@ config MAC80211_RC_DEFAULT
72 string 56 string
73 default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT 57 default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT
74 default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL 58 default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL
75 default "pid" if MAC80211_RC_DEFAULT_PID
76 default "" 59 default ""
77 60
78endif 61endif
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 1e46ffa69167..7273d2796dd1 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -17,6 +17,7 @@ mac80211-y := \
17 aes_ccm.o \ 17 aes_ccm.o \
18 aes_cmac.o \ 18 aes_cmac.o \
19 cfg.o \ 19 cfg.o \
20 ethtool.o \
20 rx.o \ 21 rx.o \
21 spectmgmt.o \ 22 spectmgmt.o \
22 tx.o \ 23 tx.o \
@@ -47,17 +48,12 @@ mac80211-$(CONFIG_PM) += pm.o
47 48
48CFLAGS_trace.o := -I$(src) 49CFLAGS_trace.o := -I$(src)
49 50
50# objects for PID algorithm
51rc80211_pid-y := rc80211_pid_algo.o
52rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
53
54rc80211_minstrel-y := rc80211_minstrel.o 51rc80211_minstrel-y := rc80211_minstrel.o
55rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o 52rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
56 53
57rc80211_minstrel_ht-y := rc80211_minstrel_ht.o 54rc80211_minstrel_ht-y := rc80211_minstrel_ht.o
58rc80211_minstrel_ht-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o 55rc80211_minstrel_ht-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o
59 56
60mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y)
61mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) 57mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
62mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) 58mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y)
63 59
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index ce9633a3cfb0..d6986f3aa5c4 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -170,10 +170,13 @@ ieee80211_stop_queue_agg(struct ieee80211_sub_if_data *sdata, int tid)
170{ 170{
171 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)]; 171 int queue = sdata->vif.hw_queue[ieee80211_ac_from_tid(tid)];
172 172
173 /* we do refcounting here, so don't use the queue reason refcounting */
174
173 if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1) 175 if (atomic_inc_return(&sdata->local->agg_queue_stop[queue]) == 1)
174 ieee80211_stop_queue_by_reason( 176 ieee80211_stop_queue_by_reason(
175 &sdata->local->hw, queue, 177 &sdata->local->hw, queue,
176 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 178 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
179 false);
177 __acquire(agg_queue); 180 __acquire(agg_queue);
178} 181}
179 182
@@ -185,7 +188,8 @@ ieee80211_wake_queue_agg(struct ieee80211_sub_if_data *sdata, int tid)
185 if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0) 188 if (atomic_dec_return(&sdata->local->agg_queue_stop[queue]) == 0)
186 ieee80211_wake_queue_by_reason( 189 ieee80211_wake_queue_by_reason(
187 &sdata->local->hw, queue, 190 &sdata->local->hw, queue,
188 IEEE80211_QUEUE_STOP_REASON_AGGREGATION); 191 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
192 false);
189 __release(agg_queue); 193 __release(agg_queue);
190} 194}
191 195
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d7513a503be1..927b4ea0128b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -468,327 +468,6 @@ void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
468 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH; 468 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
469} 469}
470 470
471static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
472{
473 struct ieee80211_sub_if_data *sdata = sta->sdata;
474 struct ieee80211_local *local = sdata->local;
475 struct rate_control_ref *ref = local->rate_ctrl;
476 struct timespec uptime;
477 u64 packets = 0;
478 u32 thr = 0;
479 int i, ac;
480
481 sinfo->generation = sdata->local->sta_generation;
482
483 sinfo->filled = STATION_INFO_INACTIVE_TIME |
484 STATION_INFO_RX_BYTES64 |
485 STATION_INFO_TX_BYTES64 |
486 STATION_INFO_RX_PACKETS |
487 STATION_INFO_TX_PACKETS |
488 STATION_INFO_TX_RETRIES |
489 STATION_INFO_TX_FAILED |
490 STATION_INFO_TX_BITRATE |
491 STATION_INFO_RX_BITRATE |
492 STATION_INFO_RX_DROP_MISC |
493 STATION_INFO_BSS_PARAM |
494 STATION_INFO_CONNECTED_TIME |
495 STATION_INFO_STA_FLAGS |
496 STATION_INFO_BEACON_LOSS_COUNT;
497
498 do_posix_clock_monotonic_gettime(&uptime);
499 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
500
501 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
502 sinfo->tx_bytes = 0;
503 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
504 sinfo->tx_bytes += sta->tx_bytes[ac];
505 packets += sta->tx_packets[ac];
506 }
507 sinfo->tx_packets = packets;
508 sinfo->rx_bytes = sta->rx_bytes;
509 sinfo->rx_packets = sta->rx_packets;
510 sinfo->tx_retries = sta->tx_retry_count;
511 sinfo->tx_failed = sta->tx_retry_failed;
512 sinfo->rx_dropped_misc = sta->rx_dropped;
513 sinfo->beacon_loss_count = sta->beacon_loss_count;
514
515 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
516 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
517 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
518 if (!local->ops->get_rssi ||
519 drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
520 sinfo->signal = (s8)sta->last_signal;
521 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
522 }
523 if (sta->chains) {
524 sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
525 STATION_INFO_CHAIN_SIGNAL_AVG;
526
527 sinfo->chains = sta->chains;
528 for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
529 sinfo->chain_signal[i] = sta->chain_signal_last[i];
530 sinfo->chain_signal_avg[i] =
531 (s8) -ewma_read(&sta->chain_signal_avg[i]);
532 }
533 }
534
535 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
536 sta_set_rate_info_rx(sta, &sinfo->rxrate);
537
538 if (ieee80211_vif_is_mesh(&sdata->vif)) {
539#ifdef CONFIG_MAC80211_MESH
540 sinfo->filled |= STATION_INFO_LLID |
541 STATION_INFO_PLID |
542 STATION_INFO_PLINK_STATE |
543 STATION_INFO_LOCAL_PM |
544 STATION_INFO_PEER_PM |
545 STATION_INFO_NONPEER_PM;
546
547 sinfo->llid = sta->llid;
548 sinfo->plid = sta->plid;
549 sinfo->plink_state = sta->plink_state;
550 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
551 sinfo->filled |= STATION_INFO_T_OFFSET;
552 sinfo->t_offset = sta->t_offset;
553 }
554 sinfo->local_pm = sta->local_pm;
555 sinfo->peer_pm = sta->peer_pm;
556 sinfo->nonpeer_pm = sta->nonpeer_pm;
557#endif
558 }
559
560 sinfo->bss_param.flags = 0;
561 if (sdata->vif.bss_conf.use_cts_prot)
562 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
563 if (sdata->vif.bss_conf.use_short_preamble)
564 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
565 if (sdata->vif.bss_conf.use_short_slot)
566 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
567 sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
568 sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
569
570 sinfo->sta_flags.set = 0;
571 sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
572 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
573 BIT(NL80211_STA_FLAG_WME) |
574 BIT(NL80211_STA_FLAG_MFP) |
575 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
576 BIT(NL80211_STA_FLAG_ASSOCIATED) |
577 BIT(NL80211_STA_FLAG_TDLS_PEER);
578 if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
579 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
580 if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
581 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
582 if (test_sta_flag(sta, WLAN_STA_WME))
583 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
584 if (test_sta_flag(sta, WLAN_STA_MFP))
585 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
586 if (test_sta_flag(sta, WLAN_STA_AUTH))
587 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
588 if (test_sta_flag(sta, WLAN_STA_ASSOC))
589 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
590 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
591 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
592
593 /* check if the driver has a SW RC implementation */
594 if (ref && ref->ops->get_expected_throughput)
595 thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
596 else
597 thr = drv_get_expected_throughput(local, &sta->sta);
598
599 if (thr != 0) {
600 sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
601 sinfo->expected_throughput = thr;
602 }
603}
604
605static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
606 "rx_packets", "rx_bytes", "wep_weak_iv_count",
607 "rx_duplicates", "rx_fragments", "rx_dropped",
608 "tx_packets", "tx_bytes", "tx_fragments",
609 "tx_filtered", "tx_retry_failed", "tx_retries",
610 "beacon_loss", "sta_state", "txrate", "rxrate", "signal",
611 "channel", "noise", "ch_time", "ch_time_busy",
612 "ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
613};
614#define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats)
615
616static int ieee80211_get_et_sset_count(struct wiphy *wiphy,
617 struct net_device *dev,
618 int sset)
619{
620 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
621 int rv = 0;
622
623 if (sset == ETH_SS_STATS)
624 rv += STA_STATS_LEN;
625
626 rv += drv_get_et_sset_count(sdata, sset);
627
628 if (rv == 0)
629 return -EOPNOTSUPP;
630 return rv;
631}
632
633static void ieee80211_get_et_stats(struct wiphy *wiphy,
634 struct net_device *dev,
635 struct ethtool_stats *stats,
636 u64 *data)
637{
638 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
639 struct ieee80211_chanctx_conf *chanctx_conf;
640 struct ieee80211_channel *channel;
641 struct sta_info *sta;
642 struct ieee80211_local *local = sdata->local;
643 struct station_info sinfo;
644 struct survey_info survey;
645 int i, q;
646#define STA_STATS_SURVEY_LEN 7
647
648 memset(data, 0, sizeof(u64) * STA_STATS_LEN);
649
650#define ADD_STA_STATS(sta) \
651 do { \
652 data[i++] += sta->rx_packets; \
653 data[i++] += sta->rx_bytes; \
654 data[i++] += sta->wep_weak_iv_count; \
655 data[i++] += sta->num_duplicates; \
656 data[i++] += sta->rx_fragments; \
657 data[i++] += sta->rx_dropped; \
658 \
659 data[i++] += sinfo.tx_packets; \
660 data[i++] += sinfo.tx_bytes; \
661 data[i++] += sta->tx_fragments; \
662 data[i++] += sta->tx_filtered_count; \
663 data[i++] += sta->tx_retry_failed; \
664 data[i++] += sta->tx_retry_count; \
665 data[i++] += sta->beacon_loss_count; \
666 } while (0)
667
668 /* For Managed stations, find the single station based on BSSID
669 * and use that. For interface types, iterate through all available
670 * stations and add stats for any station that is assigned to this
671 * network device.
672 */
673
674 mutex_lock(&local->sta_mtx);
675
676 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
677 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
678
679 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
680 goto do_survey;
681
682 sinfo.filled = 0;
683 sta_set_sinfo(sta, &sinfo);
684
685 i = 0;
686 ADD_STA_STATS(sta);
687
688 data[i++] = sta->sta_state;
689
690
691 if (sinfo.filled & STATION_INFO_TX_BITRATE)
692 data[i] = 100000 *
693 cfg80211_calculate_bitrate(&sinfo.txrate);
694 i++;
695 if (sinfo.filled & STATION_INFO_RX_BITRATE)
696 data[i] = 100000 *
697 cfg80211_calculate_bitrate(&sinfo.rxrate);
698 i++;
699
700 if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
701 data[i] = (u8)sinfo.signal_avg;
702 i++;
703 } else {
704 list_for_each_entry(sta, &local->sta_list, list) {
705 /* Make sure this station belongs to the proper dev */
706 if (sta->sdata->dev != dev)
707 continue;
708
709 sinfo.filled = 0;
710 sta_set_sinfo(sta, &sinfo);
711 i = 0;
712 ADD_STA_STATS(sta);
713 }
714 }
715
716do_survey:
717 i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
718 /* Get survey stats for current channel */
719 survey.filled = 0;
720
721 rcu_read_lock();
722 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
723 if (chanctx_conf)
724 channel = chanctx_conf->def.chan;
725 else
726 channel = NULL;
727 rcu_read_unlock();
728
729 if (channel) {
730 q = 0;
731 do {
732 survey.filled = 0;
733 if (drv_get_survey(local, q, &survey) != 0) {
734 survey.filled = 0;
735 break;
736 }
737 q++;
738 } while (channel != survey.channel);
739 }
740
741 if (survey.filled)
742 data[i++] = survey.channel->center_freq;
743 else
744 data[i++] = 0;
745 if (survey.filled & SURVEY_INFO_NOISE_DBM)
746 data[i++] = (u8)survey.noise;
747 else
748 data[i++] = -1LL;
749 if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
750 data[i++] = survey.channel_time;
751 else
752 data[i++] = -1LL;
753 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
754 data[i++] = survey.channel_time_busy;
755 else
756 data[i++] = -1LL;
757 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
758 data[i++] = survey.channel_time_ext_busy;
759 else
760 data[i++] = -1LL;
761 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
762 data[i++] = survey.channel_time_rx;
763 else
764 data[i++] = -1LL;
765 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
766 data[i++] = survey.channel_time_tx;
767 else
768 data[i++] = -1LL;
769
770 mutex_unlock(&local->sta_mtx);
771
772 if (WARN_ON(i != STA_STATS_LEN))
773 return;
774
775 drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
776}
777
778static void ieee80211_get_et_strings(struct wiphy *wiphy,
779 struct net_device *dev,
780 u32 sset, u8 *data)
781{
782 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
783 int sz_sta_stats = 0;
784
785 if (sset == ETH_SS_STATS) {
786 sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
787 memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
788 }
789 drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
790}
791
792static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, 471static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
793 int idx, u8 *mac, struct station_info *sinfo) 472 int idx, u8 *mac, struct station_info *sinfo)
794{ 473{
@@ -875,7 +554,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
875} 554}
876 555
877static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, 556static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
878 const u8 *resp, size_t resp_len) 557 const u8 *resp, size_t resp_len,
558 const struct ieee80211_csa_settings *csa)
879{ 559{
880 struct probe_resp *new, *old; 560 struct probe_resp *new, *old;
881 561
@@ -891,6 +571,11 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
891 new->len = resp_len; 571 new->len = resp_len;
892 memcpy(new->data, resp, resp_len); 572 memcpy(new->data, resp, resp_len);
893 573
574 if (csa)
575 memcpy(new->csa_counter_offsets, csa->counter_offsets_presp,
576 csa->n_counter_offsets_presp *
577 sizeof(new->csa_counter_offsets[0]));
578
894 rcu_assign_pointer(sdata->u.ap.probe_resp, new); 579 rcu_assign_pointer(sdata->u.ap.probe_resp, new);
895 if (old) 580 if (old)
896 kfree_rcu(old, rcu_head); 581 kfree_rcu(old, rcu_head);
@@ -899,7 +584,8 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
899} 584}
900 585
901static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, 586static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
902 struct cfg80211_beacon_data *params) 587 struct cfg80211_beacon_data *params,
588 const struct ieee80211_csa_settings *csa)
903{ 589{
904 struct beacon_data *new, *old; 590 struct beacon_data *new, *old;
905 int new_head_len, new_tail_len; 591 int new_head_len, new_tail_len;
@@ -943,6 +629,13 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
943 new->head_len = new_head_len; 629 new->head_len = new_head_len;
944 new->tail_len = new_tail_len; 630 new->tail_len = new_tail_len;
945 631
632 if (csa) {
633 new->csa_current_counter = csa->count;
634 memcpy(new->csa_counter_offsets, csa->counter_offsets_beacon,
635 csa->n_counter_offsets_beacon *
636 sizeof(new->csa_counter_offsets[0]));
637 }
638
946 /* copy in head */ 639 /* copy in head */
947 if (params->head) 640 if (params->head)
948 memcpy(new->head, params->head, new_head_len); 641 memcpy(new->head, params->head, new_head_len);
@@ -957,7 +650,7 @@ static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
957 memcpy(new->tail, old->tail, new_tail_len); 650 memcpy(new->tail, old->tail, new_tail_len);
958 651
959 err = ieee80211_set_probe_resp(sdata, params->probe_resp, 652 err = ieee80211_set_probe_resp(sdata, params->probe_resp,
960 params->probe_resp_len); 653 params->probe_resp_len, csa);
961 if (err < 0) 654 if (err < 0)
962 return err; 655 return err;
963 if (err == 0) 656 if (err == 0)
@@ -1042,7 +735,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
1042 sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |= 735 sdata->vif.bss_conf.p2p_noa_attr.oppps_ctwindow |=
1043 IEEE80211_P2P_OPPPS_ENABLE_BIT; 736 IEEE80211_P2P_OPPPS_ENABLE_BIT;
1044 737
1045 err = ieee80211_assign_beacon(sdata, &params->beacon); 738 err = ieee80211_assign_beacon(sdata, &params->beacon, NULL);
1046 if (err < 0) { 739 if (err < 0) {
1047 ieee80211_vif_release_channel(sdata); 740 ieee80211_vif_release_channel(sdata);
1048 return err; 741 return err;
@@ -1090,38 +783,13 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
1090 if (!old) 783 if (!old)
1091 return -ENOENT; 784 return -ENOENT;
1092 785
1093 err = ieee80211_assign_beacon(sdata, params); 786 err = ieee80211_assign_beacon(sdata, params, NULL);
1094 if (err < 0) 787 if (err < 0)
1095 return err; 788 return err;
1096 ieee80211_bss_info_change_notify(sdata, err); 789 ieee80211_bss_info_change_notify(sdata, err);
1097 return 0; 790 return 0;
1098} 791}
1099 792
1100bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local)
1101{
1102 struct ieee80211_sub_if_data *sdata;
1103
1104 lockdep_assert_held(&local->mtx);
1105
1106 rcu_read_lock();
1107 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
1108 if (!ieee80211_sdata_running(sdata))
1109 continue;
1110
1111 if (!sdata->vif.csa_active)
1112 continue;
1113
1114 if (!sdata->csa_block_tx)
1115 continue;
1116
1117 rcu_read_unlock();
1118 return true;
1119 }
1120 rcu_read_unlock();
1121
1122 return false;
1123}
1124
1125static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) 793static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1126{ 794{
1127 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 795 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1141,10 +809,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1141 /* abort any running channel switch */ 809 /* abort any running channel switch */
1142 mutex_lock(&local->mtx); 810 mutex_lock(&local->mtx);
1143 sdata->vif.csa_active = false; 811 sdata->vif.csa_active = false;
1144 if (!ieee80211_csa_needs_block_tx(local)) 812 if (sdata->csa_block_tx) {
1145 ieee80211_wake_queues_by_reason(&local->hw, 813 ieee80211_wake_vif_queues(local, sdata,
1146 IEEE80211_MAX_QUEUE_MAP, 814 IEEE80211_QUEUE_STOP_REASON_CSA);
1147 IEEE80211_QUEUE_STOP_REASON_CSA); 815 sdata->csa_block_tx = false;
816 }
817
1148 mutex_unlock(&local->mtx); 818 mutex_unlock(&local->mtx);
1149 819
1150 kfree(sdata->u.ap.next_beacon); 820 kfree(sdata->u.ap.next_beacon);
@@ -1327,9 +997,12 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1327 } 997 }
1328 } 998 }
1329 999
1330 ret = sta_apply_auth_flags(local, sta, mask, set); 1000 /* auth flags will be set later for TDLS stations */
1331 if (ret) 1001 if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
1332 return ret; 1002 ret = sta_apply_auth_flags(local, sta, mask, set);
1003 if (ret)
1004 return ret;
1005 }
1333 1006
1334 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { 1007 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
1335 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) 1008 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
@@ -1466,6 +1139,13 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1466#endif 1139#endif
1467 } 1140 }
1468 1141
1142 /* set the STA state after all sta info from usermode has been set */
1143 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) {
1144 ret = sta_apply_auth_flags(local, sta, mask, set);
1145 if (ret)
1146 return ret;
1147 }
1148
1469 return 0; 1149 return 0;
1470} 1150}
1471 1151
@@ -3073,7 +2753,8 @@ static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
3073 2753
3074 switch (sdata->vif.type) { 2754 switch (sdata->vif.type) {
3075 case NL80211_IFTYPE_AP: 2755 case NL80211_IFTYPE_AP:
3076 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); 2756 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon,
2757 NULL);
3077 kfree(sdata->u.ap.next_beacon); 2758 kfree(sdata->u.ap.next_beacon);
3078 sdata->u.ap.next_beacon = NULL; 2759 sdata->u.ap.next_beacon = NULL;
3079 2760
@@ -3111,17 +2792,35 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3111 2792
3112 sdata_assert_lock(sdata); 2793 sdata_assert_lock(sdata);
3113 lockdep_assert_held(&local->mtx); 2794 lockdep_assert_held(&local->mtx);
2795 lockdep_assert_held(&local->chanctx_mtx);
3114 2796
3115 sdata->radar_required = sdata->csa_radar_required; 2797 /*
3116 err = ieee80211_vif_change_channel(sdata, &changed); 2798 * using reservation isn't immediate as it may be deferred until later
3117 if (err < 0) 2799 * with multi-vif. once reservation is complete it will re-schedule the
3118 return err; 2800 * work with no reserved_chanctx so verify chandef to check if it
2801 * completed successfully
2802 */
3119 2803
3120 if (!local->use_chanctx) { 2804 if (sdata->reserved_chanctx) {
3121 local->_oper_chandef = sdata->csa_chandef; 2805 /*
3122 ieee80211_hw_config(local, 0); 2806 * with multi-vif csa driver may call ieee80211_csa_finish()
2807 * many times while waiting for other interfaces to use their
2808 * reservations
2809 */
2810 if (sdata->reserved_ready)
2811 return 0;
2812
2813 err = ieee80211_vif_use_reserved_context(sdata);
2814 if (err)
2815 return err;
2816
2817 return 0;
3123 } 2818 }
3124 2819
2820 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
2821 &sdata->csa_chandef))
2822 return -EINVAL;
2823
3125 sdata->vif.csa_active = false; 2824 sdata->vif.csa_active = false;
3126 2825
3127 err = ieee80211_set_after_csa_beacon(sdata, &changed); 2826 err = ieee80211_set_after_csa_beacon(sdata, &changed);
@@ -3131,10 +2830,11 @@ static int __ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
3131 ieee80211_bss_info_change_notify(sdata, changed); 2830 ieee80211_bss_info_change_notify(sdata, changed);
3132 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); 2831 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
3133 2832
3134 if (!ieee80211_csa_needs_block_tx(local)) 2833 if (sdata->csa_block_tx) {
3135 ieee80211_wake_queues_by_reason(&local->hw, 2834 ieee80211_wake_vif_queues(local, sdata,
3136 IEEE80211_MAX_QUEUE_MAP, 2835 IEEE80211_QUEUE_STOP_REASON_CSA);
3137 IEEE80211_QUEUE_STOP_REASON_CSA); 2836 sdata->csa_block_tx = false;
2837 }
3138 2838
3139 return 0; 2839 return 0;
3140} 2840}
@@ -3157,6 +2857,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
3157 2857
3158 sdata_lock(sdata); 2858 sdata_lock(sdata);
3159 mutex_lock(&local->mtx); 2859 mutex_lock(&local->mtx);
2860 mutex_lock(&local->chanctx_mtx);
3160 2861
3161 /* AP might have been stopped while waiting for the lock. */ 2862 /* AP might have been stopped while waiting for the lock. */
3162 if (!sdata->vif.csa_active) 2863 if (!sdata->vif.csa_active)
@@ -3168,6 +2869,7 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
3168 ieee80211_csa_finalize(sdata); 2869 ieee80211_csa_finalize(sdata);
3169 2870
3170unlock: 2871unlock:
2872 mutex_unlock(&local->chanctx_mtx);
3171 mutex_unlock(&local->mtx); 2873 mutex_unlock(&local->mtx);
3172 sdata_unlock(sdata); 2874 sdata_unlock(sdata);
3173} 2875}
@@ -3176,6 +2878,7 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
3176 struct cfg80211_csa_settings *params, 2878 struct cfg80211_csa_settings *params,
3177 u32 *changed) 2879 u32 *changed)
3178{ 2880{
2881 struct ieee80211_csa_settings csa = {};
3179 int err; 2882 int err;
3180 2883
3181 switch (sdata->vif.type) { 2884 switch (sdata->vif.type) {
@@ -3210,20 +2913,13 @@ static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
3210 IEEE80211_MAX_CSA_COUNTERS_NUM)) 2913 IEEE80211_MAX_CSA_COUNTERS_NUM))
3211 return -EINVAL; 2914 return -EINVAL;
3212 2915
3213 /* make sure we don't have garbage in other counters */ 2916 csa.counter_offsets_beacon = params->counter_offsets_beacon;
3214 memset(sdata->csa_counter_offset_beacon, 0, 2917 csa.counter_offsets_presp = params->counter_offsets_presp;
3215 sizeof(sdata->csa_counter_offset_beacon)); 2918 csa.n_counter_offsets_beacon = params->n_counter_offsets_beacon;
3216 memset(sdata->csa_counter_offset_presp, 0, 2919 csa.n_counter_offsets_presp = params->n_counter_offsets_presp;
3217 sizeof(sdata->csa_counter_offset_presp)); 2920 csa.count = params->count;
3218
3219 memcpy(sdata->csa_counter_offset_beacon,
3220 params->counter_offsets_beacon,
3221 params->n_counter_offsets_beacon * sizeof(u16));
3222 memcpy(sdata->csa_counter_offset_presp,
3223 params->counter_offsets_presp,
3224 params->n_counter_offsets_presp * sizeof(u16));
3225 2921
3226 err = ieee80211_assign_beacon(sdata, &params->beacon_csa); 2922 err = ieee80211_assign_beacon(sdata, &params->beacon_csa, &csa);
3227 if (err < 0) { 2923 if (err < 0) {
3228 kfree(sdata->u.ap.next_beacon); 2924 kfree(sdata->u.ap.next_beacon);
3229 return err; 2925 return err;
@@ -3319,7 +3015,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3319 struct ieee80211_local *local = sdata->local; 3015 struct ieee80211_local *local = sdata->local;
3320 struct ieee80211_chanctx_conf *conf; 3016 struct ieee80211_chanctx_conf *conf;
3321 struct ieee80211_chanctx *chanctx; 3017 struct ieee80211_chanctx *chanctx;
3322 int err, num_chanctx, changed = 0; 3018 int err, changed = 0;
3323 3019
3324 sdata_assert_lock(sdata); 3020 sdata_assert_lock(sdata);
3325 lockdep_assert_held(&local->mtx); 3021 lockdep_assert_held(&local->mtx);
@@ -3334,46 +3030,50 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3334 &sdata->vif.bss_conf.chandef)) 3030 &sdata->vif.bss_conf.chandef))
3335 return -EINVAL; 3031 return -EINVAL;
3336 3032
3033 /* don't allow another channel switch if one is already active. */
3034 if (sdata->vif.csa_active)
3035 return -EBUSY;
3036
3337 mutex_lock(&local->chanctx_mtx); 3037 mutex_lock(&local->chanctx_mtx);
3338 conf = rcu_dereference_protected(sdata->vif.chanctx_conf, 3038 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
3339 lockdep_is_held(&local->chanctx_mtx)); 3039 lockdep_is_held(&local->chanctx_mtx));
3340 if (!conf) { 3040 if (!conf) {
3341 mutex_unlock(&local->chanctx_mtx); 3041 err = -EBUSY;
3342 return -EBUSY; 3042 goto out;
3343 } 3043 }
3344 3044
3345 /* don't handle for multi-VIF cases */
3346 chanctx = container_of(conf, struct ieee80211_chanctx, conf); 3045 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
3347 if (ieee80211_chanctx_refcount(local, chanctx) > 1) { 3046 if (!chanctx) {
3348 mutex_unlock(&local->chanctx_mtx); 3047 err = -EBUSY;
3349 return -EBUSY; 3048 goto out;
3350 } 3049 }
3351 num_chanctx = 0;
3352 list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
3353 num_chanctx++;
3354 mutex_unlock(&local->chanctx_mtx);
3355 3050
3356 if (num_chanctx > 1) 3051 err = ieee80211_vif_reserve_chanctx(sdata, &params->chandef,
3357 return -EBUSY; 3052 chanctx->mode,
3053 params->radar_required);
3054 if (err)
3055 goto out;
3358 3056
3359 /* don't allow another channel switch if one is already active. */ 3057 /* if reservation is invalid then this will fail */
3360 if (sdata->vif.csa_active) 3058 err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0);
3361 return -EBUSY; 3059 if (err) {
3060 ieee80211_vif_unreserve_chanctx(sdata);
3061 goto out;
3062 }
3362 3063
3363 err = ieee80211_set_csa_beacon(sdata, params, &changed); 3064 err = ieee80211_set_csa_beacon(sdata, params, &changed);
3364 if (err) 3065 if (err) {
3365 return err; 3066 ieee80211_vif_unreserve_chanctx(sdata);
3067 goto out;
3068 }
3366 3069
3367 sdata->csa_radar_required = params->radar_required;
3368 sdata->csa_chandef = params->chandef; 3070 sdata->csa_chandef = params->chandef;
3369 sdata->csa_block_tx = params->block_tx; 3071 sdata->csa_block_tx = params->block_tx;
3370 sdata->csa_current_counter = params->count;
3371 sdata->vif.csa_active = true; 3072 sdata->vif.csa_active = true;
3372 3073
3373 if (sdata->csa_block_tx) 3074 if (sdata->csa_block_tx)
3374 ieee80211_stop_queues_by_reason(&local->hw, 3075 ieee80211_stop_vif_queues(local, sdata,
3375 IEEE80211_MAX_QUEUE_MAP, 3076 IEEE80211_QUEUE_STOP_REASON_CSA);
3376 IEEE80211_QUEUE_STOP_REASON_CSA);
3377 3077
3378 if (changed) { 3078 if (changed) {
3379 ieee80211_bss_info_change_notify(sdata, changed); 3079 ieee80211_bss_info_change_notify(sdata, changed);
@@ -3383,7 +3083,9 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3383 ieee80211_csa_finalize(sdata); 3083 ieee80211_csa_finalize(sdata);
3384 } 3084 }
3385 3085
3386 return 0; 3086out:
3087 mutex_unlock(&local->chanctx_mtx);
3088 return err;
3387} 3089}
3388 3090
3389int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 3091int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
@@ -3515,10 +3217,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3515 sdata->vif.type == NL80211_IFTYPE_ADHOC) && 3217 sdata->vif.type == NL80211_IFTYPE_ADHOC) &&
3516 params->n_csa_offsets) { 3218 params->n_csa_offsets) {
3517 int i; 3219 int i;
3518 u8 c = sdata->csa_current_counter; 3220 struct beacon_data *beacon = NULL;
3519 3221
3520 for (i = 0; i < params->n_csa_offsets; i++) 3222 rcu_read_lock();
3521 data[params->csa_offsets[i]] = c; 3223
3224 if (sdata->vif.type == NL80211_IFTYPE_AP)
3225 beacon = rcu_dereference(sdata->u.ap.beacon);
3226 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
3227 beacon = rcu_dereference(sdata->u.ibss.presp);
3228 else if (ieee80211_vif_is_mesh(&sdata->vif))
3229 beacon = rcu_dereference(sdata->u.mesh.beacon);
3230
3231 if (beacon)
3232 for (i = 0; i < params->n_csa_offsets; i++)
3233 data[params->csa_offsets[i]] =
3234 beacon->csa_current_counter;
3235
3236 rcu_read_unlock();
3522 } 3237 }
3523 3238
3524 IEEE80211_SKB_CB(skb)->flags = flags; 3239 IEEE80211_SKB_CB(skb)->flags = flags;
@@ -3598,21 +3313,6 @@ static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
3598 return drv_get_antenna(local, tx_ant, rx_ant); 3313 return drv_get_antenna(local, tx_ant, rx_ant);
3599} 3314}
3600 3315
3601static int ieee80211_set_ringparam(struct wiphy *wiphy, u32 tx, u32 rx)
3602{
3603 struct ieee80211_local *local = wiphy_priv(wiphy);
3604
3605 return drv_set_ringparam(local, tx, rx);
3606}
3607
3608static void ieee80211_get_ringparam(struct wiphy *wiphy,
3609 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
3610{
3611 struct ieee80211_local *local = wiphy_priv(wiphy);
3612
3613 drv_get_ringparam(local, tx, tx_max, rx, rx_max);
3614}
3615
3616static int ieee80211_set_rekey_data(struct wiphy *wiphy, 3316static int ieee80211_set_rekey_data(struct wiphy *wiphy,
3617 struct net_device *dev, 3317 struct net_device *dev,
3618 struct cfg80211_gtk_rekey_data *data) 3318 struct cfg80211_gtk_rekey_data *data)
@@ -3844,8 +3544,6 @@ const struct cfg80211_ops mac80211_config_ops = {
3844 .mgmt_frame_register = ieee80211_mgmt_frame_register, 3544 .mgmt_frame_register = ieee80211_mgmt_frame_register,
3845 .set_antenna = ieee80211_set_antenna, 3545 .set_antenna = ieee80211_set_antenna,
3846 .get_antenna = ieee80211_get_antenna, 3546 .get_antenna = ieee80211_get_antenna,
3847 .set_ringparam = ieee80211_set_ringparam,
3848 .get_ringparam = ieee80211_get_ringparam,
3849 .set_rekey_data = ieee80211_set_rekey_data, 3547 .set_rekey_data = ieee80211_set_rekey_data,
3850 .tdls_oper = ieee80211_tdls_oper, 3548 .tdls_oper = ieee80211_tdls_oper,
3851 .tdls_mgmt = ieee80211_tdls_mgmt, 3549 .tdls_mgmt = ieee80211_tdls_mgmt,
@@ -3854,9 +3552,6 @@ const struct cfg80211_ops mac80211_config_ops = {
3854#ifdef CONFIG_PM 3552#ifdef CONFIG_PM
3855 .set_wakeup = ieee80211_set_wakeup, 3553 .set_wakeup = ieee80211_set_wakeup,
3856#endif 3554#endif
3857 .get_et_sset_count = ieee80211_get_et_sset_count,
3858 .get_et_stats = ieee80211_get_et_stats,
3859 .get_et_strings = ieee80211_get_et_strings,
3860 .get_channel = ieee80211_cfg_get_channel, 3555 .get_channel = ieee80211_cfg_get_channel,
3861 .start_radar_detection = ieee80211_start_radar_detection, 3556 .start_radar_detection = ieee80211_start_radar_detection,
3862 .channel_switch = ieee80211_channel_switch, 3557 .channel_switch = ieee80211_channel_switch,
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index a310e33972de..c3fd4d275bf4 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -63,6 +63,20 @@ static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local)
63 return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local); 63 return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local);
64} 64}
65 65
66static struct ieee80211_chanctx *
67ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata)
68{
69 struct ieee80211_local *local = sdata->local;
70 struct ieee80211_chanctx_conf *conf;
71
72 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
73 lockdep_is_held(&local->chanctx_mtx));
74 if (!conf)
75 return NULL;
76
77 return container_of(conf, struct ieee80211_chanctx, conf);
78}
79
66static const struct cfg80211_chan_def * 80static const struct cfg80211_chan_def *
67ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local, 81ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local,
68 struct ieee80211_chanctx *ctx, 82 struct ieee80211_chanctx *ctx,
@@ -160,6 +174,9 @@ ieee80211_find_reservation_chanctx(struct ieee80211_local *local,
160 return NULL; 174 return NULL;
161 175
162 list_for_each_entry(ctx, &local->chanctx_list, list) { 176 list_for_each_entry(ctx, &local->chanctx_list, list) {
177 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
178 continue;
179
163 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 180 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
164 continue; 181 continue;
165 182
@@ -347,6 +364,9 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
347 list_for_each_entry(ctx, &local->chanctx_list, list) { 364 list_for_each_entry(ctx, &local->chanctx_list, list) {
348 const struct cfg80211_chan_def *compat; 365 const struct cfg80211_chan_def *compat;
349 366
367 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE)
368 continue;
369
350 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) 370 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
351 continue; 371 continue;
352 372
@@ -622,6 +642,7 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
622 struct ieee80211_local *local = sdata->local; 642 struct ieee80211_local *local = sdata->local;
623 struct ieee80211_chanctx_conf *conf; 643 struct ieee80211_chanctx_conf *conf;
624 struct ieee80211_chanctx *ctx; 644 struct ieee80211_chanctx *ctx;
645 bool use_reserved_switch = false;
625 646
626 lockdep_assert_held(&local->chanctx_mtx); 647 lockdep_assert_held(&local->chanctx_mtx);
627 648
@@ -632,12 +653,23 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
632 653
633 ctx = container_of(conf, struct ieee80211_chanctx, conf); 654 ctx = container_of(conf, struct ieee80211_chanctx, conf);
634 655
635 if (sdata->reserved_chanctx) 656 if (sdata->reserved_chanctx) {
657 if (sdata->reserved_chanctx->replace_state ==
658 IEEE80211_CHANCTX_REPLACES_OTHER &&
659 ieee80211_chanctx_num_reserved(local,
660 sdata->reserved_chanctx) > 1)
661 use_reserved_switch = true;
662
636 ieee80211_vif_unreserve_chanctx(sdata); 663 ieee80211_vif_unreserve_chanctx(sdata);
664 }
637 665
638 ieee80211_assign_vif_chanctx(sdata, NULL); 666 ieee80211_assign_vif_chanctx(sdata, NULL);
639 if (ieee80211_chanctx_refcount(local, ctx) == 0) 667 if (ieee80211_chanctx_refcount(local, ctx) == 0)
640 ieee80211_free_chanctx(local, ctx); 668 ieee80211_free_chanctx(local, ctx);
669
670 /* Unreserving may ready an in-place reservation. */
671 if (use_reserved_switch)
672 ieee80211_vif_use_reserved_switch(local);
641} 673}
642 674
643void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 675void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
@@ -787,70 +819,6 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
787 return ret; 819 return ret;
788} 820}
789 821
790static int __ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
791 struct ieee80211_chanctx *ctx,
792 u32 *changed)
793{
794 struct ieee80211_local *local = sdata->local;
795 const struct cfg80211_chan_def *chandef = &sdata->csa_chandef;
796 u32 chanctx_changed = 0;
797
798 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
799 IEEE80211_CHAN_DISABLED))
800 return -EINVAL;
801
802 if (ieee80211_chanctx_refcount(local, ctx) != 1)
803 return -EINVAL;
804
805 if (sdata->vif.bss_conf.chandef.width != chandef->width) {
806 chanctx_changed = IEEE80211_CHANCTX_CHANGE_WIDTH;
807 *changed |= BSS_CHANGED_BANDWIDTH;
808 }
809
810 sdata->vif.bss_conf.chandef = *chandef;
811 ctx->conf.def = *chandef;
812
813 chanctx_changed |= IEEE80211_CHANCTX_CHANGE_CHANNEL;
814 drv_change_chanctx(local, ctx, chanctx_changed);
815
816 ieee80211_recalc_chanctx_chantype(local, ctx);
817 ieee80211_recalc_smps_chanctx(local, ctx);
818 ieee80211_recalc_radar_chanctx(local, ctx);
819 ieee80211_recalc_chanctx_min_def(local, ctx);
820
821 return 0;
822}
823
824int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
825 u32 *changed)
826{
827 struct ieee80211_local *local = sdata->local;
828 struct ieee80211_chanctx_conf *conf;
829 struct ieee80211_chanctx *ctx;
830 int ret;
831
832 lockdep_assert_held(&local->mtx);
833
834 /* should never be called if not performing a channel switch. */
835 if (WARN_ON(!sdata->vif.csa_active))
836 return -EINVAL;
837
838 mutex_lock(&local->chanctx_mtx);
839 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
840 lockdep_is_held(&local->chanctx_mtx));
841 if (!conf) {
842 ret = -EINVAL;
843 goto out;
844 }
845
846 ctx = container_of(conf, struct ieee80211_chanctx, conf);
847
848 ret = __ieee80211_vif_change_channel(sdata, ctx, changed);
849 out:
850 mutex_unlock(&local->chanctx_mtx);
851 return ret;
852}
853
854static void 822static void
855__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 823__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
856 bool clear) 824 bool clear)
@@ -905,8 +873,25 @@ int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata)
905 list_del(&sdata->reserved_chanctx_list); 873 list_del(&sdata->reserved_chanctx_list);
906 sdata->reserved_chanctx = NULL; 874 sdata->reserved_chanctx = NULL;
907 875
908 if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) 876 if (ieee80211_chanctx_refcount(sdata->local, ctx) == 0) {
909 ieee80211_free_chanctx(sdata->local, ctx); 877 if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
878 if (WARN_ON(!ctx->replace_ctx))
879 return -EINVAL;
880
881 WARN_ON(ctx->replace_ctx->replace_state !=
882 IEEE80211_CHANCTX_WILL_BE_REPLACED);
883 WARN_ON(ctx->replace_ctx->replace_ctx != ctx);
884
885 ctx->replace_ctx->replace_ctx = NULL;
886 ctx->replace_ctx->replace_state =
887 IEEE80211_CHANCTX_REPLACE_NONE;
888
889 list_del_rcu(&ctx->list);
890 kfree_rcu(ctx, rcu_head);
891 } else {
892 ieee80211_free_chanctx(sdata->local, ctx);
893 }
894 }
910 895
911 return 0; 896 return 0;
912} 897}
@@ -917,40 +902,84 @@ int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
917 bool radar_required) 902 bool radar_required)
918{ 903{
919 struct ieee80211_local *local = sdata->local; 904 struct ieee80211_local *local = sdata->local;
920 struct ieee80211_chanctx_conf *conf; 905 struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx;
921 struct ieee80211_chanctx *new_ctx, *curr_ctx;
922 int ret = 0;
923 906
924 mutex_lock(&local->chanctx_mtx); 907 lockdep_assert_held(&local->chanctx_mtx);
925
926 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
927 lockdep_is_held(&local->chanctx_mtx));
928 if (!conf) {
929 ret = -EINVAL;
930 goto out;
931 }
932 908
933 curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); 909 curr_ctx = ieee80211_vif_get_chanctx(sdata);
910 if (curr_ctx && local->use_chanctx && !local->ops->switch_vif_chanctx)
911 return -ENOTSUPP;
934 912
935 new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode); 913 new_ctx = ieee80211_find_reservation_chanctx(local, chandef, mode);
936 if (!new_ctx) { 914 if (!new_ctx) {
937 if (ieee80211_chanctx_refcount(local, curr_ctx) == 1 && 915 if (ieee80211_can_create_new_chanctx(local)) {
938 (local->hw.flags & IEEE80211_HW_CHANGE_RUNNING_CHANCTX)) {
939 /* if we're the only users of the chanctx and
940 * the driver supports changing a running
941 * context, reserve our current context
942 */
943 new_ctx = curr_ctx;
944 } else if (ieee80211_can_create_new_chanctx(local)) {
945 /* create a new context and reserve it */
946 new_ctx = ieee80211_new_chanctx(local, chandef, mode); 916 new_ctx = ieee80211_new_chanctx(local, chandef, mode);
947 if (IS_ERR(new_ctx)) { 917 if (IS_ERR(new_ctx))
948 ret = PTR_ERR(new_ctx); 918 return PTR_ERR(new_ctx);
949 goto out;
950 }
951 } else { 919 } else {
952 ret = -EBUSY; 920 if (!curr_ctx ||
953 goto out; 921 (curr_ctx->replace_state ==
922 IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
923 !list_empty(&curr_ctx->reserved_vifs)) {
924 /*
925 * Another vif already requested this context
926 * for a reservation. Find another one hoping
927 * all vifs assigned to it will also switch
928 * soon enough.
929 *
930 * TODO: This needs a little more work as some
931 * cases (more than 2 chanctx capable devices)
932 * may fail which could otherwise succeed
933 * provided some channel context juggling was
934 * performed.
935 *
936 * Consider ctx1..3, vif1..6, each ctx has 2
937 * vifs. vif1 and vif2 from ctx1 request new
938 * different chandefs starting 2 in-place
939 * reserations with ctx4 and ctx5 replacing
940 * ctx1 and ctx2 respectively. Next vif5 and
941 * vif6 from ctx3 reserve ctx4. If vif3 and
942 * vif4 remain on ctx2 as they are then this
943 * fails unless `replace_ctx` from ctx5 is
944 * replaced with ctx3.
945 */
946 list_for_each_entry(ctx, &local->chanctx_list,
947 list) {
948 if (ctx->replace_state !=
949 IEEE80211_CHANCTX_REPLACE_NONE)
950 continue;
951
952 if (!list_empty(&ctx->reserved_vifs))
953 continue;
954
955 curr_ctx = ctx;
956 break;
957 }
958 }
959
960 /*
961 * If that's true then all available contexts already
962 * have reservations and cannot be used.
963 */
964 if (!curr_ctx ||
965 (curr_ctx->replace_state ==
966 IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
967 !list_empty(&curr_ctx->reserved_vifs))
968 return -EBUSY;
969
970 new_ctx = ieee80211_alloc_chanctx(local, chandef, mode);
971 if (!new_ctx)
972 return -ENOMEM;
973
974 new_ctx->replace_ctx = curr_ctx;
975 new_ctx->replace_state =
976 IEEE80211_CHANCTX_REPLACES_OTHER;
977
978 curr_ctx->replace_ctx = new_ctx;
979 curr_ctx->replace_state =
980 IEEE80211_CHANCTX_WILL_BE_REPLACED;
981
982 list_add_rcu(&new_ctx->list, &local->chanctx_list);
954 } 983 }
955 } 984 }
956 985
@@ -958,82 +987,601 @@ int ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
958 sdata->reserved_chanctx = new_ctx; 987 sdata->reserved_chanctx = new_ctx;
959 sdata->reserved_chandef = *chandef; 988 sdata->reserved_chandef = *chandef;
960 sdata->reserved_radar_required = radar_required; 989 sdata->reserved_radar_required = radar_required;
961out: 990 sdata->reserved_ready = false;
962 mutex_unlock(&local->chanctx_mtx); 991
963 return ret; 992 return 0;
964} 993}
965 994
966int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata, 995static void
967 u32 *changed) 996ieee80211_vif_chanctx_reservation_complete(struct ieee80211_sub_if_data *sdata)
968{ 997{
969 struct ieee80211_local *local = sdata->local; 998 switch (sdata->vif.type) {
970 struct ieee80211_chanctx *ctx; 999 case NL80211_IFTYPE_ADHOC:
971 struct ieee80211_chanctx *old_ctx; 1000 case NL80211_IFTYPE_AP:
972 struct ieee80211_chanctx_conf *conf; 1001 case NL80211_IFTYPE_MESH_POINT:
973 int ret; 1002 ieee80211_queue_work(&sdata->local->hw,
974 u32 tmp_changed = *changed; 1003 &sdata->csa_finalize_work);
1004 break;
1005 case NL80211_IFTYPE_STATION:
1006 ieee80211_queue_work(&sdata->local->hw,
1007 &sdata->u.mgd.chswitch_work);
1008 break;
1009 case NL80211_IFTYPE_UNSPECIFIED:
1010 case NL80211_IFTYPE_AP_VLAN:
1011 case NL80211_IFTYPE_WDS:
1012 case NL80211_IFTYPE_MONITOR:
1013 case NL80211_IFTYPE_P2P_CLIENT:
1014 case NL80211_IFTYPE_P2P_GO:
1015 case NL80211_IFTYPE_P2P_DEVICE:
1016 case NUM_NL80211_IFTYPES:
1017 WARN_ON(1);
1018 break;
1019 }
1020}
975 1021
976 /* TODO: need to recheck if the chandef is usable etc.? */ 1022static int
1023ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
1024{
1025 struct ieee80211_local *local = sdata->local;
1026 struct ieee80211_vif_chanctx_switch vif_chsw[1] = {};
1027 struct ieee80211_chanctx *old_ctx, *new_ctx;
1028 const struct cfg80211_chan_def *chandef;
1029 u32 changed = 0;
1030 int err;
977 1031
978 lockdep_assert_held(&local->mtx); 1032 lockdep_assert_held(&local->mtx);
1033 lockdep_assert_held(&local->chanctx_mtx);
979 1034
980 mutex_lock(&local->chanctx_mtx); 1035 new_ctx = sdata->reserved_chanctx;
1036 old_ctx = ieee80211_vif_get_chanctx(sdata);
981 1037
982 ctx = sdata->reserved_chanctx; 1038 if (WARN_ON(!sdata->reserved_ready))
983 if (WARN_ON(!ctx)) { 1039 return -EBUSY;
984 ret = -EINVAL; 1040
985 goto out; 1041 if (WARN_ON(!new_ctx))
986 } 1042 return -EINVAL;
1043
1044 if (WARN_ON(!old_ctx))
1045 return -EINVAL;
1046
1047 if (WARN_ON(new_ctx->replace_state ==
1048 IEEE80211_CHANCTX_REPLACES_OTHER))
1049 return -EINVAL;
1050
1051 chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1052 &sdata->reserved_chandef);
1053 if (WARN_ON(!chandef))
1054 return -EINVAL;
1055
1056 vif_chsw[0].vif = &sdata->vif;
1057 vif_chsw[0].old_ctx = &old_ctx->conf;
1058 vif_chsw[0].new_ctx = &new_ctx->conf;
1059
1060 list_del(&sdata->reserved_chanctx_list);
1061 sdata->reserved_chanctx = NULL;
1062
1063 err = drv_switch_vif_chanctx(local, vif_chsw, 1,
1064 CHANCTX_SWMODE_REASSIGN_VIF);
1065 if (err) {
1066 if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1067 ieee80211_free_chanctx(local, new_ctx);
987 1068
988 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
989 lockdep_is_held(&local->chanctx_mtx));
990 if (!conf) {
991 ret = -EINVAL;
992 goto out; 1069 goto out;
993 } 1070 }
994 1071
995 old_ctx = container_of(conf, struct ieee80211_chanctx, conf); 1072 list_move(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs);
1073 rcu_assign_pointer(sdata->vif.chanctx_conf, &new_ctx->conf);
1074
1075 if (sdata->vif.type == NL80211_IFTYPE_AP)
1076 __ieee80211_vif_copy_chanctx_to_vlans(sdata, false);
1077
1078 if (ieee80211_chanctx_refcount(local, old_ctx) == 0)
1079 ieee80211_free_chanctx(local, old_ctx);
996 1080
997 if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width) 1081 if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
998 tmp_changed |= BSS_CHANGED_BANDWIDTH; 1082 changed = BSS_CHANGED_BANDWIDTH;
999 1083
1000 sdata->vif.bss_conf.chandef = sdata->reserved_chandef; 1084 sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
1001 1085
1002 /* unref our reservation */ 1086 if (changed)
1003 sdata->reserved_chanctx = NULL; 1087 ieee80211_bss_info_change_notify(sdata, changed);
1004 sdata->radar_required = sdata->reserved_radar_required; 1088
1089out:
1090 ieee80211_vif_chanctx_reservation_complete(sdata);
1091 return err;
1092}
1093
1094static int
1095ieee80211_vif_use_reserved_assign(struct ieee80211_sub_if_data *sdata)
1096{
1097 struct ieee80211_local *local = sdata->local;
1098 struct ieee80211_chanctx *old_ctx, *new_ctx;
1099 const struct cfg80211_chan_def *chandef;
1100 int err;
1101
1102 old_ctx = ieee80211_vif_get_chanctx(sdata);
1103 new_ctx = sdata->reserved_chanctx;
1104
1105 if (WARN_ON(!sdata->reserved_ready))
1106 return -EINVAL;
1107
1108 if (WARN_ON(old_ctx))
1109 return -EINVAL;
1110
1111 if (WARN_ON(!new_ctx))
1112 return -EINVAL;
1113
1114 if (WARN_ON(new_ctx->replace_state ==
1115 IEEE80211_CHANCTX_REPLACES_OTHER))
1116 return -EINVAL;
1117
1118 chandef = ieee80211_chanctx_non_reserved_chandef(local, new_ctx,
1119 &sdata->reserved_chandef);
1120 if (WARN_ON(!chandef))
1121 return -EINVAL;
1122
1005 list_del(&sdata->reserved_chanctx_list); 1123 list_del(&sdata->reserved_chanctx_list);
1124 sdata->reserved_chanctx = NULL;
1006 1125
1007 if (old_ctx == ctx) { 1126 err = ieee80211_assign_vif_chanctx(sdata, new_ctx);
1008 /* This is our own context, just change it */ 1127 if (err) {
1009 ret = __ieee80211_vif_change_channel(sdata, old_ctx, 1128 if (ieee80211_chanctx_refcount(local, new_ctx) == 0)
1010 &tmp_changed); 1129 ieee80211_free_chanctx(local, new_ctx);
1011 if (ret) 1130
1012 goto out; 1131 goto out;
1013 } else { 1132 }
1014 ret = ieee80211_assign_vif_chanctx(sdata, ctx); 1133
1015 if (ieee80211_chanctx_refcount(local, old_ctx) == 0) 1134out:
1016 ieee80211_free_chanctx(local, old_ctx); 1135 ieee80211_vif_chanctx_reservation_complete(sdata);
1017 if (ret) { 1136 return err;
1018 /* if assign fails refcount stays the same */ 1137}
1019 if (ieee80211_chanctx_refcount(local, ctx) == 0) 1138
1020 ieee80211_free_chanctx(local, ctx); 1139static bool
1140ieee80211_vif_has_in_place_reservation(struct ieee80211_sub_if_data *sdata)
1141{
1142 struct ieee80211_chanctx *old_ctx, *new_ctx;
1143
1144 lockdep_assert_held(&sdata->local->chanctx_mtx);
1145
1146 new_ctx = sdata->reserved_chanctx;
1147 old_ctx = ieee80211_vif_get_chanctx(sdata);
1148
1149 if (!old_ctx)
1150 return false;
1151
1152 if (WARN_ON(!new_ctx))
1153 return false;
1154
1155 if (old_ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1156 return false;
1157
1158 if (new_ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1159 return false;
1160
1161 return true;
1162}
1163
1164static int ieee80211_chsw_switch_hwconf(struct ieee80211_local *local,
1165 struct ieee80211_chanctx *new_ctx)
1166{
1167 const struct cfg80211_chan_def *chandef;
1168
1169 lockdep_assert_held(&local->mtx);
1170 lockdep_assert_held(&local->chanctx_mtx);
1171
1172 chandef = ieee80211_chanctx_reserved_chandef(local, new_ctx, NULL);
1173 if (WARN_ON(!chandef))
1174 return -EINVAL;
1175
1176 local->hw.conf.radar_enabled = new_ctx->conf.radar_enabled;
1177 local->_oper_chandef = *chandef;
1178 ieee80211_hw_config(local, 0);
1179
1180 return 0;
1181}
1182
1183static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,
1184 int n_vifs)
1185{
1186 struct ieee80211_vif_chanctx_switch *vif_chsw;
1187 struct ieee80211_sub_if_data *sdata;
1188 struct ieee80211_chanctx *ctx, *old_ctx;
1189 int i, err;
1190
1191 lockdep_assert_held(&local->mtx);
1192 lockdep_assert_held(&local->chanctx_mtx);
1193
1194 vif_chsw = kzalloc(sizeof(vif_chsw[0]) * n_vifs, GFP_KERNEL);
1195 if (!vif_chsw)
1196 return -ENOMEM;
1197
1198 i = 0;
1199 list_for_each_entry(ctx, &local->chanctx_list, list) {
1200 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1201 continue;
1202
1203 if (WARN_ON(!ctx->replace_ctx)) {
1204 err = -EINVAL;
1021 goto out; 1205 goto out;
1022 } 1206 }
1023 1207
1024 if (sdata->vif.type == NL80211_IFTYPE_AP) 1208 list_for_each_entry(sdata, &ctx->reserved_vifs,
1025 __ieee80211_vif_copy_chanctx_to_vlans(sdata, false); 1209 reserved_chanctx_list) {
1210 if (!ieee80211_vif_has_in_place_reservation(
1211 sdata))
1212 continue;
1213
1214 old_ctx = ieee80211_vif_get_chanctx(sdata);
1215 vif_chsw[i].vif = &sdata->vif;
1216 vif_chsw[i].old_ctx = &old_ctx->conf;
1217 vif_chsw[i].new_ctx = &ctx->conf;
1218
1219 i++;
1220 }
1026 } 1221 }
1027 1222
1028 *changed = tmp_changed; 1223 err = drv_switch_vif_chanctx(local, vif_chsw, n_vifs,
1224 CHANCTX_SWMODE_SWAP_CONTEXTS);
1029 1225
1030 ieee80211_recalc_chanctx_chantype(local, ctx);
1031 ieee80211_recalc_smps_chanctx(local, ctx);
1032 ieee80211_recalc_radar_chanctx(local, ctx);
1033 ieee80211_recalc_chanctx_min_def(local, ctx);
1034out: 1226out:
1035 mutex_unlock(&local->chanctx_mtx); 1227 kfree(vif_chsw);
1036 return ret; 1228 return err;
1229}
1230
1231static int ieee80211_chsw_switch_ctxs(struct ieee80211_local *local)
1232{
1233 struct ieee80211_chanctx *ctx;
1234 int err;
1235
1236 lockdep_assert_held(&local->mtx);
1237 lockdep_assert_held(&local->chanctx_mtx);
1238
1239 list_for_each_entry(ctx, &local->chanctx_list, list) {
1240 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1241 continue;
1242
1243 if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1244 continue;
1245
1246 ieee80211_del_chanctx(local, ctx->replace_ctx);
1247 err = ieee80211_add_chanctx(local, ctx);
1248 if (err)
1249 goto err;
1250 }
1251
1252 return 0;
1253
1254err:
1255 WARN_ON(ieee80211_add_chanctx(local, ctx));
1256 list_for_each_entry_continue_reverse(ctx, &local->chanctx_list, list) {
1257 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1258 continue;
1259
1260 if (!list_empty(&ctx->replace_ctx->assigned_vifs))
1261 continue;
1262
1263 ieee80211_del_chanctx(local, ctx);
1264 WARN_ON(ieee80211_add_chanctx(local, ctx->replace_ctx));
1265 }
1266
1267 return err;
1268}
1269
1270int
1271ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1272{
1273 struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1274 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
1275 struct ieee80211_chanctx *new_ctx = NULL;
1276 int i, err, n_assigned, n_reserved, n_ready;
1277 int n_ctx = 0, n_vifs_switch = 0, n_vifs_assign = 0, n_vifs_ctxless = 0;
1278
1279 lockdep_assert_held(&local->mtx);
1280 lockdep_assert_held(&local->chanctx_mtx);
1281
1282 /*
1283 * If there are 2 independent pairs of channel contexts performing
1284 * cross-switch of their vifs this code will still wait until both are
1285 * ready even though it could be possible to switch one before the
1286 * other is ready.
1287 *
1288 * For practical reasons and code simplicity just do a single huge
1289 * switch.
1290 */
1291
1292 /*
1293 * Verify if the reservation is still feasible.
1294 * - if it's not then disconnect
1295 * - if it is but not all vifs necessary are ready then defer
1296 */
1297
1298 list_for_each_entry(ctx, &local->chanctx_list, list) {
1299 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1300 continue;
1301
1302 if (WARN_ON(!ctx->replace_ctx)) {
1303 err = -EINVAL;
1304 goto err;
1305 }
1306
1307 if (!local->use_chanctx)
1308 new_ctx = ctx;
1309
1310 n_ctx++;
1311
1312 n_assigned = 0;
1313 n_reserved = 0;
1314 n_ready = 0;
1315
1316 list_for_each_entry(sdata, &ctx->replace_ctx->assigned_vifs,
1317 assigned_chanctx_list) {
1318 n_assigned++;
1319 if (sdata->reserved_chanctx) {
1320 n_reserved++;
1321 if (sdata->reserved_ready)
1322 n_ready++;
1323 }
1324 }
1325
1326 if (n_assigned != n_reserved) {
1327 if (n_ready == n_reserved) {
1328 wiphy_info(local->hw.wiphy,
1329 "channel context reservation cannot be finalized because some interfaces aren't switching\n");
1330 err = -EBUSY;
1331 goto err;
1332 }
1333
1334 return -EAGAIN;
1335 }
1336
1337 ctx->conf.radar_enabled = false;
1338 list_for_each_entry(sdata, &ctx->reserved_vifs,
1339 reserved_chanctx_list) {
1340 if (ieee80211_vif_has_in_place_reservation(sdata) &&
1341 !sdata->reserved_ready)
1342 return -EAGAIN;
1343
1344 old_ctx = ieee80211_vif_get_chanctx(sdata);
1345 if (old_ctx) {
1346 if (old_ctx->replace_state ==
1347 IEEE80211_CHANCTX_WILL_BE_REPLACED)
1348 n_vifs_switch++;
1349 else
1350 n_vifs_assign++;
1351 } else {
1352 n_vifs_ctxless++;
1353 }
1354
1355 if (sdata->reserved_radar_required)
1356 ctx->conf.radar_enabled = true;
1357 }
1358 }
1359
1360 if (WARN_ON(n_ctx == 0) ||
1361 WARN_ON(n_vifs_switch == 0 &&
1362 n_vifs_assign == 0 &&
1363 n_vifs_ctxless == 0) ||
1364 WARN_ON(n_ctx > 1 && !local->use_chanctx) ||
1365 WARN_ON(!new_ctx && !local->use_chanctx)) {
1366 err = -EINVAL;
1367 goto err;
1368 }
1369
1370 /*
1371 * All necessary vifs are ready. Perform the switch now depending on
1372 * reservations and driver capabilities.
1373 */
1374
1375 if (local->use_chanctx) {
1376 if (n_vifs_switch > 0) {
1377 err = ieee80211_chsw_switch_vifs(local, n_vifs_switch);
1378 if (err)
1379 goto err;
1380 }
1381
1382 if (n_vifs_assign > 0 || n_vifs_ctxless > 0) {
1383 err = ieee80211_chsw_switch_ctxs(local);
1384 if (err)
1385 goto err;
1386 }
1387 } else {
1388 err = ieee80211_chsw_switch_hwconf(local, new_ctx);
1389 if (err)
1390 goto err;
1391 }
1392
1393 /*
1394 * Update all structures, values and pointers to point to new channel
1395 * context(s).
1396 */
1397
1398 i = 0;
1399 list_for_each_entry(ctx, &local->chanctx_list, list) {
1400 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1401 continue;
1402
1403 if (WARN_ON(!ctx->replace_ctx)) {
1404 err = -EINVAL;
1405 goto err;
1406 }
1407
1408 list_for_each_entry(sdata, &ctx->reserved_vifs,
1409 reserved_chanctx_list) {
1410 u32 changed = 0;
1411
1412 if (!ieee80211_vif_has_in_place_reservation(sdata))
1413 continue;
1414
1415 rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
1416
1417 if (sdata->vif.type == NL80211_IFTYPE_AP)
1418 __ieee80211_vif_copy_chanctx_to_vlans(sdata,
1419 false);
1420
1421 sdata->radar_required = sdata->reserved_radar_required;
1422
1423 if (sdata->vif.bss_conf.chandef.width !=
1424 sdata->reserved_chandef.width)
1425 changed = BSS_CHANGED_BANDWIDTH;
1426
1427 sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
1428 if (changed)
1429 ieee80211_bss_info_change_notify(sdata,
1430 changed);
1431
1432 ieee80211_recalc_txpower(sdata);
1433 }
1434
1435 ieee80211_recalc_chanctx_chantype(local, ctx);
1436 ieee80211_recalc_smps_chanctx(local, ctx);
1437 ieee80211_recalc_radar_chanctx(local, ctx);
1438 ieee80211_recalc_chanctx_min_def(local, ctx);
1439
1440 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1441 reserved_chanctx_list) {
1442 if (ieee80211_vif_get_chanctx(sdata) != ctx)
1443 continue;
1444
1445 list_del(&sdata->reserved_chanctx_list);
1446 list_move(&sdata->assigned_chanctx_list,
1447 &new_ctx->assigned_vifs);
1448 sdata->reserved_chanctx = NULL;
1449
1450 ieee80211_vif_chanctx_reservation_complete(sdata);
1451 }
1452
1453 /*
1454 * This context might have been a dependency for an already
1455 * ready re-assign reservation interface that was deferred. Do
1456 * not propagate error to the caller though. The in-place
1457 * reservation for originally requested interface has already
1458 * succeeded at this point.
1459 */
1460 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1461 reserved_chanctx_list) {
1462 if (WARN_ON(ieee80211_vif_has_in_place_reservation(
1463 sdata)))
1464 continue;
1465
1466 if (WARN_ON(sdata->reserved_chanctx != ctx))
1467 continue;
1468
1469 if (!sdata->reserved_ready)
1470 continue;
1471
1472 if (ieee80211_vif_get_chanctx(sdata))
1473 err = ieee80211_vif_use_reserved_reassign(
1474 sdata);
1475 else
1476 err = ieee80211_vif_use_reserved_assign(sdata);
1477
1478 if (err) {
1479 sdata_info(sdata,
1480 "failed to finalize (re-)assign reservation (err=%d)\n",
1481 err);
1482 ieee80211_vif_unreserve_chanctx(sdata);
1483 cfg80211_stop_iface(local->hw.wiphy,
1484 &sdata->wdev,
1485 GFP_KERNEL);
1486 }
1487 }
1488 }
1489
1490 /*
1491 * Finally free old contexts
1492 */
1493
1494 list_for_each_entry_safe(ctx, ctx_tmp, &local->chanctx_list, list) {
1495 if (ctx->replace_state != IEEE80211_CHANCTX_WILL_BE_REPLACED)
1496 continue;
1497
1498 ctx->replace_ctx->replace_ctx = NULL;
1499 ctx->replace_ctx->replace_state =
1500 IEEE80211_CHANCTX_REPLACE_NONE;
1501
1502 list_del_rcu(&ctx->list);
1503 kfree_rcu(ctx, rcu_head);
1504 }
1505
1506 return 0;
1507
1508err:
1509 list_for_each_entry(ctx, &local->chanctx_list, list) {
1510 if (ctx->replace_state != IEEE80211_CHANCTX_REPLACES_OTHER)
1511 continue;
1512
1513 list_for_each_entry_safe(sdata, sdata_tmp, &ctx->reserved_vifs,
1514 reserved_chanctx_list) {
1515 ieee80211_vif_unreserve_chanctx(sdata);
1516 ieee80211_vif_chanctx_reservation_complete(sdata);
1517 }
1518 }
1519
1520 return err;
1521}
1522
1523int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1524{
1525 struct ieee80211_local *local = sdata->local;
1526 struct ieee80211_chanctx *new_ctx;
1527 struct ieee80211_chanctx *old_ctx;
1528 int err;
1529
1530 lockdep_assert_held(&local->mtx);
1531 lockdep_assert_held(&local->chanctx_mtx);
1532
1533 new_ctx = sdata->reserved_chanctx;
1534 old_ctx = ieee80211_vif_get_chanctx(sdata);
1535
1536 if (WARN_ON(!new_ctx))
1537 return -EINVAL;
1538
1539 if (WARN_ON(new_ctx->replace_state ==
1540 IEEE80211_CHANCTX_WILL_BE_REPLACED))
1541 return -EINVAL;
1542
1543 if (WARN_ON(sdata->reserved_ready))
1544 return -EINVAL;
1545
1546 sdata->reserved_ready = true;
1547
1548 if (new_ctx->replace_state == IEEE80211_CHANCTX_REPLACE_NONE) {
1549 if (old_ctx)
1550 err = ieee80211_vif_use_reserved_reassign(sdata);
1551 else
1552 err = ieee80211_vif_use_reserved_assign(sdata);
1553
1554 if (err)
1555 return err;
1556 }
1557
1558 /*
1559 * In-place reservation may need to be finalized now either if:
1560 * a) sdata is taking part in the swapping itself and is the last one
1561 * b) sdata has switched with a re-assign reservation to an existing
1562 * context readying in-place switching of old_ctx
1563 *
1564 * In case of (b) do not propagate the error up because the requested
1565 * sdata already switched successfully. Just spill an extra warning.
1566 * The ieee80211_vif_use_reserved_switch() already stops all necessary
1567 * interfaces upon failure.
1568 */
1569 if ((old_ctx &&
1570 old_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) ||
1571 new_ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER) {
1572 err = ieee80211_vif_use_reserved_switch(local);
1573 if (err && err != -EAGAIN) {
1574 if (new_ctx->replace_state ==
1575 IEEE80211_CHANCTX_REPLACES_OTHER)
1576 return err;
1577
1578 wiphy_info(local->hw.wiphy,
1579 "depending in-place reservation failed (err=%d)\n",
1580 err);
1581 }
1582 }
1583
1584 return 0;
1037} 1585}
1038 1586
1039int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 1587int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
@@ -1043,6 +1591,7 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1043 struct ieee80211_local *local = sdata->local; 1591 struct ieee80211_local *local = sdata->local;
1044 struct ieee80211_chanctx_conf *conf; 1592 struct ieee80211_chanctx_conf *conf;
1045 struct ieee80211_chanctx *ctx; 1593 struct ieee80211_chanctx *ctx;
1594 const struct cfg80211_chan_def *compat;
1046 int ret; 1595 int ret;
1047 1596
1048 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef, 1597 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
@@ -1069,11 +1618,33 @@ int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1069 } 1618 }
1070 1619
1071 ctx = container_of(conf, struct ieee80211_chanctx, conf); 1620 ctx = container_of(conf, struct ieee80211_chanctx, conf);
1072 if (!cfg80211_chandef_compatible(&conf->def, chandef)) { 1621
1622 compat = cfg80211_chandef_compatible(&conf->def, chandef);
1623 if (!compat) {
1073 ret = -EINVAL; 1624 ret = -EINVAL;
1074 goto out; 1625 goto out;
1075 } 1626 }
1076 1627
1628 switch (ctx->replace_state) {
1629 case IEEE80211_CHANCTX_REPLACE_NONE:
1630 if (!ieee80211_chanctx_reserved_chandef(local, ctx, compat)) {
1631 ret = -EBUSY;
1632 goto out;
1633 }
1634 break;
1635 case IEEE80211_CHANCTX_WILL_BE_REPLACED:
1636 /* TODO: Perhaps the bandwith change could be treated as a
1637 * reservation itself? */
1638 ret = -EBUSY;
1639 goto out;
1640 case IEEE80211_CHANCTX_REPLACES_OTHER:
1641 /* channel context that is going to replace another channel
1642 * context doesn't really exist and shouldn't be assigned
1643 * anywhere yet */
1644 WARN_ON(1);
1645 break;
1646 }
1647
1077 sdata->vif.bss_conf.chandef = *chandef; 1648 sdata->vif.bss_conf.chandef = *chandef;
1078 1649
1079 ieee80211_recalc_chanctx_chantype(local, ctx); 1650 ieee80211_recalc_chanctx_chantype(local, ctx);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2ecb4deddb5d..3db96648b45a 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -124,7 +124,7 @@ static ssize_t sta_connected_time_read(struct file *file, char __user *userbuf,
124 long connected_time_secs; 124 long connected_time_secs;
125 char buf[100]; 125 char buf[100];
126 int res; 126 int res;
127 do_posix_clock_monotonic_gettime(&uptime); 127 ktime_get_ts(&uptime);
128 connected_time_secs = uptime.tv_sec - sta->last_connected; 128 connected_time_secs = uptime.tv_sec - sta->last_connected;
129 time_to_tm(connected_time_secs, 0, &result); 129 time_to_tm(connected_time_secs, 0, &result);
130 result.tm_year -= 70; 130 result.tm_year -= 70;
@@ -587,7 +587,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
587 DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count); 587 DEBUGFS_ADD_COUNTER(tx_filtered, tx_filtered_count);
588 DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed); 588 DEBUGFS_ADD_COUNTER(tx_retry_failed, tx_retry_failed);
589 DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count); 589 DEBUGFS_ADD_COUNTER(tx_retry_count, tx_retry_count);
590 DEBUGFS_ADD_COUNTER(wep_weak_iv_count, wep_weak_iv_count);
591 590
592 if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) 591 if (sizeof(sta->driver_buffered_tids) == sizeof(u32))
593 debugfs_create_x32("driver_buffered_tids", 0400, 592 debugfs_create_x32("driver_buffered_tids", 0400,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index bd782dcffcc7..11423958116a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -314,7 +314,7 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
314 314
315static inline int drv_hw_scan(struct ieee80211_local *local, 315static inline int drv_hw_scan(struct ieee80211_local *local,
316 struct ieee80211_sub_if_data *sdata, 316 struct ieee80211_sub_if_data *sdata,
317 struct cfg80211_scan_request *req) 317 struct ieee80211_scan_request *req)
318{ 318{
319 int ret; 319 int ret;
320 320
@@ -346,7 +346,7 @@ static inline int
346drv_sched_scan_start(struct ieee80211_local *local, 346drv_sched_scan_start(struct ieee80211_local *local,
347 struct ieee80211_sub_if_data *sdata, 347 struct ieee80211_sub_if_data *sdata,
348 struct cfg80211_sched_scan_request *req, 348 struct cfg80211_sched_scan_request *req,
349 struct ieee80211_sched_scan_ies *ies) 349 struct ieee80211_scan_ies *ies)
350{ 350{
351 int ret; 351 int ret;
352 352
@@ -970,6 +970,22 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
970 trace_drv_return_void(local); 970 trace_drv_return_void(local);
971} 971}
972 972
973static inline void
974drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
975 struct ieee80211_sub_if_data *sdata)
976{
977 might_sleep();
978
979 if (!check_sdata_in_driver(sdata))
980 return;
981 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
982
983 trace_drv_mgd_protect_tdls_discover(local, sdata);
984 if (local->ops->mgd_protect_tdls_discover)
985 local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
986 trace_drv_return_void(local);
987}
988
973static inline int drv_add_chanctx(struct ieee80211_local *local, 989static inline int drv_add_chanctx(struct ieee80211_local *local,
974 struct ieee80211_chanctx *ctx) 990 struct ieee80211_chanctx *ctx)
975{ 991{
diff --git a/net/mac80211/ethtool.c b/net/mac80211/ethtool.c
new file mode 100644
index 000000000000..ebfc8091557b
--- /dev/null
+++ b/net/mac80211/ethtool.c
@@ -0,0 +1,244 @@
1/*
2 * mac80211 ethtool hooks for cfg80211
3 *
4 * Copied from cfg.c - originally
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2014 Intel Corporation (Author: Johannes Berg)
7 *
8 * This file is GPLv2 as found in COPYING.
9 */
10#include <linux/types.h>
11#include <net/cfg80211.h>
12#include "ieee80211_i.h"
13#include "sta_info.h"
14#include "driver-ops.h"
15
16static int ieee80211_set_ringparam(struct net_device *dev,
17 struct ethtool_ringparam *rp)
18{
19 struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
20
21 if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
22 return -EINVAL;
23
24 return drv_set_ringparam(local, rp->tx_pending, rp->rx_pending);
25}
26
27static void ieee80211_get_ringparam(struct net_device *dev,
28 struct ethtool_ringparam *rp)
29{
30 struct ieee80211_local *local = wiphy_priv(dev->ieee80211_ptr->wiphy);
31
32 memset(rp, 0, sizeof(*rp));
33
34 drv_get_ringparam(local, &rp->tx_pending, &rp->tx_max_pending,
35 &rp->rx_pending, &rp->rx_max_pending);
36}
37
38static const char ieee80211_gstrings_sta_stats[][ETH_GSTRING_LEN] = {
39 "rx_packets", "rx_bytes",
40 "rx_duplicates", "rx_fragments", "rx_dropped",
41 "tx_packets", "tx_bytes", "tx_fragments",
42 "tx_filtered", "tx_retry_failed", "tx_retries",
43 "beacon_loss", "sta_state", "txrate", "rxrate", "signal",
44 "channel", "noise", "ch_time", "ch_time_busy",
45 "ch_time_ext_busy", "ch_time_rx", "ch_time_tx"
46};
47#define STA_STATS_LEN ARRAY_SIZE(ieee80211_gstrings_sta_stats)
48
49static int ieee80211_get_sset_count(struct net_device *dev, int sset)
50{
51 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
52 int rv = 0;
53
54 if (sset == ETH_SS_STATS)
55 rv += STA_STATS_LEN;
56
57 rv += drv_get_et_sset_count(sdata, sset);
58
59 if (rv == 0)
60 return -EOPNOTSUPP;
61 return rv;
62}
63
64static void ieee80211_get_stats(struct net_device *dev,
65 struct ethtool_stats *stats,
66 u64 *data)
67{
68 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
69 struct ieee80211_chanctx_conf *chanctx_conf;
70 struct ieee80211_channel *channel;
71 struct sta_info *sta;
72 struct ieee80211_local *local = sdata->local;
73 struct station_info sinfo;
74 struct survey_info survey;
75 int i, q;
76#define STA_STATS_SURVEY_LEN 7
77
78 memset(data, 0, sizeof(u64) * STA_STATS_LEN);
79
80#define ADD_STA_STATS(sta) \
81 do { \
82 data[i++] += sta->rx_packets; \
83 data[i++] += sta->rx_bytes; \
84 data[i++] += sta->num_duplicates; \
85 data[i++] += sta->rx_fragments; \
86 data[i++] += sta->rx_dropped; \
87 \
88 data[i++] += sinfo.tx_packets; \
89 data[i++] += sinfo.tx_bytes; \
90 data[i++] += sta->tx_fragments; \
91 data[i++] += sta->tx_filtered_count; \
92 data[i++] += sta->tx_retry_failed; \
93 data[i++] += sta->tx_retry_count; \
94 data[i++] += sta->beacon_loss_count; \
95 } while (0)
96
97 /* For Managed stations, find the single station based on BSSID
98 * and use that. For interface types, iterate through all available
99 * stations and add stats for any station that is assigned to this
100 * network device.
101 */
102
103 mutex_lock(&local->sta_mtx);
104
105 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
106 sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid);
107
108 if (!(sta && !WARN_ON(sta->sdata->dev != dev)))
109 goto do_survey;
110
111 sinfo.filled = 0;
112 sta_set_sinfo(sta, &sinfo);
113
114 i = 0;
115 ADD_STA_STATS(sta);
116
117 data[i++] = sta->sta_state;
118
119
120 if (sinfo.filled & STATION_INFO_TX_BITRATE)
121 data[i] = 100000 *
122 cfg80211_calculate_bitrate(&sinfo.txrate);
123 i++;
124 if (sinfo.filled & STATION_INFO_RX_BITRATE)
125 data[i] = 100000 *
126 cfg80211_calculate_bitrate(&sinfo.rxrate);
127 i++;
128
129 if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
130 data[i] = (u8)sinfo.signal_avg;
131 i++;
132 } else {
133 list_for_each_entry(sta, &local->sta_list, list) {
134 /* Make sure this station belongs to the proper dev */
135 if (sta->sdata->dev != dev)
136 continue;
137
138 sinfo.filled = 0;
139 sta_set_sinfo(sta, &sinfo);
140 i = 0;
141 ADD_STA_STATS(sta);
142 }
143 }
144
145do_survey:
146 i = STA_STATS_LEN - STA_STATS_SURVEY_LEN;
147 /* Get survey stats for current channel */
148 survey.filled = 0;
149
150 rcu_read_lock();
151 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
152 if (chanctx_conf)
153 channel = chanctx_conf->def.chan;
154 else
155 channel = NULL;
156 rcu_read_unlock();
157
158 if (channel) {
159 q = 0;
160 do {
161 survey.filled = 0;
162 if (drv_get_survey(local, q, &survey) != 0) {
163 survey.filled = 0;
164 break;
165 }
166 q++;
167 } while (channel != survey.channel);
168 }
169
170 if (survey.filled)
171 data[i++] = survey.channel->center_freq;
172 else
173 data[i++] = 0;
174 if (survey.filled & SURVEY_INFO_NOISE_DBM)
175 data[i++] = (u8)survey.noise;
176 else
177 data[i++] = -1LL;
178 if (survey.filled & SURVEY_INFO_CHANNEL_TIME)
179 data[i++] = survey.channel_time;
180 else
181 data[i++] = -1LL;
182 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
183 data[i++] = survey.channel_time_busy;
184 else
185 data[i++] = -1LL;
186 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
187 data[i++] = survey.channel_time_ext_busy;
188 else
189 data[i++] = -1LL;
190 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_RX)
191 data[i++] = survey.channel_time_rx;
192 else
193 data[i++] = -1LL;
194 if (survey.filled & SURVEY_INFO_CHANNEL_TIME_TX)
195 data[i++] = survey.channel_time_tx;
196 else
197 data[i++] = -1LL;
198
199 mutex_unlock(&local->sta_mtx);
200
201 if (WARN_ON(i != STA_STATS_LEN))
202 return;
203
204 drv_get_et_stats(sdata, stats, &(data[STA_STATS_LEN]));
205}
206
207static void ieee80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
208{
209 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
210 int sz_sta_stats = 0;
211
212 if (sset == ETH_SS_STATS) {
213 sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
214 memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
215 }
216 drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
217}
218
219static int ieee80211_get_regs_len(struct net_device *dev)
220{
221 return 0;
222}
223
224static void ieee80211_get_regs(struct net_device *dev,
225 struct ethtool_regs *regs,
226 void *data)
227{
228 struct wireless_dev *wdev = dev->ieee80211_ptr;
229
230 regs->version = wdev->wiphy->hw_version;
231 regs->len = 0;
232}
233
234const struct ethtool_ops ieee80211_ethtool_ops = {
235 .get_drvinfo = cfg80211_get_drvinfo,
236 .get_regs_len = ieee80211_get_regs_len,
237 .get_regs = ieee80211_get_regs,
238 .get_link = ethtool_op_get_link,
239 .get_ringparam = ieee80211_get_ringparam,
240 .set_ringparam = ieee80211_set_ringparam,
241 .get_strings = ieee80211_get_strings,
242 .get_ethtool_stats = ieee80211_get_stats,
243 .get_sset_count = ieee80211_get_sset_count,
244};
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 18ee0a256b1e..713485f9effc 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -143,7 +143,7 @@ ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
143 *pos++ = csa_settings->block_tx ? 1 : 0; 143 *pos++ = csa_settings->block_tx ? 1 : 0;
144 *pos++ = ieee80211_frequency_to_channel( 144 *pos++ = ieee80211_frequency_to_channel(
145 csa_settings->chandef.chan->center_freq); 145 csa_settings->chandef.chan->center_freq);
146 sdata->csa_counter_offset_beacon[0] = (pos - presp->head); 146 presp->csa_counter_offsets[0] = (pos - presp->head);
147 *pos++ = csa_settings->count; 147 *pos++ = csa_settings->count;
148 } 148 }
149 149
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ac9836e0aab3..9e025e1184cc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -229,16 +229,29 @@ struct ieee80211_rx_data {
229 u16 tkip_iv16; 229 u16 tkip_iv16;
230}; 230};
231 231
232struct ieee80211_csa_settings {
233 const u16 *counter_offsets_beacon;
234 const u16 *counter_offsets_presp;
235
236 int n_counter_offsets_beacon;
237 int n_counter_offsets_presp;
238
239 u8 count;
240};
241
232struct beacon_data { 242struct beacon_data {
233 u8 *head, *tail; 243 u8 *head, *tail;
234 int head_len, tail_len; 244 int head_len, tail_len;
235 struct ieee80211_meshconf_ie *meshconf; 245 struct ieee80211_meshconf_ie *meshconf;
246 u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
247 u8 csa_current_counter;
236 struct rcu_head rcu_head; 248 struct rcu_head rcu_head;
237}; 249};
238 250
239struct probe_resp { 251struct probe_resp {
240 struct rcu_head rcu_head; 252 struct rcu_head rcu_head;
241 int len; 253 int len;
254 u16 csa_counter_offsets[IEEE80211_MAX_CSA_COUNTERS_NUM];
242 u8 data[0]; 255 u8 data[0];
243}; 256};
244 257
@@ -688,6 +701,24 @@ enum ieee80211_chanctx_mode {
688 IEEE80211_CHANCTX_EXCLUSIVE 701 IEEE80211_CHANCTX_EXCLUSIVE
689}; 702};
690 703
704/**
705 * enum ieee80211_chanctx_replace_state - channel context replacement state
706 *
707 * This is used for channel context in-place reservations that require channel
708 * context switch/swap.
709 *
710 * @IEEE80211_CHANCTX_REPLACE_NONE: no replacement is taking place
711 * @IEEE80211_CHANCTX_WILL_BE_REPLACED: this channel context will be replaced
712 * by a (not yet registered) channel context pointed by %replace_ctx.
713 * @IEEE80211_CHANCTX_REPLACES_OTHER: this (not yet registered) channel context
714 * replaces an existing channel context pointed to by %replace_ctx.
715 */
716enum ieee80211_chanctx_replace_state {
717 IEEE80211_CHANCTX_REPLACE_NONE,
718 IEEE80211_CHANCTX_WILL_BE_REPLACED,
719 IEEE80211_CHANCTX_REPLACES_OTHER,
720};
721
691struct ieee80211_chanctx { 722struct ieee80211_chanctx {
692 struct list_head list; 723 struct list_head list;
693 struct rcu_head rcu_head; 724 struct rcu_head rcu_head;
@@ -695,6 +726,9 @@ struct ieee80211_chanctx {
695 struct list_head assigned_vifs; 726 struct list_head assigned_vifs;
696 struct list_head reserved_vifs; 727 struct list_head reserved_vifs;
697 728
729 enum ieee80211_chanctx_replace_state replace_state;
730 struct ieee80211_chanctx *replace_ctx;
731
698 enum ieee80211_chanctx_mode mode; 732 enum ieee80211_chanctx_mode mode;
699 bool driver_present; 733 bool driver_present;
700 734
@@ -754,9 +788,6 @@ struct ieee80211_sub_if_data {
754 struct mac80211_qos_map __rcu *qos_map; 788 struct mac80211_qos_map __rcu *qos_map;
755 789
756 struct work_struct csa_finalize_work; 790 struct work_struct csa_finalize_work;
757 u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM];
758 u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM];
759 bool csa_radar_required;
760 bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ 791 bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
761 struct cfg80211_chan_def csa_chandef; 792 struct cfg80211_chan_def csa_chandef;
762 793
@@ -767,7 +798,7 @@ struct ieee80211_sub_if_data {
767 struct ieee80211_chanctx *reserved_chanctx; 798 struct ieee80211_chanctx *reserved_chanctx;
768 struct cfg80211_chan_def reserved_chandef; 799 struct cfg80211_chan_def reserved_chandef;
769 bool reserved_radar_required; 800 bool reserved_radar_required;
770 u8 csa_current_counter; 801 bool reserved_ready;
771 802
772 /* used to reconfigure hardware SM PS */ 803 /* used to reconfigure hardware SM PS */
773 struct work_struct recalc_smps; 804 struct work_struct recalc_smps;
@@ -784,6 +815,9 @@ struct ieee80211_sub_if_data {
784 bool radar_required; 815 bool radar_required;
785 struct delayed_work dfs_cac_timer_work; 816 struct delayed_work dfs_cac_timer_work;
786 817
818 u8 tdls_peer[ETH_ALEN] __aligned(2);
819 struct delayed_work tdls_peer_del_work;
820
787 /* 821 /*
788 * AP this belongs to: self in AP mode and 822 * AP this belongs to: self in AP mode and
789 * corresponding AP in VLAN mode, NULL for 823 * corresponding AP in VLAN mode, NULL for
@@ -912,6 +946,9 @@ enum queue_stop_reason {
912 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 946 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
913 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL, 947 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
914 IEEE80211_QUEUE_STOP_REASON_FLUSH, 948 IEEE80211_QUEUE_STOP_REASON_FLUSH,
949 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN,
950
951 IEEE80211_QUEUE_STOP_REASONS,
915}; 952};
916 953
917#ifdef CONFIG_MAC80211_LEDS 954#ifdef CONFIG_MAC80211_LEDS
@@ -1008,6 +1045,7 @@ struct ieee80211_local {
1008 struct workqueue_struct *workqueue; 1045 struct workqueue_struct *workqueue;
1009 1046
1010 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; 1047 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
1048 int q_stop_reasons[IEEE80211_MAX_QUEUES][IEEE80211_QUEUE_STOP_REASONS];
1011 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 1049 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
1012 spinlock_t queue_stop_reason_lock; 1050 spinlock_t queue_stop_reason_lock;
1013 1051
@@ -1135,7 +1173,8 @@ struct ieee80211_local {
1135 unsigned long scanning; 1173 unsigned long scanning;
1136 struct cfg80211_ssid scan_ssid; 1174 struct cfg80211_ssid scan_ssid;
1137 struct cfg80211_scan_request *int_scan_req; 1175 struct cfg80211_scan_request *int_scan_req;
1138 struct cfg80211_scan_request *scan_req, *hw_scan_req; 1176 struct cfg80211_scan_request *scan_req;
1177 struct ieee80211_scan_request *hw_scan_req;
1139 struct cfg80211_chan_def scan_chandef; 1178 struct cfg80211_chan_def scan_chandef;
1140 enum ieee80211_band hw_scan_band; 1179 enum ieee80211_band hw_scan_band;
1141 int scan_channel_idx; 1180 int scan_channel_idx;
@@ -1476,7 +1515,6 @@ void ieee80211_sw_roc_work(struct work_struct *work);
1476void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); 1515void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
1477 1516
1478/* channel switch handling */ 1517/* channel switch handling */
1479bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local);
1480void ieee80211_csa_finalize_work(struct work_struct *work); 1518void ieee80211_csa_finalize_work(struct work_struct *work);
1481int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 1519int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
1482 struct cfg80211_csa_settings *params); 1520 struct cfg80211_csa_settings *params);
@@ -1705,14 +1743,24 @@ void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
1705 1743
1706void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 1744void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
1707 unsigned long queues, 1745 unsigned long queues,
1708 enum queue_stop_reason reason); 1746 enum queue_stop_reason reason,
1747 bool refcounted);
1748void ieee80211_stop_vif_queues(struct ieee80211_local *local,
1749 struct ieee80211_sub_if_data *sdata,
1750 enum queue_stop_reason reason);
1751void ieee80211_wake_vif_queues(struct ieee80211_local *local,
1752 struct ieee80211_sub_if_data *sdata,
1753 enum queue_stop_reason reason);
1709void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 1754void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
1710 unsigned long queues, 1755 unsigned long queues,
1711 enum queue_stop_reason reason); 1756 enum queue_stop_reason reason,
1757 bool refcounted);
1712void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 1758void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
1713 enum queue_stop_reason reason); 1759 enum queue_stop_reason reason,
1760 bool refcounted);
1714void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 1761void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
1715 enum queue_stop_reason reason); 1762 enum queue_stop_reason reason,
1763 bool refcounted);
1716void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); 1764void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue);
1717void ieee80211_add_pending_skb(struct ieee80211_local *local, 1765void ieee80211_add_pending_skb(struct ieee80211_local *local,
1718 struct sk_buff *skb); 1766 struct sk_buff *skb);
@@ -1730,8 +1778,10 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1730 const u8 *bssid, u16 stype, u16 reason, 1778 const u8 *bssid, u16 stype, u16 reason,
1731 bool send_frame, u8 *frame_buf); 1779 bool send_frame, u8 *frame_buf);
1732int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1780int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1733 size_t buffer_len, const u8 *ie, size_t ie_len, 1781 size_t buffer_len,
1734 enum ieee80211_band band, u32 rate_mask, 1782 struct ieee80211_scan_ies *ie_desc,
1783 const u8 *ie, size_t ie_len,
1784 u8 bands_used, u32 *rate_masks,
1735 struct cfg80211_chan_def *chandef); 1785 struct cfg80211_chan_def *chandef);
1736struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1786struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1737 u8 *dst, u32 ratemask, 1787 u8 *dst, u32 ratemask,
@@ -1791,18 +1841,14 @@ ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
1791 enum ieee80211_chanctx_mode mode, 1841 enum ieee80211_chanctx_mode mode,
1792 bool radar_required); 1842 bool radar_required);
1793int __must_check 1843int __must_check
1794ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata, 1844ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata);
1795 u32 *changed);
1796int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata); 1845int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata);
1846int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local);
1797 1847
1798int __must_check 1848int __must_check
1799ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 1849ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1800 const struct cfg80211_chan_def *chandef, 1850 const struct cfg80211_chan_def *chandef,
1801 u32 *changed); 1851 u32 *changed);
1802/* NOTE: only use ieee80211_vif_change_channel() for channel switch */
1803int __must_check
1804ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
1805 u32 *changed);
1806void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1852void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1807void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); 1853void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
1808void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 1854void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
@@ -1842,11 +1888,14 @@ int ieee80211_max_num_channels(struct ieee80211_local *local);
1842int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 1888int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
1843 const u8 *peer, u8 action_code, u8 dialog_token, 1889 const u8 *peer, u8 action_code, u8 dialog_token,
1844 u16 status_code, u32 peer_capability, 1890 u16 status_code, u32 peer_capability,
1845 const u8 *extra_ies, size_t extra_ies_len); 1891 bool initiator, const u8 *extra_ies,
1892 size_t extra_ies_len);
1846int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, 1893int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
1847 const u8 *peer, enum nl80211_tdls_operation oper); 1894 const u8 *peer, enum nl80211_tdls_operation oper);
1848 1895
1849 1896
1897extern const struct ethtool_ops ieee80211_ethtool_ops;
1898
1850#ifdef CONFIG_MAC80211_NOINLINE 1899#ifdef CONFIG_MAC80211_NOINLINE
1851#define debug_noinline noinline 1900#define debug_noinline noinline
1852#else 1901#else
@@ -1854,3 +1903,4 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
1854#endif 1903#endif
1855 1904
1856#endif /* IEEE80211_I_H */ 1905#endif /* IEEE80211_I_H */
1906void ieee80211_tdls_peer_del_work(struct work_struct *wk);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 388b863e821c..bbf51b2f0651 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -841,10 +841,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
841 sdata_lock(sdata); 841 sdata_lock(sdata);
842 mutex_lock(&local->mtx); 842 mutex_lock(&local->mtx);
843 sdata->vif.csa_active = false; 843 sdata->vif.csa_active = false;
844 if (!ieee80211_csa_needs_block_tx(local)) 844 if (sdata->csa_block_tx) {
845 ieee80211_wake_queues_by_reason(&local->hw, 845 ieee80211_wake_vif_queues(local, sdata,
846 IEEE80211_MAX_QUEUE_MAP, 846 IEEE80211_QUEUE_STOP_REASON_CSA);
847 IEEE80211_QUEUE_STOP_REASON_CSA); 847 sdata->csa_block_tx = false;
848 }
848 mutex_unlock(&local->mtx); 849 mutex_unlock(&local->mtx);
849 sdata_unlock(sdata); 850 sdata_unlock(sdata);
850 851
@@ -1671,6 +1672,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1671 ieee80211_dfs_cac_timer_work); 1672 ieee80211_dfs_cac_timer_work);
1672 INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk, 1673 INIT_DELAYED_WORK(&sdata->dec_tailroom_needed_wk,
1673 ieee80211_delayed_tailroom_dec); 1674 ieee80211_delayed_tailroom_dec);
1675 INIT_DELAYED_WORK(&sdata->tdls_peer_del_work,
1676 ieee80211_tdls_peer_del_work);
1674 1677
1675 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 1678 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
1676 struct ieee80211_supported_band *sband; 1679 struct ieee80211_supported_band *sband;
@@ -1705,6 +1708,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1705 1708
1706 ndev->features |= local->hw.netdev_features; 1709 ndev->features |= local->hw.netdev_features;
1707 1710
1711 netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops);
1712
1708 ret = register_netdevice(ndev); 1713 ret = register_netdevice(ndev);
1709 if (ret) { 1714 if (ret) {
1710 free_netdev(ndev); 1715 free_netdev(ndev);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d17c26d6e369..e0ab4320a078 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -272,7 +272,8 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
272 272
273 /* use this reason, ieee80211_reconfig will unblock it */ 273 /* use this reason, ieee80211_reconfig will unblock it */
274 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 274 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
275 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 275 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
276 false);
276 277
277 /* 278 /*
278 * Stop all Rx during the reconfig. We don't want state changes 279 * Stop all Rx during the reconfig. We don't want state changes
@@ -1187,18 +1188,12 @@ static int __init ieee80211_init(void)
1187 if (ret) 1188 if (ret)
1188 goto err_minstrel; 1189 goto err_minstrel;
1189 1190
1190 ret = rc80211_pid_init();
1191 if (ret)
1192 goto err_pid;
1193
1194 ret = ieee80211_iface_init(); 1191 ret = ieee80211_iface_init();
1195 if (ret) 1192 if (ret)
1196 goto err_netdev; 1193 goto err_netdev;
1197 1194
1198 return 0; 1195 return 0;
1199 err_netdev: 1196 err_netdev:
1200 rc80211_pid_exit();
1201 err_pid:
1202 rc80211_minstrel_ht_exit(); 1197 rc80211_minstrel_ht_exit();
1203 err_minstrel: 1198 err_minstrel:
1204 rc80211_minstrel_exit(); 1199 rc80211_minstrel_exit();
@@ -1208,7 +1203,6 @@ static int __init ieee80211_init(void)
1208 1203
1209static void __exit ieee80211_exit(void) 1204static void __exit ieee80211_exit(void)
1210{ 1205{
1211 rc80211_pid_exit();
1212 rc80211_minstrel_ht_exit(); 1206 rc80211_minstrel_ht_exit();
1213 rc80211_minstrel_exit(); 1207 rc80211_minstrel_exit();
1214 1208
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 6495a3f0428d..e9f99c1e3fad 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -679,7 +679,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
679 *pos++ = 0x0; 679 *pos++ = 0x0;
680 *pos++ = ieee80211_frequency_to_channel( 680 *pos++ = ieee80211_frequency_to_channel(
681 csa->settings.chandef.chan->center_freq); 681 csa->settings.chandef.chan->center_freq);
682 sdata->csa_counter_offset_beacon[0] = hdr_len + 6; 682 bcn->csa_counter_offsets[0] = hdr_len + 6;
683 *pos++ = csa->settings.count; 683 *pos++ = csa->settings.count;
684 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; 684 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM;
685 *pos++ = 6; 685 *pos++ = 6;
@@ -1122,7 +1122,7 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
1122 mgmt_fwd = (struct ieee80211_mgmt *) skb_put(skb, len); 1122 mgmt_fwd = (struct ieee80211_mgmt *) skb_put(skb, len);
1123 1123
1124 /* offset_ttl is based on whether the secondary channel 1124 /* offset_ttl is based on whether the secondary channel
1125 * offset is available or not. Substract 1 from the mesh TTL 1125 * offset is available or not. Subtract 1 from the mesh TTL
1126 * and disable the initiator flag before forwarding. 1126 * and disable the initiator flag before forwarding.
1127 */ 1127 */
1128 offset_ttl = (len < 42) ? 7 : 10; 1128 offset_ttl = (len < 42) ? 7 : 10;
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index e8f60aa2e848..63b874101b27 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -551,11 +551,30 @@ static void mesh_plink_timer(unsigned long data)
551 return; 551 return;
552 552
553 spin_lock_bh(&sta->lock); 553 spin_lock_bh(&sta->lock);
554 if (sta->ignore_plink_timer) { 554
555 sta->ignore_plink_timer = false; 555 /* If a timer fires just before a state transition on another CPU,
556 * we may have already extended the timeout and changed state by the
557 * time we've acquired the lock and arrived here. In that case,
558 * skip this timer and wait for the new one.
559 */
560 if (time_before(jiffies, sta->plink_timer.expires)) {
561 mpl_dbg(sta->sdata,
562 "Ignoring timer for %pM in state %s (timer adjusted)",
563 sta->sta.addr, mplstates[sta->plink_state]);
556 spin_unlock_bh(&sta->lock); 564 spin_unlock_bh(&sta->lock);
557 return; 565 return;
558 } 566 }
567
568 /* del_timer() and handler may race when entering these states */
569 if (sta->plink_state == NL80211_PLINK_LISTEN ||
570 sta->plink_state == NL80211_PLINK_ESTAB) {
571 mpl_dbg(sta->sdata,
572 "Ignoring timer for %pM in state %s (timer deleted)",
573 sta->sta.addr, mplstates[sta->plink_state]);
574 spin_unlock_bh(&sta->lock);
575 return;
576 }
577
559 mpl_dbg(sta->sdata, 578 mpl_dbg(sta->sdata,
560 "Mesh plink timer for %pM fired on state %s\n", 579 "Mesh plink timer for %pM fired on state %s\n",
561 sta->sta.addr, mplstates[sta->plink_state]); 580 sta->sta.addr, mplstates[sta->plink_state]);
@@ -773,9 +792,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
773 break; 792 break;
774 case CNF_ACPT: 793 case CNF_ACPT:
775 sta->plink_state = NL80211_PLINK_CNF_RCVD; 794 sta->plink_state = NL80211_PLINK_CNF_RCVD;
776 if (!mod_plink_timer(sta, 795 mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout);
777 mshcfg->dot11MeshConfirmTimeout))
778 sta->ignore_plink_timer = true;
779 break; 796 break;
780 default: 797 default:
781 break; 798 break;
@@ -834,8 +851,7 @@ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
834 case NL80211_PLINK_HOLDING: 851 case NL80211_PLINK_HOLDING:
835 switch (event) { 852 switch (event) {
836 case CLS_ACPT: 853 case CLS_ACPT:
837 if (del_timer(&sta->plink_timer)) 854 del_timer(&sta->plink_timer);
838 sta->ignore_plink_timer = 1;
839 mesh_plink_fsm_restart(sta); 855 mesh_plink_fsm_restart(sta);
840 break; 856 break;
841 case OPN_ACPT: 857 case OPN_ACPT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 3345401be1b3..931330bbe00c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -940,51 +940,70 @@ static void ieee80211_chswitch_work(struct work_struct *work)
940 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work); 940 container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
941 struct ieee80211_local *local = sdata->local; 941 struct ieee80211_local *local = sdata->local;
942 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 942 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
943 u32 changed = 0;
944 int ret; 943 int ret;
945 944
946 if (!ieee80211_sdata_running(sdata)) 945 if (!ieee80211_sdata_running(sdata))
947 return; 946 return;
948 947
949 sdata_lock(sdata); 948 sdata_lock(sdata);
949 mutex_lock(&local->mtx);
950 mutex_lock(&local->chanctx_mtx);
951
950 if (!ifmgd->associated) 952 if (!ifmgd->associated)
951 goto out; 953 goto out;
952 954
953 mutex_lock(&local->mtx); 955 if (!sdata->vif.csa_active)
954 ret = ieee80211_vif_change_channel(sdata, &changed); 956 goto out;
955 mutex_unlock(&local->mtx); 957
956 if (ret) { 958 /*
959 * using reservation isn't immediate as it may be deferred until later
960 * with multi-vif. once reservation is complete it will re-schedule the
961 * work with no reserved_chanctx so verify chandef to check if it
962 * completed successfully
963 */
964
965 if (sdata->reserved_chanctx) {
966 /*
967 * with multi-vif csa driver may call ieee80211_csa_finish()
968 * many times while waiting for other interfaces to use their
969 * reservations
970 */
971 if (sdata->reserved_ready)
972 goto out;
973
974 ret = ieee80211_vif_use_reserved_context(sdata);
975 if (ret) {
976 sdata_info(sdata,
977 "failed to use reserved channel context, disconnecting (err=%d)\n",
978 ret);
979 ieee80211_queue_work(&sdata->local->hw,
980 &ifmgd->csa_connection_drop_work);
981 goto out;
982 }
983
984 goto out;
985 }
986
987 if (!cfg80211_chandef_identical(&sdata->vif.bss_conf.chandef,
988 &sdata->csa_chandef)) {
957 sdata_info(sdata, 989 sdata_info(sdata,
958 "vif channel switch failed, disconnecting\n"); 990 "failed to finalize channel switch, disconnecting\n");
959 ieee80211_queue_work(&sdata->local->hw, 991 ieee80211_queue_work(&sdata->local->hw,
960 &ifmgd->csa_connection_drop_work); 992 &ifmgd->csa_connection_drop_work);
961 goto out; 993 goto out;
962 } 994 }
963 995
964 if (!local->use_chanctx) {
965 local->_oper_chandef = sdata->csa_chandef;
966 /* Call "hw_config" only if doing sw channel switch.
967 * Otherwise update the channel directly
968 */
969 if (!local->ops->channel_switch)
970 ieee80211_hw_config(local, 0);
971 else
972 local->hw.conf.chandef = local->_oper_chandef;
973 }
974
975 /* XXX: shouldn't really modify cfg80211-owned data! */ 996 /* XXX: shouldn't really modify cfg80211-owned data! */
976 ifmgd->associated->channel = sdata->csa_chandef.chan; 997 ifmgd->associated->channel = sdata->csa_chandef.chan;
977 998
978 ieee80211_bss_info_change_notify(sdata, changed);
979
980 mutex_lock(&local->mtx);
981 sdata->vif.csa_active = false; 999 sdata->vif.csa_active = false;
1000
982 /* XXX: wait for a beacon first? */ 1001 /* XXX: wait for a beacon first? */
983 if (!ieee80211_csa_needs_block_tx(local)) 1002 if (sdata->csa_block_tx) {
984 ieee80211_wake_queues_by_reason(&local->hw, 1003 ieee80211_wake_vif_queues(local, sdata,
985 IEEE80211_MAX_QUEUE_MAP, 1004 IEEE80211_QUEUE_STOP_REASON_CSA);
986 IEEE80211_QUEUE_STOP_REASON_CSA); 1005 sdata->csa_block_tx = false;
987 mutex_unlock(&local->mtx); 1006 }
988 1007
989 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; 1008 ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
990 1009
@@ -992,6 +1011,8 @@ static void ieee80211_chswitch_work(struct work_struct *work)
992 ieee80211_sta_reset_conn_monitor(sdata); 1011 ieee80211_sta_reset_conn_monitor(sdata);
993 1012
994out: 1013out:
1014 mutex_unlock(&local->chanctx_mtx);
1015 mutex_unlock(&local->mtx);
995 sdata_unlock(sdata); 1016 sdata_unlock(sdata);
996} 1017}
997 1018
@@ -1028,6 +1049,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1028 struct ieee80211_local *local = sdata->local; 1049 struct ieee80211_local *local = sdata->local;
1029 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1050 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1030 struct cfg80211_bss *cbss = ifmgd->associated; 1051 struct cfg80211_bss *cbss = ifmgd->associated;
1052 struct ieee80211_chanctx_conf *conf;
1031 struct ieee80211_chanctx *chanctx; 1053 struct ieee80211_chanctx *chanctx;
1032 enum ieee80211_band current_band; 1054 enum ieee80211_band current_band;
1033 struct ieee80211_csa_ie csa_ie; 1055 struct ieee80211_csa_ie csa_ie;
@@ -1071,7 +1093,22 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1071 1093
1072 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED; 1094 ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
1073 1095
1096 mutex_lock(&local->mtx);
1074 mutex_lock(&local->chanctx_mtx); 1097 mutex_lock(&local->chanctx_mtx);
1098 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1099 lockdep_is_held(&local->chanctx_mtx));
1100 if (!conf) {
1101 sdata_info(sdata,
1102 "no channel context assigned to vif?, disconnecting\n");
1103 ieee80211_queue_work(&local->hw,
1104 &ifmgd->csa_connection_drop_work);
1105 mutex_unlock(&local->chanctx_mtx);
1106 mutex_unlock(&local->mtx);
1107 return;
1108 }
1109
1110 chanctx = container_of(conf, struct ieee80211_chanctx, conf);
1111
1075 if (local->use_chanctx) { 1112 if (local->use_chanctx) {
1076 u32 num_chanctx = 0; 1113 u32 num_chanctx = 0;
1077 list_for_each_entry(chanctx, &local->chanctx_list, list) 1114 list_for_each_entry(chanctx, &local->chanctx_list, list)
@@ -1084,38 +1121,32 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1084 ieee80211_queue_work(&local->hw, 1121 ieee80211_queue_work(&local->hw,
1085 &ifmgd->csa_connection_drop_work); 1122 &ifmgd->csa_connection_drop_work);
1086 mutex_unlock(&local->chanctx_mtx); 1123 mutex_unlock(&local->chanctx_mtx);
1124 mutex_unlock(&local->mtx);
1087 return; 1125 return;
1088 } 1126 }
1089 } 1127 }
1090 1128
1091 if (WARN_ON(!rcu_access_pointer(sdata->vif.chanctx_conf))) { 1129 res = ieee80211_vif_reserve_chanctx(sdata, &csa_ie.chandef,
1092 ieee80211_queue_work(&local->hw, 1130 chanctx->mode, false);
1093 &ifmgd->csa_connection_drop_work); 1131 if (res) {
1094 mutex_unlock(&local->chanctx_mtx);
1095 return;
1096 }
1097 chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf),
1098 struct ieee80211_chanctx, conf);
1099 if (ieee80211_chanctx_refcount(local, chanctx) > 1) {
1100 sdata_info(sdata, 1132 sdata_info(sdata,
1101 "channel switch with multiple interfaces on the same channel, disconnecting\n"); 1133 "failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
1134 res);
1102 ieee80211_queue_work(&local->hw, 1135 ieee80211_queue_work(&local->hw,
1103 &ifmgd->csa_connection_drop_work); 1136 &ifmgd->csa_connection_drop_work);
1104 mutex_unlock(&local->chanctx_mtx); 1137 mutex_unlock(&local->chanctx_mtx);
1138 mutex_unlock(&local->mtx);
1105 return; 1139 return;
1106 } 1140 }
1107 mutex_unlock(&local->chanctx_mtx); 1141 mutex_unlock(&local->chanctx_mtx);
1108 1142
1109 sdata->csa_chandef = csa_ie.chandef;
1110
1111 mutex_lock(&local->mtx);
1112 sdata->vif.csa_active = true; 1143 sdata->vif.csa_active = true;
1144 sdata->csa_chandef = csa_ie.chandef;
1113 sdata->csa_block_tx = csa_ie.mode; 1145 sdata->csa_block_tx = csa_ie.mode;
1114 1146
1115 if (sdata->csa_block_tx) 1147 if (sdata->csa_block_tx)
1116 ieee80211_stop_queues_by_reason(&local->hw, 1148 ieee80211_stop_vif_queues(local, sdata,
1117 IEEE80211_MAX_QUEUE_MAP, 1149 IEEE80211_QUEUE_STOP_REASON_CSA);
1118 IEEE80211_QUEUE_STOP_REASON_CSA);
1119 mutex_unlock(&local->mtx); 1150 mutex_unlock(&local->mtx);
1120 1151
1121 if (local->ops->channel_switch) { 1152 if (local->ops->channel_switch) {
@@ -1385,7 +1416,8 @@ void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
1385 1416
1386 ieee80211_wake_queues_by_reason(&local->hw, 1417 ieee80211_wake_queues_by_reason(&local->hw,
1387 IEEE80211_MAX_QUEUE_MAP, 1418 IEEE80211_MAX_QUEUE_MAP,
1388 IEEE80211_QUEUE_STOP_REASON_PS); 1419 IEEE80211_QUEUE_STOP_REASON_PS,
1420 false);
1389} 1421}
1390 1422
1391void ieee80211_dynamic_ps_enable_work(struct work_struct *work) 1423void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
@@ -1830,10 +1862,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1830 ieee80211_vif_release_channel(sdata); 1862 ieee80211_vif_release_channel(sdata);
1831 1863
1832 sdata->vif.csa_active = false; 1864 sdata->vif.csa_active = false;
1833 if (!ieee80211_csa_needs_block_tx(local)) 1865 if (sdata->csa_block_tx) {
1834 ieee80211_wake_queues_by_reason(&local->hw, 1866 ieee80211_wake_vif_queues(local, sdata,
1835 IEEE80211_MAX_QUEUE_MAP, 1867 IEEE80211_QUEUE_STOP_REASON_CSA);
1836 IEEE80211_QUEUE_STOP_REASON_CSA); 1868 sdata->csa_block_tx = false;
1869 }
1837 mutex_unlock(&local->mtx); 1870 mutex_unlock(&local->mtx);
1838 1871
1839 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM; 1872 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
@@ -2079,10 +2112,11 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2079 2112
2080 mutex_lock(&local->mtx); 2113 mutex_lock(&local->mtx);
2081 sdata->vif.csa_active = false; 2114 sdata->vif.csa_active = false;
2082 if (!ieee80211_csa_needs_block_tx(local)) 2115 if (sdata->csa_block_tx) {
2083 ieee80211_wake_queues_by_reason(&local->hw, 2116 ieee80211_wake_vif_queues(local, sdata,
2084 IEEE80211_MAX_QUEUE_MAP, 2117 IEEE80211_QUEUE_STOP_REASON_CSA);
2085 IEEE80211_QUEUE_STOP_REASON_CSA); 2118 sdata->csa_block_tx = false;
2119 }
2086 mutex_unlock(&local->mtx); 2120 mutex_unlock(&local->mtx);
2087 2121
2088 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 2122 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 7a17decd27f9..ff20b2ebdb30 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -119,7 +119,8 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local)
119 * before sending nullfunc to enable powersave at the AP. 119 * before sending nullfunc to enable powersave at the AP.
120 */ 120 */
121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 121 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 122 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
123 false);
123 ieee80211_flush_queues(local, NULL); 124 ieee80211_flush_queues(local, NULL);
124 125
125 mutex_lock(&local->iflist_mtx); 126 mutex_lock(&local->iflist_mtx);
@@ -182,7 +183,8 @@ void ieee80211_offchannel_return(struct ieee80211_local *local)
182 mutex_unlock(&local->iflist_mtx); 183 mutex_unlock(&local->iflist_mtx);
183 184
184 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 185 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP,
185 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL); 186 IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL,
187 false);
186} 188}
187 189
188void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) 190void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc)
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index d478b880a0af..4c5192e0d66c 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -35,7 +35,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
35 35
36 ieee80211_stop_queues_by_reason(hw, 36 ieee80211_stop_queues_by_reason(hw,
37 IEEE80211_MAX_QUEUE_MAP, 37 IEEE80211_MAX_QUEUE_MAP,
38 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 38 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
39 false);
39 40
40 /* flush out all packets */ 41 /* flush out all packets */
41 synchronize_net(); 42 synchronize_net();
@@ -74,7 +75,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
74 } 75 }
75 ieee80211_wake_queues_by_reason(hw, 76 ieee80211_wake_queues_by_reason(hw,
76 IEEE80211_MAX_QUEUE_MAP, 77 IEEE80211_MAX_QUEUE_MAP,
77 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 78 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
79 false);
78 return err; 80 return err;
79 } else if (err > 0) { 81 } else if (err > 0) {
80 WARN_ON(err != 1); 82 WARN_ON(err != 1);
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 9aa2a1190a86..18babe302832 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -143,19 +143,6 @@ void rate_control_deinitialize(struct ieee80211_local *local);
143 143
144 144
145/* Rate control algorithms */ 145/* Rate control algorithms */
146#ifdef CONFIG_MAC80211_RC_PID
147int rc80211_pid_init(void);
148void rc80211_pid_exit(void);
149#else
150static inline int rc80211_pid_init(void)
151{
152 return 0;
153}
154static inline void rc80211_pid_exit(void)
155{
156}
157#endif
158
159#ifdef CONFIG_MAC80211_RC_MINSTREL 146#ifdef CONFIG_MAC80211_RC_MINSTREL
160int rc80211_minstrel_init(void); 147int rc80211_minstrel_init(void);
161void rc80211_minstrel_exit(void); 148void rc80211_minstrel_exit(void);
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
deleted file mode 100644
index 19111c7bf454..000000000000
--- a/net/mac80211/rc80211_pid.h
+++ /dev/null
@@ -1,278 +0,0 @@
1/*
2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
3 * Copyright 2007, Stefano Brivio <stefano.brivio@polimi.it>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#ifndef RC80211_PID_H
11#define RC80211_PID_H
12
13/* Sampling period for measuring percentage of failed frames in ms. */
14#define RC_PID_INTERVAL 125
15
16/* Exponential averaging smoothness (used for I part of PID controller) */
17#define RC_PID_SMOOTHING_SHIFT 3
18#define RC_PID_SMOOTHING (1 << RC_PID_SMOOTHING_SHIFT)
19
20/* Sharpening factor (used for D part of PID controller) */
21#define RC_PID_SHARPENING_FACTOR 0
22#define RC_PID_SHARPENING_DURATION 0
23
24/* Fixed point arithmetic shifting amount. */
25#define RC_PID_ARITH_SHIFT 8
26
27/* Proportional PID component coefficient. */
28#define RC_PID_COEFF_P 15
29/* Integral PID component coefficient. */
30#define RC_PID_COEFF_I 9
31/* Derivative PID component coefficient. */
32#define RC_PID_COEFF_D 15
33
34/* Target failed frames rate for the PID controller. NB: This effectively gives
35 * maximum failed frames percentage we're willing to accept. If the wireless
36 * link quality is good, the controller will fail to adjust failed frames
37 * percentage to the target. This is intentional.
38 */
39#define RC_PID_TARGET_PF 14
40
41/* Rate behaviour normalization quantity over time. */
42#define RC_PID_NORM_OFFSET 3
43
44/* Push high rates right after loading. */
45#define RC_PID_FAST_START 0
46
47/* Arithmetic right shift for positive and negative values for ISO C. */
48#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
49 ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
50
51enum rc_pid_event_type {
52 RC_PID_EVENT_TYPE_TX_STATUS,
53 RC_PID_EVENT_TYPE_RATE_CHANGE,
54 RC_PID_EVENT_TYPE_TX_RATE,
55 RC_PID_EVENT_TYPE_PF_SAMPLE,
56};
57
58union rc_pid_event_data {
59 /* RC_PID_EVENT_TX_STATUS */
60 struct {
61 u32 flags;
62 struct ieee80211_tx_info tx_status;
63 };
64 /* RC_PID_EVENT_TYPE_RATE_CHANGE */
65 /* RC_PID_EVENT_TYPE_TX_RATE */
66 struct {
67 int index;
68 int rate;
69 };
70 /* RC_PID_EVENT_TYPE_PF_SAMPLE */
71 struct {
72 s32 pf_sample;
73 s32 prop_err;
74 s32 int_err;
75 s32 der_err;
76 };
77};
78
79struct rc_pid_event {
80 /* The time when the event occurred */
81 unsigned long timestamp;
82
83 /* Event ID number */
84 unsigned int id;
85
86 /* Type of event */
87 enum rc_pid_event_type type;
88
89 /* type specific data */
90 union rc_pid_event_data data;
91};
92
93/* Size of the event ring buffer. */
94#define RC_PID_EVENT_RING_SIZE 32
95
96struct rc_pid_event_buffer {
97 /* Counter that generates event IDs */
98 unsigned int ev_count;
99
100 /* Ring buffer of events */
101 struct rc_pid_event ring[RC_PID_EVENT_RING_SIZE];
102
103 /* Index to the entry in events_buf to be reused */
104 unsigned int next_entry;
105
106 /* Lock that guards against concurrent access to this buffer struct */
107 spinlock_t lock;
108
109 /* Wait queue for poll/select and blocking I/O */
110 wait_queue_head_t waitqueue;
111};
112
113struct rc_pid_events_file_info {
114 /* The event buffer we read */
115 struct rc_pid_event_buffer *events;
116
117 /* The entry we have should read next */
118 unsigned int next_entry;
119};
120
121/**
122 * struct rc_pid_debugfs_entries - tunable parameters
123 *
124 * Algorithm parameters, tunable via debugfs.
125 * @target: target percentage for failed frames
126 * @sampling_period: error sampling interval in milliseconds
127 * @coeff_p: absolute value of the proportional coefficient
128 * @coeff_i: absolute value of the integral coefficient
129 * @coeff_d: absolute value of the derivative coefficient
130 * @smoothing_shift: absolute value of the integral smoothing factor (i.e.
131 * amount of smoothing introduced by the exponential moving average)
132 * @sharpen_factor: absolute value of the derivative sharpening factor (i.e.
133 * amount of emphasis given to the derivative term after low activity
134 * events)
135 * @sharpen_duration: duration of the sharpening effect after the detected low
136 * activity event, relative to sampling_period
137 * @norm_offset: amount of normalization periodically performed on the learnt
138 * rate behaviour values (lower means we should trust more what we learnt
139 * about behaviour of rates, higher means we should trust more the natural
140 * ordering of rates)
141 */
142struct rc_pid_debugfs_entries {
143 struct dentry *target;
144 struct dentry *sampling_period;
145 struct dentry *coeff_p;
146 struct dentry *coeff_i;
147 struct dentry *coeff_d;
148 struct dentry *smoothing_shift;
149 struct dentry *sharpen_factor;
150 struct dentry *sharpen_duration;
151 struct dentry *norm_offset;
152};
153
154void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
155 struct ieee80211_tx_info *stat);
156
157void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
158 int index, int rate);
159
160void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
161 int index, int rate);
162
163void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
164 s32 pf_sample, s32 prop_err,
165 s32 int_err, s32 der_err);
166
167void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
168 struct dentry *dir);
169
170void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta);
171
172struct rc_pid_sta_info {
173 unsigned long last_change;
174 unsigned long last_sample;
175
176 u32 tx_num_failed;
177 u32 tx_num_xmit;
178
179 int txrate_idx;
180
181 /* Average failed frames percentage error (i.e. actual vs. target
182 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
183 * using using an exponential weighted average technique:
184 *
185 * (RC_PID_SMOOTHING - 1) * err_avg_old + err
186 * err_avg = ------------------------------------------
187 * RC_PID_SMOOTHING
188 *
189 * where err_avg is the new approximation, err_avg_old the previous one
190 * and err is the error w.r.t. to the current failed frames percentage
191 * sample. Note that the bigger RC_PID_SMOOTHING the more weight is
192 * given to the previous estimate, resulting in smoother behavior (i.e.
193 * corresponding to a longer integration window).
194 *
195 * For computation, we actually don't use the above formula, but this
196 * one:
197 *
198 * err_avg_scaled = err_avg_old_scaled - err_avg_old + err
199 *
200 * where:
201 * err_avg_scaled = err * RC_PID_SMOOTHING
202 * err_avg_old_scaled = err_avg_old * RC_PID_SMOOTHING
203 *
204 * This avoids floating point numbers and the per_failed_old value can
205 * easily be obtained by shifting per_failed_old_scaled right by
206 * RC_PID_SMOOTHING_SHIFT.
207 */
208 s32 err_avg_sc;
209
210 /* Last framed failes percentage sample. */
211 u32 last_pf;
212
213 /* Sharpening needed. */
214 u8 sharp_cnt;
215
216#ifdef CONFIG_MAC80211_DEBUGFS
217 /* Event buffer */
218 struct rc_pid_event_buffer events;
219
220 /* Events debugfs file entry */
221 struct dentry *events_entry;
222#endif
223};
224
225/* Algorithm parameters. We keep them on a per-algorithm approach, so they can
226 * be tuned individually for each interface.
227 */
228struct rc_pid_rateinfo {
229
230 /* Map sorted rates to rates in ieee80211_hw_mode. */
231 int index;
232
233 /* Map rates in ieee80211_hw_mode to sorted rates. */
234 int rev_index;
235
236 /* Did we do any measurement on this rate? */
237 bool valid;
238
239 /* Comparison with the lowest rate. */
240 int diff;
241};
242
243struct rc_pid_info {
244
245 /* The failed frames percentage target. */
246 unsigned int target;
247
248 /* Rate at which failed frames percentage is sampled in 0.001s. */
249 unsigned int sampling_period;
250
251 /* P, I and D coefficients. */
252 int coeff_p;
253 int coeff_i;
254 int coeff_d;
255
256 /* Exponential averaging shift. */
257 unsigned int smoothing_shift;
258
259 /* Sharpening factor and duration. */
260 unsigned int sharpen_factor;
261 unsigned int sharpen_duration;
262
263 /* Normalization offset. */
264 unsigned int norm_offset;
265
266 /* Rates information. */
267 struct rc_pid_rateinfo *rinfo;
268
269 /* Index of the last used rate. */
270 int oldrate;
271
272#ifdef CONFIG_MAC80211_DEBUGFS
273 /* Debugfs entries created for the parameters above. */
274 struct rc_pid_debugfs_entries dentries;
275#endif
276};
277
278#endif /* RC80211_PID_H */
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
deleted file mode 100644
index d0da2a70fe68..000000000000
--- a/net/mac80211/rc80211_pid_algo.c
+++ /dev/null
@@ -1,478 +0,0 @@
1/*
2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005, Devicescape Software, Inc.
4 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
5 * Copyright 2007-2008, Stefano Brivio <stefano.brivio@polimi.it>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/netdevice.h>
13#include <linux/types.h>
14#include <linux/skbuff.h>
15#include <linux/debugfs.h>
16#include <linux/slab.h>
17#include <net/mac80211.h>
18#include "rate.h"
19#include "mesh.h"
20#include "rc80211_pid.h"
21
22
23/* This is an implementation of a TX rate control algorithm that uses a PID
24 * controller. Given a target failed frames rate, the controller decides about
25 * TX rate changes to meet the target failed frames rate.
26 *
27 * The controller basically computes the following:
28 *
29 * adj = CP * err + CI * err_avg + CD * (err - last_err) * (1 + sharpening)
30 *
31 * where
32 * adj adjustment value that is used to switch TX rate (see below)
33 * err current error: target vs. current failed frames percentage
34 * last_err last error
35 * err_avg average (i.e. poor man's integral) of recent errors
36 * sharpening non-zero when fast response is needed (i.e. right after
37 * association or no frames sent for a long time), heading
38 * to zero over time
39 * CP Proportional coefficient
40 * CI Integral coefficient
41 * CD Derivative coefficient
42 *
43 * CP, CI, CD are subject to careful tuning.
44 *
45 * The integral component uses a exponential moving average approach instead of
46 * an actual sliding window. The advantage is that we don't need to keep an
47 * array of the last N error values and computation is easier.
48 *
49 * Once we have the adj value, we map it to a rate by means of a learning
50 * algorithm. This algorithm keeps the state of the percentual failed frames
51 * difference between rates. The behaviour of the lowest available rate is kept
52 * as a reference value, and every time we switch between two rates, we compute
53 * the difference between the failed frames each rate exhibited. By doing so,
54 * we compare behaviours which different rates exhibited in adjacent timeslices,
55 * thus the comparison is minimally affected by external conditions. This
56 * difference gets propagated to the whole set of measurements, so that the
57 * reference is always the same. Periodically, we normalize this set so that
58 * recent events weigh the most. By comparing the adj value with this set, we
59 * avoid pejorative switches to lower rates and allow for switches to higher
60 * rates if they behaved well.
61 *
62 * Note that for the computations we use a fixed-point representation to avoid
63 * floating point arithmetic. Hence, all values are shifted left by
64 * RC_PID_ARITH_SHIFT.
65 */
66
67
68/* Adjust the rate while ensuring that we won't switch to a lower rate if it
69 * exhibited a worse failed frames behaviour and we'll choose the highest rate
70 * whose failed frames behaviour is not worse than the one of the original rate
71 * target. While at it, check that the new rate is valid. */
72static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
73 struct ieee80211_sta *sta,
74 struct rc_pid_sta_info *spinfo, int adj,
75 struct rc_pid_rateinfo *rinfo)
76{
77 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
78 int cur = spinfo->txrate_idx;
79
80 band = sband->band;
81 n_bitrates = sband->n_bitrates;
82
83 /* Map passed arguments to sorted values. */
84 cur_sorted = rinfo[cur].rev_index;
85 new_sorted = cur_sorted + adj;
86
87 /* Check limits. */
88 if (new_sorted < 0)
89 new_sorted = rinfo[0].rev_index;
90 else if (new_sorted >= n_bitrates)
91 new_sorted = rinfo[n_bitrates - 1].rev_index;
92
93 tmp = new_sorted;
94
95 if (adj < 0) {
96 /* Ensure that the rate decrease isn't disadvantageous. */
97 for (probe = cur_sorted; probe >= new_sorted; probe--)
98 if (rinfo[probe].diff <= rinfo[cur_sorted].diff &&
99 rate_supported(sta, band, rinfo[probe].index))
100 tmp = probe;
101 } else {
102 /* Look for rate increase with zero (or below) cost. */
103 for (probe = new_sorted + 1; probe < n_bitrates; probe++)
104 if (rinfo[probe].diff <= rinfo[new_sorted].diff &&
105 rate_supported(sta, band, rinfo[probe].index))
106 tmp = probe;
107 }
108
109 /* Fit the rate found to the nearest supported rate. */
110 do {
111 if (rate_supported(sta, band, rinfo[tmp].index)) {
112 spinfo->txrate_idx = rinfo[tmp].index;
113 break;
114 }
115 if (adj < 0)
116 tmp--;
117 else
118 tmp++;
119 } while (tmp < n_bitrates && tmp >= 0);
120
121#ifdef CONFIG_MAC80211_DEBUGFS
122 rate_control_pid_event_rate_change(&spinfo->events,
123 spinfo->txrate_idx,
124 sband->bitrates[spinfo->txrate_idx].bitrate);
125#endif
126}
127
128/* Normalize the failed frames per-rate differences. */
129static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
130{
131 int i, norm_offset = pinfo->norm_offset;
132 struct rc_pid_rateinfo *r = pinfo->rinfo;
133
134 if (r[0].diff > norm_offset)
135 r[0].diff -= norm_offset;
136 else if (r[0].diff < -norm_offset)
137 r[0].diff += norm_offset;
138 for (i = 0; i < l - 1; i++)
139 if (r[i + 1].diff > r[i].diff + norm_offset)
140 r[i + 1].diff -= norm_offset;
141 else if (r[i + 1].diff <= r[i].diff)
142 r[i + 1].diff += norm_offset;
143}
144
145static void rate_control_pid_sample(struct rc_pid_info *pinfo,
146 struct ieee80211_supported_band *sband,
147 struct ieee80211_sta *sta,
148 struct rc_pid_sta_info *spinfo)
149{
150 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
151 u32 pf;
152 s32 err_avg;
153 u32 err_prop;
154 u32 err_int;
155 u32 err_der;
156 int adj, i, j, tmp;
157 unsigned long period;
158
159 /* In case nothing happened during the previous control interval, turn
160 * the sharpening factor on. */
161 period = msecs_to_jiffies(pinfo->sampling_period);
162 if (jiffies - spinfo->last_sample > 2 * period)
163 spinfo->sharp_cnt = pinfo->sharpen_duration;
164
165 spinfo->last_sample = jiffies;
166
167 /* This should never happen, but in case, we assume the old sample is
168 * still a good measurement and copy it. */
169 if (unlikely(spinfo->tx_num_xmit == 0))
170 pf = spinfo->last_pf;
171 else
172 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
173
174 spinfo->tx_num_xmit = 0;
175 spinfo->tx_num_failed = 0;
176
177 /* If we just switched rate, update the rate behaviour info. */
178 if (pinfo->oldrate != spinfo->txrate_idx) {
179
180 i = rinfo[pinfo->oldrate].rev_index;
181 j = rinfo[spinfo->txrate_idx].rev_index;
182
183 tmp = (pf - spinfo->last_pf);
184 tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT);
185
186 rinfo[j].diff = rinfo[i].diff + tmp;
187 pinfo->oldrate = spinfo->txrate_idx;
188 }
189 rate_control_pid_normalize(pinfo, sband->n_bitrates);
190
191 /* Compute the proportional, integral and derivative errors. */
192 err_prop = (pinfo->target - pf) << RC_PID_ARITH_SHIFT;
193
194 err_avg = spinfo->err_avg_sc >> pinfo->smoothing_shift;
195 spinfo->err_avg_sc = spinfo->err_avg_sc - err_avg + err_prop;
196 err_int = spinfo->err_avg_sc >> pinfo->smoothing_shift;
197
198 err_der = (pf - spinfo->last_pf) *
199 (1 + pinfo->sharpen_factor * spinfo->sharp_cnt);
200 spinfo->last_pf = pf;
201 if (spinfo->sharp_cnt)
202 spinfo->sharp_cnt--;
203
204#ifdef CONFIG_MAC80211_DEBUGFS
205 rate_control_pid_event_pf_sample(&spinfo->events, pf, err_prop, err_int,
206 err_der);
207#endif
208
209 /* Compute the controller output. */
210 adj = (err_prop * pinfo->coeff_p + err_int * pinfo->coeff_i
211 + err_der * pinfo->coeff_d);
212 adj = RC_PID_DO_ARITH_RIGHT_SHIFT(adj, 2 * RC_PID_ARITH_SHIFT);
213
214 /* Change rate. */
215 if (adj)
216 rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
217}
218
219static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
220 struct ieee80211_sta *sta, void *priv_sta,
221 struct sk_buff *skb)
222{
223 struct rc_pid_info *pinfo = priv;
224 struct rc_pid_sta_info *spinfo = priv_sta;
225 unsigned long period;
226 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
227
228 if (!spinfo)
229 return;
230
231 /* Ignore all frames that were sent with a different rate than the rate
232 * we currently advise mac80211 to use. */
233 if (info->status.rates[0].idx != spinfo->txrate_idx)
234 return;
235
236 spinfo->tx_num_xmit++;
237
238#ifdef CONFIG_MAC80211_DEBUGFS
239 rate_control_pid_event_tx_status(&spinfo->events, info);
240#endif
241
242 /* We count frames that totally failed to be transmitted as two bad
243 * frames, those that made it out but had some retries as one good and
244 * one bad frame. */
245 if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
246 spinfo->tx_num_failed += 2;
247 spinfo->tx_num_xmit++;
248 } else if (info->status.rates[0].count > 1) {
249 spinfo->tx_num_failed++;
250 spinfo->tx_num_xmit++;
251 }
252
253 /* Update PID controller state. */
254 period = msecs_to_jiffies(pinfo->sampling_period);
255 if (time_after(jiffies, spinfo->last_sample + period))
256 rate_control_pid_sample(pinfo, sband, sta, spinfo);
257}
258
259static void
260rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
261 void *priv_sta,
262 struct ieee80211_tx_rate_control *txrc)
263{
264 struct sk_buff *skb = txrc->skb;
265 struct ieee80211_supported_band *sband = txrc->sband;
266 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
267 struct rc_pid_sta_info *spinfo = priv_sta;
268 int rateidx;
269
270 if (txrc->rts)
271 info->control.rates[0].count =
272 txrc->hw->conf.long_frame_max_tx_count;
273 else
274 info->control.rates[0].count =
275 txrc->hw->conf.short_frame_max_tx_count;
276
277 /* Send management frames and NO_ACK data using lowest rate. */
278 if (rate_control_send_low(sta, priv_sta, txrc))
279 return;
280
281 rateidx = spinfo->txrate_idx;
282
283 if (rateidx >= sband->n_bitrates)
284 rateidx = sband->n_bitrates - 1;
285
286 info->control.rates[0].idx = rateidx;
287
288#ifdef CONFIG_MAC80211_DEBUGFS
289 rate_control_pid_event_tx_rate(&spinfo->events,
290 rateidx, sband->bitrates[rateidx].bitrate);
291#endif
292}
293
294static void
295rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
296 struct cfg80211_chan_def *chandef,
297 struct ieee80211_sta *sta, void *priv_sta)
298{
299 struct rc_pid_sta_info *spinfo = priv_sta;
300 struct rc_pid_info *pinfo = priv;
301 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
302 int i, j, tmp;
303 bool s;
304
305 /* TODO: This routine should consider using RSSI from previous packets
306 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
307 * Until that method is implemented, we will use the lowest supported
308 * rate as a workaround. */
309
310 /* Sort the rates. This is optimized for the most common case (i.e.
311 * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
312 * mapping too. */
313 for (i = 0; i < sband->n_bitrates; i++) {
314 rinfo[i].index = i;
315 rinfo[i].rev_index = i;
316 if (RC_PID_FAST_START)
317 rinfo[i].diff = 0;
318 else
319 rinfo[i].diff = i * pinfo->norm_offset;
320 }
321 for (i = 1; i < sband->n_bitrates; i++) {
322 s = false;
323 for (j = 0; j < sband->n_bitrates - i; j++)
324 if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
325 sband->bitrates[rinfo[j + 1].index].bitrate)) {
326 tmp = rinfo[j].index;
327 rinfo[j].index = rinfo[j + 1].index;
328 rinfo[j + 1].index = tmp;
329 rinfo[rinfo[j].index].rev_index = j;
330 rinfo[rinfo[j + 1].index].rev_index = j + 1;
331 s = true;
332 }
333 if (!s)
334 break;
335 }
336
337 spinfo->txrate_idx = rate_lowest_index(sband, sta);
338}
339
340static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
341 struct dentry *debugfsdir)
342{
343 struct rc_pid_info *pinfo;
344 struct rc_pid_rateinfo *rinfo;
345 struct ieee80211_supported_band *sband;
346 int i, max_rates = 0;
347#ifdef CONFIG_MAC80211_DEBUGFS
348 struct rc_pid_debugfs_entries *de;
349#endif
350
351 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
352 if (!pinfo)
353 return NULL;
354
355 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
356 sband = hw->wiphy->bands[i];
357 if (sband && sband->n_bitrates > max_rates)
358 max_rates = sband->n_bitrates;
359 }
360
361 rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
362 if (!rinfo) {
363 kfree(pinfo);
364 return NULL;
365 }
366
367 pinfo->target = RC_PID_TARGET_PF;
368 pinfo->sampling_period = RC_PID_INTERVAL;
369 pinfo->coeff_p = RC_PID_COEFF_P;
370 pinfo->coeff_i = RC_PID_COEFF_I;
371 pinfo->coeff_d = RC_PID_COEFF_D;
372 pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
373 pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
374 pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
375 pinfo->norm_offset = RC_PID_NORM_OFFSET;
376 pinfo->rinfo = rinfo;
377 pinfo->oldrate = 0;
378
379#ifdef CONFIG_MAC80211_DEBUGFS
380 de = &pinfo->dentries;
381 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
382 debugfsdir, &pinfo->target);
383 de->sampling_period = debugfs_create_u32("sampling_period",
384 S_IRUSR | S_IWUSR, debugfsdir,
385 &pinfo->sampling_period);
386 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
387 debugfsdir, (u32 *)&pinfo->coeff_p);
388 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
389 debugfsdir, (u32 *)&pinfo->coeff_i);
390 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
391 debugfsdir, (u32 *)&pinfo->coeff_d);
392 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
393 S_IRUSR | S_IWUSR, debugfsdir,
394 &pinfo->smoothing_shift);
395 de->sharpen_factor = debugfs_create_u32("sharpen_factor",
396 S_IRUSR | S_IWUSR, debugfsdir,
397 &pinfo->sharpen_factor);
398 de->sharpen_duration = debugfs_create_u32("sharpen_duration",
399 S_IRUSR | S_IWUSR, debugfsdir,
400 &pinfo->sharpen_duration);
401 de->norm_offset = debugfs_create_u32("norm_offset",
402 S_IRUSR | S_IWUSR, debugfsdir,
403 &pinfo->norm_offset);
404#endif
405
406 return pinfo;
407}
408
409static void rate_control_pid_free(void *priv)
410{
411 struct rc_pid_info *pinfo = priv;
412#ifdef CONFIG_MAC80211_DEBUGFS
413 struct rc_pid_debugfs_entries *de = &pinfo->dentries;
414
415 debugfs_remove(de->norm_offset);
416 debugfs_remove(de->sharpen_duration);
417 debugfs_remove(de->sharpen_factor);
418 debugfs_remove(de->smoothing_shift);
419 debugfs_remove(de->coeff_d);
420 debugfs_remove(de->coeff_i);
421 debugfs_remove(de->coeff_p);
422 debugfs_remove(de->sampling_period);
423 debugfs_remove(de->target);
424#endif
425
426 kfree(pinfo->rinfo);
427 kfree(pinfo);
428}
429
430static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
431 gfp_t gfp)
432{
433 struct rc_pid_sta_info *spinfo;
434
435 spinfo = kzalloc(sizeof(*spinfo), gfp);
436 if (spinfo == NULL)
437 return NULL;
438
439 spinfo->last_sample = jiffies;
440
441#ifdef CONFIG_MAC80211_DEBUGFS
442 spin_lock_init(&spinfo->events.lock);
443 init_waitqueue_head(&spinfo->events.waitqueue);
444#endif
445
446 return spinfo;
447}
448
449static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
450 void *priv_sta)
451{
452 kfree(priv_sta);
453}
454
455static const struct rate_control_ops mac80211_rcpid = {
456 .name = "pid",
457 .tx_status = rate_control_pid_tx_status,
458 .get_rate = rate_control_pid_get_rate,
459 .rate_init = rate_control_pid_rate_init,
460 .alloc = rate_control_pid_alloc,
461 .free = rate_control_pid_free,
462 .alloc_sta = rate_control_pid_alloc_sta,
463 .free_sta = rate_control_pid_free_sta,
464#ifdef CONFIG_MAC80211_DEBUGFS
465 .add_sta_debugfs = rate_control_pid_add_sta_debugfs,
466 .remove_sta_debugfs = rate_control_pid_remove_sta_debugfs,
467#endif
468};
469
470int __init rc80211_pid_init(void)
471{
472 return ieee80211_rate_control_register(&mac80211_rcpid);
473}
474
475void rc80211_pid_exit(void)
476{
477 ieee80211_rate_control_unregister(&mac80211_rcpid);
478}
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c
deleted file mode 100644
index 6ff134650a84..000000000000
--- a/net/mac80211/rc80211_pid_debugfs.c
+++ /dev/null
@@ -1,228 +0,0 @@
1/*
2 * Copyright 2007, Mattias Nissler <mattias.nissler@gmx.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/sched.h>
10#include <linux/spinlock.h>
11#include <linux/poll.h>
12#include <linux/netdevice.h>
13#include <linux/types.h>
14#include <linux/skbuff.h>
15#include <linux/slab.h>
16#include <linux/export.h>
17
18#include <net/mac80211.h>
19#include "rate.h"
20
21#include "rc80211_pid.h"
22
23static void rate_control_pid_event(struct rc_pid_event_buffer *buf,
24 enum rc_pid_event_type type,
25 union rc_pid_event_data *data)
26{
27 struct rc_pid_event *ev;
28 unsigned long status;
29
30 spin_lock_irqsave(&buf->lock, status);
31 ev = &(buf->ring[buf->next_entry]);
32 buf->next_entry = (buf->next_entry + 1) % RC_PID_EVENT_RING_SIZE;
33
34 ev->timestamp = jiffies;
35 ev->id = buf->ev_count++;
36 ev->type = type;
37 ev->data = *data;
38
39 spin_unlock_irqrestore(&buf->lock, status);
40
41 wake_up_all(&buf->waitqueue);
42}
43
44void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
45 struct ieee80211_tx_info *stat)
46{
47 union rc_pid_event_data evd;
48
49 evd.flags = stat->flags;
50 memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info));
51 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd);
52}
53
54void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf,
55 int index, int rate)
56{
57 union rc_pid_event_data evd;
58
59 evd.index = index;
60 evd.rate = rate;
61 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_RATE_CHANGE, &evd);
62}
63
64void rate_control_pid_event_tx_rate(struct rc_pid_event_buffer *buf,
65 int index, int rate)
66{
67 union rc_pid_event_data evd;
68
69 evd.index = index;
70 evd.rate = rate;
71 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_RATE, &evd);
72}
73
74void rate_control_pid_event_pf_sample(struct rc_pid_event_buffer *buf,
75 s32 pf_sample, s32 prop_err,
76 s32 int_err, s32 der_err)
77{
78 union rc_pid_event_data evd;
79
80 evd.pf_sample = pf_sample;
81 evd.prop_err = prop_err;
82 evd.int_err = int_err;
83 evd.der_err = der_err;
84 rate_control_pid_event(buf, RC_PID_EVENT_TYPE_PF_SAMPLE, &evd);
85}
86
87static int rate_control_pid_events_open(struct inode *inode, struct file *file)
88{
89 struct rc_pid_sta_info *sinfo = inode->i_private;
90 struct rc_pid_event_buffer *events = &sinfo->events;
91 struct rc_pid_events_file_info *file_info;
92 unsigned long status;
93
94 /* Allocate a state struct */
95 file_info = kmalloc(sizeof(*file_info), GFP_KERNEL);
96 if (file_info == NULL)
97 return -ENOMEM;
98
99 spin_lock_irqsave(&events->lock, status);
100
101 file_info->next_entry = events->next_entry;
102 file_info->events = events;
103
104 spin_unlock_irqrestore(&events->lock, status);
105
106 file->private_data = file_info;
107
108 return 0;
109}
110
111static int rate_control_pid_events_release(struct inode *inode,
112 struct file *file)
113{
114 struct rc_pid_events_file_info *file_info = file->private_data;
115
116 kfree(file_info);
117
118 return 0;
119}
120
121static unsigned int rate_control_pid_events_poll(struct file *file,
122 poll_table *wait)
123{
124 struct rc_pid_events_file_info *file_info = file->private_data;
125
126 poll_wait(file, &file_info->events->waitqueue, wait);
127
128 return POLLIN | POLLRDNORM;
129}
130
131#define RC_PID_PRINT_BUF_SIZE 64
132
133static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf,
134 size_t length, loff_t *offset)
135{
136 struct rc_pid_events_file_info *file_info = file->private_data;
137 struct rc_pid_event_buffer *events = file_info->events;
138 struct rc_pid_event *ev;
139 char pb[RC_PID_PRINT_BUF_SIZE];
140 int ret;
141 int p;
142 unsigned long status;
143
144 /* Check if there is something to read. */
145 if (events->next_entry == file_info->next_entry) {
146 if (file->f_flags & O_NONBLOCK)
147 return -EAGAIN;
148
149 /* Wait */
150 ret = wait_event_interruptible(events->waitqueue,
151 events->next_entry != file_info->next_entry);
152
153 if (ret)
154 return ret;
155 }
156
157 /* Write out one event per call. I don't care whether it's a little
158 * inefficient, this is debugging code anyway. */
159 spin_lock_irqsave(&events->lock, status);
160
161 /* Get an event */
162 ev = &(events->ring[file_info->next_entry]);
163 file_info->next_entry = (file_info->next_entry + 1) %
164 RC_PID_EVENT_RING_SIZE;
165
166 /* Print information about the event. Note that userspace needs to
167 * provide large enough buffers. */
168 length = length < RC_PID_PRINT_BUF_SIZE ?
169 length : RC_PID_PRINT_BUF_SIZE;
170 p = scnprintf(pb, length, "%u %lu ", ev->id, ev->timestamp);
171 switch (ev->type) {
172 case RC_PID_EVENT_TYPE_TX_STATUS:
173 p += scnprintf(pb + p, length - p, "tx_status %u %u",
174 !(ev->data.flags & IEEE80211_TX_STAT_ACK),
175 ev->data.tx_status.status.rates[0].idx);
176 break;
177 case RC_PID_EVENT_TYPE_RATE_CHANGE:
178 p += scnprintf(pb + p, length - p, "rate_change %d %d",
179 ev->data.index, ev->data.rate);
180 break;
181 case RC_PID_EVENT_TYPE_TX_RATE:
182 p += scnprintf(pb + p, length - p, "tx_rate %d %d",
183 ev->data.index, ev->data.rate);
184 break;
185 case RC_PID_EVENT_TYPE_PF_SAMPLE:
186 p += scnprintf(pb + p, length - p,
187 "pf_sample %d %d %d %d",
188 ev->data.pf_sample, ev->data.prop_err,
189 ev->data.int_err, ev->data.der_err);
190 break;
191 }
192 p += scnprintf(pb + p, length - p, "\n");
193
194 spin_unlock_irqrestore(&events->lock, status);
195
196 if (copy_to_user(buf, pb, p))
197 return -EFAULT;
198
199 return p;
200}
201
202#undef RC_PID_PRINT_BUF_SIZE
203
204static const struct file_operations rc_pid_fop_events = {
205 .owner = THIS_MODULE,
206 .read = rate_control_pid_events_read,
207 .poll = rate_control_pid_events_poll,
208 .open = rate_control_pid_events_open,
209 .release = rate_control_pid_events_release,
210 .llseek = noop_llseek,
211};
212
213void rate_control_pid_add_sta_debugfs(void *priv, void *priv_sta,
214 struct dentry *dir)
215{
216 struct rc_pid_sta_info *spinfo = priv_sta;
217
218 spinfo->events_entry = debugfs_create_file("rc_pid_events", S_IRUGO,
219 dir, spinfo,
220 &rc_pid_fop_events);
221}
222
223void rate_control_pid_remove_sta_debugfs(void *priv, void *priv_sta)
224{
225 struct rc_pid_sta_info *spinfo = priv_sta;
226
227 debugfs_remove(spinfo->events_entry);
228}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 394e201cde6d..5f572bed1761 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1107,6 +1107,8 @@ static void sta_ps_end(struct sta_info *sta)
1107 return; 1107 return;
1108 } 1108 }
1109 1109
1110 set_sta_flag(sta, WLAN_STA_PS_DELIVER);
1111 clear_sta_flag(sta, WLAN_STA_PS_STA);
1110 ieee80211_sta_ps_deliver_wakeup(sta); 1112 ieee80211_sta_ps_deliver_wakeup(sta);
1111} 1113}
1112 1114
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f40661eb75b5..a0a938145dcc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -235,38 +235,51 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
235{ 235{
236 struct cfg80211_scan_request *req = local->scan_req; 236 struct cfg80211_scan_request *req = local->scan_req;
237 struct cfg80211_chan_def chandef; 237 struct cfg80211_chan_def chandef;
238 enum ieee80211_band band; 238 u8 bands_used = 0;
239 int i, ielen, n_chans; 239 int i, ielen, n_chans;
240 240
241 if (test_bit(SCAN_HW_CANCELLED, &local->scanning)) 241 if (test_bit(SCAN_HW_CANCELLED, &local->scanning))
242 return false; 242 return false;
243 243
244 do { 244 if (local->hw.flags & IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS) {
245 if (local->hw_scan_band == IEEE80211_NUM_BANDS)
246 return false;
247
248 band = local->hw_scan_band;
249 n_chans = 0;
250 for (i = 0; i < req->n_channels; i++) { 245 for (i = 0; i < req->n_channels; i++) {
251 if (req->channels[i]->band == band) { 246 local->hw_scan_req->req.channels[i] = req->channels[i];
252 local->hw_scan_req->channels[n_chans] = 247 bands_used |= BIT(req->channels[i]->band);
248 }
249
250 n_chans = req->n_channels;
251 } else {
252 do {
253 if (local->hw_scan_band == IEEE80211_NUM_BANDS)
254 return false;
255
256 n_chans = 0;
257
258 for (i = 0; i < req->n_channels; i++) {
259 if (req->channels[i]->band !=
260 local->hw_scan_band)
261 continue;
262 local->hw_scan_req->req.channels[n_chans] =
253 req->channels[i]; 263 req->channels[i];
254 n_chans++; 264 n_chans++;
265 bands_used |= BIT(req->channels[i]->band);
255 } 266 }
256 }
257 267
258 local->hw_scan_band++; 268 local->hw_scan_band++;
259 } while (!n_chans); 269 } while (!n_chans);
270 }
260 271
261 local->hw_scan_req->n_channels = n_chans; 272 local->hw_scan_req->req.n_channels = n_chans;
262 ieee80211_prepare_scan_chandef(&chandef, req->scan_width); 273 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
263 274
264 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, 275 ielen = ieee80211_build_preq_ies(local,
276 (u8 *)local->hw_scan_req->req.ie,
265 local->hw_scan_ies_bufsize, 277 local->hw_scan_ies_bufsize,
266 req->ie, req->ie_len, band, 278 &local->hw_scan_req->ies,
267 req->rates[band], &chandef); 279 req->ie, req->ie_len,
268 local->hw_scan_req->ie_len = ielen; 280 bands_used, req->rates, &chandef);
269 local->hw_scan_req->no_cck = req->no_cck; 281 local->hw_scan_req->req.ie_len = ielen;
282 local->hw_scan_req->req.no_cck = req->no_cck;
270 283
271 return true; 284 return true;
272} 285}
@@ -291,7 +304,9 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
291 if (WARN_ON(!local->scan_req)) 304 if (WARN_ON(!local->scan_req))
292 return; 305 return;
293 306
294 if (hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { 307 if (hw_scan && !aborted &&
308 !(local->hw.flags & IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS) &&
309 ieee80211_prep_hw_scan(local)) {
295 int rc; 310 int rc;
296 311
297 rc = drv_hw_scan(local, 312 rc = drv_hw_scan(local,
@@ -473,6 +488,21 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
473 u8 *ies; 488 u8 *ies;
474 489
475 local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len; 490 local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
491
492 if (local->hw.flags & IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS) {
493 int i, n_bands = 0;
494 u8 bands_counted = 0;
495
496 for (i = 0; i < req->n_channels; i++) {
497 if (bands_counted & BIT(req->channels[i]->band))
498 continue;
499 bands_counted |= BIT(req->channels[i]->band);
500 n_bands++;
501 }
502
503 local->hw_scan_ies_bufsize *= n_bands;
504 }
505
476 local->hw_scan_req = kmalloc( 506 local->hw_scan_req = kmalloc(
477 sizeof(*local->hw_scan_req) + 507 sizeof(*local->hw_scan_req) +
478 req->n_channels * sizeof(req->channels[0]) + 508 req->n_channels * sizeof(req->channels[0]) +
@@ -480,13 +510,13 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
480 if (!local->hw_scan_req) 510 if (!local->hw_scan_req)
481 return -ENOMEM; 511 return -ENOMEM;
482 512
483 local->hw_scan_req->ssids = req->ssids; 513 local->hw_scan_req->req.ssids = req->ssids;
484 local->hw_scan_req->n_ssids = req->n_ssids; 514 local->hw_scan_req->req.n_ssids = req->n_ssids;
485 ies = (u8 *)local->hw_scan_req + 515 ies = (u8 *)local->hw_scan_req +
486 sizeof(*local->hw_scan_req) + 516 sizeof(*local->hw_scan_req) +
487 req->n_channels * sizeof(req->channels[0]); 517 req->n_channels * sizeof(req->channels[0]);
488 local->hw_scan_req->ie = ies; 518 local->hw_scan_req->req.ie = ies;
489 local->hw_scan_req->flags = req->flags; 519 local->hw_scan_req->req.flags = req->flags;
490 520
491 local->hw_scan_band = 0; 521 local->hw_scan_band = 0;
492 522
@@ -973,9 +1003,13 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
973 struct cfg80211_sched_scan_request *req) 1003 struct cfg80211_sched_scan_request *req)
974{ 1004{
975 struct ieee80211_local *local = sdata->local; 1005 struct ieee80211_local *local = sdata->local;
976 struct ieee80211_sched_scan_ies sched_scan_ies = {}; 1006 struct ieee80211_scan_ies sched_scan_ies = {};
977 struct cfg80211_chan_def chandef; 1007 struct cfg80211_chan_def chandef;
978 int ret, i, iebufsz; 1008 int ret, i, iebufsz, num_bands = 0;
1009 u32 rate_masks[IEEE80211_NUM_BANDS] = {};
1010 u8 bands_used = 0;
1011 u8 *ie;
1012 size_t len;
979 1013
980 iebufsz = local->scan_ies_len + req->ie_len; 1014 iebufsz = local->scan_ies_len + req->ie_len;
981 1015
@@ -985,33 +1019,35 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
985 return -ENOTSUPP; 1019 return -ENOTSUPP;
986 1020
987 for (i = 0; i < IEEE80211_NUM_BANDS; i++) { 1021 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
988 if (!local->hw.wiphy->bands[i]) 1022 if (local->hw.wiphy->bands[i]) {
989 continue; 1023 bands_used |= BIT(i);
990 1024 rate_masks[i] = (u32) -1;
991 sched_scan_ies.ie[i] = kzalloc(iebufsz, GFP_KERNEL); 1025 num_bands++;
992 if (!sched_scan_ies.ie[i]) {
993 ret = -ENOMEM;
994 goto out_free;
995 } 1026 }
1027 }
996 1028
997 ieee80211_prepare_scan_chandef(&chandef, req->scan_width); 1029 ie = kzalloc(num_bands * iebufsz, GFP_KERNEL);
998 1030 if (!ie) {
999 sched_scan_ies.len[i] = 1031 ret = -ENOMEM;
1000 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], 1032 goto out;
1001 iebufsz, req->ie, req->ie_len,
1002 i, (u32) -1, &chandef);
1003 } 1033 }
1004 1034
1035 ieee80211_prepare_scan_chandef(&chandef, req->scan_width);
1036
1037 len = ieee80211_build_preq_ies(local, ie, num_bands * iebufsz,
1038 &sched_scan_ies, req->ie,
1039 req->ie_len, bands_used,
1040 rate_masks, &chandef);
1041
1005 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 1042 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
1006 if (ret == 0) { 1043 if (ret == 0) {
1007 rcu_assign_pointer(local->sched_scan_sdata, sdata); 1044 rcu_assign_pointer(local->sched_scan_sdata, sdata);
1008 local->sched_scan_req = req; 1045 local->sched_scan_req = req;
1009 } 1046 }
1010 1047
1011out_free: 1048 kfree(ie);
1012 while (i > 0)
1013 kfree(sched_scan_ies.ie[--i]);
1014 1049
1050out:
1015 if (ret) { 1051 if (ret) {
1016 /* Clean in case of failure after HW restart or upon resume. */ 1052 /* Clean in case of failure after HW restart or upon resume. */
1017 RCU_INIT_POINTER(local->sched_scan_sdata, NULL); 1053 RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a9b46d8ea22f..f41177f58b30 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -100,7 +100,8 @@ static void __cleanup_single_sta(struct sta_info *sta)
100 struct ps_data *ps; 100 struct ps_data *ps;
101 101
102 if (test_sta_flag(sta, WLAN_STA_PS_STA) || 102 if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
103 test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { 103 test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
104 test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
104 if (sta->sdata->vif.type == NL80211_IFTYPE_AP || 105 if (sta->sdata->vif.type == NL80211_IFTYPE_AP ||
105 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 106 sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
106 ps = &sdata->bss->ps; 107 ps = &sdata->bss->ps;
@@ -111,6 +112,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
111 112
112 clear_sta_flag(sta, WLAN_STA_PS_STA); 113 clear_sta_flag(sta, WLAN_STA_PS_STA);
113 clear_sta_flag(sta, WLAN_STA_PS_DRIVER); 114 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
115 clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
114 116
115 atomic_dec(&ps->num_sta_ps); 117 atomic_dec(&ps->num_sta_ps);
116 sta_info_recalc_tim(sta); 118 sta_info_recalc_tim(sta);
@@ -125,7 +127,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
125 if (ieee80211_vif_is_mesh(&sdata->vif)) 127 if (ieee80211_vif_is_mesh(&sdata->vif))
126 mesh_sta_cleanup(sta); 128 mesh_sta_cleanup(sta);
127 129
128 cancel_work_sync(&sta->drv_unblock_wk); 130 cancel_work_sync(&sta->drv_deliver_wk);
129 131
130 /* 132 /*
131 * Destroy aggregation state here. It would be nice to wait for the 133 * Destroy aggregation state here. It would be nice to wait for the
@@ -253,33 +255,23 @@ static void sta_info_hash_add(struct ieee80211_local *local,
253 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); 255 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
254} 256}
255 257
256static void sta_unblock(struct work_struct *wk) 258static void sta_deliver_ps_frames(struct work_struct *wk)
257{ 259{
258 struct sta_info *sta; 260 struct sta_info *sta;
259 261
260 sta = container_of(wk, struct sta_info, drv_unblock_wk); 262 sta = container_of(wk, struct sta_info, drv_deliver_wk);
261 263
262 if (sta->dead) 264 if (sta->dead)
263 return; 265 return;
264 266
265 if (!test_sta_flag(sta, WLAN_STA_PS_STA)) { 267 local_bh_disable();
266 local_bh_disable(); 268 if (!test_sta_flag(sta, WLAN_STA_PS_STA))
267 ieee80211_sta_ps_deliver_wakeup(sta); 269 ieee80211_sta_ps_deliver_wakeup(sta);
268 local_bh_enable(); 270 else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL))
269 } else if (test_and_clear_sta_flag(sta, WLAN_STA_PSPOLL)) {
270 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
271
272 local_bh_disable();
273 ieee80211_sta_ps_deliver_poll_response(sta); 271 ieee80211_sta_ps_deliver_poll_response(sta);
274 local_bh_enable(); 272 else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD))
275 } else if (test_and_clear_sta_flag(sta, WLAN_STA_UAPSD)) {
276 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
277
278 local_bh_disable();
279 ieee80211_sta_ps_deliver_uapsd(sta); 273 ieee80211_sta_ps_deliver_uapsd(sta);
280 local_bh_enable(); 274 local_bh_enable();
281 } else
282 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
283} 275}
284 276
285static int sta_prepare_rate_control(struct ieee80211_local *local, 277static int sta_prepare_rate_control(struct ieee80211_local *local,
@@ -341,7 +333,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
341 333
342 spin_lock_init(&sta->lock); 334 spin_lock_init(&sta->lock);
343 spin_lock_init(&sta->ps_lock); 335 spin_lock_init(&sta->ps_lock);
344 INIT_WORK(&sta->drv_unblock_wk, sta_unblock); 336 INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames);
345 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); 337 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
346 mutex_init(&sta->ampdu_mlme.mtx); 338 mutex_init(&sta->ampdu_mlme.mtx);
347#ifdef CONFIG_MAC80211_MESH 339#ifdef CONFIG_MAC80211_MESH
@@ -358,7 +350,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
358 350
359 sta->sta_state = IEEE80211_STA_NONE; 351 sta->sta_state = IEEE80211_STA_NONE;
360 352
361 do_posix_clock_monotonic_gettime(&uptime); 353 ktime_get_ts(&uptime);
362 sta->last_connected = uptime.tv_sec; 354 sta->last_connected = uptime.tv_sec;
363 ewma_init(&sta->avg_signal, 1024, 8); 355 ewma_init(&sta->avg_signal, 1024, 8);
364 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) 356 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
@@ -1141,8 +1133,15 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
1141 } 1133 }
1142 1134
1143 ieee80211_add_pending_skbs(local, &pending); 1135 ieee80211_add_pending_skbs(local, &pending);
1144 clear_sta_flag(sta, WLAN_STA_PS_DRIVER); 1136
1145 clear_sta_flag(sta, WLAN_STA_PS_STA); 1137 /* now we're no longer in the deliver code */
1138 clear_sta_flag(sta, WLAN_STA_PS_DELIVER);
1139
1140 /* The station might have polled and then woken up before we responded,
1141 * so clear these flags now to avoid them sticking around.
1142 */
1143 clear_sta_flag(sta, WLAN_STA_PSPOLL);
1144 clear_sta_flag(sta, WLAN_STA_UAPSD);
1146 spin_unlock(&sta->ps_lock); 1145 spin_unlock(&sta->ps_lock);
1147 1146
1148 atomic_dec(&ps->num_sta_ps); 1147 atomic_dec(&ps->num_sta_ps);
@@ -1543,10 +1542,26 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw,
1543 1542
1544 trace_api_sta_block_awake(sta->local, pubsta, block); 1543 trace_api_sta_block_awake(sta->local, pubsta, block);
1545 1544
1546 if (block) 1545 if (block) {
1547 set_sta_flag(sta, WLAN_STA_PS_DRIVER); 1546 set_sta_flag(sta, WLAN_STA_PS_DRIVER);
1548 else if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) 1547 return;
1549 ieee80211_queue_work(hw, &sta->drv_unblock_wk); 1548 }
1549
1550 if (!test_sta_flag(sta, WLAN_STA_PS_DRIVER))
1551 return;
1552
1553 if (!test_sta_flag(sta, WLAN_STA_PS_STA)) {
1554 set_sta_flag(sta, WLAN_STA_PS_DELIVER);
1555 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
1556 ieee80211_queue_work(hw, &sta->drv_deliver_wk);
1557 } else if (test_sta_flag(sta, WLAN_STA_PSPOLL) ||
1558 test_sta_flag(sta, WLAN_STA_UAPSD)) {
1559 /* must be asleep in this case */
1560 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
1561 ieee80211_queue_work(hw, &sta->drv_deliver_wk);
1562 } else {
1563 clear_sta_flag(sta, WLAN_STA_PS_DRIVER);
1564 }
1550} 1565}
1551EXPORT_SYMBOL(ieee80211_sta_block_awake); 1566EXPORT_SYMBOL(ieee80211_sta_block_awake);
1552 1567
@@ -1704,3 +1719,137 @@ u8 sta_info_tx_streams(struct sta_info *sta)
1704 return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK) 1719 return ((ht_cap->mcs.tx_params & IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
1705 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1; 1720 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT) + 1;
1706} 1721}
1722
1723void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1724{
1725 struct ieee80211_sub_if_data *sdata = sta->sdata;
1726 struct ieee80211_local *local = sdata->local;
1727 struct rate_control_ref *ref = local->rate_ctrl;
1728 struct timespec uptime;
1729 u64 packets = 0;
1730 u32 thr = 0;
1731 int i, ac;
1732
1733 sinfo->generation = sdata->local->sta_generation;
1734
1735 sinfo->filled = STATION_INFO_INACTIVE_TIME |
1736 STATION_INFO_RX_BYTES64 |
1737 STATION_INFO_TX_BYTES64 |
1738 STATION_INFO_RX_PACKETS |
1739 STATION_INFO_TX_PACKETS |
1740 STATION_INFO_TX_RETRIES |
1741 STATION_INFO_TX_FAILED |
1742 STATION_INFO_TX_BITRATE |
1743 STATION_INFO_RX_BITRATE |
1744 STATION_INFO_RX_DROP_MISC |
1745 STATION_INFO_BSS_PARAM |
1746 STATION_INFO_CONNECTED_TIME |
1747 STATION_INFO_STA_FLAGS |
1748 STATION_INFO_BEACON_LOSS_COUNT;
1749
1750 ktime_get_ts(&uptime);
1751 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
1752
1753 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
1754 sinfo->tx_bytes = 0;
1755 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
1756 sinfo->tx_bytes += sta->tx_bytes[ac];
1757 packets += sta->tx_packets[ac];
1758 }
1759 sinfo->tx_packets = packets;
1760 sinfo->rx_bytes = sta->rx_bytes;
1761 sinfo->rx_packets = sta->rx_packets;
1762 sinfo->tx_retries = sta->tx_retry_count;
1763 sinfo->tx_failed = sta->tx_retry_failed;
1764 sinfo->rx_dropped_misc = sta->rx_dropped;
1765 sinfo->beacon_loss_count = sta->beacon_loss_count;
1766
1767 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
1768 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
1769 sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG;
1770 if (!local->ops->get_rssi ||
1771 drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal))
1772 sinfo->signal = (s8)sta->last_signal;
1773 sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
1774 }
1775 if (sta->chains) {
1776 sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
1777 STATION_INFO_CHAIN_SIGNAL_AVG;
1778
1779 sinfo->chains = sta->chains;
1780 for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
1781 sinfo->chain_signal[i] = sta->chain_signal_last[i];
1782 sinfo->chain_signal_avg[i] =
1783 (s8) -ewma_read(&sta->chain_signal_avg[i]);
1784 }
1785 }
1786
1787 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
1788 sta_set_rate_info_rx(sta, &sinfo->rxrate);
1789
1790 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1791#ifdef CONFIG_MAC80211_MESH
1792 sinfo->filled |= STATION_INFO_LLID |
1793 STATION_INFO_PLID |
1794 STATION_INFO_PLINK_STATE |
1795 STATION_INFO_LOCAL_PM |
1796 STATION_INFO_PEER_PM |
1797 STATION_INFO_NONPEER_PM;
1798
1799 sinfo->llid = sta->llid;
1800 sinfo->plid = sta->plid;
1801 sinfo->plink_state = sta->plink_state;
1802 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
1803 sinfo->filled |= STATION_INFO_T_OFFSET;
1804 sinfo->t_offset = sta->t_offset;
1805 }
1806 sinfo->local_pm = sta->local_pm;
1807 sinfo->peer_pm = sta->peer_pm;
1808 sinfo->nonpeer_pm = sta->nonpeer_pm;
1809#endif
1810 }
1811
1812 sinfo->bss_param.flags = 0;
1813 if (sdata->vif.bss_conf.use_cts_prot)
1814 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
1815 if (sdata->vif.bss_conf.use_short_preamble)
1816 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
1817 if (sdata->vif.bss_conf.use_short_slot)
1818 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
1819 sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
1820 sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
1821
1822 sinfo->sta_flags.set = 0;
1823 sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
1824 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
1825 BIT(NL80211_STA_FLAG_WME) |
1826 BIT(NL80211_STA_FLAG_MFP) |
1827 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
1828 BIT(NL80211_STA_FLAG_ASSOCIATED) |
1829 BIT(NL80211_STA_FLAG_TDLS_PEER);
1830 if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
1831 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
1832 if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
1833 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
1834 if (test_sta_flag(sta, WLAN_STA_WME))
1835 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
1836 if (test_sta_flag(sta, WLAN_STA_MFP))
1837 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
1838 if (test_sta_flag(sta, WLAN_STA_AUTH))
1839 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
1840 if (test_sta_flag(sta, WLAN_STA_ASSOC))
1841 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
1842 if (test_sta_flag(sta, WLAN_STA_TDLS_PEER))
1843 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
1844
1845 /* check if the driver has a SW RC implementation */
1846 if (ref && ref->ops->get_expected_throughput)
1847 thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv);
1848 else
1849 thr = drv_get_expected_throughput(local, &sta->sta);
1850
1851 if (thr != 0) {
1852 sinfo->filled |= STATION_INFO_EXPECTED_THROUGHPUT;
1853 sinfo->expected_throughput = thr;
1854 }
1855}
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 4acc5fc402fa..2a04361b2162 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -58,6 +58,8 @@
58 * @WLAN_STA_TOFFSET_KNOWN: toffset calculated for this station is valid. 58 * @WLAN_STA_TOFFSET_KNOWN: toffset calculated for this station is valid.
59 * @WLAN_STA_MPSP_OWNER: local STA is owner of a mesh Peer Service Period. 59 * @WLAN_STA_MPSP_OWNER: local STA is owner of a mesh Peer Service Period.
60 * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP. 60 * @WLAN_STA_MPSP_RECIPIENT: local STA is recipient of a MPSP.
61 * @WLAN_STA_PS_DELIVER: station woke up, but we're still blocking TX
62 * until pending frames are delivered
61 */ 63 */
62enum ieee80211_sta_info_flags { 64enum ieee80211_sta_info_flags {
63 WLAN_STA_AUTH, 65 WLAN_STA_AUTH,
@@ -82,6 +84,7 @@ enum ieee80211_sta_info_flags {
82 WLAN_STA_TOFFSET_KNOWN, 84 WLAN_STA_TOFFSET_KNOWN,
83 WLAN_STA_MPSP_OWNER, 85 WLAN_STA_MPSP_OWNER,
84 WLAN_STA_MPSP_RECIPIENT, 86 WLAN_STA_MPSP_RECIPIENT,
87 WLAN_STA_PS_DELIVER,
85}; 88};
86 89
87#define ADDBA_RESP_INTERVAL HZ 90#define ADDBA_RESP_INTERVAL HZ
@@ -265,7 +268,7 @@ struct ieee80211_tx_latency_stat {
265 * @last_rx_rate_vht_nss: rx status nss of last data packet 268 * @last_rx_rate_vht_nss: rx status nss of last data packet
266 * @lock: used for locking all fields that require locking, see comments 269 * @lock: used for locking all fields that require locking, see comments
267 * in the header file. 270 * in the header file.
268 * @drv_unblock_wk: used for driver PS unblocking 271 * @drv_deliver_wk: used for delivering frames after driver PS unblocking
269 * @listen_interval: listen interval of this station, when we're acting as AP 272 * @listen_interval: listen interval of this station, when we're acting as AP
270 * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly 273 * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
271 * @ps_lock: used for powersave (when mac80211 is the AP) related locking 274 * @ps_lock: used for powersave (when mac80211 is the AP) related locking
@@ -278,7 +281,6 @@ struct ieee80211_tx_latency_stat {
278 * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on 281 * @driver_buffered_tids: bitmap of TIDs the driver has data buffered on
279 * @rx_packets: Number of MSDUs received from this STA 282 * @rx_packets: Number of MSDUs received from this STA
280 * @rx_bytes: Number of bytes received from this STA 283 * @rx_bytes: Number of bytes received from this STA
281 * @wep_weak_iv_count: number of weak WEP IVs received from this station
282 * @last_rx: time (in jiffies) when last frame was received from this STA 284 * @last_rx: time (in jiffies) when last frame was received from this STA
283 * @last_connected: time (in seconds) when a station got connected 285 * @last_connected: time (in seconds) when a station got connected
284 * @num_duplicates: number of duplicate frames received from this STA 286 * @num_duplicates: number of duplicate frames received from this STA
@@ -303,7 +305,6 @@ struct ieee80211_tx_latency_stat {
303 * @plid: Peer link ID 305 * @plid: Peer link ID
304 * @reason: Cancel reason on PLINK_HOLDING state 306 * @reason: Cancel reason on PLINK_HOLDING state
305 * @plink_retries: Retries in establishment 307 * @plink_retries: Retries in establishment
306 * @ignore_plink_timer: ignore the peer-link timer (used internally)
307 * @plink_state: peer link state 308 * @plink_state: peer link state
308 * @plink_timeout: timeout of peer link 309 * @plink_timeout: timeout of peer link
309 * @plink_timer: peer link watch timer 310 * @plink_timer: peer link watch timer
@@ -345,7 +346,7 @@ struct sta_info {
345 void *rate_ctrl_priv; 346 void *rate_ctrl_priv;
346 spinlock_t lock; 347 spinlock_t lock;
347 348
348 struct work_struct drv_unblock_wk; 349 struct work_struct drv_deliver_wk;
349 350
350 u16 listen_interval; 351 u16 listen_interval;
351 352
@@ -367,7 +368,6 @@ struct sta_info {
367 /* Updated from RX path only, no locking requirements */ 368 /* Updated from RX path only, no locking requirements */
368 unsigned long rx_packets; 369 unsigned long rx_packets;
369 u64 rx_bytes; 370 u64 rx_bytes;
370 unsigned long wep_weak_iv_count;
371 unsigned long last_rx; 371 unsigned long last_rx;
372 long last_connected; 372 long last_connected;
373 unsigned long num_duplicates; 373 unsigned long num_duplicates;
@@ -418,7 +418,6 @@ struct sta_info {
418 u16 plid; 418 u16 plid;
419 u16 reason; 419 u16 reason;
420 u8 plink_retries; 420 u8 plink_retries;
421 bool ignore_plink_timer;
422 enum nl80211_plink_state plink_state; 421 enum nl80211_plink_state plink_state;
423 u32 plink_timeout; 422 u32 plink_timeout;
424 struct timer_list plink_timer; 423 struct timer_list plink_timer;
@@ -628,6 +627,8 @@ void sta_set_rate_info_tx(struct sta_info *sta,
628 struct rate_info *rinfo); 627 struct rate_info *rinfo);
629void sta_set_rate_info_rx(struct sta_info *sta, 628void sta_set_rate_info_rx(struct sta_info *sta,
630 struct rate_info *rinfo); 629 struct rate_info *rinfo);
630void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo);
631
631void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 632void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
632 unsigned long exp_time); 633 unsigned long exp_time);
633u8 sta_info_tx_streams(struct sta_info *sta); 634u8 sta_info_tx_streams(struct sta_info *sta);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index ba29ebc86141..aa06dcad336e 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -473,8 +473,6 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
473 struct sta_info *sta, 473 struct sta_info *sta,
474 struct ieee80211_hdr *hdr) 474 struct ieee80211_hdr *hdr)
475{ 475{
476 ktime_t skb_dprt;
477 struct timespec dprt_time;
478 u32 msrmnt; 476 u32 msrmnt;
479 u16 tid; 477 u16 tid;
480 u8 *qc; 478 u8 *qc;
@@ -506,9 +504,8 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
506 504
507 tx_lat = &sta->tx_lat[tid]; 505 tx_lat = &sta->tx_lat[tid];
508 506
509 ktime_get_ts(&dprt_time); /* time stamp completion time */ 507 /* Calculate the latency */
510 skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec); 508 msrmnt = ktime_to_ms(ktime_sub(ktime_get(), skb_arv));
511 msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv));
512 509
513 if (tx_lat->max < msrmnt) /* update stats */ 510 if (tx_lat->max < msrmnt) /* update stats */
514 tx_lat->max = msrmnt; 511 tx_lat->max = msrmnt;
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 652813b2d3df..f7185338a0fa 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -8,7 +8,30 @@
8 */ 8 */
9 9
10#include <linux/ieee80211.h> 10#include <linux/ieee80211.h>
11#include <net/cfg80211.h>
11#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13#include "driver-ops.h"
14
15/* give usermode some time for retries in setting up the TDLS session */
16#define TDLS_PEER_SETUP_TIMEOUT (15 * HZ)
17
18void ieee80211_tdls_peer_del_work(struct work_struct *wk)
19{
20 struct ieee80211_sub_if_data *sdata;
21 struct ieee80211_local *local;
22
23 sdata = container_of(wk, struct ieee80211_sub_if_data,
24 tdls_peer_del_work.work);
25 local = sdata->local;
26
27 mutex_lock(&local->mtx);
28 if (!is_zero_ether_addr(sdata->tdls_peer)) {
29 tdls_dbg(sdata, "TDLS del peer %pM\n", sdata->tdls_peer);
30 sta_info_destroy_addr(sdata, sdata->tdls_peer);
31 eth_zero_addr(sdata->tdls_peer);
32 }
33 mutex_unlock(&local->mtx);
34}
12 35
13static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb) 36static void ieee80211_tdls_add_ext_capab(struct sk_buff *skb)
14{ 37{
@@ -168,28 +191,20 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
168 return 0; 191 return 0;
169} 192}
170 193
171int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, 194static int
172 const u8 *peer, u8 action_code, u8 dialog_token, 195ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
173 u16 status_code, u32 peer_capability, 196 const u8 *peer, u8 action_code,
174 const u8 *extra_ies, size_t extra_ies_len) 197 u8 dialog_token, u16 status_code,
198 u32 peer_capability, bool initiator,
199 const u8 *extra_ies, size_t extra_ies_len)
175{ 200{
176 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 201 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
177 struct ieee80211_local *local = sdata->local; 202 struct ieee80211_local *local = sdata->local;
178 struct sk_buff *skb = NULL; 203 struct sk_buff *skb = NULL;
179 bool send_direct; 204 bool send_direct;
205 const u8 *init_addr, *rsp_addr;
180 int ret; 206 int ret;
181 207
182 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
183 return -ENOTSUPP;
184
185 /* make sure we are in managed mode, and associated */
186 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
187 !sdata->u.mgd.associated)
188 return -EINVAL;
189
190 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n",
191 action_code, peer);
192
193 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 208 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
194 max(sizeof(struct ieee80211_mgmt), 209 max(sizeof(struct ieee80211_mgmt),
195 sizeof(struct ieee80211_tdls_data)) + 210 sizeof(struct ieee80211_tdls_data)) +
@@ -230,27 +245,42 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
230 if (extra_ies_len) 245 if (extra_ies_len)
231 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len); 246 memcpy(skb_put(skb, extra_ies_len), extra_ies, extra_ies_len);
232 247
233 /* the TDLS link IE is always added last */ 248 /* sanity check for initiator */
234 switch (action_code) { 249 switch (action_code) {
235 case WLAN_TDLS_SETUP_REQUEST: 250 case WLAN_TDLS_SETUP_REQUEST:
236 case WLAN_TDLS_SETUP_CONFIRM: 251 case WLAN_TDLS_SETUP_CONFIRM:
237 case WLAN_TDLS_TEARDOWN:
238 case WLAN_TDLS_DISCOVERY_REQUEST: 252 case WLAN_TDLS_DISCOVERY_REQUEST:
239 /* we are the initiator */ 253 if (!initiator) {
240 ieee80211_tdls_add_link_ie(skb, sdata->vif.addr, peer, 254 ret = -EINVAL;
241 sdata->u.mgd.bssid); 255 goto fail;
256 }
242 break; 257 break;
243 case WLAN_TDLS_SETUP_RESPONSE: 258 case WLAN_TDLS_SETUP_RESPONSE:
244 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: 259 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
245 /* we are the responder */ 260 if (initiator) {
246 ieee80211_tdls_add_link_ie(skb, peer, sdata->vif.addr, 261 ret = -EINVAL;
247 sdata->u.mgd.bssid); 262 goto fail;
263 }
264 break;
265 case WLAN_TDLS_TEARDOWN:
266 /* any value is ok */
248 break; 267 break;
249 default: 268 default:
250 ret = -ENOTSUPP; 269 ret = -ENOTSUPP;
251 goto fail; 270 goto fail;
252 } 271 }
253 272
273 if (initiator) {
274 init_addr = sdata->vif.addr;
275 rsp_addr = peer;
276 } else {
277 init_addr = peer;
278 rsp_addr = sdata->vif.addr;
279 }
280
281 ieee80211_tdls_add_link_ie(skb, init_addr, rsp_addr,
282 sdata->u.mgd.bssid);
283
254 if (send_direct) { 284 if (send_direct) {
255 ieee80211_tx_skb(sdata, skb); 285 ieee80211_tx_skb(sdata, skb);
256 return 0; 286 return 0;
@@ -284,11 +314,171 @@ fail:
284 return ret; 314 return ret;
285} 315}
286 316
317static int
318ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev,
319 const u8 *peer, u8 action_code, u8 dialog_token,
320 u16 status_code, u32 peer_capability, bool initiator,
321 const u8 *extra_ies, size_t extra_ies_len)
322{
323 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
324 struct ieee80211_local *local = sdata->local;
325 int ret;
326
327 mutex_lock(&local->mtx);
328
329 /* we don't support concurrent TDLS peer setups */
330 if (!is_zero_ether_addr(sdata->tdls_peer) &&
331 !ether_addr_equal(sdata->tdls_peer, peer)) {
332 ret = -EBUSY;
333 goto exit;
334 }
335
336 /*
337 * make sure we have a STA representing the peer so we drop or buffer
338 * non-TDLS-setup frames to the peer. We can't send other packets
339 * during setup through the AP path
340 */
341 rcu_read_lock();
342 if (!sta_info_get(sdata, peer)) {
343 rcu_read_unlock();
344 ret = -ENOLINK;
345 goto exit;
346 }
347 rcu_read_unlock();
348
349 ieee80211_flush_queues(local, sdata);
350
351 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
352 dialog_token, status_code,
353 peer_capability, initiator,
354 extra_ies, extra_ies_len);
355 if (ret < 0)
356 goto exit;
357
358 memcpy(sdata->tdls_peer, peer, ETH_ALEN);
359 ieee80211_queue_delayed_work(&sdata->local->hw,
360 &sdata->tdls_peer_del_work,
361 TDLS_PEER_SETUP_TIMEOUT);
362
363exit:
364 mutex_unlock(&local->mtx);
365 return ret;
366}
367
368static int
369ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev,
370 const u8 *peer, u8 action_code, u8 dialog_token,
371 u16 status_code, u32 peer_capability,
372 bool initiator, const u8 *extra_ies,
373 size_t extra_ies_len)
374{
375 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
376 struct ieee80211_local *local = sdata->local;
377 struct sta_info *sta;
378 int ret;
379
380 /*
381 * No packets can be transmitted to the peer via the AP during setup -
382 * the STA is set as a TDLS peer, but is not authorized.
383 * During teardown, we prevent direct transmissions by stopping the
384 * queues and flushing all direct packets.
385 */
386 ieee80211_stop_vif_queues(local, sdata,
387 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
388 ieee80211_flush_queues(local, sdata);
389
390 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
391 dialog_token, status_code,
392 peer_capability, initiator,
393 extra_ies, extra_ies_len);
394 if (ret < 0)
395 sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
396 ret);
397
398 /*
399 * Remove the STA AUTH flag to force further traffic through the AP. If
400 * the STA was unreachable, it was already removed.
401 */
402 rcu_read_lock();
403 sta = sta_info_get(sdata, peer);
404 if (sta)
405 clear_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
406 rcu_read_unlock();
407
408 ieee80211_wake_vif_queues(local, sdata,
409 IEEE80211_QUEUE_STOP_REASON_TDLS_TEARDOWN);
410
411 return 0;
412}
413
414int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
415 const u8 *peer, u8 action_code, u8 dialog_token,
416 u16 status_code, u32 peer_capability,
417 bool initiator, const u8 *extra_ies,
418 size_t extra_ies_len)
419{
420 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
421 int ret;
422
423 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
424 return -ENOTSUPP;
425
426 /* make sure we are in managed mode, and associated */
427 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
428 !sdata->u.mgd.associated)
429 return -EINVAL;
430
431 switch (action_code) {
432 case WLAN_TDLS_SETUP_REQUEST:
433 case WLAN_TDLS_SETUP_RESPONSE:
434 ret = ieee80211_tdls_mgmt_setup(wiphy, dev, peer, action_code,
435 dialog_token, status_code,
436 peer_capability, initiator,
437 extra_ies, extra_ies_len);
438 break;
439 case WLAN_TDLS_TEARDOWN:
440 ret = ieee80211_tdls_mgmt_teardown(wiphy, dev, peer,
441 action_code, dialog_token,
442 status_code,
443 peer_capability, initiator,
444 extra_ies, extra_ies_len);
445 break;
446 case WLAN_TDLS_DISCOVERY_REQUEST:
447 /*
448 * Protect the discovery so we can hear the TDLS discovery
449 * response frame. It is transmitted directly and not buffered
450 * by the AP.
451 */
452 drv_mgd_protect_tdls_discover(sdata->local, sdata);
453 /* fall-through */
454 case WLAN_TDLS_SETUP_CONFIRM:
455 case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
456 /* no special handling */
457 ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
458 action_code,
459 dialog_token,
460 status_code,
461 peer_capability,
462 initiator, extra_ies,
463 extra_ies_len);
464 break;
465 default:
466 ret = -EOPNOTSUPP;
467 break;
468 }
469
470 tdls_dbg(sdata, "TDLS mgmt action %d peer %pM status %d\n",
471 action_code, peer, ret);
472 return ret;
473}
474
287int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, 475int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
288 const u8 *peer, enum nl80211_tdls_operation oper) 476 const u8 *peer, enum nl80211_tdls_operation oper)
289{ 477{
290 struct sta_info *sta; 478 struct sta_info *sta;
291 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 479 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
480 struct ieee80211_local *local = sdata->local;
481 int ret;
292 482
293 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS)) 483 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
294 return -ENOTSUPP; 484 return -ENOTSUPP;
@@ -296,6 +486,18 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
296 if (sdata->vif.type != NL80211_IFTYPE_STATION) 486 if (sdata->vif.type != NL80211_IFTYPE_STATION)
297 return -EINVAL; 487 return -EINVAL;
298 488
489 switch (oper) {
490 case NL80211_TDLS_ENABLE_LINK:
491 case NL80211_TDLS_DISABLE_LINK:
492 break;
493 case NL80211_TDLS_TEARDOWN:
494 case NL80211_TDLS_SETUP:
495 case NL80211_TDLS_DISCOVERY_REQ:
496 /* We don't support in-driver setup/teardown/discovery */
497 return -ENOTSUPP;
498 }
499
500 mutex_lock(&local->mtx);
299 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); 501 tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer);
300 502
301 switch (oper) { 503 switch (oper) {
@@ -304,22 +506,49 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
304 sta = sta_info_get(sdata, peer); 506 sta = sta_info_get(sdata, peer);
305 if (!sta) { 507 if (!sta) {
306 rcu_read_unlock(); 508 rcu_read_unlock();
307 return -ENOLINK; 509 ret = -ENOLINK;
510 break;
308 } 511 }
309 512
310 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH); 513 set_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH);
311 rcu_read_unlock(); 514 rcu_read_unlock();
515
516 WARN_ON_ONCE(is_zero_ether_addr(sdata->tdls_peer) ||
517 !ether_addr_equal(sdata->tdls_peer, peer));
518 ret = 0;
312 break; 519 break;
313 case NL80211_TDLS_DISABLE_LINK: 520 case NL80211_TDLS_DISABLE_LINK:
314 return sta_info_destroy_addr(sdata, peer); 521 /* flush a potentially queued teardown packet */
315 case NL80211_TDLS_TEARDOWN: 522 ieee80211_flush_queues(local, sdata);
316 case NL80211_TDLS_SETUP: 523
317 case NL80211_TDLS_DISCOVERY_REQ: 524 ret = sta_info_destroy_addr(sdata, peer);
318 /* We don't support in-driver setup/teardown/discovery */ 525 break;
319 return -ENOTSUPP;
320 default: 526 default:
321 return -ENOTSUPP; 527 ret = -ENOTSUPP;
528 break;
322 } 529 }
323 530
324 return 0; 531 if (ret == 0 && ether_addr_equal(sdata->tdls_peer, peer)) {
532 cancel_delayed_work(&sdata->tdls_peer_del_work);
533 eth_zero_addr(sdata->tdls_peer);
534 }
535
536 mutex_unlock(&local->mtx);
537 return ret;
538}
539
540void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
541 enum nl80211_tdls_operation oper,
542 u16 reason_code, gfp_t gfp)
543{
544 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
545
546 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc) {
547 sdata_err(sdata, "Discarding TDLS oper %d - not STA or disconnected\n",
548 oper);
549 return;
550 }
551
552 cfg80211_tdls_oper_request(sdata->dev, peer, oper, reason_code, gfp);
325} 553}
554EXPORT_SYMBOL(ieee80211_tdls_oper_request);
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index cfe1a0688b5c..02ac535d1274 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1330,6 +1330,13 @@ DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx,
1330 TP_ARGS(local, sdata) 1330 TP_ARGS(local, sdata)
1331); 1331);
1332 1332
1333DEFINE_EVENT(local_sdata_evt, drv_mgd_protect_tdls_discover,
1334 TP_PROTO(struct ieee80211_local *local,
1335 struct ieee80211_sub_if_data *sdata),
1336
1337 TP_ARGS(local, sdata)
1338);
1339
1333DECLARE_EVENT_CLASS(local_chanctx, 1340DECLARE_EVENT_CLASS(local_chanctx,
1334 TP_PROTO(struct ieee80211_local *local, 1341 TP_PROTO(struct ieee80211_local *local,
1335 struct ieee80211_chanctx *ctx), 1342 struct ieee80211_chanctx *ctx),
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5214686d9fd1..865bdaf06ff1 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -250,7 +250,8 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
250 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 250 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
251 ieee80211_stop_queues_by_reason(&local->hw, 251 ieee80211_stop_queues_by_reason(&local->hw,
252 IEEE80211_MAX_QUEUE_MAP, 252 IEEE80211_MAX_QUEUE_MAP,
253 IEEE80211_QUEUE_STOP_REASON_PS); 253 IEEE80211_QUEUE_STOP_REASON_PS,
254 false);
254 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; 255 ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
255 ieee80211_queue_work(&local->hw, 256 ieee80211_queue_work(&local->hw,
256 &local->dynamic_ps_disable_work); 257 &local->dynamic_ps_disable_work);
@@ -469,7 +470,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
469 return TX_CONTINUE; 470 return TX_CONTINUE;
470 471
471 if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) || 472 if (unlikely((test_sta_flag(sta, WLAN_STA_PS_STA) ||
472 test_sta_flag(sta, WLAN_STA_PS_DRIVER)) && 473 test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
474 test_sta_flag(sta, WLAN_STA_PS_DELIVER)) &&
473 !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) { 475 !(info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER))) {
474 int ac = skb_get_queue_mapping(tx->skb); 476 int ac = skb_get_queue_mapping(tx->skb);
475 477
@@ -486,7 +488,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
486 * ahead and Tx the packet. 488 * ahead and Tx the packet.
487 */ 489 */
488 if (!test_sta_flag(sta, WLAN_STA_PS_STA) && 490 if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
489 !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { 491 !test_sta_flag(sta, WLAN_STA_PS_DRIVER) &&
492 !test_sta_flag(sta, WLAN_STA_PS_DELIVER)) {
490 spin_unlock(&sta->ps_lock); 493 spin_unlock(&sta->ps_lock);
491 return TX_CONTINUE; 494 return TX_CONTINUE;
492 } 495 }
@@ -1618,12 +1621,12 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1618{ 1621{
1619 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1622 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1620 struct ieee80211_chanctx_conf *chanctx_conf; 1623 struct ieee80211_chanctx_conf *chanctx_conf;
1621 struct ieee80211_channel *chan;
1622 struct ieee80211_radiotap_header *prthdr = 1624 struct ieee80211_radiotap_header *prthdr =
1623 (struct ieee80211_radiotap_header *)skb->data; 1625 (struct ieee80211_radiotap_header *)skb->data;
1624 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1626 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1625 struct ieee80211_hdr *hdr; 1627 struct ieee80211_hdr *hdr;
1626 struct ieee80211_sub_if_data *tmp_sdata, *sdata; 1628 struct ieee80211_sub_if_data *tmp_sdata, *sdata;
1629 struct cfg80211_chan_def *chandef;
1627 u16 len_rthdr; 1630 u16 len_rthdr;
1628 int hdrlen; 1631 int hdrlen;
1629 1632
@@ -1721,9 +1724,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1721 } 1724 }
1722 1725
1723 if (chanctx_conf) 1726 if (chanctx_conf)
1724 chan = chanctx_conf->def.chan; 1727 chandef = &chanctx_conf->def;
1725 else if (!local->use_chanctx) 1728 else if (!local->use_chanctx)
1726 chan = local->_oper_chandef.chan; 1729 chandef = &local->_oper_chandef;
1727 else 1730 else
1728 goto fail_rcu; 1731 goto fail_rcu;
1729 1732
@@ -1743,10 +1746,11 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1743 * radar detection by itself. We can do that later by adding a 1746 * radar detection by itself. We can do that later by adding a
1744 * monitor flag interfaces used for AP support. 1747 * monitor flag interfaces used for AP support.
1745 */ 1748 */
1746 if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))) 1749 if (!cfg80211_reg_can_beacon(local->hw.wiphy, chandef,
1750 sdata->vif.type))
1747 goto fail_rcu; 1751 goto fail_rcu;
1748 1752
1749 ieee80211_xmit(sdata, skb, chan->band); 1753 ieee80211_xmit(sdata, skb, chandef->chan->band);
1750 rcu_read_unlock(); 1754 rcu_read_unlock();
1751 1755
1752 return NETDEV_TX_OK; 1756 return NETDEV_TX_OK;
@@ -1767,15 +1771,12 @@ fail:
1767static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, 1771static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
1768 struct sk_buff *skb) 1772 struct sk_buff *skb)
1769{ 1773{
1770 struct timespec skb_arv;
1771 struct ieee80211_tx_latency_bin_ranges *tx_latency; 1774 struct ieee80211_tx_latency_bin_ranges *tx_latency;
1772 1775
1773 tx_latency = rcu_dereference(local->tx_latency); 1776 tx_latency = rcu_dereference(local->tx_latency);
1774 if (!tx_latency) 1777 if (!tx_latency)
1775 return; 1778 return;
1776 1779 skb->tstamp = ktime_get();
1777 ktime_get_ts(&skb_arv);
1778 skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec);
1779} 1780}
1780 1781
1781/** 1782/**
@@ -1810,7 +1811,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1810 int nh_pos, h_pos; 1811 int nh_pos, h_pos;
1811 struct sta_info *sta = NULL; 1812 struct sta_info *sta = NULL;
1812 bool wme_sta = false, authorized = false, tdls_auth = false; 1813 bool wme_sta = false, authorized = false, tdls_auth = false;
1813 bool tdls_direct = false; 1814 bool tdls_peer = false, tdls_setup_frame = false;
1814 bool multicast; 1815 bool multicast;
1815 u32 info_flags = 0; 1816 u32 info_flags = 0;
1816 u16 info_id = 0; 1817 u16 info_id = 0;
@@ -1952,34 +1953,35 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1952#endif 1953#endif
1953 case NL80211_IFTYPE_STATION: 1954 case NL80211_IFTYPE_STATION:
1954 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { 1955 if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1955 bool tdls_peer = false;
1956
1957 sta = sta_info_get(sdata, skb->data); 1956 sta = sta_info_get(sdata, skb->data);
1958 if (sta) { 1957 if (sta) {
1959 authorized = test_sta_flag(sta, 1958 authorized = test_sta_flag(sta,
1960 WLAN_STA_AUTHORIZED); 1959 WLAN_STA_AUTHORIZED);
1961 wme_sta = test_sta_flag(sta, WLAN_STA_WME); 1960 wme_sta = test_sta_flag(sta, WLAN_STA_WME);
1962 tdls_peer = test_sta_flag(sta, 1961 tdls_peer = test_sta_flag(sta,
1963 WLAN_STA_TDLS_PEER); 1962 WLAN_STA_TDLS_PEER);
1964 tdls_auth = test_sta_flag(sta, 1963 tdls_auth = test_sta_flag(sta,
1965 WLAN_STA_TDLS_PEER_AUTH); 1964 WLAN_STA_TDLS_PEER_AUTH);
1966 } 1965 }
1967 1966
1968 /* 1967 if (tdls_peer)
1969 * If the TDLS link is enabled, send everything 1968 tdls_setup_frame =
1970 * directly. Otherwise, allow TDLS setup frames 1969 ethertype == ETH_P_TDLS &&
1971 * to be transmitted indirectly. 1970 skb->len > 14 &&
1972 */ 1971 skb->data[14] == WLAN_TDLS_SNAP_RFTYPE;
1973 tdls_direct = tdls_peer && (tdls_auth ||
1974 !(ethertype == ETH_P_TDLS && skb->len > 14 &&
1975 skb->data[14] == WLAN_TDLS_SNAP_RFTYPE));
1976 } 1972 }
1977 1973
1978 if (tdls_direct) { 1974 /*
1979 /* link during setup - throw out frames to peer */ 1975 * TDLS link during setup - throw out frames to peer. We allow
1980 if (!tdls_auth) 1976 * TDLS-setup frames to unauthorized peers for the special case
1981 goto fail_rcu; 1977 * of a link teardown after a TDLS sta is removed due to being
1978 * unreachable.
1979 */
1980 if (tdls_peer && !tdls_auth && !tdls_setup_frame)
1981 goto fail_rcu;
1982 1982
1983 /* send direct packets to authorized TDLS peers */
1984 if (tdls_peer && tdls_auth) {
1983 /* DA SA BSSID */ 1985 /* DA SA BSSID */
1984 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1986 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1985 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1987 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
@@ -2423,7 +2425,7 @@ static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata,
2423 u8 *beacon_data; 2425 u8 *beacon_data;
2424 size_t beacon_data_len; 2426 size_t beacon_data_len;
2425 int i; 2427 int i;
2426 u8 count = sdata->csa_current_counter; 2428 u8 count = beacon->csa_current_counter;
2427 2429
2428 switch (sdata->vif.type) { 2430 switch (sdata->vif.type) {
2429 case NL80211_IFTYPE_AP: 2431 case NL80211_IFTYPE_AP:
@@ -2442,46 +2444,53 @@ static void ieee80211_set_csa(struct ieee80211_sub_if_data *sdata,
2442 return; 2444 return;
2443 } 2445 }
2444 2446
2447 rcu_read_lock();
2445 for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) { 2448 for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; ++i) {
2446 u16 counter_offset_beacon = 2449 resp = rcu_dereference(sdata->u.ap.probe_resp);
2447 sdata->csa_counter_offset_beacon[i];
2448 u16 counter_offset_presp = sdata->csa_counter_offset_presp[i];
2449 2450
2450 if (counter_offset_beacon) { 2451 if (beacon->csa_counter_offsets[i]) {
2451 if (WARN_ON(counter_offset_beacon >= beacon_data_len)) 2452 if (WARN_ON_ONCE(beacon->csa_counter_offsets[i] >=
2452 return; 2453 beacon_data_len)) {
2453
2454 beacon_data[counter_offset_beacon] = count;
2455 }
2456
2457 if (sdata->vif.type == NL80211_IFTYPE_AP &&
2458 counter_offset_presp) {
2459 rcu_read_lock();
2460 resp = rcu_dereference(sdata->u.ap.probe_resp);
2461
2462 /* If nl80211 accepted the offset, this should
2463 * not happen.
2464 */
2465 if (WARN_ON(!resp)) {
2466 rcu_read_unlock(); 2454 rcu_read_unlock();
2467 return; 2455 return;
2468 } 2456 }
2469 resp->data[counter_offset_presp] = count; 2457
2470 rcu_read_unlock(); 2458 beacon_data[beacon->csa_counter_offsets[i]] = count;
2471 } 2459 }
2460
2461 if (sdata->vif.type == NL80211_IFTYPE_AP && resp)
2462 resp->data[resp->csa_counter_offsets[i]] = count;
2472 } 2463 }
2464 rcu_read_unlock();
2473} 2465}
2474 2466
2475u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif) 2467u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
2476{ 2468{
2477 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 2469 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
2470 struct beacon_data *beacon = NULL;
2471 u8 count = 0;
2472
2473 rcu_read_lock();
2478 2474
2479 sdata->csa_current_counter--; 2475 if (sdata->vif.type == NL80211_IFTYPE_AP)
2476 beacon = rcu_dereference(sdata->u.ap.beacon);
2477 else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
2478 beacon = rcu_dereference(sdata->u.ibss.presp);
2479 else if (ieee80211_vif_is_mesh(&sdata->vif))
2480 beacon = rcu_dereference(sdata->u.mesh.beacon);
2481
2482 if (!beacon)
2483 goto unlock;
2484
2485 beacon->csa_current_counter--;
2480 2486
2481 /* the counter should never reach 0 */ 2487 /* the counter should never reach 0 */
2482 WARN_ON(!sdata->csa_current_counter); 2488 WARN_ON_ONCE(!beacon->csa_current_counter);
2489 count = beacon->csa_current_counter;
2483 2490
2484 return sdata->csa_current_counter; 2491unlock:
2492 rcu_read_unlock();
2493 return count;
2485} 2494}
2486EXPORT_SYMBOL(ieee80211_csa_update_counter); 2495EXPORT_SYMBOL(ieee80211_csa_update_counter);
2487 2496
@@ -2491,7 +2500,6 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
2491 struct beacon_data *beacon = NULL; 2500 struct beacon_data *beacon = NULL;
2492 u8 *beacon_data; 2501 u8 *beacon_data;
2493 size_t beacon_data_len; 2502 size_t beacon_data_len;
2494 int counter_beacon = sdata->csa_counter_offset_beacon[0];
2495 int ret = false; 2503 int ret = false;
2496 2504
2497 if (!ieee80211_sdata_running(sdata)) 2505 if (!ieee80211_sdata_running(sdata))
@@ -2529,10 +2537,13 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
2529 goto out; 2537 goto out;
2530 } 2538 }
2531 2539
2532 if (WARN_ON(counter_beacon > beacon_data_len)) 2540 if (!beacon->csa_counter_offsets[0])
2533 goto out; 2541 goto out;
2534 2542
2535 if (beacon_data[counter_beacon] == 1) 2543 if (WARN_ON_ONCE(beacon->csa_counter_offsets[0] > beacon_data_len))
2544 goto out;
2545
2546 if (beacon_data[beacon->csa_counter_offsets[0]] == 1)
2536 ret = true; 2547 ret = true;
2537 out: 2548 out:
2538 rcu_read_unlock(); 2549 rcu_read_unlock();
@@ -2548,6 +2559,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
2548 bool is_template) 2559 bool is_template)
2549{ 2560{
2550 struct ieee80211_local *local = hw_to_local(hw); 2561 struct ieee80211_local *local = hw_to_local(hw);
2562 struct beacon_data *beacon = NULL;
2551 struct sk_buff *skb = NULL; 2563 struct sk_buff *skb = NULL;
2552 struct ieee80211_tx_info *info; 2564 struct ieee80211_tx_info *info;
2553 struct ieee80211_sub_if_data *sdata = NULL; 2565 struct ieee80211_sub_if_data *sdata = NULL;
@@ -2569,10 +2581,10 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
2569 2581
2570 if (sdata->vif.type == NL80211_IFTYPE_AP) { 2582 if (sdata->vif.type == NL80211_IFTYPE_AP) {
2571 struct ieee80211_if_ap *ap = &sdata->u.ap; 2583 struct ieee80211_if_ap *ap = &sdata->u.ap;
2572 struct beacon_data *beacon = rcu_dereference(ap->beacon);
2573 2584
2585 beacon = rcu_dereference(ap->beacon);
2574 if (beacon) { 2586 if (beacon) {
2575 if (sdata->vif.csa_active) { 2587 if (beacon->csa_counter_offsets[0]) {
2576 if (!is_template) 2588 if (!is_template)
2577 ieee80211_csa_update_counter(vif); 2589 ieee80211_csa_update_counter(vif);
2578 2590
@@ -2613,37 +2625,37 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
2613 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 2625 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2614 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 2626 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
2615 struct ieee80211_hdr *hdr; 2627 struct ieee80211_hdr *hdr;
2616 struct beacon_data *presp = rcu_dereference(ifibss->presp);
2617 2628
2618 if (!presp) 2629 beacon = rcu_dereference(ifibss->presp);
2630 if (!beacon)
2619 goto out; 2631 goto out;
2620 2632
2621 if (sdata->vif.csa_active) { 2633 if (beacon->csa_counter_offsets[0]) {
2622 if (!is_template) 2634 if (!is_template)
2623 ieee80211_csa_update_counter(vif); 2635 ieee80211_csa_update_counter(vif);
2624 2636
2625 ieee80211_set_csa(sdata, presp); 2637 ieee80211_set_csa(sdata, beacon);
2626 } 2638 }
2627 2639
2628 skb = dev_alloc_skb(local->tx_headroom + presp->head_len + 2640 skb = dev_alloc_skb(local->tx_headroom + beacon->head_len +
2629 local->hw.extra_beacon_tailroom); 2641 local->hw.extra_beacon_tailroom);
2630 if (!skb) 2642 if (!skb)
2631 goto out; 2643 goto out;
2632 skb_reserve(skb, local->tx_headroom); 2644 skb_reserve(skb, local->tx_headroom);
2633 memcpy(skb_put(skb, presp->head_len), presp->head, 2645 memcpy(skb_put(skb, beacon->head_len), beacon->head,
2634 presp->head_len); 2646 beacon->head_len);
2635 2647
2636 hdr = (struct ieee80211_hdr *) skb->data; 2648 hdr = (struct ieee80211_hdr *) skb->data;
2637 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2649 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2638 IEEE80211_STYPE_BEACON); 2650 IEEE80211_STYPE_BEACON);
2639 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 2651 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
2640 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 2652 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
2641 struct beacon_data *bcn = rcu_dereference(ifmsh->beacon);
2642 2653
2643 if (!bcn) 2654 beacon = rcu_dereference(ifmsh->beacon);
2655 if (!beacon)
2644 goto out; 2656 goto out;
2645 2657
2646 if (sdata->vif.csa_active) { 2658 if (beacon->csa_counter_offsets[0]) {
2647 if (!is_template) 2659 if (!is_template)
2648 /* TODO: For mesh csa_counter is in TU, so 2660 /* TODO: For mesh csa_counter is in TU, so
2649 * decrementing it by one isn't correct, but 2661 * decrementing it by one isn't correct, but
@@ -2652,40 +2664,42 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,
2652 */ 2664 */
2653 ieee80211_csa_update_counter(vif); 2665 ieee80211_csa_update_counter(vif);
2654 2666
2655 ieee80211_set_csa(sdata, bcn); 2667 ieee80211_set_csa(sdata, beacon);
2656 } 2668 }
2657 2669
2658 if (ifmsh->sync_ops) 2670 if (ifmsh->sync_ops)
2659 ifmsh->sync_ops->adjust_tbtt(sdata, bcn); 2671 ifmsh->sync_ops->adjust_tbtt(sdata, beacon);
2660 2672
2661 skb = dev_alloc_skb(local->tx_headroom + 2673 skb = dev_alloc_skb(local->tx_headroom +
2662 bcn->head_len + 2674 beacon->head_len +
2663 256 + /* TIM IE */ 2675 256 + /* TIM IE */
2664 bcn->tail_len + 2676 beacon->tail_len +
2665 local->hw.extra_beacon_tailroom); 2677 local->hw.extra_beacon_tailroom);
2666 if (!skb) 2678 if (!skb)
2667 goto out; 2679 goto out;
2668 skb_reserve(skb, local->tx_headroom); 2680 skb_reserve(skb, local->tx_headroom);
2669 memcpy(skb_put(skb, bcn->head_len), bcn->head, bcn->head_len); 2681 memcpy(skb_put(skb, beacon->head_len), beacon->head,
2682 beacon->head_len);
2670 ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template); 2683 ieee80211_beacon_add_tim(sdata, &ifmsh->ps, skb, is_template);
2671 2684
2672 if (offs) { 2685 if (offs) {
2673 offs->tim_offset = bcn->head_len; 2686 offs->tim_offset = beacon->head_len;
2674 offs->tim_length = skb->len - bcn->head_len; 2687 offs->tim_length = skb->len - beacon->head_len;
2675 } 2688 }
2676 2689
2677 memcpy(skb_put(skb, bcn->tail_len), bcn->tail, bcn->tail_len); 2690 memcpy(skb_put(skb, beacon->tail_len), beacon->tail,
2691 beacon->tail_len);
2678 } else { 2692 } else {
2679 WARN_ON(1); 2693 WARN_ON(1);
2680 goto out; 2694 goto out;
2681 } 2695 }
2682 2696
2683 /* CSA offsets */ 2697 /* CSA offsets */
2684 if (offs) { 2698 if (offs && beacon) {
2685 int i; 2699 int i;
2686 2700
2687 for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) { 2701 for (i = 0; i < IEEE80211_MAX_CSA_COUNTERS_NUM; i++) {
2688 u16 csa_off = sdata->csa_counter_offset_beacon[i]; 2702 u16 csa_off = beacon->csa_counter_offsets[i];
2689 2703
2690 if (!csa_off) 2704 if (!csa_off)
2691 continue; 2705 continue;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6886601afe1c..ea79668c2e5f 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -317,7 +317,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
317} 317}
318 318
319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, 319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
320 enum queue_stop_reason reason) 320 enum queue_stop_reason reason,
321 bool refcounted)
321{ 322{
322 struct ieee80211_local *local = hw_to_local(hw); 323 struct ieee80211_local *local = hw_to_local(hw);
323 324
@@ -329,7 +330,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
329 if (!test_bit(reason, &local->queue_stop_reasons[queue])) 330 if (!test_bit(reason, &local->queue_stop_reasons[queue]))
330 return; 331 return;
331 332
332 __clear_bit(reason, &local->queue_stop_reasons[queue]); 333 if (!refcounted)
334 local->q_stop_reasons[queue][reason] = 0;
335 else
336 local->q_stop_reasons[queue][reason]--;
337
338 if (local->q_stop_reasons[queue][reason] == 0)
339 __clear_bit(reason, &local->queue_stop_reasons[queue]);
333 340
334 if (local->queue_stop_reasons[queue] != 0) 341 if (local->queue_stop_reasons[queue] != 0)
335 /* someone still has this queue stopped */ 342 /* someone still has this queue stopped */
@@ -344,25 +351,28 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
344} 351}
345 352
346void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 353void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
347 enum queue_stop_reason reason) 354 enum queue_stop_reason reason,
355 bool refcounted)
348{ 356{
349 struct ieee80211_local *local = hw_to_local(hw); 357 struct ieee80211_local *local = hw_to_local(hw);
350 unsigned long flags; 358 unsigned long flags;
351 359
352 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 360 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
353 __ieee80211_wake_queue(hw, queue, reason); 361 __ieee80211_wake_queue(hw, queue, reason, refcounted);
354 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 362 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
355} 363}
356 364
357void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 365void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
358{ 366{
359 ieee80211_wake_queue_by_reason(hw, queue, 367 ieee80211_wake_queue_by_reason(hw, queue,
360 IEEE80211_QUEUE_STOP_REASON_DRIVER); 368 IEEE80211_QUEUE_STOP_REASON_DRIVER,
369 false);
361} 370}
362EXPORT_SYMBOL(ieee80211_wake_queue); 371EXPORT_SYMBOL(ieee80211_wake_queue);
363 372
364static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, 373static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
365 enum queue_stop_reason reason) 374 enum queue_stop_reason reason,
375 bool refcounted)
366{ 376{
367 struct ieee80211_local *local = hw_to_local(hw); 377 struct ieee80211_local *local = hw_to_local(hw);
368 struct ieee80211_sub_if_data *sdata; 378 struct ieee80211_sub_if_data *sdata;
@@ -373,10 +383,13 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
373 if (WARN_ON(queue >= hw->queues)) 383 if (WARN_ON(queue >= hw->queues))
374 return; 384 return;
375 385
376 if (test_bit(reason, &local->queue_stop_reasons[queue])) 386 if (!refcounted)
377 return; 387 local->q_stop_reasons[queue][reason] = 1;
388 else
389 local->q_stop_reasons[queue][reason]++;
378 390
379 __set_bit(reason, &local->queue_stop_reasons[queue]); 391 if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
392 return;
380 393
381 if (local->hw.queues < IEEE80211_NUM_ACS) 394 if (local->hw.queues < IEEE80211_NUM_ACS)
382 n_acs = 1; 395 n_acs = 1;
@@ -398,20 +411,22 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
398} 411}
399 412
400void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 413void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
401 enum queue_stop_reason reason) 414 enum queue_stop_reason reason,
415 bool refcounted)
402{ 416{
403 struct ieee80211_local *local = hw_to_local(hw); 417 struct ieee80211_local *local = hw_to_local(hw);
404 unsigned long flags; 418 unsigned long flags;
405 419
406 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 420 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
407 __ieee80211_stop_queue(hw, queue, reason); 421 __ieee80211_stop_queue(hw, queue, reason, refcounted);
408 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 422 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
409} 423}
410 424
411void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 425void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
412{ 426{
413 ieee80211_stop_queue_by_reason(hw, queue, 427 ieee80211_stop_queue_by_reason(hw, queue,
414 IEEE80211_QUEUE_STOP_REASON_DRIVER); 428 IEEE80211_QUEUE_STOP_REASON_DRIVER,
429 false);
415} 430}
416EXPORT_SYMBOL(ieee80211_stop_queue); 431EXPORT_SYMBOL(ieee80211_stop_queue);
417 432
@@ -429,9 +444,11 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
429 } 444 }
430 445
431 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 446 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
432 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 447 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
448 false);
433 __skb_queue_tail(&local->pending[queue], skb); 449 __skb_queue_tail(&local->pending[queue], skb);
434 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 450 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
451 false);
435 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 452 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
436} 453}
437 454
@@ -455,20 +472,23 @@ void ieee80211_add_pending_skbs(struct ieee80211_local *local,
455 queue = info->hw_queue; 472 queue = info->hw_queue;
456 473
457 __ieee80211_stop_queue(hw, queue, 474 __ieee80211_stop_queue(hw, queue,
458 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 475 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
476 false);
459 477
460 __skb_queue_tail(&local->pending[queue], skb); 478 __skb_queue_tail(&local->pending[queue], skb);
461 } 479 }
462 480
463 for (i = 0; i < hw->queues; i++) 481 for (i = 0; i < hw->queues; i++)
464 __ieee80211_wake_queue(hw, i, 482 __ieee80211_wake_queue(hw, i,
465 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 483 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
484 false);
466 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 485 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
467} 486}
468 487
469void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 488void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
470 unsigned long queues, 489 unsigned long queues,
471 enum queue_stop_reason reason) 490 enum queue_stop_reason reason,
491 bool refcounted)
472{ 492{
473 struct ieee80211_local *local = hw_to_local(hw); 493 struct ieee80211_local *local = hw_to_local(hw);
474 unsigned long flags; 494 unsigned long flags;
@@ -477,7 +497,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
477 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 497 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
478 498
479 for_each_set_bit(i, &queues, hw->queues) 499 for_each_set_bit(i, &queues, hw->queues)
480 __ieee80211_stop_queue(hw, i, reason); 500 __ieee80211_stop_queue(hw, i, reason, refcounted);
481 501
482 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 502 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
483} 503}
@@ -485,7 +505,8 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
485void ieee80211_stop_queues(struct ieee80211_hw *hw) 505void ieee80211_stop_queues(struct ieee80211_hw *hw)
486{ 506{
487 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 507 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
488 IEEE80211_QUEUE_STOP_REASON_DRIVER); 508 IEEE80211_QUEUE_STOP_REASON_DRIVER,
509 false);
489} 510}
490EXPORT_SYMBOL(ieee80211_stop_queues); 511EXPORT_SYMBOL(ieee80211_stop_queues);
491 512
@@ -508,7 +529,8 @@ EXPORT_SYMBOL(ieee80211_queue_stopped);
508 529
509void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 530void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
510 unsigned long queues, 531 unsigned long queues,
511 enum queue_stop_reason reason) 532 enum queue_stop_reason reason,
533 bool refcounted)
512{ 534{
513 struct ieee80211_local *local = hw_to_local(hw); 535 struct ieee80211_local *local = hw_to_local(hw);
514 unsigned long flags; 536 unsigned long flags;
@@ -517,7 +539,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
517 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 539 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
518 540
519 for_each_set_bit(i, &queues, hw->queues) 541 for_each_set_bit(i, &queues, hw->queues)
520 __ieee80211_wake_queue(hw, i, reason); 542 __ieee80211_wake_queue(hw, i, reason, refcounted);
521 543
522 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 544 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
523} 545}
@@ -525,17 +547,16 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
525void ieee80211_wake_queues(struct ieee80211_hw *hw) 547void ieee80211_wake_queues(struct ieee80211_hw *hw)
526{ 548{
527 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 549 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
528 IEEE80211_QUEUE_STOP_REASON_DRIVER); 550 IEEE80211_QUEUE_STOP_REASON_DRIVER,
551 false);
529} 552}
530EXPORT_SYMBOL(ieee80211_wake_queues); 553EXPORT_SYMBOL(ieee80211_wake_queues);
531 554
532void ieee80211_flush_queues(struct ieee80211_local *local, 555static unsigned int
533 struct ieee80211_sub_if_data *sdata) 556ieee80211_get_vif_queues(struct ieee80211_local *local,
557 struct ieee80211_sub_if_data *sdata)
534{ 558{
535 u32 queues; 559 unsigned int queues;
536
537 if (!local->ops->flush)
538 return;
539 560
540 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { 561 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
541 int ac; 562 int ac;
@@ -551,13 +572,46 @@ void ieee80211_flush_queues(struct ieee80211_local *local,
551 queues = BIT(local->hw.queues) - 1; 572 queues = BIT(local->hw.queues) - 1;
552 } 573 }
553 574
554 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 575 return queues;
555 IEEE80211_QUEUE_STOP_REASON_FLUSH); 576}
577
578void ieee80211_flush_queues(struct ieee80211_local *local,
579 struct ieee80211_sub_if_data *sdata)
580{
581 unsigned int queues;
582
583 if (!local->ops->flush)
584 return;
585
586 queues = ieee80211_get_vif_queues(local, sdata);
587
588 ieee80211_stop_queues_by_reason(&local->hw, queues,
589 IEEE80211_QUEUE_STOP_REASON_FLUSH,
590 false);
556 591
557 drv_flush(local, sdata, queues, false); 592 drv_flush(local, sdata, queues, false);
558 593
559 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 594 ieee80211_wake_queues_by_reason(&local->hw, queues,
560 IEEE80211_QUEUE_STOP_REASON_FLUSH); 595 IEEE80211_QUEUE_STOP_REASON_FLUSH,
596 false);
597}
598
599void ieee80211_stop_vif_queues(struct ieee80211_local *local,
600 struct ieee80211_sub_if_data *sdata,
601 enum queue_stop_reason reason)
602{
603 ieee80211_stop_queues_by_reason(&local->hw,
604 ieee80211_get_vif_queues(local, sdata),
605 reason, true);
606}
607
608void ieee80211_wake_vif_queues(struct ieee80211_local *local,
609 struct ieee80211_sub_if_data *sdata,
610 enum queue_stop_reason reason)
611{
612 ieee80211_wake_queues_by_reason(&local->hw,
613 ieee80211_get_vif_queues(local, sdata),
614 reason, true);
561} 615}
562 616
563static void __iterate_active_interfaces(struct ieee80211_local *local, 617static void __iterate_active_interfaces(struct ieee80211_local *local,
@@ -1165,14 +1219,17 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1165 } 1219 }
1166} 1220}
1167 1221
1168int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1222static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
1169 size_t buffer_len, const u8 *ie, size_t ie_len, 1223 u8 *buffer, size_t buffer_len,
1170 enum ieee80211_band band, u32 rate_mask, 1224 const u8 *ie, size_t ie_len,
1171 struct cfg80211_chan_def *chandef) 1225 enum ieee80211_band band,
1226 u32 rate_mask,
1227 struct cfg80211_chan_def *chandef,
1228 size_t *offset)
1172{ 1229{
1173 struct ieee80211_supported_band *sband; 1230 struct ieee80211_supported_band *sband;
1174 u8 *pos = buffer, *end = buffer + buffer_len; 1231 u8 *pos = buffer, *end = buffer + buffer_len;
1175 size_t offset = 0, noffset; 1232 size_t noffset;
1176 int supp_rates_len, i; 1233 int supp_rates_len, i;
1177 u8 rates[32]; 1234 u8 rates[32];
1178 int num_rates; 1235 int num_rates;
@@ -1180,6 +1237,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1180 int shift; 1237 int shift;
1181 u32 rate_flags; 1238 u32 rate_flags;
1182 1239
1240 *offset = 0;
1241
1183 sband = local->hw.wiphy->bands[band]; 1242 sband = local->hw.wiphy->bands[band];
1184 if (WARN_ON_ONCE(!sband)) 1243 if (WARN_ON_ONCE(!sband))
1185 return 0; 1244 return 0;
@@ -1218,12 +1277,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1218 noffset = ieee80211_ie_split(ie, ie_len, 1277 noffset = ieee80211_ie_split(ie, ie_len,
1219 before_extrates, 1278 before_extrates,
1220 ARRAY_SIZE(before_extrates), 1279 ARRAY_SIZE(before_extrates),
1221 offset); 1280 *offset);
1222 if (end - pos < noffset - offset) 1281 if (end - pos < noffset - *offset)
1223 goto out_err; 1282 goto out_err;
1224 memcpy(pos, ie + offset, noffset - offset); 1283 memcpy(pos, ie + *offset, noffset - *offset);
1225 pos += noffset - offset; 1284 pos += noffset - *offset;
1226 offset = noffset; 1285 *offset = noffset;
1227 } 1286 }
1228 1287
1229 ext_rates_len = num_rates - supp_rates_len; 1288 ext_rates_len = num_rates - supp_rates_len;
@@ -1257,12 +1316,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1257 }; 1316 };
1258 noffset = ieee80211_ie_split(ie, ie_len, 1317 noffset = ieee80211_ie_split(ie, ie_len,
1259 before_ht, ARRAY_SIZE(before_ht), 1318 before_ht, ARRAY_SIZE(before_ht),
1260 offset); 1319 *offset);
1261 if (end - pos < noffset - offset) 1320 if (end - pos < noffset - *offset)
1262 goto out_err; 1321 goto out_err;
1263 memcpy(pos, ie + offset, noffset - offset); 1322 memcpy(pos, ie + *offset, noffset - *offset);
1264 pos += noffset - offset; 1323 pos += noffset - *offset;
1265 offset = noffset; 1324 *offset = noffset;
1266 } 1325 }
1267 1326
1268 if (sband->ht_cap.ht_supported) { 1327 if (sband->ht_cap.ht_supported) {
@@ -1297,12 +1356,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1297 }; 1356 };
1298 noffset = ieee80211_ie_split(ie, ie_len, 1357 noffset = ieee80211_ie_split(ie, ie_len,
1299 before_vht, ARRAY_SIZE(before_vht), 1358 before_vht, ARRAY_SIZE(before_vht),
1300 offset); 1359 *offset);
1301 if (end - pos < noffset - offset) 1360 if (end - pos < noffset - *offset)
1302 goto out_err; 1361 goto out_err;
1303 memcpy(pos, ie + offset, noffset - offset); 1362 memcpy(pos, ie + *offset, noffset - *offset);
1304 pos += noffset - offset; 1363 pos += noffset - *offset;
1305 offset = noffset; 1364 *offset = noffset;
1306 } 1365 }
1307 1366
1308 if (sband->vht_cap.vht_supported) { 1367 if (sband->vht_cap.vht_supported) {
@@ -1312,21 +1371,54 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1312 sband->vht_cap.cap); 1371 sband->vht_cap.cap);
1313 } 1372 }
1314 1373
1315 /* add any remaining custom IEs */
1316 if (ie && ie_len) {
1317 noffset = ie_len;
1318 if (end - pos < noffset - offset)
1319 goto out_err;
1320 memcpy(pos, ie + offset, noffset - offset);
1321 pos += noffset - offset;
1322 }
1323
1324 return pos - buffer; 1374 return pos - buffer;
1325 out_err: 1375 out_err:
1326 WARN_ONCE(1, "not enough space for preq IEs\n"); 1376 WARN_ONCE(1, "not enough space for preq IEs\n");
1327 return pos - buffer; 1377 return pos - buffer;
1328} 1378}
1329 1379
1380int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1381 size_t buffer_len,
1382 struct ieee80211_scan_ies *ie_desc,
1383 const u8 *ie, size_t ie_len,
1384 u8 bands_used, u32 *rate_masks,
1385 struct cfg80211_chan_def *chandef)
1386{
1387 size_t pos = 0, old_pos = 0, custom_ie_offset = 0;
1388 int i;
1389
1390 memset(ie_desc, 0, sizeof(*ie_desc));
1391
1392 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
1393 if (bands_used & BIT(i)) {
1394 pos += ieee80211_build_preq_ies_band(local,
1395 buffer + pos,
1396 buffer_len - pos,
1397 ie, ie_len, i,
1398 rate_masks[i],
1399 chandef,
1400 &custom_ie_offset);
1401 ie_desc->ies[i] = buffer + old_pos;
1402 ie_desc->len[i] = pos - old_pos;
1403 old_pos = pos;
1404 }
1405 }
1406
1407 /* add any remaining custom IEs */
1408 if (ie && ie_len) {
1409 if (WARN_ONCE(buffer_len - pos < ie_len - custom_ie_offset,
1410 "not enough space for preq custom IEs\n"))
1411 return pos;
1412 memcpy(buffer + pos, ie + custom_ie_offset,
1413 ie_len - custom_ie_offset);
1414 ie_desc->common_ies = buffer + pos;
1415 ie_desc->common_ie_len = ie_len - custom_ie_offset;
1416 pos += ie_len - custom_ie_offset;
1417 }
1418
1419 return pos;
1420};
1421
1330struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1422struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1331 u8 *dst, u32 ratemask, 1423 u8 *dst, u32 ratemask,
1332 struct ieee80211_channel *chan, 1424 struct ieee80211_channel *chan,
@@ -1339,6 +1431,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1339 struct sk_buff *skb; 1431 struct sk_buff *skb;
1340 struct ieee80211_mgmt *mgmt; 1432 struct ieee80211_mgmt *mgmt;
1341 int ies_len; 1433 int ies_len;
1434 u32 rate_masks[IEEE80211_NUM_BANDS] = {};
1435 struct ieee80211_scan_ies dummy_ie_desc;
1342 1436
1343 /* 1437 /*
1344 * Do not send DS Channel parameter for directed probe requests 1438 * Do not send DS Channel parameter for directed probe requests
@@ -1356,10 +1450,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1356 if (!skb) 1450 if (!skb)
1357 return NULL; 1451 return NULL;
1358 1452
1453 rate_masks[chan->band] = ratemask;
1359 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1454 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1360 skb_tailroom(skb), 1455 skb_tailroom(skb), &dummy_ie_desc,
1361 ie, ie_len, chan->band, 1456 ie, ie_len, BIT(chan->band),
1362 ratemask, &chandef); 1457 rate_masks, &chandef);
1363 skb_put(skb, ies_len); 1458 skb_put(skb, ies_len);
1364 1459
1365 if (dst) { 1460 if (dst) {
@@ -1603,7 +1698,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1603 if (local->use_chanctx) { 1698 if (local->use_chanctx) {
1604 mutex_lock(&local->chanctx_mtx); 1699 mutex_lock(&local->chanctx_mtx);
1605 list_for_each_entry(ctx, &local->chanctx_list, list) 1700 list_for_each_entry(ctx, &local->chanctx_list, list)
1606 WARN_ON(drv_add_chanctx(local, ctx)); 1701 if (ctx->replace_state !=
1702 IEEE80211_CHANCTX_REPLACES_OTHER)
1703 WARN_ON(drv_add_chanctx(local, ctx));
1607 mutex_unlock(&local->chanctx_mtx); 1704 mutex_unlock(&local->chanctx_mtx);
1608 1705
1609 list_for_each_entry(sdata, &local->interfaces, list) { 1706 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -1797,7 +1894,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1797 } 1894 }
1798 1895
1799 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 1896 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
1800 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1897 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
1898 false);
1801 1899
1802 /* 1900 /*
1803 * Reconfigure sched scan if it was interrupted by FW restart or 1901 * Reconfigure sched scan if it was interrupted by FW restart or
@@ -2835,6 +2933,35 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local,
2835 ps->dtim_count = dtim_count; 2933 ps->dtim_count = dtim_count;
2836} 2934}
2837 2935
2936static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
2937 struct ieee80211_chanctx *ctx)
2938{
2939 struct ieee80211_sub_if_data *sdata;
2940 u8 radar_detect = 0;
2941
2942 lockdep_assert_held(&local->chanctx_mtx);
2943
2944 if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED))
2945 return 0;
2946
2947 list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
2948 if (sdata->reserved_radar_required)
2949 radar_detect |= BIT(sdata->reserved_chandef.width);
2950
2951 /*
2952 * An in-place reservation context should not have any assigned vifs
2953 * until it replaces the other context.
2954 */
2955 WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
2956 !list_empty(&ctx->assigned_vifs));
2957
2958 list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
2959 if (sdata->radar_required)
2960 radar_detect |= BIT(sdata->vif.bss_conf.chandef.width);
2961
2962 return radar_detect;
2963}
2964
2838int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, 2965int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
2839 const struct cfg80211_chan_def *chandef, 2966 const struct cfg80211_chan_def *chandef,
2840 enum ieee80211_chanctx_mode chanmode, 2967 enum ieee80211_chanctx_mode chanmode,
@@ -2876,8 +3003,9 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
2876 num[iftype] = 1; 3003 num[iftype] = 1;
2877 3004
2878 list_for_each_entry(ctx, &local->chanctx_list, list) { 3005 list_for_each_entry(ctx, &local->chanctx_list, list) {
2879 if (ctx->conf.radar_enabled) 3006 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
2880 radar_detect |= BIT(ctx->conf.def.width); 3007 continue;
3008 radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
2881 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { 3009 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
2882 num_different_channels++; 3010 num_different_channels++;
2883 continue; 3011 continue;
@@ -2934,10 +3062,12 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
2934 lockdep_assert_held(&local->chanctx_mtx); 3062 lockdep_assert_held(&local->chanctx_mtx);
2935 3063
2936 list_for_each_entry(ctx, &local->chanctx_list, list) { 3064 list_for_each_entry(ctx, &local->chanctx_list, list) {
3065 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
3066 continue;
3067
2937 num_different_channels++; 3068 num_different_channels++;
2938 3069
2939 if (ctx->conf.radar_enabled) 3070 radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
2940 radar_detect |= BIT(ctx->conf.def.width);
2941 } 3071 }
2942 3072
2943 list_for_each_entry_rcu(sdata, &local->interfaces, list) 3073 list_for_each_entry_rcu(sdata, &local->interfaces, list)
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6ee2b5863572..9181fb6d6437 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -271,22 +271,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
271 return ret; 271 return ret;
272} 272}
273 273
274
275static bool ieee80211_wep_is_weak_iv(struct sk_buff *skb,
276 struct ieee80211_key *key)
277{
278 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
279 unsigned int hdrlen;
280 u8 *ivpos;
281 u32 iv;
282
283 hdrlen = ieee80211_hdrlen(hdr->frame_control);
284 ivpos = skb->data + hdrlen;
285 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
286
287 return ieee80211_wep_weak_iv(iv, key->conf.keylen);
288}
289
290ieee80211_rx_result 274ieee80211_rx_result
291ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) 275ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
292{ 276{
@@ -301,16 +285,12 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
301 if (!(status->flag & RX_FLAG_DECRYPTED)) { 285 if (!(status->flag & RX_FLAG_DECRYPTED)) {
302 if (skb_linearize(rx->skb)) 286 if (skb_linearize(rx->skb))
303 return RX_DROP_UNUSABLE; 287 return RX_DROP_UNUSABLE;
304 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
305 rx->sta->wep_weak_iv_count++;
306 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) 288 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
307 return RX_DROP_UNUSABLE; 289 return RX_DROP_UNUSABLE;
308 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { 290 } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
309 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + 291 if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) +
310 IEEE80211_WEP_IV_LEN)) 292 IEEE80211_WEP_IV_LEN))
311 return RX_DROP_UNUSABLE; 293 return RX_DROP_UNUSABLE;
312 if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
313 rx->sta->wep_weak_iv_count++;
314 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 294 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
315 /* remove ICV */ 295 /* remove ICV */
316 if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) 296 if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
diff --git a/net/wireless/core.c b/net/wireless/core.c
index a1c40654dd9b..afee5e0455ea 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -25,7 +25,6 @@
25#include "sysfs.h" 25#include "sysfs.h"
26#include "debugfs.h" 26#include "debugfs.h"
27#include "wext-compat.h" 27#include "wext-compat.h"
28#include "ethtool.h"
29#include "rdev-ops.h" 28#include "rdev-ops.h"
30 29
31/* name for sysfs, %d is appended */ 30/* name for sysfs, %d is appended */
@@ -927,8 +926,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
927 /* allow mac80211 to determine the timeout */ 926 /* allow mac80211 to determine the timeout */
928 wdev->ps_timeout = -1; 927 wdev->ps_timeout = -1;
929 928
930 netdev_set_default_ethtool_ops(dev, &cfg80211_ethtool_ops);
931
932 if ((wdev->iftype == NL80211_IFTYPE_STATION || 929 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
933 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || 930 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
934 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) 931 wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
diff --git a/net/wireless/ethtool.c b/net/wireless/ethtool.c
index d4860bfc020e..e9e91298c70d 100644
--- a/net/wireless/ethtool.c
+++ b/net/wireless/ethtool.c
@@ -1,11 +1,9 @@
1#include <linux/utsname.h> 1#include <linux/utsname.h>
2#include <net/cfg80211.h> 2#include <net/cfg80211.h>
3#include "core.h" 3#include "core.h"
4#include "ethtool.h"
5#include "rdev-ops.h" 4#include "rdev-ops.h"
6 5
7static void cfg80211_get_drvinfo(struct net_device *dev, 6void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
8 struct ethtool_drvinfo *info)
9{ 7{
10 struct wireless_dev *wdev = dev->ieee80211_ptr; 8 struct wireless_dev *wdev = dev->ieee80211_ptr;
11 9
@@ -23,84 +21,4 @@ static void cfg80211_get_drvinfo(struct net_device *dev,
23 strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)), 21 strlcpy(info->bus_info, dev_name(wiphy_dev(wdev->wiphy)),
24 sizeof(info->bus_info)); 22 sizeof(info->bus_info));
25} 23}
26 24EXPORT_SYMBOL(cfg80211_get_drvinfo);
27static int cfg80211_get_regs_len(struct net_device *dev)
28{
29 /* For now, return 0... */
30 return 0;
31}
32
33static void cfg80211_get_regs(struct net_device *dev, struct ethtool_regs *regs,
34 void *data)
35{
36 struct wireless_dev *wdev = dev->ieee80211_ptr;
37
38 regs->version = wdev->wiphy->hw_version;
39 regs->len = 0;
40}
41
42static void cfg80211_get_ringparam(struct net_device *dev,
43 struct ethtool_ringparam *rp)
44{
45 struct wireless_dev *wdev = dev->ieee80211_ptr;
46 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
47
48 memset(rp, 0, sizeof(*rp));
49
50 if (rdev->ops->get_ringparam)
51 rdev_get_ringparam(rdev, &rp->tx_pending, &rp->tx_max_pending,
52 &rp->rx_pending, &rp->rx_max_pending);
53}
54
55static int cfg80211_set_ringparam(struct net_device *dev,
56 struct ethtool_ringparam *rp)
57{
58 struct wireless_dev *wdev = dev->ieee80211_ptr;
59 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
60
61 if (rp->rx_mini_pending != 0 || rp->rx_jumbo_pending != 0)
62 return -EINVAL;
63
64 if (rdev->ops->set_ringparam)
65 return rdev_set_ringparam(rdev, rp->tx_pending, rp->rx_pending);
66
67 return -ENOTSUPP;
68}
69
70static int cfg80211_get_sset_count(struct net_device *dev, int sset)
71{
72 struct wireless_dev *wdev = dev->ieee80211_ptr;
73 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
74 if (rdev->ops->get_et_sset_count)
75 return rdev_get_et_sset_count(rdev, dev, sset);
76 return -EOPNOTSUPP;
77}
78
79static void cfg80211_get_stats(struct net_device *dev,
80 struct ethtool_stats *stats, u64 *data)
81{
82 struct wireless_dev *wdev = dev->ieee80211_ptr;
83 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
84 if (rdev->ops->get_et_stats)
85 rdev_get_et_stats(rdev, dev, stats, data);
86}
87
88static void cfg80211_get_strings(struct net_device *dev, u32 sset, u8 *data)
89{
90 struct wireless_dev *wdev = dev->ieee80211_ptr;
91 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
92 if (rdev->ops->get_et_strings)
93 rdev_get_et_strings(rdev, dev, sset, data);
94}
95
96const struct ethtool_ops cfg80211_ethtool_ops = {
97 .get_drvinfo = cfg80211_get_drvinfo,
98 .get_regs_len = cfg80211_get_regs_len,
99 .get_regs = cfg80211_get_regs,
100 .get_link = ethtool_op_get_link,
101 .get_ringparam = cfg80211_get_ringparam,
102 .set_ringparam = cfg80211_set_ringparam,
103 .get_strings = cfg80211_get_strings,
104 .get_ethtool_stats = cfg80211_get_stats,
105 .get_sset_count = cfg80211_get_sset_count,
106};
diff --git a/net/wireless/ethtool.h b/net/wireless/ethtool.h
deleted file mode 100644
index 695ecad20bd6..000000000000
--- a/net/wireless/ethtool.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __CFG80211_ETHTOOL__
2#define __CFG80211_ETHTOOL__
3
4extern const struct ethtool_ops cfg80211_ethtool_ops;
5
6#endif /* __CFG80211_ETHTOOL__ */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ba4f1723c83a..c10295138eb5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -337,6 +337,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
337 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, 337 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
338 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, 338 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
339 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, 339 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
340 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
340 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, 341 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
341 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, 342 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
342 .len = IEEE80211_MAX_DATA_LEN }, 343 .len = IEEE80211_MAX_DATA_LEN },
@@ -6012,17 +6013,6 @@ skip_beacons:
6012 params.radar_required = true; 6013 params.radar_required = true;
6013 } 6014 }
6014 6015
6015 /* TODO: I left this here for now. With channel switch, the
6016 * verification is a bit more complicated, because we only do
6017 * it later when the channel switch really happens.
6018 */
6019 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
6020 params.chandef.chan,
6021 CHAN_MODE_SHARED,
6022 radar_detect_width);
6023 if (err)
6024 return err;
6025
6026 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 6016 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
6027 params.block_tx = true; 6017 params.block_tx = true;
6028 6018
@@ -7365,6 +7355,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7365 u32 peer_capability = 0; 7355 u32 peer_capability = 0;
7366 u16 status_code; 7356 u16 status_code;
7367 u8 *peer; 7357 u8 *peer;
7358 bool initiator;
7368 7359
7369 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) || 7360 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
7370 !rdev->ops->tdls_mgmt) 7361 !rdev->ops->tdls_mgmt)
@@ -7381,12 +7372,14 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
7381 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); 7372 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
7382 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); 7373 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
7383 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); 7374 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
7375 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
7384 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]) 7376 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
7385 peer_capability = 7377 peer_capability =
7386 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]); 7378 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
7387 7379
7388 return rdev_tdls_mgmt(rdev, dev, peer, action_code, 7380 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
7389 dialog_token, status_code, peer_capability, 7381 dialog_token, status_code, peer_capability,
7382 initiator,
7390 nla_data(info->attrs[NL80211_ATTR_IE]), 7383 nla_data(info->attrs[NL80211_ATTR_IE]),
7391 nla_len(info->attrs[NL80211_ATTR_IE])); 7384 nla_len(info->attrs[NL80211_ATTR_IE]));
7392} 7385}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index d95bbe348138..56c2240c30ce 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -714,25 +714,6 @@ static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev,
714 return ret; 714 return ret;
715} 715}
716 716
717static inline int rdev_set_ringparam(struct cfg80211_registered_device *rdev,
718 u32 tx, u32 rx)
719{
720 int ret;
721 trace_rdev_set_ringparam(&rdev->wiphy, tx, rx);
722 ret = rdev->ops->set_ringparam(&rdev->wiphy, tx, rx);
723 trace_rdev_return_int(&rdev->wiphy, ret);
724 return ret;
725}
726
727static inline void rdev_get_ringparam(struct cfg80211_registered_device *rdev,
728 u32 *tx, u32 *tx_max, u32 *rx,
729 u32 *rx_max)
730{
731 trace_rdev_get_ringparam(&rdev->wiphy);
732 rdev->ops->get_ringparam(&rdev->wiphy, tx, tx_max, rx, rx_max);
733 trace_rdev_return_void_tx_rx(&rdev->wiphy, *tx, *tx_max, *rx, *rx_max);
734}
735
736static inline int 717static inline int
737rdev_sched_scan_start(struct cfg80211_registered_device *rdev, 718rdev_sched_scan_start(struct cfg80211_registered_device *rdev,
738 struct net_device *dev, 719 struct net_device *dev,
@@ -770,15 +751,15 @@ static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev,
770 struct net_device *dev, u8 *peer, 751 struct net_device *dev, u8 *peer,
771 u8 action_code, u8 dialog_token, 752 u8 action_code, u8 dialog_token,
772 u16 status_code, u32 peer_capability, 753 u16 status_code, u32 peer_capability,
773 const u8 *buf, size_t len) 754 bool initiator, const u8 *buf, size_t len)
774{ 755{
775 int ret; 756 int ret;
776 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 757 trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
777 dialog_token, status_code, peer_capability, 758 dialog_token, status_code, peer_capability,
778 buf, len); 759 initiator, buf, len);
779 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code, 760 ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
780 dialog_token, status_code, peer_capability, 761 dialog_token, status_code, peer_capability,
781 buf, len); 762 initiator, buf, len);
782 trace_rdev_return_int(&rdev->wiphy, ret); 763 trace_rdev_return_int(&rdev->wiphy, ret);
783 return ret; 764 return ret;
784} 765}
@@ -816,35 +797,6 @@ static inline int rdev_set_noack_map(struct cfg80211_registered_device *rdev,
816} 797}
817 798
818static inline int 799static inline int
819rdev_get_et_sset_count(struct cfg80211_registered_device *rdev,
820 struct net_device *dev, int sset)
821{
822 int ret;
823 trace_rdev_get_et_sset_count(&rdev->wiphy, dev, sset);
824 ret = rdev->ops->get_et_sset_count(&rdev->wiphy, dev, sset);
825 trace_rdev_return_int(&rdev->wiphy, ret);
826 return ret;
827}
828
829static inline void rdev_get_et_stats(struct cfg80211_registered_device *rdev,
830 struct net_device *dev,
831 struct ethtool_stats *stats, u64 *data)
832{
833 trace_rdev_get_et_stats(&rdev->wiphy, dev);
834 rdev->ops->get_et_stats(&rdev->wiphy, dev, stats, data);
835 trace_rdev_return_void(&rdev->wiphy);
836}
837
838static inline void rdev_get_et_strings(struct cfg80211_registered_device *rdev,
839 struct net_device *dev, u32 sset,
840 u8 *data)
841{
842 trace_rdev_get_et_strings(&rdev->wiphy, dev, sset);
843 rdev->ops->get_et_strings(&rdev->wiphy, dev, sset, data);
844 trace_rdev_return_void(&rdev->wiphy);
845}
846
847static inline int
848rdev_get_channel(struct cfg80211_registered_device *rdev, 800rdev_get_channel(struct cfg80211_registered_device *rdev,
849 struct wireless_dev *wdev, 801 struct wireless_dev *wdev,
850 struct cfg80211_chan_def *chandef) 802 struct cfg80211_chan_def *chandef)
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 560ed77084e9..85474ee501eb 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -298,11 +298,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_return_void,
298 TP_ARGS(wiphy) 298 TP_ARGS(wiphy)
299); 299);
300 300
301DEFINE_EVENT(wiphy_only_evt, rdev_get_ringparam,
302 TP_PROTO(struct wiphy *wiphy),
303 TP_ARGS(wiphy)
304);
305
306DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna, 301DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
307 TP_PROTO(struct wiphy *wiphy), 302 TP_PROTO(struct wiphy *wiphy),
308 TP_ARGS(wiphy) 303 TP_ARGS(wiphy)
@@ -580,11 +575,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap,
580 TP_ARGS(wiphy, netdev) 575 TP_ARGS(wiphy, netdev)
581); 576);
582 577
583DEFINE_EVENT(wiphy_netdev_evt, rdev_get_et_stats,
584 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
585 TP_ARGS(wiphy, netdev)
586);
587
588DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop, 578DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop,
589 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev), 579 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
590 TP_ARGS(wiphy, netdev) 580 TP_ARGS(wiphy, netdev)
@@ -1439,11 +1429,6 @@ DECLARE_EVENT_CLASS(tx_rx_evt,
1439 WIPHY_PR_ARG, __entry->tx, __entry->rx) 1429 WIPHY_PR_ARG, __entry->tx, __entry->rx)
1440); 1430);
1441 1431
1442DEFINE_EVENT(tx_rx_evt, rdev_set_ringparam,
1443 TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
1444 TP_ARGS(wiphy, rx, tx)
1445);
1446
1447DEFINE_EVENT(tx_rx_evt, rdev_set_antenna, 1432DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
1448 TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx), 1433 TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
1449 TP_ARGS(wiphy, rx, tx) 1434 TP_ARGS(wiphy, rx, tx)
@@ -1469,9 +1454,9 @@ TRACE_EVENT(rdev_tdls_mgmt,
1469 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 1454 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
1470 u8 *peer, u8 action_code, u8 dialog_token, 1455 u8 *peer, u8 action_code, u8 dialog_token,
1471 u16 status_code, u32 peer_capability, 1456 u16 status_code, u32 peer_capability,
1472 const u8 *buf, size_t len), 1457 bool initiator, const u8 *buf, size_t len),
1473 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code, 1458 TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code,
1474 peer_capability, buf, len), 1459 peer_capability, initiator, buf, len),
1475 TP_STRUCT__entry( 1460 TP_STRUCT__entry(
1476 WIPHY_ENTRY 1461 WIPHY_ENTRY
1477 NETDEV_ENTRY 1462 NETDEV_ENTRY
@@ -1480,6 +1465,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
1480 __field(u8, dialog_token) 1465 __field(u8, dialog_token)
1481 __field(u16, status_code) 1466 __field(u16, status_code)
1482 __field(u32, peer_capability) 1467 __field(u32, peer_capability)
1468 __field(bool, initiator)
1483 __dynamic_array(u8, buf, len) 1469 __dynamic_array(u8, buf, len)
1484 ), 1470 ),
1485 TP_fast_assign( 1471 TP_fast_assign(
@@ -1490,13 +1476,16 @@ TRACE_EVENT(rdev_tdls_mgmt,
1490 __entry->dialog_token = dialog_token; 1476 __entry->dialog_token = dialog_token;
1491 __entry->status_code = status_code; 1477 __entry->status_code = status_code;
1492 __entry->peer_capability = peer_capability; 1478 __entry->peer_capability = peer_capability;
1479 __entry->initiator = initiator;
1493 memcpy(__get_dynamic_array(buf), buf, len); 1480 memcpy(__get_dynamic_array(buf), buf, len);
1494 ), 1481 ),
1495 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, " 1482 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
1496 "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ", 1483 "dialog_token: %u, status_code: %u, peer_capability: %u "
1484 "initiator: %s buf: %#.2x ",
1497 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), 1485 WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
1498 __entry->action_code, __entry->dialog_token, 1486 __entry->action_code, __entry->dialog_token,
1499 __entry->status_code, __entry->peer_capability, 1487 __entry->status_code, __entry->peer_capability,
1488 BOOL_TO_STR(__entry->initiator),
1500 ((u8 *)__get_dynamic_array(buf))[0]) 1489 ((u8 *)__get_dynamic_array(buf))[0])
1501); 1490);
1502 1491
@@ -1725,40 +1714,6 @@ TRACE_EVENT(rdev_set_noack_map,
1725 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map) 1714 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->noack_map)
1726); 1715);
1727 1716
1728TRACE_EVENT(rdev_get_et_sset_count,
1729 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, int sset),
1730 TP_ARGS(wiphy, netdev, sset),
1731 TP_STRUCT__entry(
1732 WIPHY_ENTRY
1733 NETDEV_ENTRY
1734 __field(int, sset)
1735 ),
1736 TP_fast_assign(
1737 WIPHY_ASSIGN;
1738 NETDEV_ASSIGN;
1739 __entry->sset = sset;
1740 ),
1741 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %d",
1742 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1743);
1744
1745TRACE_EVENT(rdev_get_et_strings,
1746 TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u32 sset),
1747 TP_ARGS(wiphy, netdev, sset),
1748 TP_STRUCT__entry(
1749 WIPHY_ENTRY
1750 NETDEV_ENTRY
1751 __field(u32, sset)
1752 ),
1753 TP_fast_assign(
1754 WIPHY_ASSIGN;
1755 NETDEV_ASSIGN;
1756 __entry->sset = sset;
1757 ),
1758 TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", sset: %u",
1759 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->sset)
1760);
1761
1762DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel, 1717DEFINE_EVENT(wiphy_wdev_evt, rdev_get_channel,
1763 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev), 1718 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
1764 TP_ARGS(wiphy, wdev) 1719 TP_ARGS(wiphy, wdev)