aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/regulatory.txt4
-rw-r--r--MAINTAINERS19
-rw-r--r--drivers/bcma/host_pci.c1
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c4
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig10
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h31
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c114
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c122
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_wow.c422
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9340_initvals.h390
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h32
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h1559
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h64
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h559
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h56
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c115
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c26
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c541
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c45
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c264
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c589
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c7
-rw-r--r--drivers/net/wireless/ath/regd.c378
-rw-r--r--drivers/net/wireless/ath/wcn36xx/hal.h2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c3
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c21
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h2
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.c384
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcdc.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c51
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h482
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h15
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c392
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c22
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c36
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c194
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h42
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c462
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h54
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.h61
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h304
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c173
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/p2p.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.c62
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/proto.h57
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h33
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/channel.c38
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c66
-rw-r--r--drivers/net/wireless/cw1200/cw1200_sdio.c4
-rw-r--r--drivers/net/wireless/cw1200/scan.c15
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c5
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c8
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c11
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c8
-rw-r--r--drivers/net/wireless/iwlegacy/common.c4
-rw-r--r--drivers/net/wireless/iwlegacy/debug.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/debugfs.c8
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c4
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c6
-rw-r--r--drivers/net/wireless/libertas/if_spi.c1
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c101
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c25
-rw-r--r--drivers/net/wireless/mwifiex/scan.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c35
-rw-r--r--drivers/net/wireless/prism54/islpci_dev.c1
-rw-r--r--drivers/net/wireless/prism54/islpci_hotplug.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c37
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c3
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c2
-rw-r--r--drivers/net/wireless/rtlwifi/base.c3
-rw-r--r--drivers/net/wireless/rtlwifi/core.c11
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c2
-rw-r--r--drivers/net/wireless/rtlwifi/regd.c61
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/dm.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c327
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h14
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c39
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.c9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/dm.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/phy.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/rf.c29
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c16
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/table.c40
-rw-r--r--drivers/net/wireless/rtlwifi/stats.c14
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c8
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h33
-rw-r--r--drivers/net/wireless/ti/wl1251/acx.c209
-rw-r--r--drivers/net/wireless/ti/wl12xx/scan.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/scan.c12
-rw-r--r--include/linux/ieee80211.h8
-rw-r--r--include/net/cfg80211.h76
-rw-r--r--include/net/mac80211.h40
-rw-r--r--include/net/regulatory.h80
-rw-r--r--include/uapi/linux/nl80211.h47
-rw-r--r--net/mac80211/cfg.c123
-rw-r--r--net/mac80211/chan.c141
-rw-r--r--net/mac80211/debugfs.c168
-rw-r--r--net/mac80211/debugfs_sta.c134
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/ieee80211_i.h43
-rw-r--r--net/mac80211/iface.c14
-rw-r--r--net/mac80211/key.c62
-rw-r--r--net/mac80211/key.h13
-rw-r--r--net/mac80211/main.c147
-rw-r--r--net/mac80211/mesh.c7
-rw-r--r--net/mac80211/mesh.h6
-rw-r--r--net/mac80211/mesh_hwmp.c91
-rw-r--r--net/mac80211/mesh_pathtbl.c7
-rw-r--r--net/mac80211/mesh_plink.c708
-rw-r--r--net/mac80211/mesh_ps.c3
-rw-r--r--net/mac80211/mesh_sync.c28
-rw-r--r--net/mac80211/mlme.c43
-rw-r--r--net/mac80211/rate.h4
-rw-r--r--net/mac80211/rc80211_minstrel.c3
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c22
-rw-r--r--net/mac80211/rc80211_minstrel_ht_debugfs.c3
-rw-r--r--net/mac80211/rx.c88
-rw-r--r--net/mac80211/scan.c10
-rw-r--r--net/mac80211/sta_info.c40
-rw-r--r--net/mac80211/sta_info.h38
-rw-r--r--net/mac80211/status.c78
-rw-r--r--net/mac80211/trace.h21
-rw-r--r--net/mac80211/tx.c41
-rw-r--r--net/mac80211/util.c95
-rw-r--r--net/mac80211/vht.c7
-rw-r--r--net/mac80211/wpa.c116
-rw-r--r--net/mac80211/wpa.h2
-rw-r--r--net/wireless/chan.c203
-rw-r--r--net/wireless/core.c6
-rw-r--r--net/wireless/core.h18
-rw-r--r--net/wireless/genregdb.awk45
-rw-r--r--net/wireless/ibss.c4
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/mlme.c20
-rw-r--r--net/wireless/nl80211.c107
-rw-r--r--net/wireless/nl80211.h2
-rw-r--r--net/wireless/rdev-ops.h12
-rw-r--r--net/wireless/reg.c802
-rw-r--r--net/wireless/reg.h3
-rw-r--r--net/wireless/trace.h15
161 files changed, 7162 insertions, 6258 deletions
diff --git a/Documentation/networking/regulatory.txt b/Documentation/networking/regulatory.txt
index 9551622d0a7b..356f791af574 100644
--- a/Documentation/networking/regulatory.txt
+++ b/Documentation/networking/regulatory.txt
@@ -159,10 +159,10 @@ struct ieee80211_regdomain mydriver_jp_regdom = {
159 REG_RULE(2412-20, 2484+20, 40, 6, 20, 0), 159 REG_RULE(2412-20, 2484+20, 40, 6, 20, 0),
160 /* IEEE 802.11a, channels 34..48 */ 160 /* IEEE 802.11a, channels 34..48 */
161 REG_RULE(5170-20, 5240+20, 40, 6, 20, 161 REG_RULE(5170-20, 5240+20, 40, 6, 20,
162 NL80211_RRF_PASSIVE_SCAN), 162 NL80211_RRF_NO_IR),
163 /* IEEE 802.11a, channels 52..64 */ 163 /* IEEE 802.11a, channels 52..64 */
164 REG_RULE(5260-20, 5320+20, 40, 6, 20, 164 REG_RULE(5260-20, 5320+20, 40, 6, 20,
165 NL80211_RRF_NO_IBSS | 165 NL80211_RRF_NO_IR|
166 NL80211_RRF_DFS), 166 NL80211_RRF_DFS),
167 } 167 }
168}; 168};
diff --git a/MAINTAINERS b/MAINTAINERS
index 4afcfb4c892b..b9ea9321adde 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1458,17 +1458,6 @@ T: git git://github.com/kvalo/ath.git
1458S: Supported 1458S: Supported
1459F: drivers/net/wireless/ath/ath6kl/ 1459F: drivers/net/wireless/ath/ath6kl/
1460 1460
1461ATHEROS ATH9K WIRELESS DRIVER
1462M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
1463M: Jouni Malinen <jouni@qca.qualcomm.com>
1464M: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
1465M: Senthil Balasubramanian <senthilb@qca.qualcomm.com>
1466L: linux-wireless@vger.kernel.org
1467L: ath9k-devel@lists.ath9k.org
1468W: http://wireless.kernel.org/en/users/Drivers/ath9k
1469S: Supported
1470F: drivers/net/wireless/ath/ath9k/
1471
1472WILOCITY WIL6210 WIRELESS DRIVER 1461WILOCITY WIL6210 WIRELESS DRIVER
1473M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> 1462M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
1474L: linux-wireless@vger.kernel.org 1463L: linux-wireless@vger.kernel.org
@@ -6928,6 +6917,14 @@ T: git git://linuxtv.org/anttip/media_tree.git
6928S: Maintained 6917S: Maintained
6929F: drivers/media/tuners/qt1010* 6918F: drivers/media/tuners/qt1010*
6930 6919
6920QUALCOMM ATHEROS ATH9K WIRELESS DRIVER
6921M: QCA ath9k Development <ath9k-devel@qca.qualcomm.com>
6922L: linux-wireless@vger.kernel.org
6923L: ath9k-devel@lists.ath9k.org
6924W: http://wireless.kernel.org/en/users/Drivers/ath9k
6925S: Supported
6926F: drivers/net/wireless/ath/ath9k/
6927
6931QUALCOMM ATHEROS ATH10K WIRELESS DRIVER 6928QUALCOMM ATHEROS ATH10K WIRELESS DRIVER
6932M: Kalle Valo <kvalo@qca.qualcomm.com> 6929M: Kalle Valo <kvalo@qca.qualcomm.com>
6933L: ath10k@lists.infradead.org 6930L: ath10k@lists.infradead.org
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 6fb98b53533f..12a4ff751359 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -238,7 +238,6 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
238 pci_release_regions(dev); 238 pci_release_regions(dev);
239 pci_disable_device(dev); 239 pci_disable_device(dev);
240 kfree(bus); 240 kfree(bus);
241 pci_set_drvdata(dev, NULL);
242} 241}
243 242
244#ifdef CONFIG_PM_SLEEP 243#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 97ac8c87cba2..06fe2b8fa22d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1351,12 +1351,12 @@ static int ath10k_update_channel_list(struct ath10k *ar)
1351 ch->allow_vht = true; 1351 ch->allow_vht = true;
1352 1352
1353 ch->allow_ibss = 1353 ch->allow_ibss =
1354 !(channel->flags & IEEE80211_CHAN_NO_IBSS); 1354 !(channel->flags & IEEE80211_CHAN_NO_IR);
1355 1355
1356 ch->ht40plus = 1356 ch->ht40plus =
1357 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS); 1357 !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS);
1358 1358
1359 passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN; 1359 passive = channel->flags & IEEE80211_CHAN_NO_IR;
1360 ch->passive = passive; 1360 ch->passive = passive;
1361 1361
1362 ch->freq = channel->center_freq; 1362 ch->freq = channel->center_freq;
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 2437ad26949d..fd4c89df67e1 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1109,7 +1109,9 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1109 (mode == WMI_11G_HT20) ? 1109 (mode == WMI_11G_HT20) ?
1110 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); 1110 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
1111 1111
1112 mutex_lock(&vif->wdev.mtx);
1112 cfg80211_ch_switch_notify(vif->ndev, &chandef); 1113 cfg80211_ch_switch_notify(vif->ndev, &chandef);
1114 mutex_unlock(&vif->wdev.mtx);
1113} 1115}
1114 1116
1115static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 1117static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
@@ -3169,12 +3171,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3169} 3171}
3170 3172
3171static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3173static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3172 struct ieee80211_channel *chan, bool offchan, 3174 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3173 unsigned int wait, const u8 *buf, size_t len,
3174 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3175{ 3175{
3176 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3176 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3177 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3177 struct ath6kl *ar = ath6kl_priv(vif->ndev);
3178 struct ieee80211_channel *chan = params->chan;
3179 const u8 *buf = params->buf;
3180 size_t len = params->len;
3181 unsigned int wait = params->wait;
3182 bool no_cck = params->no_cck;
3178 u32 id, freq; 3183 u32 id, freq;
3179 const struct ieee80211_mgmt *mgmt; 3184 const struct ieee80211_mgmt *mgmt;
3180 bool more_data, queued; 3185 bool more_data, queued;
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 32f139e2e897..30d273c61bff 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -86,7 +86,7 @@ config ATH9K_DFS_CERTIFIED
86 86
87config ATH9K_TX99 87config ATH9K_TX99
88 bool "Atheros ath9k TX99 testing support" 88 bool "Atheros ath9k TX99 testing support"
89 depends on CFG80211_CERTIFICATION_ONUS 89 depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
90 default n 90 default n
91 ---help--- 91 ---help---
92 Say N. This should only be enabled on systems undergoing 92 Say N. This should only be enabled on systems undergoing
@@ -104,6 +104,14 @@ config ATH9K_TX99
104 be evaluated to meet the RF exposure limits set forth in the 104 be evaluated to meet the RF exposure limits set forth in the
105 governmental SAR regulations. 105 governmental SAR regulations.
106 106
107config ATH9K_WOW
108 bool "Wake on Wireless LAN support (EXPERIMENTAL)"
109 depends on ATH9K && PM
110 default n
111 ---help---
112 This option enables Wake on Wireless LAN support for certain cards.
113 Currently, AR9462 is supported.
114
107config ATH9K_LEGACY_RATE_CONTROL 115config ATH9K_LEGACY_RATE_CONTROL
108 bool "Atheros ath9k rate control" 116 bool "Atheros ath9k rate control"
109 depends on ATH9K 117 depends on ATH9K
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6205ef5a9321..337c459eda28 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -13,9 +13,9 @@ ath9k-$(CONFIG_ATH9K_PCI) += pci.o
13ath9k-$(CONFIG_ATH9K_AHB) += ahb.o 13ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
14ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o 14ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
15ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o 15ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o
16ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \ 16ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += dfs.o
17 dfs.o 17ath9k-$(CONFIG_ATH9K_TX99) += tx99.o
18ath9k-$(CONFIG_PM_SLEEP) += wow.o 18ath9k-$(CONFIG_ATH9K_WOW) += wow.o
19 19
20obj-$(CONFIG_ATH9K) += ath9k.o 20obj-$(CONFIG_ATH9K) += ath9k.o
21 21
@@ -41,6 +41,8 @@ ath9k_hw-y:= \
41 ar9003_eeprom.o \ 41 ar9003_eeprom.o \
42 ar9003_paprd.o 42 ar9003_paprd.o
43 43
44ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
45
44ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ 46ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
45 ar9003_mci.o 47 ar9003_mci.o
46obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 48obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 7546b9a7dcbf..e7cdf1100f56 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -352,7 +352,7 @@ static const u32 ar9300_2p2_baseband_postamble[][5] = {
352 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 352 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
353 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 353 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
354 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 354 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
355 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 355 {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
356 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 356 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
357 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 357 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
358 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, 358 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
@@ -378,9 +378,9 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
378 {0x00009814, 0x9280c00a}, 378 {0x00009814, 0x9280c00a},
379 {0x00009818, 0x00000000}, 379 {0x00009818, 0x00000000},
380 {0x0000981c, 0x00020028}, 380 {0x0000981c, 0x00020028},
381 {0x00009834, 0x6400a290}, 381 {0x00009834, 0x6400a190},
382 {0x00009838, 0x0108ecff}, 382 {0x00009838, 0x0108ecff},
383 {0x0000983c, 0x0d000600}, 383 {0x0000983c, 0x14000600},
384 {0x00009880, 0x201fff00}, 384 {0x00009880, 0x201fff00},
385 {0x00009884, 0x00001042}, 385 {0x00009884, 0x00001042},
386 {0x000098a4, 0x00200400}, 386 {0x000098a4, 0x00200400},
@@ -401,7 +401,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
401 {0x00009d04, 0x40206c10}, 401 {0x00009d04, 0x40206c10},
402 {0x00009d08, 0x009c4060}, 402 {0x00009d08, 0x009c4060},
403 {0x00009d0c, 0x9883800a}, 403 {0x00009d0c, 0x9883800a},
404 {0x00009d10, 0x01834061}, 404 {0x00009d10, 0x01884061},
405 {0x00009d14, 0x00c0040b}, 405 {0x00009d14, 0x00c0040b},
406 {0x00009d18, 0x00000000}, 406 {0x00009d18, 0x00000000},
407 {0x00009e08, 0x0038230c}, 407 {0x00009e08, 0x0038230c},
@@ -459,7 +459,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
459 {0x0000a3e8, 0x20202020}, 459 {0x0000a3e8, 0x20202020},
460 {0x0000a3ec, 0x20202020}, 460 {0x0000a3ec, 0x20202020},
461 {0x0000a3f0, 0x00000000}, 461 {0x0000a3f0, 0x00000000},
462 {0x0000a3f4, 0x00000246}, 462 {0x0000a3f4, 0x00000000},
463 {0x0000a3f8, 0x0c9bd380}, 463 {0x0000a3f8, 0x0c9bd380},
464 {0x0000a3fc, 0x000f0f01}, 464 {0x0000a3fc, 0x000f0f01},
465 {0x0000a400, 0x8fa91f01}, 465 {0x0000a400, 0x8fa91f01},
@@ -644,7 +644,7 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
644 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, 644 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
645 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, 645 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
646 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 646 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
647 {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, 647 {0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9},
648 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, 648 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
649 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, 649 {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
650 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, 650 {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
@@ -1086,8 +1086,8 @@ static const u32 ar9300Common_rx_gain_table_2p2[][2] = {
1086 {0x0000b074, 0x00000000}, 1086 {0x0000b074, 0x00000000},
1087 {0x0000b078, 0x00000000}, 1087 {0x0000b078, 0x00000000},
1088 {0x0000b07c, 0x00000000}, 1088 {0x0000b07c, 0x00000000},
1089 {0x0000b080, 0x2a2d2f32}, 1089 {0x0000b080, 0x23232323},
1090 {0x0000b084, 0x21232328}, 1090 {0x0000b084, 0x21232323},
1091 {0x0000b088, 0x19191c1e}, 1091 {0x0000b088, 0x19191c1e},
1092 {0x0000b08c, 0x12141417}, 1092 {0x0000b08c, 0x12141417},
1093 {0x0000b090, 0x07070e0e}, 1093 {0x0000b090, 0x07070e0e},
@@ -1385,9 +1385,9 @@ static const u32 ar9300_2p2_mac_core[][2] = {
1385 {0x000081f8, 0x00000000}, 1385 {0x000081f8, 0x00000000},
1386 {0x000081fc, 0x00000000}, 1386 {0x000081fc, 0x00000000},
1387 {0x00008240, 0x00100000}, 1387 {0x00008240, 0x00100000},
1388 {0x00008244, 0x0010f424}, 1388 {0x00008244, 0x0010f400},
1389 {0x00008248, 0x00000800}, 1389 {0x00008248, 0x00000800},
1390 {0x0000824c, 0x0001e848}, 1390 {0x0000824c, 0x0001e800},
1391 {0x00008250, 0x00000000}, 1391 {0x00008250, 0x00000000},
1392 {0x00008254, 0x00000000}, 1392 {0x00008254, 0x00000000},
1393 {0x00008258, 0x00000000}, 1393 {0x00008258, 0x00000000},
@@ -1726,16 +1726,23 @@ static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2[][2] = {
1726 1726
1727static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = { 1727static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = {
1728 /* Addr allmodes */ 1728 /* Addr allmodes */
1729 {0x00004040, 0x08253e5e}, 1729 {0x00004040, 0x0825365e},
1730 {0x00004040, 0x0008003b}, 1730 {0x00004040, 0x0008003b},
1731 {0x00004044, 0x00000000}, 1731 {0x00004044, 0x00000000},
1732}; 1732};
1733 1733
1734static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = { 1734static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = {
1735 /* Addr allmodes */ 1735 /* Addr allmodes */
1736 {0x00004040, 0x08213e5e}, 1736 {0x00004040, 0x0821365e},
1737 {0x00004040, 0x0008003b}, 1737 {0x00004040, 0x0008003b},
1738 {0x00004044, 0x00000000}, 1738 {0x00004044, 0x00000000},
1739}; 1739};
1740 1740
1741static const u32 ar9300_2p2_baseband_core_txfir_coeff_japan_2484[][2] = {
1742 /* Addr allmodes */
1743 {0x0000a398, 0x00000000},
1744 {0x0000a39c, 0x6f7f0301},
1745 {0x0000a3a0, 0xca9228ee},
1746};
1747
1741#endif /* INITVALS_9003_2P2_H */ 1748#endif /* INITVALS_9003_2P2_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 22934d3ca544..aa0127265746 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1040,14 +1040,14 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
1040 } 1040 }
1041} 1041}
1042 1042
1043static bool ar9003_hw_init_cal(struct ath_hw *ah, 1043static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
1044 struct ath9k_channel *chan) 1044 struct ath9k_channel *chan)
1045{ 1045{
1046 struct ath_common *common = ath9k_hw_common(ah); 1046 struct ath_common *common = ath9k_hw_common(ah);
1047 struct ath9k_hw_cal_data *caldata = ah->caldata; 1047 struct ath9k_hw_cal_data *caldata = ah->caldata;
1048 bool txiqcal_done = false; 1048 bool txiqcal_done = false;
1049 bool is_reusable = true, status = true; 1049 bool is_reusable = true, status = true;
1050 bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; 1050 bool run_rtt_cal = false, run_agc_cal;
1051 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); 1051 bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
1052 u32 rx_delay = 0; 1052 u32 rx_delay = 0;
1053 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | 1053 u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
@@ -1119,22 +1119,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
1119 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, 1119 REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
1120 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); 1120 AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
1121 txiqcal_done = run_agc_cal = true; 1121 txiqcal_done = run_agc_cal = true;
1122 } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) {
1123 run_agc_cal = true;
1124 sep_iq_cal = true;
1125 } 1122 }
1126 1123
1127skip_tx_iqcal: 1124skip_tx_iqcal:
1128 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) 1125 if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal)
1129 ar9003_mci_init_cal_req(ah, &is_reusable); 1126 ar9003_mci_init_cal_req(ah, &is_reusable);
1130 1127
1131 if (sep_iq_cal) {
1132 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1133 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1134 udelay(5);
1135 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1136 }
1137
1138 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { 1128 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) {
1139 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); 1129 rx_delay = REG_READ(ah, AR_PHY_RX_DELAY);
1140 /* Disable BB_active */ 1130 /* Disable BB_active */
@@ -1228,13 +1218,109 @@ skip_tx_iqcal:
1228 return true; 1218 return true;
1229} 1219}
1230 1220
1221static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
1222 struct ath9k_channel *chan)
1223{
1224 struct ath_common *common = ath9k_hw_common(ah);
1225 struct ath9k_hw_cal_data *caldata = ah->caldata;
1226 bool txiqcal_done = false;
1227 bool is_reusable = true, status = true;
1228 bool run_agc_cal = false, sep_iq_cal = false;
1229
1230 /* Use chip chainmask only for calibration */
1231 ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
1232
1233 if (ah->enabled_cals & TX_CL_CAL) {
1234 REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
1235 run_agc_cal = true;
1236 }
1237
1238 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
1239 goto skip_tx_iqcal;
1240
1241 /* Do Tx IQ Calibration */
1242 REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
1243 AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
1244 DELPT);
1245
1246 /*
1247 * For AR9485 or later chips, TxIQ cal runs as part of
1248 * AGC calibration. Specifically, AR9550 in SoC chips.
1249 */
1250 if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
1251 txiqcal_done = true;
1252 run_agc_cal = true;
1253 } else {
1254 sep_iq_cal = true;
1255 run_agc_cal = true;
1256 }
1257
1258 /*
1259 * In the SoC family, this will run for AR9300, AR9331 and AR9340.
1260 */
1261 if (sep_iq_cal) {
1262 txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
1263 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1264 udelay(5);
1265 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
1266 }
1267
1268skip_tx_iqcal:
1269 if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
1270 /* Calibrate the AGC */
1271 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
1272 REG_READ(ah, AR_PHY_AGC_CONTROL) |
1273 AR_PHY_AGC_CONTROL_CAL);
1274
1275 /* Poll for offset calibration complete */
1276 status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
1277 AR_PHY_AGC_CONTROL_CAL,
1278 0, AH_WAIT_TIMEOUT);
1279 }
1280
1281 if (!status) {
1282 ath_dbg(common, CALIBRATE,
1283 "offset calibration failed to complete in %d ms; noisy environment?\n",
1284 AH_WAIT_TIMEOUT / 1000);
1285 return false;
1286 }
1287
1288 if (txiqcal_done)
1289 ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
1290
1291 /* Revert chainmask to runtime parameters */
1292 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
1293
1294 /* Initialize list pointers */
1295 ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
1296
1297 INIT_CAL(&ah->iq_caldata);
1298 INSERT_CAL(ah, &ah->iq_caldata);
1299 ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
1300
1301 /* Initialize current pointer to first element in list */
1302 ah->cal_list_curr = ah->cal_list;
1303
1304 if (ah->cal_list_curr)
1305 ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
1306
1307 if (caldata)
1308 caldata->CalValid = 0;
1309
1310 return true;
1311}
1312
1231void ar9003_hw_attach_calib_ops(struct ath_hw *ah) 1313void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
1232{ 1314{
1233 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1315 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1234 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1316 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1235 1317
1318 if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah))
1319 priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
1320 else
1321 priv_ops->init_cal = ar9003_hw_init_cal_soc;
1322
1236 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; 1323 priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
1237 priv_ops->init_cal = ar9003_hw_init_cal;
1238 priv_ops->setup_calibration = ar9003_hw_setup_calibration; 1324 priv_ops->setup_calibration = ar9003_hw_setup_calibration;
1239 1325
1240 ops->calibrate = ar9003_hw_calibrate; 1326 ops->calibrate = ar9003_hw_calibrate;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 20e49095db2a..d8c1eee8ea53 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -26,6 +26,7 @@
26#include "ar9462_2p0_initvals.h" 26#include "ar9462_2p0_initvals.h"
27#include "ar9462_2p1_initvals.h" 27#include "ar9462_2p1_initvals.h"
28#include "ar9565_1p0_initvals.h" 28#include "ar9565_1p0_initvals.h"
29#include "ar9565_1p1_initvals.h"
29 30
30/* General hardware code for the AR9003 hadware family */ 31/* General hardware code for the AR9003 hadware family */
31 32
@@ -148,7 +149,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
148 ar9340Modes_high_ob_db_tx_gain_table_1p0); 149 ar9340Modes_high_ob_db_tx_gain_table_1p0);
149 150
150 INIT_INI_ARRAY(&ah->iniModesFastClock, 151 INIT_INI_ARRAY(&ah->iniModesFastClock,
151 ar9340Modes_fast_clock_1p0); 152 ar9340Modes_fast_clock_1p0);
153 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
154 ar9340_1p0_baseband_core_txfir_coeff_japan_2484);
152 155
153 if (!ah->is_clk_25mhz) 156 if (!ah->is_clk_25mhz)
154 INIT_INI_ARRAY(&ah->iniAdditional, 157 INIT_INI_ARRAY(&ah->iniAdditional,
@@ -223,6 +226,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
223 ar9462_2p1_modes_fast_clock); 226 ar9462_2p1_modes_fast_clock);
224 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 227 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
225 ar9462_2p1_baseband_core_txfir_coeff_japan_2484); 228 ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
229 INIT_INI_ARRAY(&ah->iniPcieSerdes,
230 ar9462_2p1_pciephy_clkreq_disable_L1);
231 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
232 ar9462_2p1_pciephy_clkreq_disable_L1);
226 } else if (AR_SREV_9462_20(ah)) { 233 } else if (AR_SREV_9462_20(ah)) {
227 234
228 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); 235 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -247,18 +254,18 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
247 ar9462_2p0_soc_postamble); 254 ar9462_2p0_soc_postamble);
248 255
249 INIT_INI_ARRAY(&ah->iniModesRxGain, 256 INIT_INI_ARRAY(&ah->iniModesRxGain,
250 ar9462_common_rx_gain_table_2p0); 257 ar9462_2p0_common_rx_gain);
251 258
252 /* Awake -> Sleep Setting */ 259 /* Awake -> Sleep Setting */
253 INIT_INI_ARRAY(&ah->iniPcieSerdes, 260 INIT_INI_ARRAY(&ah->iniPcieSerdes,
254 ar9462_pciephy_clkreq_disable_L1_2p0); 261 ar9462_2p0_pciephy_clkreq_disable_L1);
255 /* Sleep -> Awake Setting */ 262 /* Sleep -> Awake Setting */
256 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 263 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
257 ar9462_pciephy_clkreq_disable_L1_2p0); 264 ar9462_2p0_pciephy_clkreq_disable_L1);
258 265
259 /* Fast clock modal settings */ 266 /* Fast clock modal settings */
260 INIT_INI_ARRAY(&ah->iniModesFastClock, 267 INIT_INI_ARRAY(&ah->iniModesFastClock,
261 ar9462_modes_fast_clock_2p0); 268 ar9462_2p0_modes_fast_clock);
262 269
263 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 270 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
264 ar9462_2p0_baseband_core_txfir_coeff_japan_2484); 271 ar9462_2p0_baseband_core_txfir_coeff_japan_2484);
@@ -330,7 +337,44 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
330 ar9580_1p0_low_ob_db_tx_gain_table); 337 ar9580_1p0_low_ob_db_tx_gain_table);
331 338
332 INIT_INI_ARRAY(&ah->iniModesFastClock, 339 INIT_INI_ARRAY(&ah->iniModesFastClock,
333 ar9580_1p0_modes_fast_clock); 340 ar9580_1p0_modes_fast_clock);
341 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
342 ar9580_1p0_baseband_core_txfir_coeff_japan_2484);
343 } else if (AR_SREV_9565_11_OR_LATER(ah)) {
344 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
345 ar9565_1p1_mac_core);
346 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
347 ar9565_1p1_mac_postamble);
348
349 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
350 ar9565_1p1_baseband_core);
351 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
352 ar9565_1p1_baseband_postamble);
353
354 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
355 ar9565_1p1_radio_core);
356 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
357 ar9565_1p1_radio_postamble);
358
359 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
360 ar9565_1p1_soc_preamble);
361 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
362 ar9565_1p1_soc_postamble);
363
364 INIT_INI_ARRAY(&ah->iniModesRxGain,
365 ar9565_1p1_Common_rx_gain_table);
366 INIT_INI_ARRAY(&ah->iniModesTxGain,
367 ar9565_1p1_Modes_lowest_ob_db_tx_gain_table);
368
369 INIT_INI_ARRAY(&ah->iniPcieSerdes,
370 ar9565_1p1_pciephy_clkreq_disable_L1);
371 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
372 ar9565_1p1_pciephy_clkreq_disable_L1);
373
374 INIT_INI_ARRAY(&ah->iniModesFastClock,
375 ar9565_1p1_modes_fast_clock);
376 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
377 ar9565_1p1_baseband_core_txfir_coeff_japan_2484);
334 } else if (AR_SREV_9565(ah)) { 378 } else if (AR_SREV_9565(ah)) {
335 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 379 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
336 ar9565_1p0_mac_core); 380 ar9565_1p0_mac_core);
@@ -411,7 +455,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
411 455
412 /* Fast clock modal settings */ 456 /* Fast clock modal settings */
413 INIT_INI_ARRAY(&ah->iniModesFastClock, 457 INIT_INI_ARRAY(&ah->iniModesFastClock,
414 ar9300Modes_fast_clock_2p2); 458 ar9300Modes_fast_clock_2p2);
459 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
460 ar9300_2p2_baseband_core_txfir_coeff_japan_2484);
415 } 461 }
416} 462}
417 463
@@ -440,7 +486,10 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
440 ar9462_2p1_modes_low_ob_db_tx_gain); 486 ar9462_2p1_modes_low_ob_db_tx_gain);
441 else if (AR_SREV_9462_20(ah)) 487 else if (AR_SREV_9462_20(ah))
442 INIT_INI_ARRAY(&ah->iniModesTxGain, 488 INIT_INI_ARRAY(&ah->iniModesTxGain,
443 ar9462_modes_low_ob_db_tx_gain_table_2p0); 489 ar9462_2p0_modes_low_ob_db_tx_gain);
490 else if (AR_SREV_9565_11(ah))
491 INIT_INI_ARRAY(&ah->iniModesTxGain,
492 ar9565_1p1_modes_low_ob_db_tx_gain_table);
444 else if (AR_SREV_9565(ah)) 493 else if (AR_SREV_9565(ah))
445 INIT_INI_ARRAY(&ah->iniModesTxGain, 494 INIT_INI_ARRAY(&ah->iniModesTxGain,
446 ar9565_1p0_modes_low_ob_db_tx_gain_table); 495 ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -474,7 +523,10 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
474 ar9462_2p1_modes_high_ob_db_tx_gain); 523 ar9462_2p1_modes_high_ob_db_tx_gain);
475 else if (AR_SREV_9462_20(ah)) 524 else if (AR_SREV_9462_20(ah))
476 INIT_INI_ARRAY(&ah->iniModesTxGain, 525 INIT_INI_ARRAY(&ah->iniModesTxGain,
477 ar9462_modes_high_ob_db_tx_gain_table_2p0); 526 ar9462_2p0_modes_high_ob_db_tx_gain);
527 else if (AR_SREV_9565_11(ah))
528 INIT_INI_ARRAY(&ah->iniModesTxGain,
529 ar9565_1p1_modes_high_ob_db_tx_gain_table);
478 else if (AR_SREV_9565(ah)) 530 else if (AR_SREV_9565(ah))
479 INIT_INI_ARRAY(&ah->iniModesTxGain, 531 INIT_INI_ARRAY(&ah->iniModesTxGain,
480 ar9565_1p0_modes_high_ob_db_tx_gain_table); 532 ar9565_1p0_modes_high_ob_db_tx_gain_table);
@@ -500,6 +552,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
500 else if (AR_SREV_9580(ah)) 552 else if (AR_SREV_9580(ah))
501 INIT_INI_ARRAY(&ah->iniModesTxGain, 553 INIT_INI_ARRAY(&ah->iniModesTxGain,
502 ar9580_1p0_low_ob_db_tx_gain_table); 554 ar9580_1p0_low_ob_db_tx_gain_table);
555 else if (AR_SREV_9565_11(ah))
556 INIT_INI_ARRAY(&ah->iniModesTxGain,
557 ar9565_1p1_modes_low_ob_db_tx_gain_table);
503 else if (AR_SREV_9565(ah)) 558 else if (AR_SREV_9565(ah))
504 INIT_INI_ARRAY(&ah->iniModesTxGain, 559 INIT_INI_ARRAY(&ah->iniModesTxGain,
505 ar9565_1p0_modes_low_ob_db_tx_gain_table); 560 ar9565_1p0_modes_low_ob_db_tx_gain_table);
@@ -525,6 +580,9 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
525 else if (AR_SREV_9580(ah)) 580 else if (AR_SREV_9580(ah))
526 INIT_INI_ARRAY(&ah->iniModesTxGain, 581 INIT_INI_ARRAY(&ah->iniModesTxGain,
527 ar9580_1p0_high_power_tx_gain_table); 582 ar9580_1p0_high_power_tx_gain_table);
583 else if (AR_SREV_9565_11(ah))
584 INIT_INI_ARRAY(&ah->iniModesTxGain,
585 ar9565_1p1_modes_high_power_tx_gain_table);
528 else if (AR_SREV_9565(ah)) 586 else if (AR_SREV_9565(ah))
529 INIT_INI_ARRAY(&ah->iniModesTxGain, 587 INIT_INI_ARRAY(&ah->iniModesTxGain,
530 ar9565_1p0_modes_high_power_tx_gain_table); 588 ar9565_1p0_modes_high_power_tx_gain_table);
@@ -546,7 +604,7 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
546 ar9462_2p1_modes_mix_ob_db_tx_gain); 604 ar9462_2p1_modes_mix_ob_db_tx_gain);
547 else if (AR_SREV_9462_20(ah)) 605 else if (AR_SREV_9462_20(ah))
548 INIT_INI_ARRAY(&ah->iniModesTxGain, 606 INIT_INI_ARRAY(&ah->iniModesTxGain,
549 ar9462_modes_mix_ob_db_tx_gain_table_2p0); 607 ar9462_2p0_modes_mix_ob_db_tx_gain);
550 else 608 else
551 INIT_INI_ARRAY(&ah->iniModesTxGain, 609 INIT_INI_ARRAY(&ah->iniModesTxGain,
552 ar9300Modes_mixed_ob_db_tx_gain_table_2p2); 610 ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -581,6 +639,13 @@ static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
581 ar9580_1p0_type6_tx_gain_table); 639 ar9580_1p0_type6_tx_gain_table);
582} 640}
583 641
642static void ar9003_tx_gain_table_mode7(struct ath_hw *ah)
643{
644 if (AR_SREV_9340(ah))
645 INIT_INI_ARRAY(&ah->iniModesTxGain,
646 ar9340_cus227_tx_gain_table_1p0);
647}
648
584typedef void (*ath_txgain_tab)(struct ath_hw *ah); 649typedef void (*ath_txgain_tab)(struct ath_hw *ah);
585 650
586static void ar9003_tx_gain_table_apply(struct ath_hw *ah) 651static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
@@ -593,6 +658,7 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
593 ar9003_tx_gain_table_mode4, 658 ar9003_tx_gain_table_mode4,
594 ar9003_tx_gain_table_mode5, 659 ar9003_tx_gain_table_mode5,
595 ar9003_tx_gain_table_mode6, 660 ar9003_tx_gain_table_mode6,
661 ar9003_tx_gain_table_mode7,
596 }; 662 };
597 int idx = ar9003_hw_get_tx_gain_idx(ah); 663 int idx = ar9003_hw_get_tx_gain_idx(ah);
598 664
@@ -629,7 +695,10 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
629 ar9462_2p1_common_rx_gain); 695 ar9462_2p1_common_rx_gain);
630 else if (AR_SREV_9462_20(ah)) 696 else if (AR_SREV_9462_20(ah))
631 INIT_INI_ARRAY(&ah->iniModesRxGain, 697 INIT_INI_ARRAY(&ah->iniModesRxGain,
632 ar9462_common_rx_gain_table_2p0); 698 ar9462_2p0_common_rx_gain);
699 else if (AR_SREV_9565_11(ah))
700 INIT_INI_ARRAY(&ah->iniModesRxGain,
701 ar9565_1p1_Common_rx_gain_table);
633 else if (AR_SREV_9565(ah)) 702 else if (AR_SREV_9565(ah))
634 INIT_INI_ARRAY(&ah->iniModesRxGain, 703 INIT_INI_ARRAY(&ah->iniModesRxGain,
635 ar9565_1p0_Common_rx_gain_table); 704 ar9565_1p0_Common_rx_gain_table);
@@ -657,7 +726,7 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
657 ar9462_2p1_common_wo_xlna_rx_gain); 726 ar9462_2p1_common_wo_xlna_rx_gain);
658 else if (AR_SREV_9462_20(ah)) 727 else if (AR_SREV_9462_20(ah))
659 INIT_INI_ARRAY(&ah->iniModesRxGain, 728 INIT_INI_ARRAY(&ah->iniModesRxGain,
660 ar9462_common_wo_xlna_rx_gain_table_2p0); 729 ar9462_2p0_common_wo_xlna_rx_gain);
661 else if (AR_SREV_9550(ah)) { 730 else if (AR_SREV_9550(ah)) {
662 INIT_INI_ARRAY(&ah->iniModesRxGain, 731 INIT_INI_ARRAY(&ah->iniModesRxGain,
663 ar955x_1p0_common_wo_xlna_rx_gain_table); 732 ar955x_1p0_common_wo_xlna_rx_gain_table);
@@ -666,6 +735,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
666 } else if (AR_SREV_9580(ah)) 735 } else if (AR_SREV_9580(ah))
667 INIT_INI_ARRAY(&ah->iniModesRxGain, 736 INIT_INI_ARRAY(&ah->iniModesRxGain,
668 ar9580_1p0_wo_xlna_rx_gain_table); 737 ar9580_1p0_wo_xlna_rx_gain_table);
738 else if (AR_SREV_9565_11(ah))
739 INIT_INI_ARRAY(&ah->iniModesRxGain,
740 ar9565_1p1_common_wo_xlna_rx_gain_table);
669 else if (AR_SREV_9565(ah)) 741 else if (AR_SREV_9565(ah))
670 INIT_INI_ARRAY(&ah->iniModesRxGain, 742 INIT_INI_ARRAY(&ah->iniModesRxGain,
671 ar9565_1p0_common_wo_xlna_rx_gain_table); 743 ar9565_1p0_common_wo_xlna_rx_gain_table);
@@ -687,7 +759,7 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
687 ar9462_2p1_baseband_postamble_5g_xlna); 759 ar9462_2p1_baseband_postamble_5g_xlna);
688 } else if (AR_SREV_9462_20(ah)) { 760 } else if (AR_SREV_9462_20(ah)) {
689 INIT_INI_ARRAY(&ah->iniModesRxGain, 761 INIT_INI_ARRAY(&ah->iniModesRxGain,
690 ar9462_common_mixed_rx_gain_table_2p0); 762 ar9462_2p0_common_mixed_rx_gain);
691 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, 763 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
692 ar9462_2p0_baseband_core_mix_rxgain); 764 ar9462_2p0_baseband_core_mix_rxgain);
693 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble, 765 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
@@ -701,12 +773,12 @@ static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
701{ 773{
702 if (AR_SREV_9462_21(ah)) { 774 if (AR_SREV_9462_21(ah)) {
703 INIT_INI_ARRAY(&ah->iniModesRxGain, 775 INIT_INI_ARRAY(&ah->iniModesRxGain,
704 ar9462_2p1_common_5g_xlna_only_rx_gain); 776 ar9462_2p1_common_5g_xlna_only_rxgain);
705 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 777 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
706 ar9462_2p1_baseband_postamble_5g_xlna); 778 ar9462_2p1_baseband_postamble_5g_xlna);
707 } else if (AR_SREV_9462_20(ah)) { 779 } else if (AR_SREV_9462_20(ah)) {
708 INIT_INI_ARRAY(&ah->iniModesRxGain, 780 INIT_INI_ARRAY(&ah->iniModesRxGain,
709 ar9462_2p0_5g_xlna_only_rxgain); 781 ar9462_2p0_common_5g_xlna_only_rxgain);
710 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 782 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
711 ar9462_2p0_baseband_postamble_5g_xlna); 783 ar9462_2p0_baseband_postamble_5g_xlna);
712 } 784 }
@@ -750,6 +822,9 @@ static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
750static void ar9003_hw_configpcipowersave(struct ath_hw *ah, 822static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
751 bool power_off) 823 bool power_off)
752{ 824{
825 unsigned int i;
826 struct ar5416IniArray *array;
827
753 /* 828 /*
754 * Increase L1 Entry Latency. Some WB222 boards don't have 829 * Increase L1 Entry Latency. Some WB222 boards don't have
755 * this change in eeprom/OTP. 830 * this change in eeprom/OTP.
@@ -775,18 +850,13 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
775 * Configire PCIE after Ini init. SERDES values now come from ini file 850 * Configire PCIE after Ini init. SERDES values now come from ini file
776 * This enables PCIe low power mode. 851 * This enables PCIe low power mode.
777 */ 852 */
778 if (ah->config.pcieSerDesWrite) { 853 array = power_off ? &ah->iniPcieSerdes :
779 unsigned int i; 854 &ah->iniPcieSerdesLowPower;
780 struct ar5416IniArray *array;
781 855
782 array = power_off ? &ah->iniPcieSerdes : 856 for (i = 0; i < array->ia_rows; i++) {
783 &ah->iniPcieSerdesLowPower; 857 REG_WRITE(ah,
784 858 INI_RA(array, i, 0),
785 for (i = 0; i < array->ia_rows; i++) { 859 INI_RA(array, i, 1));
786 REG_WRITE(ah,
787 INI_RA(array, i, 0),
788 INI_RA(array, i, 1));
789 }
790 } 860 }
791} 861}
792 862
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index d39b79f5e841..39b71b3d6919 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struct ath_hw *ah)
641 else 641 else
642 ah->enabled_cals &= ~TX_IQ_CAL; 642 ah->enabled_cals &= ~TX_IQ_CAL;
643 643
644 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
645 ah->enabled_cals |= TX_CL_CAL;
646 else
647 ah->enabled_cals &= ~TX_CL_CAL;
648 } 644 }
645
646 if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
647 ah->enabled_cals |= TX_CL_CAL;
648 else
649 ah->enabled_cals &= ~TX_CL_CAL;
649} 650}
650 651
651static void ar9003_hw_prog_ini(struct ath_hw *ah, 652static void ar9003_hw_prog_ini(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_wow.c b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
new file mode 100644
index 000000000000..81c88dd606dc
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (c) 2012 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include <linux/export.h>
18#include "ath9k.h"
19#include "reg.h"
20#include "hw-ops.h"
21
22const char *ath9k_hw_wow_event_to_string(u32 wow_event)
23{
24 if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
25 return "Magic pattern";
26 if (wow_event & AH_WOW_USER_PATTERN_EN)
27 return "User pattern";
28 if (wow_event & AH_WOW_LINK_CHANGE)
29 return "Link change";
30 if (wow_event & AH_WOW_BEACON_MISS)
31 return "Beacon miss";
32
33 return "unknown reason";
34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36
37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
38{
39 struct ath_common *common = ath9k_hw_common(ah);
40
41 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
42
43 /* set rx disable bit */
44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
45
46 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
49 return;
50 }
51
52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
53}
54
55static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
56{
57 struct ath_common *common = ath9k_hw_common(ah);
58 u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
59 u32 ctl[13] = {0};
60 u32 data_word[KAL_NUM_DATA_WORDS];
61 u8 i;
62 u32 wow_ka_data_word0;
63
64 memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
65 memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
66
67 /* set the transmit buffer */
68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
69 ctl[1] = 0;
70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
71 ctl[4] = 0;
72 ctl[7] = (ah->txchainmask) << 2;
73 ctl[2] = 0xf << 16; /* tx_tries 0 */
74
75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
77
78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
79
80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
82 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
83 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
84 data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
85 (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
86 data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
87 (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
88 data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
89 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
90 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
91
92 if (AR_SREV_9462_20(ah)) {
93 /* AR9462 2.0 has an extra descriptor word (time based
94 * discard) compared to other chips */
95 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
96 wow_ka_data_word0 = AR_WOW_TXBUF(13);
97 } else {
98 wow_ka_data_word0 = AR_WOW_TXBUF(12);
99 }
100
101 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
102 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
103
104}
105
106void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
107 u8 *user_mask, int pattern_count,
108 int pattern_len)
109{
110 int i;
111 u32 pattern_val, mask_val;
112 u32 set, clr;
113
114 /* FIXME: should check count by querying the hardware capability */
115 if (pattern_count >= MAX_NUM_PATTERN)
116 return;
117
118 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
119
120 /* set the registers for pattern */
121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
122 memcpy(&pattern_val, user_pattern, 4);
123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
124 pattern_val);
125 user_pattern += 4;
126 }
127
128 /* set the registers for mask */
129 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
130 memcpy(&mask_val, user_mask, 4);
131 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
132 user_mask += 4;
133 }
134
135 /* set the pattern length to be matched
136 *
137 * AR_WOW_LENGTH1_REG1
138 * bit 31:24 pattern 0 length
139 * bit 23:16 pattern 1 length
140 * bit 15:8 pattern 2 length
141 * bit 7:0 pattern 3 length
142 *
143 * AR_WOW_LENGTH1_REG2
144 * bit 31:24 pattern 4 length
145 * bit 23:16 pattern 5 length
146 * bit 15:8 pattern 6 length
147 * bit 7:0 pattern 7 length
148 *
149 * the below logic writes out the new
150 * pattern length for the corresponding
151 * pattern_count, while masking out the
152 * other fields
153 */
154
155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
156
157 if (pattern_count < 4) {
158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
160 AR_WOW_LEN1_SHIFT(pattern_count);
161 clr = AR_WOW_LENGTH1_MASK(pattern_count);
162 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
163 } else {
164 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
165 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
166 AR_WOW_LEN2_SHIFT(pattern_count);
167 clr = AR_WOW_LENGTH2_MASK(pattern_count);
168 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
169 }
170
171}
172EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
173
174u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
175{
176 u32 wow_status = 0;
177 u32 val = 0, rval;
178
179 /*
180 * read the WoW status register to know
181 * the wakeup reason
182 */
183 rval = REG_READ(ah, AR_WOW_PATTERN);
184 val = AR_WOW_STATUS(rval);
185
186 /*
187 * mask only the WoW events that we have enabled. Sometimes
188 * we have spurious WoW events from the AR_WOW_PATTERN
189 * register. This mask will clean it up.
190 */
191
192 val &= ah->wow_event_mask;
193
194 if (val) {
195 if (val & AR_WOW_MAGIC_PAT_FOUND)
196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
197 if (AR_WOW_PATTERN_FOUND(val))
198 wow_status |= AH_WOW_USER_PATTERN_EN;
199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
200 wow_status |= AH_WOW_LINK_CHANGE;
201 if (val & AR_WOW_BEACON_FAIL)
202 wow_status |= AH_WOW_BEACON_MISS;
203 }
204
205 /*
206 * set and clear WOW_PME_CLEAR registers for the chip to
207 * generate next wow signal.
208 * disable D3 before accessing other registers ?
209 */
210
211 /* do we need to check the bit value 0x01000000 (7-10) ?? */
212 REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
213 AR_PMCTRL_PWR_STATE_D1D3);
214
215 /*
216 * clear all events
217 */
218 REG_WRITE(ah, AR_WOW_PATTERN,
219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
220
221 /*
222 * restore the beacon threshold to init value
223 */
224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
225
226 /*
227 * Restore the way the PCI-E reset, Power-On-Reset, external
228 * PCIE_POR_SHORT pins are tied to its original value.
229 * Previously just before WoW sleep, we untie the PCI-E
230 * reset to our Chip's Power On Reset so that any PCI-E
231 * reset from the bus will not reset our chip
232 */
233 if (ah->is_pciexpress)
234 ath9k_hw_configpcipowersave(ah, false);
235
236 ah->wow_event_mask = 0;
237
238 return wow_status;
239}
240EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
241
242void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
243{
244 u32 wow_event_mask;
245 u32 set, clr;
246
247 /*
248 * wow_event_mask is a mask to the AR_WOW_PATTERN register to
249 * indicate which WoW events we have enabled. The WoW events
250 * are from the 'pattern_enable' in this function and
251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
252 */
253 wow_event_mask = ah->wow_event_mask;
254
255 /*
256 * Untie Power-on-Reset from the PCI-E-Reset. When we are in
257 * WOW sleep, we do want the Reset from the PCI-E to disturb
258 * our hw state
259 */
260 if (ah->is_pciexpress) {
261 /*
262 * we need to untie the internal POR (power-on-reset)
263 * to the external PCI-E reset. We also need to tie
264 * the PCI-E Phy reset to the PCI-E reset.
265 */
266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
268 REG_RMW(ah, AR_WA, set, clr);
269 }
270
271 /*
272 * set the power states appropriately and enable PME
273 */
274 set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
275 AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
276
277 /*
278 * set and clear WOW_PME_CLEAR registers for the chip
279 * to generate next wow signal.
280 */
281 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
282 clr = AR_PMCTRL_WOW_PME_CLR;
283 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
284
285 /*
286 * Setup for:
287 * - beacon misses
288 * - magic pattern
289 * - keep alive timeout
290 * - pattern matching
291 */
292
293 /*
294 * Program default values for pattern backoff, aifs/slot/KAL count,
295 * beacon miss timeout, KAL timeout, etc.
296 */
297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
299
300 set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
301 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
302 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
303 REG_SET_BIT(ah, AR_WOW_COUNT, set);
304
305 if (pattern_enable & AH_WOW_BEACON_MISS)
306 set = AR_WOW_BEACON_TIMO;
307 /* We are not using beacon miss, program a large value */
308 else
309 set = AR_WOW_BEACON_TIMO_MAX;
310
311 REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
312
313 /*
314 * Keep alive timo in ms except AR9280
315 */
316 if (!pattern_enable)
317 set = AR_WOW_KEEP_ALIVE_NEVER;
318 else
319 set = KAL_TIMEOUT * 32;
320
321 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
322
323 /*
324 * Keep alive delay in us. based on 'power on clock',
325 * therefore in usec
326 */
327 set = KAL_DELAY * 1000;
328 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
329
330 /*
331 * Create keep alive pattern to respond to beacons
332 */
333 ath9k_wow_create_keep_alive_pattern(ah);
334
335 /*
336 * Configure MAC WoW Registers
337 */
338 set = 0;
339 /* Send keep alive timeouts anyway */
340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
341
342 if (pattern_enable & AH_WOW_LINK_CHANGE)
343 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
344 else
345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
346
347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
349
350 /*
351 * we are relying on a bmiss failure. ensure we have
352 * enough threshold to prevent false positives
353 */
354 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
355 AR_WOW_BMISSTHRESHOLD);
356
357 set = 0;
358 clr = 0;
359
360 if (pattern_enable & AH_WOW_BEACON_MISS) {
361 set = AR_WOW_BEACON_FAIL_EN;
362 wow_event_mask |= AR_WOW_BEACON_FAIL;
363 } else {
364 clr = AR_WOW_BEACON_FAIL_EN;
365 }
366
367 REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
368
369 set = 0;
370 clr = 0;
371 /*
372 * Enable the magic packet registers
373 */
374 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
375 set = AR_WOW_MAGIC_EN;
376 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
377 } else {
378 clr = AR_WOW_MAGIC_EN;
379 }
380 set |= AR_WOW_MAC_INTR_EN;
381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
382
383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
384 AR_WOW_PATTERN_SUPPORTED);
385
386 /*
387 * Set the power states appropriately and enable PME
388 */
389 clr = 0;
390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
391 AR_PMCTRL_PWR_PM_CTRL_ENA;
392
393 clr = AR_PCIE_PM_CTRL_ENA;
394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
395
396 /*
397 * this is needed to prevent the chip waking up
398 * the host within 3-4 seconds with certain
399 * platform/BIOS. The fix is to enable
400 * D1 & D3 to match original definition and
401 * also match the OTP value. Anyway this
402 * is more related to SW WOW.
403 */
404 clr = AR_PMCTRL_PWR_STATE_D1D3;
405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
406
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
409
410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
411
412 /* to bring down WOW power low margin */
413 set = BIT(13);
414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
415 /* HW WoW */
416 clr = BIT(5);
417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
418
419 ath9k_hw_set_powermode_wow_sleep(ah);
420 ah->wow_event_mask = wow_event_mask;
421}
422EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
index 25db9215985a..7f22cb2a4941 100644
--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
@@ -18,6 +18,18 @@
18#ifndef INITVALS_9340_H 18#ifndef INITVALS_9340_H
19#define INITVALS_9340_H 19#define INITVALS_9340_H
20 20
21#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
22
23#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
24
25#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
26
27#define ar9340Common_rx_gain_table_1p0 ar9300Common_rx_gain_table_2p2
28
29#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
30
31#define ar9340_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
32
21static const u32 ar9340_1p0_radio_postamble[][5] = { 33static const u32 ar9340_1p0_radio_postamble[][5] = {
22 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 34 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
23 {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, 35 {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
@@ -100,8 +112,6 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
100 {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, 112 {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
101}; 113};
102 114
103#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2
104
105static const u32 ar9340_1p0_radio_core[][2] = { 115static const u32 ar9340_1p0_radio_core[][2] = {
106 /* Addr allmodes */ 116 /* Addr allmodes */
107 {0x00016000, 0x36db6db6}, 117 {0x00016000, 0x36db6db6},
@@ -215,16 +225,12 @@ static const u32 ar9340_1p0_radio_core_40M[][2] = {
215 {0x0000824c, 0x0001e800}, 225 {0x0000824c, 0x0001e800},
216}; 226};
217 227
218#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble
219
220#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble
221
222static const u32 ar9340_1p0_baseband_postamble[][5] = { 228static const u32 ar9340_1p0_baseband_postamble[][5] = {
223 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 229 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
224 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, 230 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
225 {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, 231 {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
226 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, 232 {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
227 {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, 233 {0x00009828, 0x06903081, 0x06903081, 0x09103881, 0x09103881},
228 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, 234 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
229 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, 235 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
230 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, 236 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
@@ -340,9 +346,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
340 {0x0000a370, 0x00000000}, 346 {0x0000a370, 0x00000000},
341 {0x0000a390, 0x00000001}, 347 {0x0000a390, 0x00000001},
342 {0x0000a394, 0x00000444}, 348 {0x0000a394, 0x00000444},
343 {0x0000a398, 0x001f0e0f}, 349 {0x0000a398, 0x00000000},
344 {0x0000a39c, 0x0075393f}, 350 {0x0000a39c, 0x210d0401},
345 {0x0000a3a0, 0xb79f6427}, 351 {0x0000a3a0, 0xab9a7144},
346 {0x0000a3a4, 0x00000000}, 352 {0x0000a3a4, 0x00000000},
347 {0x0000a3a8, 0xaaaaaaaa}, 353 {0x0000a3a8, 0xaaaaaaaa},
348 {0x0000a3ac, 0x3c466478}, 354 {0x0000a3ac, 0x3c466478},
@@ -714,266 +720,6 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
714 {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, 720 {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000},
715}; 721};
716 722
717static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
718 /* Addr allmodes */
719 {0x0000a000, 0x00010000},
720 {0x0000a004, 0x00030002},
721 {0x0000a008, 0x00050004},
722 {0x0000a00c, 0x00810080},
723 {0x0000a010, 0x00830082},
724 {0x0000a014, 0x01810180},
725 {0x0000a018, 0x01830182},
726 {0x0000a01c, 0x01850184},
727 {0x0000a020, 0x01890188},
728 {0x0000a024, 0x018b018a},
729 {0x0000a028, 0x018d018c},
730 {0x0000a02c, 0x01910190},
731 {0x0000a030, 0x01930192},
732 {0x0000a034, 0x01950194},
733 {0x0000a038, 0x038a0196},
734 {0x0000a03c, 0x038c038b},
735 {0x0000a040, 0x0390038d},
736 {0x0000a044, 0x03920391},
737 {0x0000a048, 0x03940393},
738 {0x0000a04c, 0x03960395},
739 {0x0000a050, 0x00000000},
740 {0x0000a054, 0x00000000},
741 {0x0000a058, 0x00000000},
742 {0x0000a05c, 0x00000000},
743 {0x0000a060, 0x00000000},
744 {0x0000a064, 0x00000000},
745 {0x0000a068, 0x00000000},
746 {0x0000a06c, 0x00000000},
747 {0x0000a070, 0x00000000},
748 {0x0000a074, 0x00000000},
749 {0x0000a078, 0x00000000},
750 {0x0000a07c, 0x00000000},
751 {0x0000a080, 0x22222229},
752 {0x0000a084, 0x1d1d1d1d},
753 {0x0000a088, 0x1d1d1d1d},
754 {0x0000a08c, 0x1d1d1d1d},
755 {0x0000a090, 0x171d1d1d},
756 {0x0000a094, 0x11111717},
757 {0x0000a098, 0x00030311},
758 {0x0000a09c, 0x00000000},
759 {0x0000a0a0, 0x00000000},
760 {0x0000a0a4, 0x00000000},
761 {0x0000a0a8, 0x00000000},
762 {0x0000a0ac, 0x00000000},
763 {0x0000a0b0, 0x00000000},
764 {0x0000a0b4, 0x00000000},
765 {0x0000a0b8, 0x00000000},
766 {0x0000a0bc, 0x00000000},
767 {0x0000a0c0, 0x001f0000},
768 {0x0000a0c4, 0x01000101},
769 {0x0000a0c8, 0x011e011f},
770 {0x0000a0cc, 0x011c011d},
771 {0x0000a0d0, 0x02030204},
772 {0x0000a0d4, 0x02010202},
773 {0x0000a0d8, 0x021f0200},
774 {0x0000a0dc, 0x0302021e},
775 {0x0000a0e0, 0x03000301},
776 {0x0000a0e4, 0x031e031f},
777 {0x0000a0e8, 0x0402031d},
778 {0x0000a0ec, 0x04000401},
779 {0x0000a0f0, 0x041e041f},
780 {0x0000a0f4, 0x0502041d},
781 {0x0000a0f8, 0x05000501},
782 {0x0000a0fc, 0x051e051f},
783 {0x0000a100, 0x06010602},
784 {0x0000a104, 0x061f0600},
785 {0x0000a108, 0x061d061e},
786 {0x0000a10c, 0x07020703},
787 {0x0000a110, 0x07000701},
788 {0x0000a114, 0x00000000},
789 {0x0000a118, 0x00000000},
790 {0x0000a11c, 0x00000000},
791 {0x0000a120, 0x00000000},
792 {0x0000a124, 0x00000000},
793 {0x0000a128, 0x00000000},
794 {0x0000a12c, 0x00000000},
795 {0x0000a130, 0x00000000},
796 {0x0000a134, 0x00000000},
797 {0x0000a138, 0x00000000},
798 {0x0000a13c, 0x00000000},
799 {0x0000a140, 0x001f0000},
800 {0x0000a144, 0x01000101},
801 {0x0000a148, 0x011e011f},
802 {0x0000a14c, 0x011c011d},
803 {0x0000a150, 0x02030204},
804 {0x0000a154, 0x02010202},
805 {0x0000a158, 0x021f0200},
806 {0x0000a15c, 0x0302021e},
807 {0x0000a160, 0x03000301},
808 {0x0000a164, 0x031e031f},
809 {0x0000a168, 0x0402031d},
810 {0x0000a16c, 0x04000401},
811 {0x0000a170, 0x041e041f},
812 {0x0000a174, 0x0502041d},
813 {0x0000a178, 0x05000501},
814 {0x0000a17c, 0x051e051f},
815 {0x0000a180, 0x06010602},
816 {0x0000a184, 0x061f0600},
817 {0x0000a188, 0x061d061e},
818 {0x0000a18c, 0x07020703},
819 {0x0000a190, 0x07000701},
820 {0x0000a194, 0x00000000},
821 {0x0000a198, 0x00000000},
822 {0x0000a19c, 0x00000000},
823 {0x0000a1a0, 0x00000000},
824 {0x0000a1a4, 0x00000000},
825 {0x0000a1a8, 0x00000000},
826 {0x0000a1ac, 0x00000000},
827 {0x0000a1b0, 0x00000000},
828 {0x0000a1b4, 0x00000000},
829 {0x0000a1b8, 0x00000000},
830 {0x0000a1bc, 0x00000000},
831 {0x0000a1c0, 0x00000000},
832 {0x0000a1c4, 0x00000000},
833 {0x0000a1c8, 0x00000000},
834 {0x0000a1cc, 0x00000000},
835 {0x0000a1d0, 0x00000000},
836 {0x0000a1d4, 0x00000000},
837 {0x0000a1d8, 0x00000000},
838 {0x0000a1dc, 0x00000000},
839 {0x0000a1e0, 0x00000000},
840 {0x0000a1e4, 0x00000000},
841 {0x0000a1e8, 0x00000000},
842 {0x0000a1ec, 0x00000000},
843 {0x0000a1f0, 0x00000396},
844 {0x0000a1f4, 0x00000396},
845 {0x0000a1f8, 0x00000396},
846 {0x0000a1fc, 0x00000196},
847 {0x0000b000, 0x00010000},
848 {0x0000b004, 0x00030002},
849 {0x0000b008, 0x00050004},
850 {0x0000b00c, 0x00810080},
851 {0x0000b010, 0x00830082},
852 {0x0000b014, 0x01810180},
853 {0x0000b018, 0x01830182},
854 {0x0000b01c, 0x01850184},
855 {0x0000b020, 0x02810280},
856 {0x0000b024, 0x02830282},
857 {0x0000b028, 0x02850284},
858 {0x0000b02c, 0x02890288},
859 {0x0000b030, 0x028b028a},
860 {0x0000b034, 0x0388028c},
861 {0x0000b038, 0x038a0389},
862 {0x0000b03c, 0x038c038b},
863 {0x0000b040, 0x0390038d},
864 {0x0000b044, 0x03920391},
865 {0x0000b048, 0x03940393},
866 {0x0000b04c, 0x03960395},
867 {0x0000b050, 0x00000000},
868 {0x0000b054, 0x00000000},
869 {0x0000b058, 0x00000000},
870 {0x0000b05c, 0x00000000},
871 {0x0000b060, 0x00000000},
872 {0x0000b064, 0x00000000},
873 {0x0000b068, 0x00000000},
874 {0x0000b06c, 0x00000000},
875 {0x0000b070, 0x00000000},
876 {0x0000b074, 0x00000000},
877 {0x0000b078, 0x00000000},
878 {0x0000b07c, 0x00000000},
879 {0x0000b080, 0x23232323},
880 {0x0000b084, 0x21232323},
881 {0x0000b088, 0x19191c1e},
882 {0x0000b08c, 0x12141417},
883 {0x0000b090, 0x07070e0e},
884 {0x0000b094, 0x03030305},
885 {0x0000b098, 0x00000003},
886 {0x0000b09c, 0x00000000},
887 {0x0000b0a0, 0x00000000},
888 {0x0000b0a4, 0x00000000},
889 {0x0000b0a8, 0x00000000},
890 {0x0000b0ac, 0x00000000},
891 {0x0000b0b0, 0x00000000},
892 {0x0000b0b4, 0x00000000},
893 {0x0000b0b8, 0x00000000},
894 {0x0000b0bc, 0x00000000},
895 {0x0000b0c0, 0x003f0020},
896 {0x0000b0c4, 0x00400041},
897 {0x0000b0c8, 0x0140005f},
898 {0x0000b0cc, 0x0160015f},
899 {0x0000b0d0, 0x017e017f},
900 {0x0000b0d4, 0x02410242},
901 {0x0000b0d8, 0x025f0240},
902 {0x0000b0dc, 0x027f0260},
903 {0x0000b0e0, 0x0341027e},
904 {0x0000b0e4, 0x035f0340},
905 {0x0000b0e8, 0x037f0360},
906 {0x0000b0ec, 0x04400441},
907 {0x0000b0f0, 0x0460045f},
908 {0x0000b0f4, 0x0541047f},
909 {0x0000b0f8, 0x055f0540},
910 {0x0000b0fc, 0x057f0560},
911 {0x0000b100, 0x06400641},
912 {0x0000b104, 0x0660065f},
913 {0x0000b108, 0x067e067f},
914 {0x0000b10c, 0x07410742},
915 {0x0000b110, 0x075f0740},
916 {0x0000b114, 0x077f0760},
917 {0x0000b118, 0x07800781},
918 {0x0000b11c, 0x07a0079f},
919 {0x0000b120, 0x07c107bf},
920 {0x0000b124, 0x000007c0},
921 {0x0000b128, 0x00000000},
922 {0x0000b12c, 0x00000000},
923 {0x0000b130, 0x00000000},
924 {0x0000b134, 0x00000000},
925 {0x0000b138, 0x00000000},
926 {0x0000b13c, 0x00000000},
927 {0x0000b140, 0x003f0020},
928 {0x0000b144, 0x00400041},
929 {0x0000b148, 0x0140005f},
930 {0x0000b14c, 0x0160015f},
931 {0x0000b150, 0x017e017f},
932 {0x0000b154, 0x02410242},
933 {0x0000b158, 0x025f0240},
934 {0x0000b15c, 0x027f0260},
935 {0x0000b160, 0x0341027e},
936 {0x0000b164, 0x035f0340},
937 {0x0000b168, 0x037f0360},
938 {0x0000b16c, 0x04400441},
939 {0x0000b170, 0x0460045f},
940 {0x0000b174, 0x0541047f},
941 {0x0000b178, 0x055f0540},
942 {0x0000b17c, 0x057f0560},
943 {0x0000b180, 0x06400641},
944 {0x0000b184, 0x0660065f},
945 {0x0000b188, 0x067e067f},
946 {0x0000b18c, 0x07410742},
947 {0x0000b190, 0x075f0740},
948 {0x0000b194, 0x077f0760},
949 {0x0000b198, 0x07800781},
950 {0x0000b19c, 0x07a0079f},
951 {0x0000b1a0, 0x07c107bf},
952 {0x0000b1a4, 0x000007c0},
953 {0x0000b1a8, 0x00000000},
954 {0x0000b1ac, 0x00000000},
955 {0x0000b1b0, 0x00000000},
956 {0x0000b1b4, 0x00000000},
957 {0x0000b1b8, 0x00000000},
958 {0x0000b1bc, 0x00000000},
959 {0x0000b1c0, 0x00000000},
960 {0x0000b1c4, 0x00000000},
961 {0x0000b1c8, 0x00000000},
962 {0x0000b1cc, 0x00000000},
963 {0x0000b1d0, 0x00000000},
964 {0x0000b1d4, 0x00000000},
965 {0x0000b1d8, 0x00000000},
966 {0x0000b1dc, 0x00000000},
967 {0x0000b1e0, 0x00000000},
968 {0x0000b1e4, 0x00000000},
969 {0x0000b1e8, 0x00000000},
970 {0x0000b1ec, 0x00000000},
971 {0x0000b1f0, 0x00000396},
972 {0x0000b1f4, 0x00000396},
973 {0x0000b1f8, 0x00000396},
974 {0x0000b1fc, 0x00000196},
975};
976
977static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { 723static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
978 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 724 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
979 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 725 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -1437,8 +1183,6 @@ static const u32 ar9340_1p0_mac_core[][2] = {
1437 {0x000083d0, 0x000101ff}, 1183 {0x000083d0, 0x000101ff},
1438}; 1184};
1439 1185
1440#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2
1441
1442static const u32 ar9340_1p0_soc_preamble[][2] = { 1186static const u32 ar9340_1p0_soc_preamble[][2] = {
1443 /* Addr allmodes */ 1187 /* Addr allmodes */
1444 {0x00007008, 0x00000000}, 1188 {0x00007008, 0x00000000},
@@ -1447,4 +1191,106 @@ static const u32 ar9340_1p0_soc_preamble[][2] = {
1447 {0x00007038, 0x000004c2}, 1191 {0x00007038, 0x000004c2},
1448}; 1192};
1449 1193
1194static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = {
1195 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1196 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1197 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1198 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1199 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1200 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1201 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1202 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1203 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1204 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1205 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1206 {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
1207 {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402},
1208 {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
1209 {0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603},
1210 {0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02},
1211 {0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04},
1212 {0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20},
1213 {0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20},
1214 {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
1215 {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
1216 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
1217 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
1218 {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
1219 {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
1220 {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83},
1221 {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84},
1222 {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3},
1223 {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5},
1224 {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9},
1225 {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb},
1226 {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1227 {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1228 {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1229 {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1230 {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1231 {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1232 {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec},
1233 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
1234 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
1235 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
1236 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
1237 {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
1238 {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
1239 {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
1240 {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
1241 {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
1242 {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
1243 {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
1244 {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
1245 {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
1246 {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
1247 {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
1248 {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
1249 {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
1250 {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
1251 {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
1252 {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
1253 {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
1254 {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
1255 {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
1256 {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
1257 {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
1258 {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1259 {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1260 {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1261 {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1262 {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1263 {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1264 {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
1265 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1266 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1267 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1268 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1269 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1270 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1271 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1272 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1273 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1274 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1275 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1276 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1277 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1278 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1279 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1280 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1281 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1282 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1283 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1284 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1285 {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
1286 {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
1287 {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015},
1288 {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000},
1289 {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
1290 {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266},
1291 {0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011},
1292 {0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c},
1293 {0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030},
1294};
1295
1450#endif /* INITVALS_9340_H */ 1296#endif /* INITVALS_9340_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 092b9d412e7f..739094384369 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -20,7 +20,7 @@
20 20
21/* AR9462 2.0 */ 21/* AR9462 2.0 */
22 22
23static const u32 ar9462_modes_fast_clock_2p0[][3] = { 23static const u32 ar9462_2p0_modes_fast_clock[][3] = {
24 /* Addr 5G_HT20 5G_HT40 */ 24 /* Addr 5G_HT20 5G_HT40 */
25 {0x00001030, 0x00000268, 0x000004d0}, 25 {0x00001030, 0x00000268, 0x000004d0},
26 {0x00001070, 0x0000018c, 0x00000318}, 26 {0x00001070, 0x0000018c, 0x00000318},
@@ -33,13 +33,6 @@ static const u32 ar9462_modes_fast_clock_2p0[][3] = {
33 {0x0000a254, 0x00000898, 0x00001130}, 33 {0x0000a254, 0x00000898, 0x00001130},
34}; 34};
35 35
36static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
37 /* Addr allmodes */
38 {0x00018c00, 0x18253ede},
39 {0x00018c04, 0x000801d8},
40 {0x00018c08, 0x0003780c},
41};
42
43static const u32 ar9462_2p0_baseband_postamble[][5] = { 36static const u32 ar9462_2p0_baseband_postamble[][5] = {
44 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 37 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
45 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, 38 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -99,7 +92,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
99 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 92 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
100}; 93};
101 94
102static const u32 ar9462_common_rx_gain_table_2p0[][2] = { 95static const u32 ar9462_2p0_common_rx_gain[][2] = {
103 /* Addr allmodes */ 96 /* Addr allmodes */
104 {0x0000a000, 0x00010000}, 97 {0x0000a000, 0x00010000},
105 {0x0000a004, 0x00030002}, 98 {0x0000a004, 0x00030002},
@@ -359,20 +352,13 @@ static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
359 {0x0000b1fc, 0x00000196}, 352 {0x0000b1fc, 0x00000196},
360}; 353};
361 354
362static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = { 355static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = {
363 /* Addr allmodes */ 356 /* Addr allmodes */
364 {0x00018c00, 0x18213ede}, 357 {0x00018c00, 0x18213ede},
365 {0x00018c04, 0x000801d8}, 358 {0x00018c04, 0x000801d8},
366 {0x00018c08, 0x0003780c}, 359 {0x00018c08, 0x0003780c},
367}; 360};
368 361
369static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
370 /* Addr allmodes */
371 {0x00018c00, 0x18212ede},
372 {0x00018c04, 0x000801d8},
373 {0x00018c08, 0x0003780c},
374};
375
376static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { 362static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
377 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 363 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
378 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, 364 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
@@ -380,7 +366,7 @@ static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = {
380 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 366 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
381}; 367};
382 368
383static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { 369static const u32 ar9462_2p0_common_wo_xlna_rx_gain[][2] = {
384 /* Addr allmodes */ 370 /* Addr allmodes */
385 {0x0000a000, 0x00010000}, 371 {0x0000a000, 0x00010000},
386 {0x0000a004, 0x00030002}, 372 {0x0000a004, 0x00030002},
@@ -647,7 +633,7 @@ static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
647 {0x0000a3a0, 0xca9228ee}, 633 {0x0000a3a0, 0xca9228ee},
648}; 634};
649 635
650static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { 636static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = {
651 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 637 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
652 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 638 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
653 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 639 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -879,7 +865,7 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 865 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
880}; 866};
881 867
882static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = { 868static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 869 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 870 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
885 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 871 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -942,7 +928,7 @@ static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
942 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, 928 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
943}; 929};
944 930
945static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { 931static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = {
946 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 932 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
947 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 933 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
948 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, 934 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
@@ -1252,7 +1238,7 @@ static const u32 ar9462_2p0_mac_postamble[][5] = {
1252 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, 1238 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
1253}; 1239};
1254 1240
1255static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = { 1241static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = {
1256 /* Addr allmodes */ 1242 /* Addr allmodes */
1257 {0x0000a000, 0x00010000}, 1243 {0x0000a000, 0x00010000},
1258 {0x0000a004, 0x00030002}, 1244 {0x0000a004, 0x00030002},
@@ -1517,7 +1503,7 @@ static const u32 ar9462_2p0_baseband_postamble_5g_xlna[][5] = {
1517 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, 1503 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1518}; 1504};
1519 1505
1520static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = { 1506static const u32 ar9462_2p0_common_5g_xlna_only_rxgain[][2] = {
1521 /* Addr allmodes */ 1507 /* Addr allmodes */
1522 {0x0000a000, 0x00010000}, 1508 {0x0000a000, 0x00010000},
1523 {0x0000a004, 0x00030002}, 1509 {0x0000a004, 0x00030002},
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
index 57fc5f459d0a..dc3adda46e8b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
@@ -20,6 +20,44 @@
20 20
21/* AR9462 2.1 */ 21/* AR9462 2.1 */
22 22
23#define ar9462_2p1_mac_postamble ar9462_2p0_mac_postamble
24
25#define ar9462_2p1_baseband_core ar9462_2p0_baseband_core
26
27#define ar9462_2p1_radio_core ar9462_2p0_radio_core
28
29#define ar9462_2p1_radio_postamble ar9462_2p0_radio_postamble
30
31#define ar9462_2p1_soc_postamble ar9462_2p0_soc_postamble
32
33#define ar9462_2p1_radio_postamble_sys2ant ar9462_2p0_radio_postamble_sys2ant
34
35#define ar9462_2p1_common_rx_gain ar9462_2p0_common_rx_gain
36
37#define ar9462_2p1_common_mixed_rx_gain ar9462_2p0_common_mixed_rx_gain
38
39#define ar9462_2p1_common_5g_xlna_only_rxgain ar9462_2p0_common_5g_xlna_only_rxgain
40
41#define ar9462_2p1_baseband_core_mix_rxgain ar9462_2p0_baseband_core_mix_rxgain
42
43#define ar9462_2p1_baseband_postamble_mix_rxgain ar9462_2p0_baseband_postamble_mix_rxgain
44
45#define ar9462_2p1_baseband_postamble_5g_xlna ar9462_2p0_baseband_postamble_5g_xlna
46
47#define ar9462_2p1_common_wo_xlna_rx_gain ar9462_2p0_common_wo_xlna_rx_gain
48
49#define ar9462_2p1_modes_low_ob_db_tx_gain ar9462_2p0_modes_low_ob_db_tx_gain
50
51#define ar9462_2p1_modes_high_ob_db_tx_gain ar9462_2p0_modes_high_ob_db_tx_gain
52
53#define ar9462_2p1_modes_mix_ob_db_tx_gain ar9462_2p0_modes_mix_ob_db_tx_gain
54
55#define ar9462_2p1_modes_fast_clock ar9462_2p0_modes_fast_clock
56
57#define ar9462_2p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
58
59#define ar9462_2p1_pciephy_clkreq_disable_L1 ar9462_2p0_pciephy_clkreq_disable_L1
60
23static const u32 ar9462_2p1_mac_core[][2] = { 61static const u32 ar9462_2p1_mac_core[][2] = {
24 /* Addr allmodes */ 62 /* Addr allmodes */
25 {0x00000008, 0x00000000}, 63 {0x00000008, 0x00000000},
@@ -183,168 +221,6 @@ static const u32 ar9462_2p1_mac_core[][2] = {
183 {0x000083d0, 0x000301ff}, 221 {0x000083d0, 0x000301ff},
184}; 222};
185 223
186static const u32 ar9462_2p1_mac_postamble[][5] = {
187 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
188 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
189 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
190 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
191 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
192 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
193 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
194 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
195 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
196};
197
198static const u32 ar9462_2p1_baseband_core[][2] = {
199 /* Addr allmodes */
200 {0x00009800, 0xafe68e30},
201 {0x00009804, 0xfd14e000},
202 {0x00009808, 0x9c0a9f6b},
203 {0x0000980c, 0x04900000},
204 {0x00009814, 0x9280c00a},
205 {0x00009818, 0x00000000},
206 {0x0000981c, 0x00020028},
207 {0x00009834, 0x6400a290},
208 {0x00009838, 0x0108ecff},
209 {0x0000983c, 0x0d000600},
210 {0x00009880, 0x201fff00},
211 {0x00009884, 0x00001042},
212 {0x000098a4, 0x00200400},
213 {0x000098b0, 0x32440bbe},
214 {0x000098d0, 0x004b6a8e},
215 {0x000098d4, 0x00000820},
216 {0x000098dc, 0x00000000},
217 {0x000098e4, 0x01ffffff},
218 {0x000098e8, 0x01ffffff},
219 {0x000098ec, 0x01ffffff},
220 {0x000098f0, 0x00000000},
221 {0x000098f4, 0x00000000},
222 {0x00009bf0, 0x80000000},
223 {0x00009c04, 0xff55ff55},
224 {0x00009c08, 0x0320ff55},
225 {0x00009c0c, 0x00000000},
226 {0x00009c10, 0x00000000},
227 {0x00009c14, 0x00046384},
228 {0x00009c18, 0x05b6b440},
229 {0x00009c1c, 0x00b6b440},
230 {0x00009d00, 0xc080a333},
231 {0x00009d04, 0x40206c10},
232 {0x00009d08, 0x009c4060},
233 {0x00009d0c, 0x9883800a},
234 {0x00009d10, 0x01834061},
235 {0x00009d14, 0x00c0040b},
236 {0x00009d18, 0x00000000},
237 {0x00009e08, 0x0038230c},
238 {0x00009e24, 0x990bb515},
239 {0x00009e28, 0x0c6f0000},
240 {0x00009e30, 0x06336f77},
241 {0x00009e34, 0x6af6532f},
242 {0x00009e38, 0x0cc80c00},
243 {0x00009e40, 0x15262820},
244 {0x00009e4c, 0x00001004},
245 {0x00009e50, 0x00ff03f1},
246 {0x00009e54, 0xe4c555c2},
247 {0x00009e58, 0xfd857722},
248 {0x00009e5c, 0xe9198724},
249 {0x00009fc0, 0x803e4788},
250 {0x00009fc4, 0x0001efb5},
251 {0x00009fcc, 0x40000014},
252 {0x00009fd0, 0x0a193b93},
253 {0x0000a20c, 0x00000000},
254 {0x0000a220, 0x00000000},
255 {0x0000a224, 0x00000000},
256 {0x0000a228, 0x10002310},
257 {0x0000a23c, 0x00000000},
258 {0x0000a244, 0x0c000000},
259 {0x0000a2a0, 0x00000001},
260 {0x0000a2c0, 0x00000001},
261 {0x0000a2c8, 0x00000000},
262 {0x0000a2cc, 0x18c43433},
263 {0x0000a2d4, 0x00000000},
264 {0x0000a2ec, 0x00000000},
265 {0x0000a2f0, 0x00000000},
266 {0x0000a2f4, 0x00000000},
267 {0x0000a2f8, 0x00000000},
268 {0x0000a344, 0x00000000},
269 {0x0000a34c, 0x00000000},
270 {0x0000a350, 0x0000a000},
271 {0x0000a364, 0x00000000},
272 {0x0000a370, 0x00000000},
273 {0x0000a390, 0x00000001},
274 {0x0000a394, 0x00000444},
275 {0x0000a398, 0x001f0e0f},
276 {0x0000a39c, 0x0075393f},
277 {0x0000a3a0, 0xb79f6427},
278 {0x0000a3c0, 0x20202020},
279 {0x0000a3c4, 0x22222220},
280 {0x0000a3c8, 0x20200020},
281 {0x0000a3cc, 0x20202020},
282 {0x0000a3d0, 0x20202020},
283 {0x0000a3d4, 0x20202020},
284 {0x0000a3d8, 0x20202020},
285 {0x0000a3dc, 0x20202020},
286 {0x0000a3e0, 0x20202020},
287 {0x0000a3e4, 0x20202020},
288 {0x0000a3e8, 0x20202020},
289 {0x0000a3ec, 0x20202020},
290 {0x0000a3f0, 0x00000000},
291 {0x0000a3f4, 0x00000006},
292 {0x0000a3f8, 0x0c9bd380},
293 {0x0000a3fc, 0x000f0f01},
294 {0x0000a400, 0x8fa91f01},
295 {0x0000a404, 0x00000000},
296 {0x0000a408, 0x0e79e5c6},
297 {0x0000a40c, 0x00820820},
298 {0x0000a414, 0x1ce739ce},
299 {0x0000a418, 0x2d001dce},
300 {0x0000a434, 0x00000000},
301 {0x0000a438, 0x00001801},
302 {0x0000a43c, 0x00100000},
303 {0x0000a444, 0x00000000},
304 {0x0000a448, 0x05000080},
305 {0x0000a44c, 0x00000001},
306 {0x0000a450, 0x00010000},
307 {0x0000a454, 0x07000000},
308 {0x0000a644, 0xbfad9d74},
309 {0x0000a648, 0x0048060a},
310 {0x0000a64c, 0x00002037},
311 {0x0000a670, 0x03020100},
312 {0x0000a674, 0x09080504},
313 {0x0000a678, 0x0d0c0b0a},
314 {0x0000a67c, 0x13121110},
315 {0x0000a680, 0x31301514},
316 {0x0000a684, 0x35343332},
317 {0x0000a688, 0x00000036},
318 {0x0000a690, 0x00000838},
319 {0x0000a6b0, 0x0000000a},
320 {0x0000a6b4, 0x00512c01},
321 {0x0000a7c0, 0x00000000},
322 {0x0000a7c4, 0xfffffffc},
323 {0x0000a7c8, 0x00000000},
324 {0x0000a7cc, 0x00000000},
325 {0x0000a7d0, 0x00000000},
326 {0x0000a7d4, 0x00000004},
327 {0x0000a7dc, 0x00000000},
328 {0x0000a7f0, 0x80000000},
329 {0x0000a8d0, 0x004b6a8e},
330 {0x0000a8d4, 0x00000820},
331 {0x0000a8dc, 0x00000000},
332 {0x0000a8f0, 0x00000000},
333 {0x0000a8f4, 0x00000000},
334 {0x0000abf0, 0x80000000},
335 {0x0000b2d0, 0x00000080},
336 {0x0000b2d4, 0x00000000},
337 {0x0000b2ec, 0x00000000},
338 {0x0000b2f0, 0x00000000},
339 {0x0000b2f4, 0x00000000},
340 {0x0000b2f8, 0x00000000},
341 {0x0000b408, 0x0e79e5c0},
342 {0x0000b40c, 0x00820820},
343 {0x0000b420, 0x00000000},
344 {0x0000b6b0, 0x0000000a},
345 {0x0000b6b4, 0x00000001},
346};
347
348static const u32 ar9462_2p1_baseband_postamble[][5] = { 224static const u32 ar9462_2p1_baseband_postamble[][5] = {
349 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 225 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
350 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, 226 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
@@ -404,72 +280,6 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = {
404 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, 280 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
405}; 281};
406 282
407static const u32 ar9462_2p1_radio_core[][2] = {
408 /* Addr allmodes */
409 {0x00016000, 0x36db6db6},
410 {0x00016004, 0x6db6db40},
411 {0x00016008, 0x73f00000},
412 {0x0001600c, 0x00000000},
413 {0x00016010, 0x6d820001},
414 {0x00016040, 0x7f80fff8},
415 {0x0001604c, 0x2699e04f},
416 {0x00016050, 0x6db6db6c},
417 {0x00016058, 0x6c200000},
418 {0x00016080, 0x000c0000},
419 {0x00016084, 0x9a68048c},
420 {0x00016088, 0x54214514},
421 {0x0001608c, 0x1203040b},
422 {0x00016090, 0x24926490},
423 {0x00016098, 0xd2888888},
424 {0x000160a0, 0x0a108ffe},
425 {0x000160a4, 0x812fc491},
426 {0x000160a8, 0x423c8000},
427 {0x000160b4, 0x92000000},
428 {0x000160b8, 0x0285dddc},
429 {0x000160bc, 0x02908888},
430 {0x000160c0, 0x00adb6d0},
431 {0x000160c4, 0x6db6db60},
432 {0x000160c8, 0x6db6db6c},
433 {0x000160cc, 0x0de6c1b0},
434 {0x00016100, 0x3fffbe04},
435 {0x00016104, 0xfff80000},
436 {0x00016108, 0x00200400},
437 {0x00016110, 0x00000000},
438 {0x00016144, 0x02084080},
439 {0x00016148, 0x000080c0},
440 {0x00016280, 0x050a0001},
441 {0x00016284, 0x3d841418},
442 {0x00016288, 0x00000000},
443 {0x0001628c, 0xe3000000},
444 {0x00016290, 0xa1005080},
445 {0x00016294, 0x00000020},
446 {0x00016298, 0x54a82900},
447 {0x00016340, 0x121e4276},
448 {0x00016344, 0x00300000},
449 {0x00016400, 0x36db6db6},
450 {0x00016404, 0x6db6db40},
451 {0x00016408, 0x73f00000},
452 {0x0001640c, 0x00000000},
453 {0x00016410, 0x6c800001},
454 {0x00016440, 0x7f80fff8},
455 {0x0001644c, 0x4699e04f},
456 {0x00016450, 0x6db6db6c},
457 {0x00016500, 0x3fffbe04},
458 {0x00016504, 0xfff80000},
459 {0x00016508, 0x00200400},
460 {0x00016510, 0x00000000},
461 {0x00016544, 0x02084080},
462 {0x00016548, 0x000080c0},
463};
464
465static const u32 ar9462_2p1_radio_postamble[][5] = {
466 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
467 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
468 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
469 {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
470 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
471};
472
473static const u32 ar9462_2p1_soc_preamble[][2] = { 283static const u32 ar9462_2p1_soc_preamble[][2] = {
474 /* Addr allmodes */ 284 /* Addr allmodes */
475 {0x000040a4, 0x00a0c9c9}, 285 {0x000040a4, 0x00a0c9c9},
@@ -478,1297 +288,4 @@ static const u32 ar9462_2p1_soc_preamble[][2] = {
478 {0x00007038, 0x000004c2}, 288 {0x00007038, 0x000004c2},
479}; 289};
480 290
481static const u32 ar9462_2p1_soc_postamble[][5] = {
482 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
483 {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
484};
485
486static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
487 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
488 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
489 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
490 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
491};
492
493static const u32 ar9462_2p1_common_rx_gain[][2] = {
494 /* Addr allmodes */
495 {0x0000a000, 0x00010000},
496 {0x0000a004, 0x00030002},
497 {0x0000a008, 0x00050004},
498 {0x0000a00c, 0x00810080},
499 {0x0000a010, 0x00830082},
500 {0x0000a014, 0x01810180},
501 {0x0000a018, 0x01830182},
502 {0x0000a01c, 0x01850184},
503 {0x0000a020, 0x01890188},
504 {0x0000a024, 0x018b018a},
505 {0x0000a028, 0x018d018c},
506 {0x0000a02c, 0x01910190},
507 {0x0000a030, 0x01930192},
508 {0x0000a034, 0x01950194},
509 {0x0000a038, 0x038a0196},
510 {0x0000a03c, 0x038c038b},
511 {0x0000a040, 0x0390038d},
512 {0x0000a044, 0x03920391},
513 {0x0000a048, 0x03940393},
514 {0x0000a04c, 0x03960395},
515 {0x0000a050, 0x00000000},
516 {0x0000a054, 0x00000000},
517 {0x0000a058, 0x00000000},
518 {0x0000a05c, 0x00000000},
519 {0x0000a060, 0x00000000},
520 {0x0000a064, 0x00000000},
521 {0x0000a068, 0x00000000},
522 {0x0000a06c, 0x00000000},
523 {0x0000a070, 0x00000000},
524 {0x0000a074, 0x00000000},
525 {0x0000a078, 0x00000000},
526 {0x0000a07c, 0x00000000},
527 {0x0000a080, 0x22222229},
528 {0x0000a084, 0x1d1d1d1d},
529 {0x0000a088, 0x1d1d1d1d},
530 {0x0000a08c, 0x1d1d1d1d},
531 {0x0000a090, 0x171d1d1d},
532 {0x0000a094, 0x11111717},
533 {0x0000a098, 0x00030311},
534 {0x0000a09c, 0x00000000},
535 {0x0000a0a0, 0x00000000},
536 {0x0000a0a4, 0x00000000},
537 {0x0000a0a8, 0x00000000},
538 {0x0000a0ac, 0x00000000},
539 {0x0000a0b0, 0x00000000},
540 {0x0000a0b4, 0x00000000},
541 {0x0000a0b8, 0x00000000},
542 {0x0000a0bc, 0x00000000},
543 {0x0000a0c0, 0x001f0000},
544 {0x0000a0c4, 0x01000101},
545 {0x0000a0c8, 0x011e011f},
546 {0x0000a0cc, 0x011c011d},
547 {0x0000a0d0, 0x02030204},
548 {0x0000a0d4, 0x02010202},
549 {0x0000a0d8, 0x021f0200},
550 {0x0000a0dc, 0x0302021e},
551 {0x0000a0e0, 0x03000301},
552 {0x0000a0e4, 0x031e031f},
553 {0x0000a0e8, 0x0402031d},
554 {0x0000a0ec, 0x04000401},
555 {0x0000a0f0, 0x041e041f},
556 {0x0000a0f4, 0x0502041d},
557 {0x0000a0f8, 0x05000501},
558 {0x0000a0fc, 0x051e051f},
559 {0x0000a100, 0x06010602},
560 {0x0000a104, 0x061f0600},
561 {0x0000a108, 0x061d061e},
562 {0x0000a10c, 0x07020703},
563 {0x0000a110, 0x07000701},
564 {0x0000a114, 0x00000000},
565 {0x0000a118, 0x00000000},
566 {0x0000a11c, 0x00000000},
567 {0x0000a120, 0x00000000},
568 {0x0000a124, 0x00000000},
569 {0x0000a128, 0x00000000},
570 {0x0000a12c, 0x00000000},
571 {0x0000a130, 0x00000000},
572 {0x0000a134, 0x00000000},
573 {0x0000a138, 0x00000000},
574 {0x0000a13c, 0x00000000},
575 {0x0000a140, 0x001f0000},
576 {0x0000a144, 0x01000101},
577 {0x0000a148, 0x011e011f},
578 {0x0000a14c, 0x011c011d},
579 {0x0000a150, 0x02030204},
580 {0x0000a154, 0x02010202},
581 {0x0000a158, 0x021f0200},
582 {0x0000a15c, 0x0302021e},
583 {0x0000a160, 0x03000301},
584 {0x0000a164, 0x031e031f},
585 {0x0000a168, 0x0402031d},
586 {0x0000a16c, 0x04000401},
587 {0x0000a170, 0x041e041f},
588 {0x0000a174, 0x0502041d},
589 {0x0000a178, 0x05000501},
590 {0x0000a17c, 0x051e051f},
591 {0x0000a180, 0x06010602},
592 {0x0000a184, 0x061f0600},
593 {0x0000a188, 0x061d061e},
594 {0x0000a18c, 0x07020703},
595 {0x0000a190, 0x07000701},
596 {0x0000a194, 0x00000000},
597 {0x0000a198, 0x00000000},
598 {0x0000a19c, 0x00000000},
599 {0x0000a1a0, 0x00000000},
600 {0x0000a1a4, 0x00000000},
601 {0x0000a1a8, 0x00000000},
602 {0x0000a1ac, 0x00000000},
603 {0x0000a1b0, 0x00000000},
604 {0x0000a1b4, 0x00000000},
605 {0x0000a1b8, 0x00000000},
606 {0x0000a1bc, 0x00000000},
607 {0x0000a1c0, 0x00000000},
608 {0x0000a1c4, 0x00000000},
609 {0x0000a1c8, 0x00000000},
610 {0x0000a1cc, 0x00000000},
611 {0x0000a1d0, 0x00000000},
612 {0x0000a1d4, 0x00000000},
613 {0x0000a1d8, 0x00000000},
614 {0x0000a1dc, 0x00000000},
615 {0x0000a1e0, 0x00000000},
616 {0x0000a1e4, 0x00000000},
617 {0x0000a1e8, 0x00000000},
618 {0x0000a1ec, 0x00000000},
619 {0x0000a1f0, 0x00000396},
620 {0x0000a1f4, 0x00000396},
621 {0x0000a1f8, 0x00000396},
622 {0x0000a1fc, 0x00000196},
623 {0x0000b000, 0x00010000},
624 {0x0000b004, 0x00030002},
625 {0x0000b008, 0x00050004},
626 {0x0000b00c, 0x00810080},
627 {0x0000b010, 0x00830082},
628 {0x0000b014, 0x01810180},
629 {0x0000b018, 0x01830182},
630 {0x0000b01c, 0x01850184},
631 {0x0000b020, 0x02810280},
632 {0x0000b024, 0x02830282},
633 {0x0000b028, 0x02850284},
634 {0x0000b02c, 0x02890288},
635 {0x0000b030, 0x028b028a},
636 {0x0000b034, 0x0388028c},
637 {0x0000b038, 0x038a0389},
638 {0x0000b03c, 0x038c038b},
639 {0x0000b040, 0x0390038d},
640 {0x0000b044, 0x03920391},
641 {0x0000b048, 0x03940393},
642 {0x0000b04c, 0x03960395},
643 {0x0000b050, 0x00000000},
644 {0x0000b054, 0x00000000},
645 {0x0000b058, 0x00000000},
646 {0x0000b05c, 0x00000000},
647 {0x0000b060, 0x00000000},
648 {0x0000b064, 0x00000000},
649 {0x0000b068, 0x00000000},
650 {0x0000b06c, 0x00000000},
651 {0x0000b070, 0x00000000},
652 {0x0000b074, 0x00000000},
653 {0x0000b078, 0x00000000},
654 {0x0000b07c, 0x00000000},
655 {0x0000b080, 0x2a2d2f32},
656 {0x0000b084, 0x21232328},
657 {0x0000b088, 0x19191c1e},
658 {0x0000b08c, 0x12141417},
659 {0x0000b090, 0x07070e0e},
660 {0x0000b094, 0x03030305},
661 {0x0000b098, 0x00000003},
662 {0x0000b09c, 0x00000000},
663 {0x0000b0a0, 0x00000000},
664 {0x0000b0a4, 0x00000000},
665 {0x0000b0a8, 0x00000000},
666 {0x0000b0ac, 0x00000000},
667 {0x0000b0b0, 0x00000000},
668 {0x0000b0b4, 0x00000000},
669 {0x0000b0b8, 0x00000000},
670 {0x0000b0bc, 0x00000000},
671 {0x0000b0c0, 0x003f0020},
672 {0x0000b0c4, 0x00400041},
673 {0x0000b0c8, 0x0140005f},
674 {0x0000b0cc, 0x0160015f},
675 {0x0000b0d0, 0x017e017f},
676 {0x0000b0d4, 0x02410242},
677 {0x0000b0d8, 0x025f0240},
678 {0x0000b0dc, 0x027f0260},
679 {0x0000b0e0, 0x0341027e},
680 {0x0000b0e4, 0x035f0340},
681 {0x0000b0e8, 0x037f0360},
682 {0x0000b0ec, 0x04400441},
683 {0x0000b0f0, 0x0460045f},
684 {0x0000b0f4, 0x0541047f},
685 {0x0000b0f8, 0x055f0540},
686 {0x0000b0fc, 0x057f0560},
687 {0x0000b100, 0x06400641},
688 {0x0000b104, 0x0660065f},
689 {0x0000b108, 0x067e067f},
690 {0x0000b10c, 0x07410742},
691 {0x0000b110, 0x075f0740},
692 {0x0000b114, 0x077f0760},
693 {0x0000b118, 0x07800781},
694 {0x0000b11c, 0x07a0079f},
695 {0x0000b120, 0x07c107bf},
696 {0x0000b124, 0x000007c0},
697 {0x0000b128, 0x00000000},
698 {0x0000b12c, 0x00000000},
699 {0x0000b130, 0x00000000},
700 {0x0000b134, 0x00000000},
701 {0x0000b138, 0x00000000},
702 {0x0000b13c, 0x00000000},
703 {0x0000b140, 0x003f0020},
704 {0x0000b144, 0x00400041},
705 {0x0000b148, 0x0140005f},
706 {0x0000b14c, 0x0160015f},
707 {0x0000b150, 0x017e017f},
708 {0x0000b154, 0x02410242},
709 {0x0000b158, 0x025f0240},
710 {0x0000b15c, 0x027f0260},
711 {0x0000b160, 0x0341027e},
712 {0x0000b164, 0x035f0340},
713 {0x0000b168, 0x037f0360},
714 {0x0000b16c, 0x04400441},
715 {0x0000b170, 0x0460045f},
716 {0x0000b174, 0x0541047f},
717 {0x0000b178, 0x055f0540},
718 {0x0000b17c, 0x057f0560},
719 {0x0000b180, 0x06400641},
720 {0x0000b184, 0x0660065f},
721 {0x0000b188, 0x067e067f},
722 {0x0000b18c, 0x07410742},
723 {0x0000b190, 0x075f0740},
724 {0x0000b194, 0x077f0760},
725 {0x0000b198, 0x07800781},
726 {0x0000b19c, 0x07a0079f},
727 {0x0000b1a0, 0x07c107bf},
728 {0x0000b1a4, 0x000007c0},
729 {0x0000b1a8, 0x00000000},
730 {0x0000b1ac, 0x00000000},
731 {0x0000b1b0, 0x00000000},
732 {0x0000b1b4, 0x00000000},
733 {0x0000b1b8, 0x00000000},
734 {0x0000b1bc, 0x00000000},
735 {0x0000b1c0, 0x00000000},
736 {0x0000b1c4, 0x00000000},
737 {0x0000b1c8, 0x00000000},
738 {0x0000b1cc, 0x00000000},
739 {0x0000b1d0, 0x00000000},
740 {0x0000b1d4, 0x00000000},
741 {0x0000b1d8, 0x00000000},
742 {0x0000b1dc, 0x00000000},
743 {0x0000b1e0, 0x00000000},
744 {0x0000b1e4, 0x00000000},
745 {0x0000b1e8, 0x00000000},
746 {0x0000b1ec, 0x00000000},
747 {0x0000b1f0, 0x00000396},
748 {0x0000b1f4, 0x00000396},
749 {0x0000b1f8, 0x00000396},
750 {0x0000b1fc, 0x00000196},
751};
752
753static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
754 /* Addr allmodes */
755 {0x0000a000, 0x00010000},
756 {0x0000a004, 0x00030002},
757 {0x0000a008, 0x00050004},
758 {0x0000a00c, 0x00810080},
759 {0x0000a010, 0x00830082},
760 {0x0000a014, 0x01810180},
761 {0x0000a018, 0x01830182},
762 {0x0000a01c, 0x01850184},
763 {0x0000a020, 0x01890188},
764 {0x0000a024, 0x018b018a},
765 {0x0000a028, 0x018d018c},
766 {0x0000a02c, 0x03820190},
767 {0x0000a030, 0x03840383},
768 {0x0000a034, 0x03880385},
769 {0x0000a038, 0x038a0389},
770 {0x0000a03c, 0x038c038b},
771 {0x0000a040, 0x0390038d},
772 {0x0000a044, 0x03920391},
773 {0x0000a048, 0x03940393},
774 {0x0000a04c, 0x03960395},
775 {0x0000a050, 0x00000000},
776 {0x0000a054, 0x00000000},
777 {0x0000a058, 0x00000000},
778 {0x0000a05c, 0x00000000},
779 {0x0000a060, 0x00000000},
780 {0x0000a064, 0x00000000},
781 {0x0000a068, 0x00000000},
782 {0x0000a06c, 0x00000000},
783 {0x0000a070, 0x00000000},
784 {0x0000a074, 0x00000000},
785 {0x0000a078, 0x00000000},
786 {0x0000a07c, 0x00000000},
787 {0x0000a080, 0x29292929},
788 {0x0000a084, 0x29292929},
789 {0x0000a088, 0x29292929},
790 {0x0000a08c, 0x29292929},
791 {0x0000a090, 0x22292929},
792 {0x0000a094, 0x1d1d2222},
793 {0x0000a098, 0x0c111117},
794 {0x0000a09c, 0x00030303},
795 {0x0000a0a0, 0x00000000},
796 {0x0000a0a4, 0x00000000},
797 {0x0000a0a8, 0x00000000},
798 {0x0000a0ac, 0x00000000},
799 {0x0000a0b0, 0x00000000},
800 {0x0000a0b4, 0x00000000},
801 {0x0000a0b8, 0x00000000},
802 {0x0000a0bc, 0x00000000},
803 {0x0000a0c0, 0x001f0000},
804 {0x0000a0c4, 0x01000101},
805 {0x0000a0c8, 0x011e011f},
806 {0x0000a0cc, 0x011c011d},
807 {0x0000a0d0, 0x02030204},
808 {0x0000a0d4, 0x02010202},
809 {0x0000a0d8, 0x021f0200},
810 {0x0000a0dc, 0x0302021e},
811 {0x0000a0e0, 0x03000301},
812 {0x0000a0e4, 0x031e031f},
813 {0x0000a0e8, 0x0402031d},
814 {0x0000a0ec, 0x04000401},
815 {0x0000a0f0, 0x041e041f},
816 {0x0000a0f4, 0x0502041d},
817 {0x0000a0f8, 0x05000501},
818 {0x0000a0fc, 0x051e051f},
819 {0x0000a100, 0x06010602},
820 {0x0000a104, 0x061f0600},
821 {0x0000a108, 0x061d061e},
822 {0x0000a10c, 0x07020703},
823 {0x0000a110, 0x07000701},
824 {0x0000a114, 0x00000000},
825 {0x0000a118, 0x00000000},
826 {0x0000a11c, 0x00000000},
827 {0x0000a120, 0x00000000},
828 {0x0000a124, 0x00000000},
829 {0x0000a128, 0x00000000},
830 {0x0000a12c, 0x00000000},
831 {0x0000a130, 0x00000000},
832 {0x0000a134, 0x00000000},
833 {0x0000a138, 0x00000000},
834 {0x0000a13c, 0x00000000},
835 {0x0000a140, 0x001f0000},
836 {0x0000a144, 0x01000101},
837 {0x0000a148, 0x011e011f},
838 {0x0000a14c, 0x011c011d},
839 {0x0000a150, 0x02030204},
840 {0x0000a154, 0x02010202},
841 {0x0000a158, 0x021f0200},
842 {0x0000a15c, 0x0302021e},
843 {0x0000a160, 0x03000301},
844 {0x0000a164, 0x031e031f},
845 {0x0000a168, 0x0402031d},
846 {0x0000a16c, 0x04000401},
847 {0x0000a170, 0x041e041f},
848 {0x0000a174, 0x0502041d},
849 {0x0000a178, 0x05000501},
850 {0x0000a17c, 0x051e051f},
851 {0x0000a180, 0x06010602},
852 {0x0000a184, 0x061f0600},
853 {0x0000a188, 0x061d061e},
854 {0x0000a18c, 0x07020703},
855 {0x0000a190, 0x07000701},
856 {0x0000a194, 0x00000000},
857 {0x0000a198, 0x00000000},
858 {0x0000a19c, 0x00000000},
859 {0x0000a1a0, 0x00000000},
860 {0x0000a1a4, 0x00000000},
861 {0x0000a1a8, 0x00000000},
862 {0x0000a1ac, 0x00000000},
863 {0x0000a1b0, 0x00000000},
864 {0x0000a1b4, 0x00000000},
865 {0x0000a1b8, 0x00000000},
866 {0x0000a1bc, 0x00000000},
867 {0x0000a1c0, 0x00000000},
868 {0x0000a1c4, 0x00000000},
869 {0x0000a1c8, 0x00000000},
870 {0x0000a1cc, 0x00000000},
871 {0x0000a1d0, 0x00000000},
872 {0x0000a1d4, 0x00000000},
873 {0x0000a1d8, 0x00000000},
874 {0x0000a1dc, 0x00000000},
875 {0x0000a1e0, 0x00000000},
876 {0x0000a1e4, 0x00000000},
877 {0x0000a1e8, 0x00000000},
878 {0x0000a1ec, 0x00000000},
879 {0x0000a1f0, 0x00000396},
880 {0x0000a1f4, 0x00000396},
881 {0x0000a1f8, 0x00000396},
882 {0x0000a1fc, 0x00000196},
883 {0x0000b000, 0x00010000},
884 {0x0000b004, 0x00030002},
885 {0x0000b008, 0x00050004},
886 {0x0000b00c, 0x00810080},
887 {0x0000b010, 0x00830082},
888 {0x0000b014, 0x01810180},
889 {0x0000b018, 0x01830182},
890 {0x0000b01c, 0x01850184},
891 {0x0000b020, 0x02810280},
892 {0x0000b024, 0x02830282},
893 {0x0000b028, 0x02850284},
894 {0x0000b02c, 0x02890288},
895 {0x0000b030, 0x028b028a},
896 {0x0000b034, 0x0388028c},
897 {0x0000b038, 0x038a0389},
898 {0x0000b03c, 0x038c038b},
899 {0x0000b040, 0x0390038d},
900 {0x0000b044, 0x03920391},
901 {0x0000b048, 0x03940393},
902 {0x0000b04c, 0x03960395},
903 {0x0000b050, 0x00000000},
904 {0x0000b054, 0x00000000},
905 {0x0000b058, 0x00000000},
906 {0x0000b05c, 0x00000000},
907 {0x0000b060, 0x00000000},
908 {0x0000b064, 0x00000000},
909 {0x0000b068, 0x00000000},
910 {0x0000b06c, 0x00000000},
911 {0x0000b070, 0x00000000},
912 {0x0000b074, 0x00000000},
913 {0x0000b078, 0x00000000},
914 {0x0000b07c, 0x00000000},
915 {0x0000b080, 0x2a2d2f32},
916 {0x0000b084, 0x21232328},
917 {0x0000b088, 0x19191c1e},
918 {0x0000b08c, 0x12141417},
919 {0x0000b090, 0x07070e0e},
920 {0x0000b094, 0x03030305},
921 {0x0000b098, 0x00000003},
922 {0x0000b09c, 0x00000000},
923 {0x0000b0a0, 0x00000000},
924 {0x0000b0a4, 0x00000000},
925 {0x0000b0a8, 0x00000000},
926 {0x0000b0ac, 0x00000000},
927 {0x0000b0b0, 0x00000000},
928 {0x0000b0b4, 0x00000000},
929 {0x0000b0b8, 0x00000000},
930 {0x0000b0bc, 0x00000000},
931 {0x0000b0c0, 0x003f0020},
932 {0x0000b0c4, 0x00400041},
933 {0x0000b0c8, 0x0140005f},
934 {0x0000b0cc, 0x0160015f},
935 {0x0000b0d0, 0x017e017f},
936 {0x0000b0d4, 0x02410242},
937 {0x0000b0d8, 0x025f0240},
938 {0x0000b0dc, 0x027f0260},
939 {0x0000b0e0, 0x0341027e},
940 {0x0000b0e4, 0x035f0340},
941 {0x0000b0e8, 0x037f0360},
942 {0x0000b0ec, 0x04400441},
943 {0x0000b0f0, 0x0460045f},
944 {0x0000b0f4, 0x0541047f},
945 {0x0000b0f8, 0x055f0540},
946 {0x0000b0fc, 0x057f0560},
947 {0x0000b100, 0x06400641},
948 {0x0000b104, 0x0660065f},
949 {0x0000b108, 0x067e067f},
950 {0x0000b10c, 0x07410742},
951 {0x0000b110, 0x075f0740},
952 {0x0000b114, 0x077f0760},
953 {0x0000b118, 0x07800781},
954 {0x0000b11c, 0x07a0079f},
955 {0x0000b120, 0x07c107bf},
956 {0x0000b124, 0x000007c0},
957 {0x0000b128, 0x00000000},
958 {0x0000b12c, 0x00000000},
959 {0x0000b130, 0x00000000},
960 {0x0000b134, 0x00000000},
961 {0x0000b138, 0x00000000},
962 {0x0000b13c, 0x00000000},
963 {0x0000b140, 0x003f0020},
964 {0x0000b144, 0x00400041},
965 {0x0000b148, 0x0140005f},
966 {0x0000b14c, 0x0160015f},
967 {0x0000b150, 0x017e017f},
968 {0x0000b154, 0x02410242},
969 {0x0000b158, 0x025f0240},
970 {0x0000b15c, 0x027f0260},
971 {0x0000b160, 0x0341027e},
972 {0x0000b164, 0x035f0340},
973 {0x0000b168, 0x037f0360},
974 {0x0000b16c, 0x04400441},
975 {0x0000b170, 0x0460045f},
976 {0x0000b174, 0x0541047f},
977 {0x0000b178, 0x055f0540},
978 {0x0000b17c, 0x057f0560},
979 {0x0000b180, 0x06400641},
980 {0x0000b184, 0x0660065f},
981 {0x0000b188, 0x067e067f},
982 {0x0000b18c, 0x07410742},
983 {0x0000b190, 0x075f0740},
984 {0x0000b194, 0x077f0760},
985 {0x0000b198, 0x07800781},
986 {0x0000b19c, 0x07a0079f},
987 {0x0000b1a0, 0x07c107bf},
988 {0x0000b1a4, 0x000007c0},
989 {0x0000b1a8, 0x00000000},
990 {0x0000b1ac, 0x00000000},
991 {0x0000b1b0, 0x00000000},
992 {0x0000b1b4, 0x00000000},
993 {0x0000b1b8, 0x00000000},
994 {0x0000b1bc, 0x00000000},
995 {0x0000b1c0, 0x00000000},
996 {0x0000b1c4, 0x00000000},
997 {0x0000b1c8, 0x00000000},
998 {0x0000b1cc, 0x00000000},
999 {0x0000b1d0, 0x00000000},
1000 {0x0000b1d4, 0x00000000},
1001 {0x0000b1d8, 0x00000000},
1002 {0x0000b1dc, 0x00000000},
1003 {0x0000b1e0, 0x00000000},
1004 {0x0000b1e4, 0x00000000},
1005 {0x0000b1e8, 0x00000000},
1006 {0x0000b1ec, 0x00000000},
1007 {0x0000b1f0, 0x00000396},
1008 {0x0000b1f4, 0x00000396},
1009 {0x0000b1f8, 0x00000396},
1010 {0x0000b1fc, 0x00000196},
1011};
1012
1013static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
1014 /* Addr allmodes */
1015 {0x00009fd0, 0x0a2d6b93},
1016};
1017
1018static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
1019 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1020 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
1021 {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
1022 {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
1023 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
1024 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
1025 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
1026};
1027
1028static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
1029 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1030 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1031};
1032
1033static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
1034 /* Addr allmodes */
1035 {0x0000a000, 0x00010000},
1036 {0x0000a004, 0x00030002},
1037 {0x0000a008, 0x00050004},
1038 {0x0000a00c, 0x00810080},
1039 {0x0000a010, 0x00830082},
1040 {0x0000a014, 0x01810180},
1041 {0x0000a018, 0x01830182},
1042 {0x0000a01c, 0x01850184},
1043 {0x0000a020, 0x01890188},
1044 {0x0000a024, 0x018b018a},
1045 {0x0000a028, 0x018d018c},
1046 {0x0000a02c, 0x03820190},
1047 {0x0000a030, 0x03840383},
1048 {0x0000a034, 0x03880385},
1049 {0x0000a038, 0x038a0389},
1050 {0x0000a03c, 0x038c038b},
1051 {0x0000a040, 0x0390038d},
1052 {0x0000a044, 0x03920391},
1053 {0x0000a048, 0x03940393},
1054 {0x0000a04c, 0x03960395},
1055 {0x0000a050, 0x00000000},
1056 {0x0000a054, 0x00000000},
1057 {0x0000a058, 0x00000000},
1058 {0x0000a05c, 0x00000000},
1059 {0x0000a060, 0x00000000},
1060 {0x0000a064, 0x00000000},
1061 {0x0000a068, 0x00000000},
1062 {0x0000a06c, 0x00000000},
1063 {0x0000a070, 0x00000000},
1064 {0x0000a074, 0x00000000},
1065 {0x0000a078, 0x00000000},
1066 {0x0000a07c, 0x00000000},
1067 {0x0000a080, 0x29292929},
1068 {0x0000a084, 0x29292929},
1069 {0x0000a088, 0x29292929},
1070 {0x0000a08c, 0x29292929},
1071 {0x0000a090, 0x22292929},
1072 {0x0000a094, 0x1d1d2222},
1073 {0x0000a098, 0x0c111117},
1074 {0x0000a09c, 0x00030303},
1075 {0x0000a0a0, 0x00000000},
1076 {0x0000a0a4, 0x00000000},
1077 {0x0000a0a8, 0x00000000},
1078 {0x0000a0ac, 0x00000000},
1079 {0x0000a0b0, 0x00000000},
1080 {0x0000a0b4, 0x00000000},
1081 {0x0000a0b8, 0x00000000},
1082 {0x0000a0bc, 0x00000000},
1083 {0x0000a0c0, 0x001f0000},
1084 {0x0000a0c4, 0x01000101},
1085 {0x0000a0c8, 0x011e011f},
1086 {0x0000a0cc, 0x011c011d},
1087 {0x0000a0d0, 0x02030204},
1088 {0x0000a0d4, 0x02010202},
1089 {0x0000a0d8, 0x021f0200},
1090 {0x0000a0dc, 0x0302021e},
1091 {0x0000a0e0, 0x03000301},
1092 {0x0000a0e4, 0x031e031f},
1093 {0x0000a0e8, 0x0402031d},
1094 {0x0000a0ec, 0x04000401},
1095 {0x0000a0f0, 0x041e041f},
1096 {0x0000a0f4, 0x0502041d},
1097 {0x0000a0f8, 0x05000501},
1098 {0x0000a0fc, 0x051e051f},
1099 {0x0000a100, 0x06010602},
1100 {0x0000a104, 0x061f0600},
1101 {0x0000a108, 0x061d061e},
1102 {0x0000a10c, 0x07020703},
1103 {0x0000a110, 0x07000701},
1104 {0x0000a114, 0x00000000},
1105 {0x0000a118, 0x00000000},
1106 {0x0000a11c, 0x00000000},
1107 {0x0000a120, 0x00000000},
1108 {0x0000a124, 0x00000000},
1109 {0x0000a128, 0x00000000},
1110 {0x0000a12c, 0x00000000},
1111 {0x0000a130, 0x00000000},
1112 {0x0000a134, 0x00000000},
1113 {0x0000a138, 0x00000000},
1114 {0x0000a13c, 0x00000000},
1115 {0x0000a140, 0x001f0000},
1116 {0x0000a144, 0x01000101},
1117 {0x0000a148, 0x011e011f},
1118 {0x0000a14c, 0x011c011d},
1119 {0x0000a150, 0x02030204},
1120 {0x0000a154, 0x02010202},
1121 {0x0000a158, 0x021f0200},
1122 {0x0000a15c, 0x0302021e},
1123 {0x0000a160, 0x03000301},
1124 {0x0000a164, 0x031e031f},
1125 {0x0000a168, 0x0402031d},
1126 {0x0000a16c, 0x04000401},
1127 {0x0000a170, 0x041e041f},
1128 {0x0000a174, 0x0502041d},
1129 {0x0000a178, 0x05000501},
1130 {0x0000a17c, 0x051e051f},
1131 {0x0000a180, 0x06010602},
1132 {0x0000a184, 0x061f0600},
1133 {0x0000a188, 0x061d061e},
1134 {0x0000a18c, 0x07020703},
1135 {0x0000a190, 0x07000701},
1136 {0x0000a194, 0x00000000},
1137 {0x0000a198, 0x00000000},
1138 {0x0000a19c, 0x00000000},
1139 {0x0000a1a0, 0x00000000},
1140 {0x0000a1a4, 0x00000000},
1141 {0x0000a1a8, 0x00000000},
1142 {0x0000a1ac, 0x00000000},
1143 {0x0000a1b0, 0x00000000},
1144 {0x0000a1b4, 0x00000000},
1145 {0x0000a1b8, 0x00000000},
1146 {0x0000a1bc, 0x00000000},
1147 {0x0000a1c0, 0x00000000},
1148 {0x0000a1c4, 0x00000000},
1149 {0x0000a1c8, 0x00000000},
1150 {0x0000a1cc, 0x00000000},
1151 {0x0000a1d0, 0x00000000},
1152 {0x0000a1d4, 0x00000000},
1153 {0x0000a1d8, 0x00000000},
1154 {0x0000a1dc, 0x00000000},
1155 {0x0000a1e0, 0x00000000},
1156 {0x0000a1e4, 0x00000000},
1157 {0x0000a1e8, 0x00000000},
1158 {0x0000a1ec, 0x00000000},
1159 {0x0000a1f0, 0x00000396},
1160 {0x0000a1f4, 0x00000396},
1161 {0x0000a1f8, 0x00000396},
1162 {0x0000a1fc, 0x00000196},
1163 {0x0000b000, 0x00010000},
1164 {0x0000b004, 0x00030002},
1165 {0x0000b008, 0x00050004},
1166 {0x0000b00c, 0x00810080},
1167 {0x0000b010, 0x00830082},
1168 {0x0000b014, 0x01810180},
1169 {0x0000b018, 0x01830182},
1170 {0x0000b01c, 0x01850184},
1171 {0x0000b020, 0x02810280},
1172 {0x0000b024, 0x02830282},
1173 {0x0000b028, 0x02850284},
1174 {0x0000b02c, 0x02890288},
1175 {0x0000b030, 0x028b028a},
1176 {0x0000b034, 0x0388028c},
1177 {0x0000b038, 0x038a0389},
1178 {0x0000b03c, 0x038c038b},
1179 {0x0000b040, 0x0390038d},
1180 {0x0000b044, 0x03920391},
1181 {0x0000b048, 0x03940393},
1182 {0x0000b04c, 0x03960395},
1183 {0x0000b050, 0x00000000},
1184 {0x0000b054, 0x00000000},
1185 {0x0000b058, 0x00000000},
1186 {0x0000b05c, 0x00000000},
1187 {0x0000b060, 0x00000000},
1188 {0x0000b064, 0x00000000},
1189 {0x0000b068, 0x00000000},
1190 {0x0000b06c, 0x00000000},
1191 {0x0000b070, 0x00000000},
1192 {0x0000b074, 0x00000000},
1193 {0x0000b078, 0x00000000},
1194 {0x0000b07c, 0x00000000},
1195 {0x0000b080, 0x32323232},
1196 {0x0000b084, 0x2f2f3232},
1197 {0x0000b088, 0x23282a2d},
1198 {0x0000b08c, 0x1c1e2123},
1199 {0x0000b090, 0x14171919},
1200 {0x0000b094, 0x0e0e1214},
1201 {0x0000b098, 0x03050707},
1202 {0x0000b09c, 0x00030303},
1203 {0x0000b0a0, 0x00000000},
1204 {0x0000b0a4, 0x00000000},
1205 {0x0000b0a8, 0x00000000},
1206 {0x0000b0ac, 0x00000000},
1207 {0x0000b0b0, 0x00000000},
1208 {0x0000b0b4, 0x00000000},
1209 {0x0000b0b8, 0x00000000},
1210 {0x0000b0bc, 0x00000000},
1211 {0x0000b0c0, 0x003f0020},
1212 {0x0000b0c4, 0x00400041},
1213 {0x0000b0c8, 0x0140005f},
1214 {0x0000b0cc, 0x0160015f},
1215 {0x0000b0d0, 0x017e017f},
1216 {0x0000b0d4, 0x02410242},
1217 {0x0000b0d8, 0x025f0240},
1218 {0x0000b0dc, 0x027f0260},
1219 {0x0000b0e0, 0x0341027e},
1220 {0x0000b0e4, 0x035f0340},
1221 {0x0000b0e8, 0x037f0360},
1222 {0x0000b0ec, 0x04400441},
1223 {0x0000b0f0, 0x0460045f},
1224 {0x0000b0f4, 0x0541047f},
1225 {0x0000b0f8, 0x055f0540},
1226 {0x0000b0fc, 0x057f0560},
1227 {0x0000b100, 0x06400641},
1228 {0x0000b104, 0x0660065f},
1229 {0x0000b108, 0x067e067f},
1230 {0x0000b10c, 0x07410742},
1231 {0x0000b110, 0x075f0740},
1232 {0x0000b114, 0x077f0760},
1233 {0x0000b118, 0x07800781},
1234 {0x0000b11c, 0x07a0079f},
1235 {0x0000b120, 0x07c107bf},
1236 {0x0000b124, 0x000007c0},
1237 {0x0000b128, 0x00000000},
1238 {0x0000b12c, 0x00000000},
1239 {0x0000b130, 0x00000000},
1240 {0x0000b134, 0x00000000},
1241 {0x0000b138, 0x00000000},
1242 {0x0000b13c, 0x00000000},
1243 {0x0000b140, 0x003f0020},
1244 {0x0000b144, 0x00400041},
1245 {0x0000b148, 0x0140005f},
1246 {0x0000b14c, 0x0160015f},
1247 {0x0000b150, 0x017e017f},
1248 {0x0000b154, 0x02410242},
1249 {0x0000b158, 0x025f0240},
1250 {0x0000b15c, 0x027f0260},
1251 {0x0000b160, 0x0341027e},
1252 {0x0000b164, 0x035f0340},
1253 {0x0000b168, 0x037f0360},
1254 {0x0000b16c, 0x04400441},
1255 {0x0000b170, 0x0460045f},
1256 {0x0000b174, 0x0541047f},
1257 {0x0000b178, 0x055f0540},
1258 {0x0000b17c, 0x057f0560},
1259 {0x0000b180, 0x06400641},
1260 {0x0000b184, 0x0660065f},
1261 {0x0000b188, 0x067e067f},
1262 {0x0000b18c, 0x07410742},
1263 {0x0000b190, 0x075f0740},
1264 {0x0000b194, 0x077f0760},
1265 {0x0000b198, 0x07800781},
1266 {0x0000b19c, 0x07a0079f},
1267 {0x0000b1a0, 0x07c107bf},
1268 {0x0000b1a4, 0x000007c0},
1269 {0x0000b1a8, 0x00000000},
1270 {0x0000b1ac, 0x00000000},
1271 {0x0000b1b0, 0x00000000},
1272 {0x0000b1b4, 0x00000000},
1273 {0x0000b1b8, 0x00000000},
1274 {0x0000b1bc, 0x00000000},
1275 {0x0000b1c0, 0x00000000},
1276 {0x0000b1c4, 0x00000000},
1277 {0x0000b1c8, 0x00000000},
1278 {0x0000b1cc, 0x00000000},
1279 {0x0000b1d0, 0x00000000},
1280 {0x0000b1d4, 0x00000000},
1281 {0x0000b1d8, 0x00000000},
1282 {0x0000b1dc, 0x00000000},
1283 {0x0000b1e0, 0x00000000},
1284 {0x0000b1e4, 0x00000000},
1285 {0x0000b1e8, 0x00000000},
1286 {0x0000b1ec, 0x00000000},
1287 {0x0000b1f0, 0x00000396},
1288 {0x0000b1f4, 0x00000396},
1289 {0x0000b1f8, 0x00000396},
1290 {0x0000b1fc, 0x00000196},
1291};
1292
1293static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
1294 /* Addr allmodes */
1295 {0x0000a000, 0x00010000},
1296 {0x0000a004, 0x00030002},
1297 {0x0000a008, 0x00050004},
1298 {0x0000a00c, 0x00810080},
1299 {0x0000a010, 0x00830082},
1300 {0x0000a014, 0x01810180},
1301 {0x0000a018, 0x01830182},
1302 {0x0000a01c, 0x01850184},
1303 {0x0000a020, 0x01890188},
1304 {0x0000a024, 0x018b018a},
1305 {0x0000a028, 0x018d018c},
1306 {0x0000a02c, 0x03820190},
1307 {0x0000a030, 0x03840383},
1308 {0x0000a034, 0x03880385},
1309 {0x0000a038, 0x038a0389},
1310 {0x0000a03c, 0x038c038b},
1311 {0x0000a040, 0x0390038d},
1312 {0x0000a044, 0x03920391},
1313 {0x0000a048, 0x03940393},
1314 {0x0000a04c, 0x03960395},
1315 {0x0000a050, 0x00000000},
1316 {0x0000a054, 0x00000000},
1317 {0x0000a058, 0x00000000},
1318 {0x0000a05c, 0x00000000},
1319 {0x0000a060, 0x00000000},
1320 {0x0000a064, 0x00000000},
1321 {0x0000a068, 0x00000000},
1322 {0x0000a06c, 0x00000000},
1323 {0x0000a070, 0x00000000},
1324 {0x0000a074, 0x00000000},
1325 {0x0000a078, 0x00000000},
1326 {0x0000a07c, 0x00000000},
1327 {0x0000a080, 0x29292929},
1328 {0x0000a084, 0x29292929},
1329 {0x0000a088, 0x29292929},
1330 {0x0000a08c, 0x29292929},
1331 {0x0000a090, 0x22292929},
1332 {0x0000a094, 0x1d1d2222},
1333 {0x0000a098, 0x0c111117},
1334 {0x0000a09c, 0x00030303},
1335 {0x0000a0a0, 0x00000000},
1336 {0x0000a0a4, 0x00000000},
1337 {0x0000a0a8, 0x00000000},
1338 {0x0000a0ac, 0x00000000},
1339 {0x0000a0b0, 0x00000000},
1340 {0x0000a0b4, 0x00000000},
1341 {0x0000a0b8, 0x00000000},
1342 {0x0000a0bc, 0x00000000},
1343 {0x0000a0c0, 0x001f0000},
1344 {0x0000a0c4, 0x01000101},
1345 {0x0000a0c8, 0x011e011f},
1346 {0x0000a0cc, 0x011c011d},
1347 {0x0000a0d0, 0x02030204},
1348 {0x0000a0d4, 0x02010202},
1349 {0x0000a0d8, 0x021f0200},
1350 {0x0000a0dc, 0x0302021e},
1351 {0x0000a0e0, 0x03000301},
1352 {0x0000a0e4, 0x031e031f},
1353 {0x0000a0e8, 0x0402031d},
1354 {0x0000a0ec, 0x04000401},
1355 {0x0000a0f0, 0x041e041f},
1356 {0x0000a0f4, 0x0502041d},
1357 {0x0000a0f8, 0x05000501},
1358 {0x0000a0fc, 0x051e051f},
1359 {0x0000a100, 0x06010602},
1360 {0x0000a104, 0x061f0600},
1361 {0x0000a108, 0x061d061e},
1362 {0x0000a10c, 0x07020703},
1363 {0x0000a110, 0x07000701},
1364 {0x0000a114, 0x00000000},
1365 {0x0000a118, 0x00000000},
1366 {0x0000a11c, 0x00000000},
1367 {0x0000a120, 0x00000000},
1368 {0x0000a124, 0x00000000},
1369 {0x0000a128, 0x00000000},
1370 {0x0000a12c, 0x00000000},
1371 {0x0000a130, 0x00000000},
1372 {0x0000a134, 0x00000000},
1373 {0x0000a138, 0x00000000},
1374 {0x0000a13c, 0x00000000},
1375 {0x0000a140, 0x001f0000},
1376 {0x0000a144, 0x01000101},
1377 {0x0000a148, 0x011e011f},
1378 {0x0000a14c, 0x011c011d},
1379 {0x0000a150, 0x02030204},
1380 {0x0000a154, 0x02010202},
1381 {0x0000a158, 0x021f0200},
1382 {0x0000a15c, 0x0302021e},
1383 {0x0000a160, 0x03000301},
1384 {0x0000a164, 0x031e031f},
1385 {0x0000a168, 0x0402031d},
1386 {0x0000a16c, 0x04000401},
1387 {0x0000a170, 0x041e041f},
1388 {0x0000a174, 0x0502041d},
1389 {0x0000a178, 0x05000501},
1390 {0x0000a17c, 0x051e051f},
1391 {0x0000a180, 0x06010602},
1392 {0x0000a184, 0x061f0600},
1393 {0x0000a188, 0x061d061e},
1394 {0x0000a18c, 0x07020703},
1395 {0x0000a190, 0x07000701},
1396 {0x0000a194, 0x00000000},
1397 {0x0000a198, 0x00000000},
1398 {0x0000a19c, 0x00000000},
1399 {0x0000a1a0, 0x00000000},
1400 {0x0000a1a4, 0x00000000},
1401 {0x0000a1a8, 0x00000000},
1402 {0x0000a1ac, 0x00000000},
1403 {0x0000a1b0, 0x00000000},
1404 {0x0000a1b4, 0x00000000},
1405 {0x0000a1b8, 0x00000000},
1406 {0x0000a1bc, 0x00000000},
1407 {0x0000a1c0, 0x00000000},
1408 {0x0000a1c4, 0x00000000},
1409 {0x0000a1c8, 0x00000000},
1410 {0x0000a1cc, 0x00000000},
1411 {0x0000a1d0, 0x00000000},
1412 {0x0000a1d4, 0x00000000},
1413 {0x0000a1d8, 0x00000000},
1414 {0x0000a1dc, 0x00000000},
1415 {0x0000a1e0, 0x00000000},
1416 {0x0000a1e4, 0x00000000},
1417 {0x0000a1e8, 0x00000000},
1418 {0x0000a1ec, 0x00000000},
1419 {0x0000a1f0, 0x00000396},
1420 {0x0000a1f4, 0x00000396},
1421 {0x0000a1f8, 0x00000396},
1422 {0x0000a1fc, 0x00000196},
1423 {0x0000b000, 0x00010000},
1424 {0x0000b004, 0x00030002},
1425 {0x0000b008, 0x00050004},
1426 {0x0000b00c, 0x00810080},
1427 {0x0000b010, 0x00830082},
1428 {0x0000b014, 0x01810180},
1429 {0x0000b018, 0x01830182},
1430 {0x0000b01c, 0x01850184},
1431 {0x0000b020, 0x02810280},
1432 {0x0000b024, 0x02830282},
1433 {0x0000b028, 0x02850284},
1434 {0x0000b02c, 0x02890288},
1435 {0x0000b030, 0x028b028a},
1436 {0x0000b034, 0x0388028c},
1437 {0x0000b038, 0x038a0389},
1438 {0x0000b03c, 0x038c038b},
1439 {0x0000b040, 0x0390038d},
1440 {0x0000b044, 0x03920391},
1441 {0x0000b048, 0x03940393},
1442 {0x0000b04c, 0x03960395},
1443 {0x0000b050, 0x00000000},
1444 {0x0000b054, 0x00000000},
1445 {0x0000b058, 0x00000000},
1446 {0x0000b05c, 0x00000000},
1447 {0x0000b060, 0x00000000},
1448 {0x0000b064, 0x00000000},
1449 {0x0000b068, 0x00000000},
1450 {0x0000b06c, 0x00000000},
1451 {0x0000b070, 0x00000000},
1452 {0x0000b074, 0x00000000},
1453 {0x0000b078, 0x00000000},
1454 {0x0000b07c, 0x00000000},
1455 {0x0000b080, 0x2a2d2f32},
1456 {0x0000b084, 0x21232328},
1457 {0x0000b088, 0x19191c1e},
1458 {0x0000b08c, 0x12141417},
1459 {0x0000b090, 0x07070e0e},
1460 {0x0000b094, 0x03030305},
1461 {0x0000b098, 0x00000003},
1462 {0x0000b09c, 0x00000000},
1463 {0x0000b0a0, 0x00000000},
1464 {0x0000b0a4, 0x00000000},
1465 {0x0000b0a8, 0x00000000},
1466 {0x0000b0ac, 0x00000000},
1467 {0x0000b0b0, 0x00000000},
1468 {0x0000b0b4, 0x00000000},
1469 {0x0000b0b8, 0x00000000},
1470 {0x0000b0bc, 0x00000000},
1471 {0x0000b0c0, 0x003f0020},
1472 {0x0000b0c4, 0x00400041},
1473 {0x0000b0c8, 0x0140005f},
1474 {0x0000b0cc, 0x0160015f},
1475 {0x0000b0d0, 0x017e017f},
1476 {0x0000b0d4, 0x02410242},
1477 {0x0000b0d8, 0x025f0240},
1478 {0x0000b0dc, 0x027f0260},
1479 {0x0000b0e0, 0x0341027e},
1480 {0x0000b0e4, 0x035f0340},
1481 {0x0000b0e8, 0x037f0360},
1482 {0x0000b0ec, 0x04400441},
1483 {0x0000b0f0, 0x0460045f},
1484 {0x0000b0f4, 0x0541047f},
1485 {0x0000b0f8, 0x055f0540},
1486 {0x0000b0fc, 0x057f0560},
1487 {0x0000b100, 0x06400641},
1488 {0x0000b104, 0x0660065f},
1489 {0x0000b108, 0x067e067f},
1490 {0x0000b10c, 0x07410742},
1491 {0x0000b110, 0x075f0740},
1492 {0x0000b114, 0x077f0760},
1493 {0x0000b118, 0x07800781},
1494 {0x0000b11c, 0x07a0079f},
1495 {0x0000b120, 0x07c107bf},
1496 {0x0000b124, 0x000007c0},
1497 {0x0000b128, 0x00000000},
1498 {0x0000b12c, 0x00000000},
1499 {0x0000b130, 0x00000000},
1500 {0x0000b134, 0x00000000},
1501 {0x0000b138, 0x00000000},
1502 {0x0000b13c, 0x00000000},
1503 {0x0000b140, 0x003f0020},
1504 {0x0000b144, 0x00400041},
1505 {0x0000b148, 0x0140005f},
1506 {0x0000b14c, 0x0160015f},
1507 {0x0000b150, 0x017e017f},
1508 {0x0000b154, 0x02410242},
1509 {0x0000b158, 0x025f0240},
1510 {0x0000b15c, 0x027f0260},
1511 {0x0000b160, 0x0341027e},
1512 {0x0000b164, 0x035f0340},
1513 {0x0000b168, 0x037f0360},
1514 {0x0000b16c, 0x04400441},
1515 {0x0000b170, 0x0460045f},
1516 {0x0000b174, 0x0541047f},
1517 {0x0000b178, 0x055f0540},
1518 {0x0000b17c, 0x057f0560},
1519 {0x0000b180, 0x06400641},
1520 {0x0000b184, 0x0660065f},
1521 {0x0000b188, 0x067e067f},
1522 {0x0000b18c, 0x07410742},
1523 {0x0000b190, 0x075f0740},
1524 {0x0000b194, 0x077f0760},
1525 {0x0000b198, 0x07800781},
1526 {0x0000b19c, 0x07a0079f},
1527 {0x0000b1a0, 0x07c107bf},
1528 {0x0000b1a4, 0x000007c0},
1529 {0x0000b1a8, 0x00000000},
1530 {0x0000b1ac, 0x00000000},
1531 {0x0000b1b0, 0x00000000},
1532 {0x0000b1b4, 0x00000000},
1533 {0x0000b1b8, 0x00000000},
1534 {0x0000b1bc, 0x00000000},
1535 {0x0000b1c0, 0x00000000},
1536 {0x0000b1c4, 0x00000000},
1537 {0x0000b1c8, 0x00000000},
1538 {0x0000b1cc, 0x00000000},
1539 {0x0000b1d0, 0x00000000},
1540 {0x0000b1d4, 0x00000000},
1541 {0x0000b1d8, 0x00000000},
1542 {0x0000b1dc, 0x00000000},
1543 {0x0000b1e0, 0x00000000},
1544 {0x0000b1e4, 0x00000000},
1545 {0x0000b1e8, 0x00000000},
1546 {0x0000b1ec, 0x00000000},
1547 {0x0000b1f0, 0x00000396},
1548 {0x0000b1f4, 0x00000396},
1549 {0x0000b1f8, 0x00000396},
1550 {0x0000b1fc, 0x00000196},
1551};
1552
1553static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1555 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1556 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1557 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1558 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1559 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1560 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1561 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1562 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1563 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1564 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1565 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1566 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1567 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1568 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1569 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1570 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1571 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1572 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1573 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1574 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1575 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1576 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1577 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1578 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1579 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1580 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1581 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1582 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1583 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1584 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1585 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1586 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1587 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1588 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1589 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1590 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1591 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1592 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1593 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1594 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1595 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1596 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1597 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1598 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1599 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1600 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1601 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1602 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1603 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1604 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1605 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1606 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1607 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1608 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1609 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1610 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1611 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1612 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1613 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1614 {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1615 {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
1616 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1617 {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1618 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
1619 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1620};
1621
1622static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
1623 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1624 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1625 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1626 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1627 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1628 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1629 {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
1630 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1631 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1632 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1633 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1634 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1635 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1636 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
1637 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
1638 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1639 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
1640 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
1641 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
1642 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
1643 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
1644 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
1645 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
1646 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
1647 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1648 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1649 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
1650 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
1651 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
1652 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1653 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1654 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
1655 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
1656 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
1657 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
1658 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
1659 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1660 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1661 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1662 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1663 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1664 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1665 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1666 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1667 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1668 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1669 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1670 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1671 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1672 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1673 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1674 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1675 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1676 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1677 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1678 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1679 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1680 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1681 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1682 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1683 {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1684 {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
1685 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1686 {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1687 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
1688 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1689};
1690
1691static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
1692 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1693 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1694 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1695 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1696 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1697 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1698 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
1699 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1700 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1701 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1702 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1703 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1704 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1705 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
1706 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
1707 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1708 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
1709 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
1710 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
1711 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
1712 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
1713 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
1714 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
1715 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
1716 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
1717 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
1718 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
1719 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
1720 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
1721 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
1722 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
1723 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
1724 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
1725 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
1726 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
1727 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
1728 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1729 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1730 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1731 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1732 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1733 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1734 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1735 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1736 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1737 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1738 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1739 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1740 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1741 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1742 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1743 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1744 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1745 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1746 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1747 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1748 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1749 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1750 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1751 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1752};
1753
1754static const u32 ar9462_2p1_modes_fast_clock[][3] = {
1755 /* Addr 5G_HT20 5G_HT40 */
1756 {0x00001030, 0x00000268, 0x000004d0},
1757 {0x00001070, 0x0000018c, 0x00000318},
1758 {0x000010b0, 0x00000fd0, 0x00001fa0},
1759 {0x00008014, 0x044c044c, 0x08980898},
1760 {0x0000801c, 0x148ec02b, 0x148ec057},
1761 {0x00008318, 0x000044c0, 0x00008980},
1762 {0x00009e00, 0x0372131c, 0x0372131c},
1763 {0x0000a230, 0x0000400b, 0x00004016},
1764 {0x0000a254, 0x00000898, 0x00001130},
1765};
1766
1767static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
1768 /* Addr allmodes */
1769 {0x0000a398, 0x00000000},
1770 {0x0000a39c, 0x6f7f0301},
1771 {0x0000a3a0, 0xca9228ee},
1772};
1773
1774#endif /* INITVALS_9462_2P1_H */ 291#endif /* INITVALS_9462_2P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
new file mode 100644
index 000000000000..56810539971e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef INITVALS_9565_1P1_H
19#define INITVALS_9565_1P1_H
20
21/* AR9565 1.1 */
22
23#define ar9565_1p1_mac_core ar9565_1p0_mac_core
24
25#define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble
26
27#define ar9565_1p1_baseband_core ar9565_1p0_baseband_core
28
29#define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble
30
31#define ar9565_1p1_radio_core ar9565_1p0_radio_core
32
33#define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble
34
35#define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble
36
37#define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table
38
39#define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table
40
41#define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1
42
43#define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock
44
45#define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table
46
47#define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table
48
49#define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table
50
51#define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table
52
53#define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484
54
55static const u32 ar9565_1p1_radio_postamble[][5] = {
56 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
57 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
58 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
59 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
60 {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000},
61 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
62};
63
64#endif /* INITVALS_9565_1P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
index bdee2ed67219..75bef1179d0d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -20,18 +20,34 @@
20 20
21/* AR9580 1.0 */ 21/* AR9580 1.0 */
22 22
23#define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble
24
25#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
26
27#define ar9580_1p0_radio_core ar9300_2p2_radio_core
28
29#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
30
31#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
32
33#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
34
35#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
36
23#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 37#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2
24 38
39#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9300_2p2_baseband_core_txfir_coeff_japan_2484
40
25static const u32 ar9580_1p0_radio_postamble[][5] = { 41static const u32 ar9580_1p0_radio_postamble[][5] = {
26 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 42 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
27 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, 43 {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
28 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, 44 {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
29 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, 45 {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
30 {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 46 {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
31 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 47 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
32 {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 48 {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
33 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 49 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
34 {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, 50 {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
35 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, 51 {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
36}; 52};
37 53
@@ -44,9 +60,9 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
44 {0x00009814, 0x3280c00a}, 60 {0x00009814, 0x3280c00a},
45 {0x00009818, 0x00000000}, 61 {0x00009818, 0x00000000},
46 {0x0000981c, 0x00020028}, 62 {0x0000981c, 0x00020028},
47 {0x00009834, 0x6400a290}, 63 {0x00009834, 0x6400a190},
48 {0x00009838, 0x0108ecff}, 64 {0x00009838, 0x0108ecff},
49 {0x0000983c, 0x0d000600}, 65 {0x0000983c, 0x14000600},
50 {0x00009880, 0x201fff00}, 66 {0x00009880, 0x201fff00},
51 {0x00009884, 0x00001042}, 67 {0x00009884, 0x00001042},
52 {0x000098a4, 0x00200400}, 68 {0x000098a4, 0x00200400},
@@ -67,7 +83,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
67 {0x00009d04, 0x40206c10}, 83 {0x00009d04, 0x40206c10},
68 {0x00009d08, 0x009c4060}, 84 {0x00009d08, 0x009c4060},
69 {0x00009d0c, 0x9883800a}, 85 {0x00009d0c, 0x9883800a},
70 {0x00009d10, 0x01834061}, 86 {0x00009d10, 0x01884061},
71 {0x00009d14, 0x00c0040b}, 87 {0x00009d14, 0x00c0040b},
72 {0x00009d18, 0x00000000}, 88 {0x00009d18, 0x00000000},
73 {0x00009e08, 0x0038230c}, 89 {0x00009e08, 0x0038230c},
@@ -198,8 +214,6 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
198 {0x0000c420, 0x00000000}, 214 {0x0000c420, 0x00000000},
199}; 215};
200 216
201#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble
202
203static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { 217static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
204 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 218 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
205 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, 219 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
@@ -306,7 +320,112 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = {
306 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 320 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
307}; 321};
308 322
309#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table 323static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = {
324 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
325 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
326 {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
327 {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
328 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
329 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
330 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
331 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
332 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
333 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
334 {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
335 {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
336 {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
337 {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
338 {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
339 {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
340 {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
341 {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
342 {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
343 {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
344 {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
345 {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
346 {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
347 {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
348 {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
349 {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83},
350 {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84},
351 {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
352 {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
353 {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
354 {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
355 {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
356 {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
357 {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
358 {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
359 {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
360 {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
361 {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
362 {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
363 {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
364 {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
365 {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
366 {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
367 {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
368 {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
369 {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
370 {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
371 {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
372 {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
373 {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
374 {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
375 {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
376 {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
377 {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
378 {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
379 {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
380 {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
381 {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
382 {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
383 {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
384 {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
385 {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
386 {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
387 {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
388 {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
389 {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
390 {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
391 {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
392 {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
393 {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
394 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
395 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
396 {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
397 {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
398 {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
399 {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
400 {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
401 {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
402 {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
403 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
404 {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
405 {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
406 {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
407 {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
408 {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
409 {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
410 {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
411 {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
412 {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
413 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
414 {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
415 {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
416 {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
417 {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
418 {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
419 {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
420 {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
421 {0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408},
422 {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
423 {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
424 {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
425 {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
426 {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001},
427 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
428};
310 429
311static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { 430static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
312 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 431 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
@@ -414,8 +533,6 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = {
414 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 533 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
415}; 534};
416 535
417#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484
418
419static const u32 ar9580_1p0_mac_core[][2] = { 536static const u32 ar9580_1p0_mac_core[][2] = {
420 /* Addr allmodes */ 537 /* Addr allmodes */
421 {0x00000008, 0x00000000}, 538 {0x00000008, 0x00000000},
@@ -679,14 +796,6 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = {
679 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 796 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
680}; 797};
681 798
682#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2
683
684#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble
685
686#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2
687
688#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2
689
690static const u32 ar9580_1p0_type6_tx_gain_table[][5] = { 799static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
691 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 800 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
692 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, 801 {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
@@ -761,160 +870,264 @@ static const u32 ar9580_1p0_type6_tx_gain_table[][5] = {
761 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, 870 {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
762}; 871};
763 872
764static const u32 ar9580_1p0_soc_preamble[][2] = { 873static const u32 ar9580_1p0_rx_gain_table[][2] = {
765 /* Addr allmodes */
766 {0x000040a4, 0x00a0c1c9},
767 {0x00007008, 0x00000000},
768 {0x00007020, 0x00000000},
769 {0x00007034, 0x00000002},
770 {0x00007038, 0x000004c2},
771 {0x00007048, 0x00000008},
772};
773
774#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0
775
776static const u32 ar9580_1p0_radio_core[][2] = {
777 /* Addr allmodes */ 874 /* Addr allmodes */
778 {0x00016000, 0x36db6db6}, 875 {0x0000a000, 0x00010000},
779 {0x00016004, 0x6db6db40}, 876 {0x0000a004, 0x00030002},
780 {0x00016008, 0x73f00000}, 877 {0x0000a008, 0x00050004},
781 {0x0001600c, 0x00000000}, 878 {0x0000a00c, 0x00810080},
782 {0x00016040, 0x7f80fff8}, 879 {0x0000a010, 0x00830082},
783 {0x0001604c, 0x76d005b5}, 880 {0x0000a014, 0x01810180},
784 {0x00016050, 0x556cf031}, 881 {0x0000a018, 0x01830182},
785 {0x00016054, 0x13449440}, 882 {0x0000a01c, 0x01850184},
786 {0x00016058, 0x0c51c92c}, 883 {0x0000a020, 0x01890188},
787 {0x0001605c, 0x3db7fffc}, 884 {0x0000a024, 0x018b018a},
788 {0x00016060, 0xfffffffc}, 885 {0x0000a028, 0x018d018c},
789 {0x00016064, 0x000f0278}, 886 {0x0000a02c, 0x01910190},
790 {0x0001606c, 0x6db60000}, 887 {0x0000a030, 0x01930192},
791 {0x00016080, 0x00000000}, 888 {0x0000a034, 0x01950194},
792 {0x00016084, 0x0e48048c}, 889 {0x0000a038, 0x038a0196},
793 {0x00016088, 0x54214514}, 890 {0x0000a03c, 0x038c038b},
794 {0x0001608c, 0x119f481e}, 891 {0x0000a040, 0x0390038d},
795 {0x00016090, 0x24926490}, 892 {0x0000a044, 0x03920391},
796 {0x00016098, 0xd2888888}, 893 {0x0000a048, 0x03940393},
797 {0x000160a0, 0x0a108ffe}, 894 {0x0000a04c, 0x03960395},
798 {0x000160a4, 0x812fc370}, 895 {0x0000a050, 0x00000000},
799 {0x000160a8, 0x423c8000}, 896 {0x0000a054, 0x00000000},
800 {0x000160b4, 0x92480080}, 897 {0x0000a058, 0x00000000},
801 {0x000160c0, 0x00adb6d0}, 898 {0x0000a05c, 0x00000000},
802 {0x000160c4, 0x6db6db60}, 899 {0x0000a060, 0x00000000},
803 {0x000160c8, 0x6db6db6c}, 900 {0x0000a064, 0x00000000},
804 {0x000160cc, 0x01e6c000}, 901 {0x0000a068, 0x00000000},
805 {0x00016100, 0x3fffbe01}, 902 {0x0000a06c, 0x00000000},
806 {0x00016104, 0xfff80000}, 903 {0x0000a070, 0x00000000},
807 {0x00016108, 0x00080010}, 904 {0x0000a074, 0x00000000},
808 {0x00016144, 0x02084080}, 905 {0x0000a078, 0x00000000},
809 {0x00016148, 0x00000000}, 906 {0x0000a07c, 0x00000000},
810 {0x00016280, 0x058a0001}, 907 {0x0000a080, 0x22222229},
811 {0x00016284, 0x3d840208}, 908 {0x0000a084, 0x1d1d1d1d},
812 {0x00016288, 0x05a20408}, 909 {0x0000a088, 0x1d1d1d1d},
813 {0x0001628c, 0x00038c07}, 910 {0x0000a08c, 0x1d1d1d1d},
814 {0x00016290, 0x00000004}, 911 {0x0000a090, 0x171d1d1d},
815 {0x00016294, 0x458aa14f}, 912 {0x0000a094, 0x11111717},
816 {0x00016380, 0x00000000}, 913 {0x0000a098, 0x00030311},
817 {0x00016384, 0x00000000}, 914 {0x0000a09c, 0x00000000},
818 {0x00016388, 0x00800700}, 915 {0x0000a0a0, 0x00000000},
819 {0x0001638c, 0x00800700}, 916 {0x0000a0a4, 0x00000000},
820 {0x00016390, 0x00800700}, 917 {0x0000a0a8, 0x00000000},
821 {0x00016394, 0x00000000}, 918 {0x0000a0ac, 0x00000000},
822 {0x00016398, 0x00000000}, 919 {0x0000a0b0, 0x00000000},
823 {0x0001639c, 0x00000000}, 920 {0x0000a0b4, 0x00000000},
824 {0x000163a0, 0x00000001}, 921 {0x0000a0b8, 0x00000000},
825 {0x000163a4, 0x00000001}, 922 {0x0000a0bc, 0x00000000},
826 {0x000163a8, 0x00000000}, 923 {0x0000a0c0, 0x001f0000},
827 {0x000163ac, 0x00000000}, 924 {0x0000a0c4, 0x01000101},
828 {0x000163b0, 0x00000000}, 925 {0x0000a0c8, 0x011e011f},
829 {0x000163b4, 0x00000000}, 926 {0x0000a0cc, 0x011c011d},
830 {0x000163b8, 0x00000000}, 927 {0x0000a0d0, 0x02030204},
831 {0x000163bc, 0x00000000}, 928 {0x0000a0d4, 0x02010202},
832 {0x000163c0, 0x000000a0}, 929 {0x0000a0d8, 0x021f0200},
833 {0x000163c4, 0x000c0000}, 930 {0x0000a0dc, 0x0302021e},
834 {0x000163c8, 0x14021402}, 931 {0x0000a0e0, 0x03000301},
835 {0x000163cc, 0x00001402}, 932 {0x0000a0e4, 0x031e031f},
836 {0x000163d0, 0x00000000}, 933 {0x0000a0e8, 0x0402031d},
837 {0x000163d4, 0x00000000}, 934 {0x0000a0ec, 0x04000401},
838 {0x00016400, 0x36db6db6}, 935 {0x0000a0f0, 0x041e041f},
839 {0x00016404, 0x6db6db40}, 936 {0x0000a0f4, 0x0502041d},
840 {0x00016408, 0x73f00000}, 937 {0x0000a0f8, 0x05000501},
841 {0x0001640c, 0x00000000}, 938 {0x0000a0fc, 0x051e051f},
842 {0x00016440, 0x7f80fff8}, 939 {0x0000a100, 0x06010602},
843 {0x0001644c, 0x76d005b5}, 940 {0x0000a104, 0x061f0600},
844 {0x00016450, 0x556cf031}, 941 {0x0000a108, 0x061d061e},
845 {0x00016454, 0x13449440}, 942 {0x0000a10c, 0x07020703},
846 {0x00016458, 0x0c51c92c}, 943 {0x0000a110, 0x07000701},
847 {0x0001645c, 0x3db7fffc}, 944 {0x0000a114, 0x00000000},
848 {0x00016460, 0xfffffffc}, 945 {0x0000a118, 0x00000000},
849 {0x00016464, 0x000f0278}, 946 {0x0000a11c, 0x00000000},
850 {0x0001646c, 0x6db60000}, 947 {0x0000a120, 0x00000000},
851 {0x00016500, 0x3fffbe01}, 948 {0x0000a124, 0x00000000},
852 {0x00016504, 0xfff80000}, 949 {0x0000a128, 0x00000000},
853 {0x00016508, 0x00080010}, 950 {0x0000a12c, 0x00000000},
854 {0x00016544, 0x02084080}, 951 {0x0000a130, 0x00000000},
855 {0x00016548, 0x00000000}, 952 {0x0000a134, 0x00000000},
856 {0x00016780, 0x00000000}, 953 {0x0000a138, 0x00000000},
857 {0x00016784, 0x00000000}, 954 {0x0000a13c, 0x00000000},
858 {0x00016788, 0x00800700}, 955 {0x0000a140, 0x001f0000},
859 {0x0001678c, 0x00800700}, 956 {0x0000a144, 0x01000101},
860 {0x00016790, 0x00800700}, 957 {0x0000a148, 0x011e011f},
861 {0x00016794, 0x00000000}, 958 {0x0000a14c, 0x011c011d},
862 {0x00016798, 0x00000000}, 959 {0x0000a150, 0x02030204},
863 {0x0001679c, 0x00000000}, 960 {0x0000a154, 0x02010202},
864 {0x000167a0, 0x00000001}, 961 {0x0000a158, 0x021f0200},
865 {0x000167a4, 0x00000001}, 962 {0x0000a15c, 0x0302021e},
866 {0x000167a8, 0x00000000}, 963 {0x0000a160, 0x03000301},
867 {0x000167ac, 0x00000000}, 964 {0x0000a164, 0x031e031f},
868 {0x000167b0, 0x00000000}, 965 {0x0000a168, 0x0402031d},
869 {0x000167b4, 0x00000000}, 966 {0x0000a16c, 0x04000401},
870 {0x000167b8, 0x00000000}, 967 {0x0000a170, 0x041e041f},
871 {0x000167bc, 0x00000000}, 968 {0x0000a174, 0x0502041d},
872 {0x000167c0, 0x000000a0}, 969 {0x0000a178, 0x05000501},
873 {0x000167c4, 0x000c0000}, 970 {0x0000a17c, 0x051e051f},
874 {0x000167c8, 0x14021402}, 971 {0x0000a180, 0x06010602},
875 {0x000167cc, 0x00001402}, 972 {0x0000a184, 0x061f0600},
876 {0x000167d0, 0x00000000}, 973 {0x0000a188, 0x061d061e},
877 {0x000167d4, 0x00000000}, 974 {0x0000a18c, 0x07020703},
878 {0x00016800, 0x36db6db6}, 975 {0x0000a190, 0x07000701},
879 {0x00016804, 0x6db6db40}, 976 {0x0000a194, 0x00000000},
880 {0x00016808, 0x73f00000}, 977 {0x0000a198, 0x00000000},
881 {0x0001680c, 0x00000000}, 978 {0x0000a19c, 0x00000000},
882 {0x00016840, 0x7f80fff8}, 979 {0x0000a1a0, 0x00000000},
883 {0x0001684c, 0x76d005b5}, 980 {0x0000a1a4, 0x00000000},
884 {0x00016850, 0x556cf031}, 981 {0x0000a1a8, 0x00000000},
885 {0x00016854, 0x13449440}, 982 {0x0000a1ac, 0x00000000},
886 {0x00016858, 0x0c51c92c}, 983 {0x0000a1b0, 0x00000000},
887 {0x0001685c, 0x3db7fffc}, 984 {0x0000a1b4, 0x00000000},
888 {0x00016860, 0xfffffffc}, 985 {0x0000a1b8, 0x00000000},
889 {0x00016864, 0x000f0278}, 986 {0x0000a1bc, 0x00000000},
890 {0x0001686c, 0x6db60000}, 987 {0x0000a1c0, 0x00000000},
891 {0x00016900, 0x3fffbe01}, 988 {0x0000a1c4, 0x00000000},
892 {0x00016904, 0xfff80000}, 989 {0x0000a1c8, 0x00000000},
893 {0x00016908, 0x00080010}, 990 {0x0000a1cc, 0x00000000},
894 {0x00016944, 0x02084080}, 991 {0x0000a1d0, 0x00000000},
895 {0x00016948, 0x00000000}, 992 {0x0000a1d4, 0x00000000},
896 {0x00016b80, 0x00000000}, 993 {0x0000a1d8, 0x00000000},
897 {0x00016b84, 0x00000000}, 994 {0x0000a1dc, 0x00000000},
898 {0x00016b88, 0x00800700}, 995 {0x0000a1e0, 0x00000000},
899 {0x00016b8c, 0x00800700}, 996 {0x0000a1e4, 0x00000000},
900 {0x00016b90, 0x00800700}, 997 {0x0000a1e8, 0x00000000},
901 {0x00016b94, 0x00000000}, 998 {0x0000a1ec, 0x00000000},
902 {0x00016b98, 0x00000000}, 999 {0x0000a1f0, 0x00000396},
903 {0x00016b9c, 0x00000000}, 1000 {0x0000a1f4, 0x00000396},
904 {0x00016ba0, 0x00000001}, 1001 {0x0000a1f8, 0x00000396},
905 {0x00016ba4, 0x00000001}, 1002 {0x0000a1fc, 0x00000196},
906 {0x00016ba8, 0x00000000}, 1003 {0x0000b000, 0x00010000},
907 {0x00016bac, 0x00000000}, 1004 {0x0000b004, 0x00030002},
908 {0x00016bb0, 0x00000000}, 1005 {0x0000b008, 0x00050004},
909 {0x00016bb4, 0x00000000}, 1006 {0x0000b00c, 0x00810080},
910 {0x00016bb8, 0x00000000}, 1007 {0x0000b010, 0x00830082},
911 {0x00016bbc, 0x00000000}, 1008 {0x0000b014, 0x01810180},
912 {0x00016bc0, 0x000000a0}, 1009 {0x0000b018, 0x01830182},
913 {0x00016bc4, 0x000c0000}, 1010 {0x0000b01c, 0x01850184},
914 {0x00016bc8, 0x14021402}, 1011 {0x0000b020, 0x02810280},
915 {0x00016bcc, 0x00001402}, 1012 {0x0000b024, 0x02830282},
916 {0x00016bd0, 0x00000000}, 1013 {0x0000b028, 0x02850284},
917 {0x00016bd4, 0x00000000}, 1014 {0x0000b02c, 0x02890288},
1015 {0x0000b030, 0x028b028a},
1016 {0x0000b034, 0x0388028c},
1017 {0x0000b038, 0x038a0389},
1018 {0x0000b03c, 0x038c038b},
1019 {0x0000b040, 0x0390038d},
1020 {0x0000b044, 0x03920391},
1021 {0x0000b048, 0x03940393},
1022 {0x0000b04c, 0x03960395},
1023 {0x0000b050, 0x00000000},
1024 {0x0000b054, 0x00000000},
1025 {0x0000b058, 0x00000000},
1026 {0x0000b05c, 0x00000000},
1027 {0x0000b060, 0x00000000},
1028 {0x0000b064, 0x00000000},
1029 {0x0000b068, 0x00000000},
1030 {0x0000b06c, 0x00000000},
1031 {0x0000b070, 0x00000000},
1032 {0x0000b074, 0x00000000},
1033 {0x0000b078, 0x00000000},
1034 {0x0000b07c, 0x00000000},
1035 {0x0000b080, 0x23232323},
1036 {0x0000b084, 0x21232323},
1037 {0x0000b088, 0x19191c1e},
1038 {0x0000b08c, 0x12141417},
1039 {0x0000b090, 0x07070e0e},
1040 {0x0000b094, 0x03030305},
1041 {0x0000b098, 0x00000003},
1042 {0x0000b09c, 0x00000000},
1043 {0x0000b0a0, 0x00000000},
1044 {0x0000b0a4, 0x00000000},
1045 {0x0000b0a8, 0x00000000},
1046 {0x0000b0ac, 0x00000000},
1047 {0x0000b0b0, 0x00000000},
1048 {0x0000b0b4, 0x00000000},
1049 {0x0000b0b8, 0x00000000},
1050 {0x0000b0bc, 0x00000000},
1051 {0x0000b0c0, 0x003f0020},
1052 {0x0000b0c4, 0x00400041},
1053 {0x0000b0c8, 0x0140005f},
1054 {0x0000b0cc, 0x0160015f},
1055 {0x0000b0d0, 0x017e017f},
1056 {0x0000b0d4, 0x02410242},
1057 {0x0000b0d8, 0x025f0240},
1058 {0x0000b0dc, 0x027f0260},
1059 {0x0000b0e0, 0x0341027e},
1060 {0x0000b0e4, 0x035f0340},
1061 {0x0000b0e8, 0x037f0360},
1062 {0x0000b0ec, 0x04400441},
1063 {0x0000b0f0, 0x0460045f},
1064 {0x0000b0f4, 0x0541047f},
1065 {0x0000b0f8, 0x055f0540},
1066 {0x0000b0fc, 0x057f0560},
1067 {0x0000b100, 0x06400641},
1068 {0x0000b104, 0x0660065f},
1069 {0x0000b108, 0x067e067f},
1070 {0x0000b10c, 0x07410742},
1071 {0x0000b110, 0x075f0740},
1072 {0x0000b114, 0x077f0760},
1073 {0x0000b118, 0x07800781},
1074 {0x0000b11c, 0x07a0079f},
1075 {0x0000b120, 0x07c107bf},
1076 {0x0000b124, 0x000007c0},
1077 {0x0000b128, 0x00000000},
1078 {0x0000b12c, 0x00000000},
1079 {0x0000b130, 0x00000000},
1080 {0x0000b134, 0x00000000},
1081 {0x0000b138, 0x00000000},
1082 {0x0000b13c, 0x00000000},
1083 {0x0000b140, 0x003f0020},
1084 {0x0000b144, 0x00400041},
1085 {0x0000b148, 0x0140005f},
1086 {0x0000b14c, 0x0160015f},
1087 {0x0000b150, 0x017e017f},
1088 {0x0000b154, 0x02410242},
1089 {0x0000b158, 0x025f0240},
1090 {0x0000b15c, 0x027f0260},
1091 {0x0000b160, 0x0341027e},
1092 {0x0000b164, 0x035f0340},
1093 {0x0000b168, 0x037f0360},
1094 {0x0000b16c, 0x04400441},
1095 {0x0000b170, 0x0460045f},
1096 {0x0000b174, 0x0541047f},
1097 {0x0000b178, 0x055f0540},
1098 {0x0000b17c, 0x057f0560},
1099 {0x0000b180, 0x06400641},
1100 {0x0000b184, 0x0660065f},
1101 {0x0000b188, 0x067e067f},
1102 {0x0000b18c, 0x07410742},
1103 {0x0000b190, 0x075f0740},
1104 {0x0000b194, 0x077f0760},
1105 {0x0000b198, 0x07800781},
1106 {0x0000b19c, 0x07a0079f},
1107 {0x0000b1a0, 0x07c107bf},
1108 {0x0000b1a4, 0x000007c0},
1109 {0x0000b1a8, 0x00000000},
1110 {0x0000b1ac, 0x00000000},
1111 {0x0000b1b0, 0x00000000},
1112 {0x0000b1b4, 0x00000000},
1113 {0x0000b1b8, 0x00000000},
1114 {0x0000b1bc, 0x00000000},
1115 {0x0000b1c0, 0x00000000},
1116 {0x0000b1c4, 0x00000000},
1117 {0x0000b1c8, 0x00000000},
1118 {0x0000b1cc, 0x00000000},
1119 {0x0000b1d0, 0x00000000},
1120 {0x0000b1d4, 0x00000000},
1121 {0x0000b1d8, 0x00000000},
1122 {0x0000b1dc, 0x00000000},
1123 {0x0000b1e0, 0x00000000},
1124 {0x0000b1e4, 0x00000000},
1125 {0x0000b1e8, 0x00000000},
1126 {0x0000b1ec, 0x00000000},
1127 {0x0000b1f0, 0x00000396},
1128 {0x0000b1f4, 0x00000396},
1129 {0x0000b1f8, 0x00000396},
1130 {0x0000b1fc, 0x00000196},
918}; 1131};
919 1132
920static const u32 ar9580_1p0_baseband_postamble[][5] = { 1133static const u32 ar9580_1p0_baseband_postamble[][5] = {
@@ -956,7 +1169,7 @@ static const u32 ar9580_1p0_baseband_postamble[][5] = {
956 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, 1169 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
957 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, 1170 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
958 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, 1171 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
959 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, 1172 {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982},
960 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, 1173 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
961 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, 1174 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
962 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, 1175 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 60a5da53668f..5e5d5cb2458c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -459,6 +459,7 @@ void ath_check_ani(struct ath_softc *sc);
459int ath_update_survey_stats(struct ath_softc *sc); 459int ath_update_survey_stats(struct ath_softc *sc);
460void ath_update_survey_nf(struct ath_softc *sc, int channel); 460void ath_update_survey_nf(struct ath_softc *sc, int channel);
461void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); 461void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type);
462void ath_ps_full_sleep(unsigned long data);
462 463
463/**********/ 464/**********/
464/* BTCOEX */ 465/* BTCOEX */
@@ -570,6 +571,34 @@ static inline void ath_fill_led_pin(struct ath_softc *sc)
570} 571}
571#endif 572#endif
572 573
574/************************/
575/* Wake on Wireless LAN */
576/************************/
577
578#ifdef CONFIG_ATH9K_WOW
579void ath9k_init_wow(struct ieee80211_hw *hw);
580int ath9k_suspend(struct ieee80211_hw *hw,
581 struct cfg80211_wowlan *wowlan);
582int ath9k_resume(struct ieee80211_hw *hw);
583void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled);
584#else
585static inline void ath9k_init_wow(struct ieee80211_hw *hw)
586{
587}
588static inline int ath9k_suspend(struct ieee80211_hw *hw,
589 struct cfg80211_wowlan *wowlan)
590{
591 return 0;
592}
593static inline int ath9k_resume(struct ieee80211_hw *hw)
594{
595 return 0;
596}
597static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
598{
599}
600#endif /* CONFIG_ATH9K_WOW */
601
573/*******************************/ 602/*******************************/
574/* Antenna diversity/combining */ 603/* Antenna diversity/combining */
575/*******************************/ 604/*******************************/
@@ -642,6 +671,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
642#define ATH9K_PCI_AR9565_1ANT 0x0080 671#define ATH9K_PCI_AR9565_1ANT 0x0080
643#define ATH9K_PCI_AR9565_2ANT 0x0100 672#define ATH9K_PCI_AR9565_2ANT 0x0100
644#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 673#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200
674#define ATH9K_PCI_KILLER 0x0400
645 675
646/* 676/*
647 * Default cache line size, in bytes. 677 * Default cache line size, in bytes.
@@ -724,6 +754,7 @@ struct ath_softc {
724 struct work_struct hw_check_work; 754 struct work_struct hw_check_work;
725 struct work_struct hw_reset_work; 755 struct work_struct hw_reset_work;
726 struct completion paprd_complete; 756 struct completion paprd_complete;
757 wait_queue_head_t tx_wait;
727 758
728 unsigned int hw_busy_count; 759 unsigned int hw_busy_count;
729 unsigned long sc_flags; 760 unsigned long sc_flags;
@@ -760,6 +791,7 @@ struct ath_softc {
760 struct delayed_work tx_complete_work; 791 struct delayed_work tx_complete_work;
761 struct delayed_work hw_pll_work; 792 struct delayed_work hw_pll_work;
762 struct timer_list rx_poll_timer; 793 struct timer_list rx_poll_timer;
794 struct timer_list sleep_timer;
763 795
764#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 796#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
765 struct ath_btcoex btcoex; 797 struct ath_btcoex btcoex;
@@ -784,7 +816,7 @@ struct ath_softc {
784 bool tx99_state; 816 bool tx99_state;
785 s16 tx99_power; 817 s16 tx99_power;
786 818
787#ifdef CONFIG_PM_SLEEP 819#ifdef CONFIG_ATH9K_WOW
788 atomic_t wow_got_bmiss_intr; 820 atomic_t wow_got_bmiss_intr;
789 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ 821 atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */
790 u32 wow_intr_before_sleep; 822 u32 wow_intr_before_sleep;
@@ -947,10 +979,25 @@ struct fft_sample_ht20_40 {
947 u8 data[SPECTRAL_HT20_40_NUM_BINS]; 979 u8 data[SPECTRAL_HT20_40_NUM_BINS];
948} __packed; 980} __packed;
949 981
950int ath9k_tx99_init(struct ath_softc *sc); 982/********/
951void ath9k_tx99_deinit(struct ath_softc *sc); 983/* TX99 */
984/********/
985
986#ifdef CONFIG_ATH9K_TX99
987void ath9k_tx99_init_debug(struct ath_softc *sc);
952int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, 988int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
953 struct ath_tx_control *txctl); 989 struct ath_tx_control *txctl);
990#else
991static inline void ath9k_tx99_init_debug(struct ath_softc *sc)
992{
993}
994static inline int ath9k_tx99_send(struct ath_softc *sc,
995 struct sk_buff *skb,
996 struct ath_tx_control *txctl)
997{
998 return 0;
999}
1000#endif /* CONFIG_ATH9K_TX99 */
954 1001
955void ath9k_tasklet(unsigned long data); 1002void ath9k_tasklet(unsigned long data);
956int ath_cabq_update(struct ath_softc *); 1003int ath_cabq_update(struct ath_softc *);
@@ -967,6 +1014,9 @@ extern bool is_ath9k_unloaded;
967 1014
968u8 ath9k_parse_mpdudensity(u8 mpdudensity); 1015u8 ath9k_parse_mpdudensity(u8 mpdudensity);
969irqreturn_t ath_isr(int irq, void *dev); 1016irqreturn_t ath_isr(int irq, void *dev);
1017int ath_reset(struct ath_softc *sc);
1018void ath_cancel_work(struct ath_softc *sc);
1019void ath_restart_work(struct ath_softc *sc);
970int ath9k_init_device(u16 devid, struct ath_softc *sc, 1020int ath9k_init_device(u16 devid, struct ath_softc *sc,
971 const struct ath_bus_ops *bus_ops); 1021 const struct ath_bus_ops *bus_ops);
972void ath9k_deinit_device(struct ath_softc *sc); 1022void ath9k_deinit_device(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 83a2c59f680b..2f7dccfdb727 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1778,111 +1778,6 @@ void ath9k_deinit_debug(struct ath_softc *sc)
1778 } 1778 }
1779} 1779}
1780 1780
1781static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
1782 size_t count, loff_t *ppos)
1783{
1784 struct ath_softc *sc = file->private_data;
1785 char buf[3];
1786 unsigned int len;
1787
1788 len = sprintf(buf, "%d\n", sc->tx99_state);
1789 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1790}
1791
1792static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
1793 size_t count, loff_t *ppos)
1794{
1795 struct ath_softc *sc = file->private_data;
1796 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1797 char buf[32];
1798 bool start;
1799 ssize_t len;
1800 int r;
1801
1802 if (sc->nvifs > 1)
1803 return -EOPNOTSUPP;
1804
1805 len = min(count, sizeof(buf) - 1);
1806 if (copy_from_user(buf, user_buf, len))
1807 return -EFAULT;
1808
1809 if (strtobool(buf, &start))
1810 return -EINVAL;
1811
1812 if (start == sc->tx99_state) {
1813 if (!start)
1814 return count;
1815 ath_dbg(common, XMIT, "Resetting TX99\n");
1816 ath9k_tx99_deinit(sc);
1817 }
1818
1819 if (!start) {
1820 ath9k_tx99_deinit(sc);
1821 return count;
1822 }
1823
1824 r = ath9k_tx99_init(sc);
1825 if (r)
1826 return r;
1827
1828 return count;
1829}
1830
1831static const struct file_operations fops_tx99 = {
1832 .read = read_file_tx99,
1833 .write = write_file_tx99,
1834 .open = simple_open,
1835 .owner = THIS_MODULE,
1836 .llseek = default_llseek,
1837};
1838
1839static ssize_t read_file_tx99_power(struct file *file,
1840 char __user *user_buf,
1841 size_t count, loff_t *ppos)
1842{
1843 struct ath_softc *sc = file->private_data;
1844 char buf[32];
1845 unsigned int len;
1846
1847 len = sprintf(buf, "%d (%d dBm)\n",
1848 sc->tx99_power,
1849 sc->tx99_power / 2);
1850
1851 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1852}
1853
1854static ssize_t write_file_tx99_power(struct file *file,
1855 const char __user *user_buf,
1856 size_t count, loff_t *ppos)
1857{
1858 struct ath_softc *sc = file->private_data;
1859 int r;
1860 u8 tx_power;
1861
1862 r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
1863 if (r)
1864 return r;
1865
1866 if (tx_power > MAX_RATE_POWER)
1867 return -EINVAL;
1868
1869 sc->tx99_power = tx_power;
1870
1871 ath9k_ps_wakeup(sc);
1872 ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
1873 ath9k_ps_restore(sc);
1874
1875 return count;
1876}
1877
1878static const struct file_operations fops_tx99_power = {
1879 .read = read_file_tx99_power,
1880 .write = write_file_tx99_power,
1881 .open = simple_open,
1882 .owner = THIS_MODULE,
1883 .llseek = default_llseek,
1884};
1885
1886int ath9k_init_debug(struct ath_hw *ah) 1781int ath9k_init_debug(struct ath_hw *ah)
1887{ 1782{
1888 struct ath_common *common = ath9k_hw_common(ah); 1783 struct ath_common *common = ath9k_hw_common(ah);
@@ -1899,6 +1794,7 @@ int ath9k_init_debug(struct ath_hw *ah)
1899#endif 1794#endif
1900 1795
1901 ath9k_dfs_init_debug(sc); 1796 ath9k_dfs_init_debug(sc);
1797 ath9k_tx99_init_debug(sc);
1902 1798
1903 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, 1799 debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
1904 &fops_dma); 1800 &fops_dma);
@@ -1974,15 +1870,6 @@ int ath9k_init_debug(struct ath_hw *ah)
1974 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, 1870 debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc,
1975 &fops_btcoex); 1871 &fops_btcoex);
1976#endif 1872#endif
1977 if (config_enabled(CONFIG_ATH9K_TX99) &&
1978 AR_SREV_9300_20_OR_LATER(ah)) {
1979 debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
1980 sc->debug.debugfs_phy, sc,
1981 &fops_tx99);
1982 debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
1983 sc->debug.debugfs_phy, sc,
1984 &fops_tx99_power);
1985 }
1986 1873
1987 return 0; 1874 return 0;
1988} 1875}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8918035da3a3..779d38a98a0e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -17,6 +17,7 @@
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/time.h>
20#include <asm/unaligned.h> 21#include <asm/unaligned.h>
21 22
22#include "hw.h" 23#include "hw.h"
@@ -453,7 +454,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
453 } 454 }
454 455
455 ah->config.rx_intr_mitigation = true; 456 ah->config.rx_intr_mitigation = true;
456 ah->config.pcieSerDesWrite = true;
457 457
458 /* 458 /*
459 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 459 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
@@ -1501,8 +1501,9 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1501 int r; 1501 int r;
1502 1502
1503 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { 1503 if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
1504 band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); 1504 u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags;
1505 mode_diff = (chan->channelFlags != ah->curchan->channelFlags); 1505 band_switch = !!(flags_diff & CHANNEL_5GHZ);
1506 mode_diff = !!(flags_diff & ~CHANNEL_HT);
1506 } 1507 }
1507 1508
1508 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { 1509 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
@@ -1814,7 +1815,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
1814 * If cross-band fcc is not supoprted, bail out if channelFlags differ. 1815 * If cross-band fcc is not supoprted, bail out if channelFlags differ.
1815 */ 1816 */
1816 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && 1817 if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
1817 chan->channelFlags != ah->curchan->channelFlags) 1818 ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT))
1818 goto fail; 1819 goto fail;
1819 1820
1820 if (!ath9k_hw_check_alive(ah)) 1821 if (!ath9k_hw_check_alive(ah))
@@ -1855,10 +1856,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1855 struct ath9k_hw_cal_data *caldata, bool fastcc) 1856 struct ath9k_hw_cal_data *caldata, bool fastcc)
1856{ 1857{
1857 struct ath_common *common = ath9k_hw_common(ah); 1858 struct ath_common *common = ath9k_hw_common(ah);
1859 struct timespec ts;
1858 u32 saveLedState; 1860 u32 saveLedState;
1859 u32 saveDefAntenna; 1861 u32 saveDefAntenna;
1860 u32 macStaId1; 1862 u32 macStaId1;
1861 u64 tsf = 0; 1863 u64 tsf = 0;
1864 s64 usec = 0;
1862 int r; 1865 int r;
1863 bool start_mci_reset = false; 1866 bool start_mci_reset = false;
1864 bool save_fullsleep = ah->chip_fullsleep; 1867 bool save_fullsleep = ah->chip_fullsleep;
@@ -1901,10 +1904,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1901 1904
1902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; 1905 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
1903 1906
1904 /* For chips on which RTC reset is done, save TSF before it gets cleared */ 1907 /* Save TSF before chip reset, a cold reset clears it */
1905 if (AR_SREV_9100(ah) || 1908 tsf = ath9k_hw_gettsf64(ah);
1906 (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) 1909 getrawmonotonic(&ts);
1907 tsf = ath9k_hw_gettsf64(ah); 1910 usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
1908 1911
1909 saveLedState = REG_READ(ah, AR_CFG_LED) & 1912 saveLedState = REG_READ(ah, AR_CFG_LED) &
1910 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | 1913 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
@@ -1937,8 +1940,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1937 } 1940 }
1938 1941
1939 /* Restore TSF */ 1942 /* Restore TSF */
1940 if (tsf) 1943 getrawmonotonic(&ts);
1941 ath9k_hw_settsf64(ah, tsf); 1944 usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
1945 ath9k_hw_settsf64(ah, tsf + usec);
1942 1946
1943 if (AR_SREV_9280_20_OR_LATER(ah)) 1947 if (AR_SREV_9280_20_OR_LATER(ah))
1944 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 1948 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 a2c9a5dbac6b..e50843600989 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -283,7 +283,6 @@ struct ath9k_ops_config {
283 int additional_swba_backoff; 283 int additional_swba_backoff;
284 int ack_6mb; 284 int ack_6mb;
285 u32 cwm_ignore_extcca; 285 u32 cwm_ignore_extcca;
286 bool pcieSerDesWrite;
287 u8 pcie_clock_req; 286 u8 pcie_clock_req;
288 u32 pcie_waen; 287 u32 pcie_waen;
289 u8 analog_shiftreg; 288 u8 analog_shiftreg;
@@ -921,7 +920,7 @@ struct ath_hw {
921 /* Enterprise mode cap */ 920 /* Enterprise mode cap */
922 u32 ent_mode; 921 u32 ent_mode;
923 922
924#ifdef CONFIG_PM_SLEEP 923#ifdef CONFIG_ATH9K_WOW
925 u32 wow_event_mask; 924 u32 wow_event_mask;
926#endif 925#endif
927 bool is_clk_25mhz; 926 bool is_clk_25mhz;
@@ -1127,7 +1126,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
1127#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ 1126#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
1128 1127
1129 1128
1130#ifdef CONFIG_PM_SLEEP 1129#ifdef CONFIG_ATH9K_WOW
1131const char *ath9k_hw_wow_event_to_string(u32 wow_event); 1130const char *ath9k_hw_wow_event_to_string(u32 wow_event);
1132void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, 1131void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
1133 u8 *user_mask, int pattern_count, 1132 u8 *user_mask, int pattern_count,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 710192ed27ed..8f4c1674b76e 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -589,6 +589,9 @@ static void ath9k_init_platform(struct ath_softc *sc)
589 if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) 589 if (sc->driver_data & ATH9K_PCI_AR9565_2ANT)
590 ath_info(common, "WB335 2-ANT card detected\n"); 590 ath_info(common, "WB335 2-ANT card detected\n");
591 591
592 if (sc->driver_data & ATH9K_PCI_KILLER)
593 ath_info(common, "Killer Wireless card detected\n");
594
592 /* 595 /*
593 * Some WB335 cards do not support antenna diversity. Since 596 * Some WB335 cards do not support antenna diversity. Since
594 * we use a hardcoded value for AR9565 instead of using the 597 * we use a hardcoded value for AR9565 instead of using the
@@ -688,6 +691,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
688 common = ath9k_hw_common(ah); 691 common = ath9k_hw_common(ah);
689 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); 692 sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
690 sc->tx99_power = MAX_RATE_POWER + 1; 693 sc->tx99_power = MAX_RATE_POWER + 1;
694 init_waitqueue_head(&sc->tx_wait);
691 695
692 if (!pdata) { 696 if (!pdata) {
693 ah->ah_flags |= AH_USE_EEPROM; 697 ah->ah_flags |= AH_USE_EEPROM;
@@ -735,6 +739,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
735 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, 739 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
736 (unsigned long)sc); 740 (unsigned long)sc);
737 741
742 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
738 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 743 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
739 INIT_WORK(&sc->hw_check_work, ath_hw_check); 744 INIT_WORK(&sc->hw_check_work, ath_hw_check);
740 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); 745 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
@@ -873,15 +878,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
873 } 878 }
874}; 879};
875 880
876#ifdef CONFIG_PM
877static const struct wiphy_wowlan_support ath9k_wowlan_support = {
878 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
879 .n_patterns = MAX_NUM_USER_PATTERN,
880 .pattern_min_len = 1,
881 .pattern_max_len = MAX_PATTERN_SIZE,
882};
883#endif
884
885void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 881void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
886{ 882{
887 struct ath_hw *ah = sc->sc_ah; 883 struct ath_hw *ah = sc->sc_ah;
@@ -931,16 +927,6 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
931 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; 927 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
932 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; 928 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
933 929
934#ifdef CONFIG_PM_SLEEP
935 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
936 (sc->driver_data & ATH9K_PCI_WOW) &&
937 device_can_wakeup(sc->dev))
938 hw->wiphy->wowlan = &ath9k_wowlan_support;
939
940 atomic_set(&sc->wow_sleep_proc_intr, -1);
941 atomic_set(&sc->wow_got_bmiss_intr, -1);
942#endif
943
944 hw->queues = 4; 930 hw->queues = 4;
945 hw->max_rates = 4; 931 hw->max_rates = 4;
946 hw->channel_change_time = 5000; 932 hw->channel_change_time = 5000;
@@ -966,6 +952,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
966 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 952 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
967 &sc->sbands[IEEE80211_BAND_5GHZ]; 953 &sc->sbands[IEEE80211_BAND_5GHZ];
968 954
955 ath9k_init_wow(hw);
969 ath9k_reload_chainmask_settings(sc); 956 ath9k_reload_chainmask_settings(sc);
970 957
971 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 958 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
@@ -1064,6 +1051,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
1064 if (ATH_TXQ_SETUP(sc, i)) 1051 if (ATH_TXQ_SETUP(sc, i))
1065 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1052 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1066 1053
1054 del_timer_sync(&sc->sleep_timer);
1067 ath9k_hw_deinit(sc->sc_ah); 1055 ath9k_hw_deinit(sc->sc_ah);
1068 if (sc->dfs_detector != NULL) 1056 if (sc->dfs_detector != NULL)
1069 sc->dfs_detector->exit(sc->dfs_detector); 1057 sc->dfs_detector->exit(sc->dfs_detector);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 74f452c7b166..b1dcf89138d3 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
82 return ret; 82 return ret;
83} 83}
84 84
85void ath_ps_full_sleep(unsigned long data)
86{
87 struct ath_softc *sc = (struct ath_softc *) data;
88 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
89 bool reset;
90
91 spin_lock(&common->cc_lock);
92 ath_hw_cycle_counters_update(common);
93 spin_unlock(&common->cc_lock);
94
95 ath9k_hw_setrxabort(sc->sc_ah, 1);
96 ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
97
98 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
99}
100
85void ath9k_ps_wakeup(struct ath_softc *sc) 101void ath9k_ps_wakeup(struct ath_softc *sc)
86{ 102{
87 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 103 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
@@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
92 if (++sc->ps_usecount != 1) 108 if (++sc->ps_usecount != 1)
93 goto unlock; 109 goto unlock;
94 110
111 del_timer_sync(&sc->sleep_timer);
95 power_mode = sc->sc_ah->power_mode; 112 power_mode = sc->sc_ah->power_mode;
96 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 113 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
97 114
@@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc *sc)
117 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 134 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
118 enum ath9k_power_mode mode; 135 enum ath9k_power_mode mode;
119 unsigned long flags; 136 unsigned long flags;
120 bool reset;
121 137
122 spin_lock_irqsave(&sc->sc_pm_lock, flags); 138 spin_lock_irqsave(&sc->sc_pm_lock, flags);
123 if (--sc->ps_usecount != 0) 139 if (--sc->ps_usecount != 0)
124 goto unlock; 140 goto unlock;
125 141
126 if (sc->ps_idle) { 142 if (sc->ps_idle) {
127 ath9k_hw_setrxabort(sc->sc_ah, 1); 143 mod_timer(&sc->sleep_timer, jiffies + HZ / 10);
128 ath9k_hw_stopdmarecv(sc->sc_ah, &reset); 144 goto unlock;
129 mode = ATH9K_PM_FULL_SLEEP; 145 }
130 } else if (sc->ps_enabled && 146
147 if (sc->ps_enabled &&
131 !(sc->ps_flags & (PS_WAIT_FOR_BEACON | 148 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
132 PS_WAIT_FOR_CAB | 149 PS_WAIT_FOR_CAB |
133 PS_WAIT_FOR_PSPOLL_DATA | 150 PS_WAIT_FOR_PSPOLL_DATA |
@@ -163,13 +180,13 @@ static void __ath_cancel_work(struct ath_softc *sc)
163#endif 180#endif
164} 181}
165 182
166static void ath_cancel_work(struct ath_softc *sc) 183void ath_cancel_work(struct ath_softc *sc)
167{ 184{
168 __ath_cancel_work(sc); 185 __ath_cancel_work(sc);
169 cancel_work_sync(&sc->hw_reset_work); 186 cancel_work_sync(&sc->hw_reset_work);
170} 187}
171 188
172static void ath_restart_work(struct ath_softc *sc) 189void ath_restart_work(struct ath_softc *sc)
173{ 190{
174 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 191 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
175 192
@@ -487,6 +504,8 @@ void ath9k_tasklet(unsigned long data)
487 ath_tx_edma_tasklet(sc); 504 ath_tx_edma_tasklet(sc);
488 else 505 else
489 ath_tx_tasklet(sc); 506 ath_tx_tasklet(sc);
507
508 wake_up(&sc->tx_wait);
490 } 509 }
491 510
492 ath9k_btcoex_handle_interrupt(sc, status); 511 ath9k_btcoex_handle_interrupt(sc, status);
@@ -579,7 +598,8 @@ irqreturn_t ath_isr(int irq, void *dev)
579 598
580 goto chip_reset; 599 goto chip_reset;
581 } 600 }
582#ifdef CONFIG_PM_SLEEP 601
602#ifdef CONFIG_ATH9K_WOW
583 if (status & ATH9K_INT_BMISS) { 603 if (status & ATH9K_INT_BMISS) {
584 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { 604 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
585 ath_dbg(common, ANY, "during WoW we got a BMISS\n"); 605 ath_dbg(common, ANY, "during WoW we got a BMISS\n");
@@ -588,6 +608,8 @@ irqreturn_t ath_isr(int irq, void *dev)
588 } 608 }
589 } 609 }
590#endif 610#endif
611
612
591 if (status & ATH9K_INT_SWBA) 613 if (status & ATH9K_INT_SWBA)
592 tasklet_schedule(&sc->bcon_tasklet); 614 tasklet_schedule(&sc->bcon_tasklet);
593 615
@@ -627,7 +649,7 @@ chip_reset:
627#undef SCHED_INTR 649#undef SCHED_INTR
628} 650}
629 651
630static int ath_reset(struct ath_softc *sc) 652int ath_reset(struct ath_softc *sc)
631{ 653{
632 int r; 654 int r;
633 655
@@ -1817,13 +1839,31 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
1817 mutex_unlock(&sc->mutex); 1839 mutex_unlock(&sc->mutex);
1818} 1840}
1819 1841
1842static bool ath9k_has_tx_pending(struct ath_softc *sc)
1843{
1844 int i, npend;
1845
1846 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1847 if (!ATH_TXQ_SETUP(sc, i))
1848 continue;
1849
1850 if (!sc->tx.txq[i].axq_depth)
1851 continue;
1852
1853 npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
1854 if (npend)
1855 break;
1856 }
1857
1858 return !!npend;
1859}
1860
1820static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1861static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1821{ 1862{
1822 struct ath_softc *sc = hw->priv; 1863 struct ath_softc *sc = hw->priv;
1823 struct ath_hw *ah = sc->sc_ah; 1864 struct ath_hw *ah = sc->sc_ah;
1824 struct ath_common *common = ath9k_hw_common(ah); 1865 struct ath_common *common = ath9k_hw_common(ah);
1825 int timeout = 200; /* ms */ 1866 int timeout = HZ / 5; /* 200 ms */
1826 int i, j;
1827 bool drain_txq; 1867 bool drain_txq;
1828 1868
1829 mutex_lock(&sc->mutex); 1869 mutex_lock(&sc->mutex);
@@ -1841,25 +1881,9 @@ static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
1841 return; 1881 return;
1842 } 1882 }
1843 1883
1844 for (j = 0; j < timeout; j++) { 1884 if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
1845 bool npend = false; 1885 timeout) > 0)
1846 1886 drop = false;
1847 if (j)
1848 usleep_range(1000, 2000);
1849
1850 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1851 if (!ATH_TXQ_SETUP(sc, i))
1852 continue;
1853
1854 npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
1855
1856 if (npend)
1857 break;
1858 }
1859
1860 if (!npend)
1861 break;
1862 }
1863 1887
1864 if (drop) { 1888 if (drop) {
1865 ath9k_ps_wakeup(sc); 1889 ath9k_ps_wakeup(sc);
@@ -2021,333 +2045,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
2021 return 0; 2045 return 0;
2022} 2046}
2023 2047
2024#ifdef CONFIG_PM_SLEEP
2025
2026static void ath9k_wow_map_triggers(struct ath_softc *sc,
2027 struct cfg80211_wowlan *wowlan,
2028 u32 *wow_triggers)
2029{
2030 if (wowlan->disconnect)
2031 *wow_triggers |= AH_WOW_LINK_CHANGE |
2032 AH_WOW_BEACON_MISS;
2033 if (wowlan->magic_pkt)
2034 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
2035
2036 if (wowlan->n_patterns)
2037 *wow_triggers |= AH_WOW_USER_PATTERN_EN;
2038
2039 sc->wow_enabled = *wow_triggers;
2040
2041}
2042
2043static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2044{
2045 struct ath_hw *ah = sc->sc_ah;
2046 struct ath_common *common = ath9k_hw_common(ah);
2047 int pattern_count = 0;
2048 int i, byte_cnt;
2049 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
2050 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
2051
2052 memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
2053 memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
2054
2055 /*
2056 * Create Dissassociate / Deauthenticate packet filter
2057 *
2058 * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
2059 * +--------------+----------+---------+--------+--------+----
2060 * + Frame Control+ Duration + DA + SA + BSSID +
2061 * +--------------+----------+---------+--------+--------+----
2062 *
2063 * The above is the management frame format for disassociate/
2064 * deauthenticate pattern, from this we need to match the first byte
2065 * of 'Frame Control' and DA, SA, and BSSID fields
2066 * (skipping 2nd byte of FC and Duration feild.
2067 *
2068 * Disassociate pattern
2069 * --------------------
2070 * Frame control = 00 00 1010
2071 * DA, SA, BSSID = x:x:x:x:x:x
2072 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2073 * | x:x:x:x:x:x -- 22 bytes
2074 *
2075 * Deauthenticate pattern
2076 * ----------------------
2077 * Frame control = 00 00 1100
2078 * DA, SA, BSSID = x:x:x:x:x:x
2079 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2080 * | x:x:x:x:x:x -- 22 bytes
2081 */
2082
2083 /* Create Disassociate Pattern first */
2084
2085 byte_cnt = 0;
2086
2087 /* Fill out the mask with all FF's */
2088
2089 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
2090 dis_deauth_mask[i] = 0xff;
2091
2092 /* copy the first byte of frame control field */
2093 dis_deauth_pattern[byte_cnt] = 0xa0;
2094 byte_cnt++;
2095
2096 /* skip 2nd byte of frame control and Duration field */
2097 byte_cnt += 3;
2098
2099 /*
2100 * need not match the destination mac address, it can be a broadcast
2101 * mac address or an unicast to this station
2102 */
2103 byte_cnt += 6;
2104
2105 /* copy the source mac address */
2106 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2107
2108 byte_cnt += 6;
2109
2110 /* copy the bssid, its same as the source mac address */
2111
2112 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2113
2114 /* Create Disassociate pattern mask */
2115
2116 dis_deauth_mask[0] = 0xfe;
2117 dis_deauth_mask[1] = 0x03;
2118 dis_deauth_mask[2] = 0xc0;
2119
2120 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
2121
2122 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2123 pattern_count, byte_cnt);
2124
2125 pattern_count++;
2126 /*
2127 * for de-authenticate pattern, only the first byte of the frame
2128 * control field gets changed from 0xA0 to 0xC0
2129 */
2130 dis_deauth_pattern[0] = 0xC0;
2131
2132 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2133 pattern_count, byte_cnt);
2134
2135}
2136
2137static void ath9k_wow_add_pattern(struct ath_softc *sc,
2138 struct cfg80211_wowlan *wowlan)
2139{
2140 struct ath_hw *ah = sc->sc_ah;
2141 struct ath9k_wow_pattern *wow_pattern = NULL;
2142 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
2143 int mask_len;
2144 s8 i = 0;
2145
2146 if (!wowlan->n_patterns)
2147 return;
2148
2149 /*
2150 * Add the new user configured patterns
2151 */
2152 for (i = 0; i < wowlan->n_patterns; i++) {
2153
2154 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
2155
2156 if (!wow_pattern)
2157 return;
2158
2159 /*
2160 * TODO: convert the generic user space pattern to
2161 * appropriate chip specific/802.11 pattern.
2162 */
2163
2164 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
2165 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
2166 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
2167 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
2168 patterns[i].pattern_len);
2169 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
2170 wow_pattern->pattern_len = patterns[i].pattern_len;
2171
2172 /*
2173 * just need to take care of deauth and disssoc pattern,
2174 * make sure we don't overwrite them.
2175 */
2176
2177 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
2178 wow_pattern->mask_bytes,
2179 i + 2,
2180 wow_pattern->pattern_len);
2181 kfree(wow_pattern);
2182
2183 }
2184
2185}
2186
2187static int ath9k_suspend(struct ieee80211_hw *hw,
2188 struct cfg80211_wowlan *wowlan)
2189{
2190 struct ath_softc *sc = hw->priv;
2191 struct ath_hw *ah = sc->sc_ah;
2192 struct ath_common *common = ath9k_hw_common(ah);
2193 u32 wow_triggers_enabled = 0;
2194 int ret = 0;
2195
2196 mutex_lock(&sc->mutex);
2197
2198 ath_cancel_work(sc);
2199 ath_stop_ani(sc);
2200 del_timer_sync(&sc->rx_poll_timer);
2201
2202 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
2203 ath_dbg(common, ANY, "Device not present\n");
2204 ret = -EINVAL;
2205 goto fail_wow;
2206 }
2207
2208 if (WARN_ON(!wowlan)) {
2209 ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
2210 ret = -EINVAL;
2211 goto fail_wow;
2212 }
2213
2214 if (!device_can_wakeup(sc->dev)) {
2215 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
2216 ret = 1;
2217 goto fail_wow;
2218 }
2219
2220 /*
2221 * none of the sta vifs are associated
2222 * and we are not currently handling multivif
2223 * cases, for instance we have to seperately
2224 * configure 'keep alive frame' for each
2225 * STA.
2226 */
2227
2228 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
2229 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
2230 ret = 1;
2231 goto fail_wow;
2232 }
2233
2234 if (sc->nvifs > 1) {
2235 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
2236 ret = 1;
2237 goto fail_wow;
2238 }
2239
2240 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
2241
2242 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
2243 wow_triggers_enabled);
2244
2245 ath9k_ps_wakeup(sc);
2246
2247 ath9k_stop_btcoex(sc);
2248
2249 /*
2250 * Enable wake up on recieving disassoc/deauth
2251 * frame by default.
2252 */
2253 ath9k_wow_add_disassoc_deauth_pattern(sc);
2254
2255 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
2256 ath9k_wow_add_pattern(sc, wowlan);
2257
2258 spin_lock_bh(&sc->sc_pcu_lock);
2259 /*
2260 * To avoid false wake, we enable beacon miss interrupt only
2261 * when we go to sleep. We save the current interrupt mask
2262 * so we can restore it after the system wakes up
2263 */
2264 sc->wow_intr_before_sleep = ah->imask;
2265 ah->imask &= ~ATH9K_INT_GLOBAL;
2266 ath9k_hw_disable_interrupts(ah);
2267 ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
2268 ath9k_hw_set_interrupts(ah);
2269 ath9k_hw_enable_interrupts(ah);
2270
2271 spin_unlock_bh(&sc->sc_pcu_lock);
2272
2273 /*
2274 * we can now sync irq and kill any running tasklets, since we already
2275 * disabled interrupts and not holding a spin lock
2276 */
2277 synchronize_irq(sc->irq);
2278 tasklet_kill(&sc->intr_tq);
2279
2280 ath9k_hw_wow_enable(ah, wow_triggers_enabled);
2281
2282 ath9k_ps_restore(sc);
2283 ath_dbg(common, ANY, "WoW enabled in ath9k\n");
2284 atomic_inc(&sc->wow_sleep_proc_intr);
2285
2286fail_wow:
2287 mutex_unlock(&sc->mutex);
2288 return ret;
2289}
2290
2291static int ath9k_resume(struct ieee80211_hw *hw)
2292{
2293 struct ath_softc *sc = hw->priv;
2294 struct ath_hw *ah = sc->sc_ah;
2295 struct ath_common *common = ath9k_hw_common(ah);
2296 u32 wow_status;
2297
2298 mutex_lock(&sc->mutex);
2299
2300 ath9k_ps_wakeup(sc);
2301
2302 spin_lock_bh(&sc->sc_pcu_lock);
2303
2304 ath9k_hw_disable_interrupts(ah);
2305 ah->imask = sc->wow_intr_before_sleep;
2306 ath9k_hw_set_interrupts(ah);
2307 ath9k_hw_enable_interrupts(ah);
2308
2309 spin_unlock_bh(&sc->sc_pcu_lock);
2310
2311 wow_status = ath9k_hw_wow_wakeup(ah);
2312
2313 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
2314 /*
2315 * some devices may not pick beacon miss
2316 * as the reason they woke up so we add
2317 * that here for that shortcoming.
2318 */
2319 wow_status |= AH_WOW_BEACON_MISS;
2320 atomic_dec(&sc->wow_got_bmiss_intr);
2321 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
2322 }
2323
2324 atomic_dec(&sc->wow_sleep_proc_intr);
2325
2326 if (wow_status) {
2327 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
2328 ath9k_hw_wow_event_to_string(wow_status), wow_status);
2329 }
2330
2331 ath_restart_work(sc);
2332 ath9k_start_btcoex(sc);
2333
2334 ath9k_ps_restore(sc);
2335 mutex_unlock(&sc->mutex);
2336
2337 return 0;
2338}
2339
2340static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
2341{
2342 struct ath_softc *sc = hw->priv;
2343
2344 mutex_lock(&sc->mutex);
2345 device_init_wakeup(sc->dev, 1);
2346 device_set_wakeup_enable(sc->dev, enabled);
2347 mutex_unlock(&sc->mutex);
2348}
2349
2350#endif
2351static void ath9k_sw_scan_start(struct ieee80211_hw *hw) 2048static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
2352{ 2049{
2353 struct ath_softc *sc = hw->priv; 2050 struct ath_softc *sc = hw->priv;
@@ -2373,134 +2070,6 @@ static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw,
2373 sc->csa_vif = vif; 2070 sc->csa_vif = vif;
2374} 2071}
2375 2072
2376static void ath9k_tx99_stop(struct ath_softc *sc)
2377{
2378 struct ath_hw *ah = sc->sc_ah;
2379 struct ath_common *common = ath9k_hw_common(ah);
2380
2381 ath_drain_all_txq(sc);
2382 ath_startrecv(sc);
2383
2384 ath9k_hw_set_interrupts(ah);
2385 ath9k_hw_enable_interrupts(ah);
2386
2387 ieee80211_wake_queues(sc->hw);
2388
2389 kfree_skb(sc->tx99_skb);
2390 sc->tx99_skb = NULL;
2391 sc->tx99_state = false;
2392
2393 ath9k_hw_tx99_stop(sc->sc_ah);
2394 ath_dbg(common, XMIT, "TX99 stopped\n");
2395}
2396
2397static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
2398{
2399 static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
2400 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
2401 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
2402 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
2403 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
2404 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
2405 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
2406 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
2407 u32 len = 1200;
2408 struct ieee80211_hw *hw = sc->hw;
2409 struct ieee80211_hdr *hdr;
2410 struct ieee80211_tx_info *tx_info;
2411 struct sk_buff *skb;
2412
2413 skb = alloc_skb(len, GFP_KERNEL);
2414 if (!skb)
2415 return NULL;
2416
2417 skb_put(skb, len);
2418
2419 memset(skb->data, 0, len);
2420
2421 hdr = (struct ieee80211_hdr *)skb->data;
2422 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
2423 hdr->duration_id = 0;
2424
2425 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
2426 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
2427 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
2428
2429 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
2430
2431 tx_info = IEEE80211_SKB_CB(skb);
2432 memset(tx_info, 0, sizeof(*tx_info));
2433 tx_info->band = hw->conf.chandef.chan->band;
2434 tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
2435 tx_info->control.vif = sc->tx99_vif;
2436
2437 memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
2438
2439 return skb;
2440}
2441
2442void ath9k_tx99_deinit(struct ath_softc *sc)
2443{
2444 ath_reset(sc);
2445
2446 ath9k_ps_wakeup(sc);
2447 ath9k_tx99_stop(sc);
2448 ath9k_ps_restore(sc);
2449}
2450
2451int ath9k_tx99_init(struct ath_softc *sc)
2452{
2453 struct ieee80211_hw *hw = sc->hw;
2454 struct ath_hw *ah = sc->sc_ah;
2455 struct ath_common *common = ath9k_hw_common(ah);
2456 struct ath_tx_control txctl;
2457 int r;
2458
2459 if (sc->sc_flags & SC_OP_INVALID) {
2460 ath_err(common,
2461 "driver is in invalid state unable to use TX99");
2462 return -EINVAL;
2463 }
2464
2465 sc->tx99_skb = ath9k_build_tx99_skb(sc);
2466 if (!sc->tx99_skb)
2467 return -ENOMEM;
2468
2469 memset(&txctl, 0, sizeof(txctl));
2470 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
2471
2472 ath_reset(sc);
2473
2474 ath9k_ps_wakeup(sc);
2475
2476 ath9k_hw_disable_interrupts(ah);
2477 atomic_set(&ah->intr_ref_cnt, -1);
2478 ath_drain_all_txq(sc);
2479 ath_stoprecv(sc);
2480
2481 sc->tx99_state = true;
2482
2483 ieee80211_stop_queues(hw);
2484
2485 if (sc->tx99_power == MAX_RATE_POWER + 1)
2486 sc->tx99_power = MAX_RATE_POWER;
2487
2488 ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
2489 r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
2490 if (r) {
2491 ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
2492 return r;
2493 }
2494
2495 ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
2496 sc->tx99_power,
2497 sc->tx99_power / 2);
2498
2499 /* We leave the harware awake as it will be chugging on */
2500
2501 return 0;
2502}
2503
2504struct ieee80211_ops ath9k_ops = { 2073struct ieee80211_ops ath9k_ops = {
2505 .tx = ath9k_tx, 2074 .tx = ath9k_tx,
2506 .start = ath9k_start, 2075 .start = ath9k_start,
@@ -2531,7 +2100,7 @@ struct ieee80211_ops ath9k_ops = {
2531 .set_antenna = ath9k_set_antenna, 2100 .set_antenna = ath9k_set_antenna,
2532 .get_antenna = ath9k_get_antenna, 2101 .get_antenna = ath9k_get_antenna,
2533 2102
2534#ifdef CONFIG_PM_SLEEP 2103#ifdef CONFIG_ATH9K_WOW
2535 .suspend = ath9k_suspend, 2104 .suspend = ath9k_suspend,
2536 .resume = ath9k_resume, 2105 .resume = ath9k_resume,
2537 .set_wakeup = ath9k_set_wakeup, 2106 .set_wakeup = ath9k_set_wakeup,
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b5656fce4ff5..e9a585758941 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -87,6 +87,19 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
87 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ 87 { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */
88 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ 88 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
89 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ 89 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
90
91 /* Killer Wireless (3x3) */
92 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
93 0x0030,
94 0x1A56,
95 0x2000),
96 .driver_data = ATH9K_PCI_KILLER },
97 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
98 0x0030,
99 0x1A56,
100 0x2001),
101 .driver_data = ATH9K_PCI_KILLER },
102
90 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ 103 { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
91 104
92 /* PCI-E CUS198 */ 105 /* PCI-E CUS198 */
@@ -354,6 +367,13 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
354 0x1783), 367 0x1783),
355 .driver_data = ATH9K_PCI_WOW }, 368 .driver_data = ATH9K_PCI_WOW },
356 369
370 /* Killer Wireless (2x2) */
371 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
372 0x0030,
373 0x1A56,
374 0x2003),
375 .driver_data = ATH9K_PCI_KILLER },
376
357 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ 377 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
358 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ 378 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
359 379
@@ -448,6 +468,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
448 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 468 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
449 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 469 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
450 0x0036, 470 0x0036,
471 0x11AD, /* LITEON */
472 0x0682),
473 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
474 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
475 0x0036,
451 PCI_VENDOR_ID_AZWAVE, 476 PCI_VENDOR_ID_AZWAVE,
452 0x213A), 477 0x213A),
453 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 478 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -458,6 +483,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
458 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 483 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
459 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 484 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
460 0x0036, 485 0x0036,
486 PCI_VENDOR_ID_LENOVO,
487 0x4026),
488 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
489 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
490 0x0036,
461 PCI_VENDOR_ID_HP, 491 PCI_VENDOR_ID_HP,
462 0x18E3), 492 0x18E3),
463 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 493 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -468,6 +498,11 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
468 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 498 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
469 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, 499 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
470 0x0036, 500 0x0036,
501 PCI_VENDOR_ID_HP,
502 0x2005),
503 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
504 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
505 0x0036,
471 PCI_VENDOR_ID_DELL, 506 PCI_VENDOR_ID_DELL,
472 0x020E), 507 0x020E),
473 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, 508 .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV },
@@ -545,6 +580,16 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
545 0x185F, /* WNC */ 580 0x185F, /* WNC */
546 0x3027), 581 0x3027),
547 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, 582 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
583 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
584 0x0036,
585 0x185F, /* WNC */
586 0xA120),
587 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
588 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
589 0x0036,
590 PCI_VENDOR_ID_FOXCONN,
591 0xE07F),
592 .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV },
548 593
549 /* PCI-E AR9565 (WB335) */ 594 /* PCI-E AR9565 (WB335) */
550 { PCI_VDEVICE(ATHEROS, 0x0036), 595 { PCI_VDEVICE(ATHEROS, 0x0036),
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index a13b2d143d9e..259a4b307707 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -809,6 +809,8 @@
809#define AR_SREV_REVISION_9462_21 3 809#define AR_SREV_REVISION_9462_21 3
810#define AR_SREV_VERSION_9565 0x2C0 810#define AR_SREV_VERSION_9565 0x2C0
811#define AR_SREV_REVISION_9565_10 0 811#define AR_SREV_REVISION_9565_10 0
812#define AR_SREV_REVISION_9565_101 1
813#define AR_SREV_REVISION_9565_11 2
812#define AR_SREV_VERSION_9550 0x400 814#define AR_SREV_VERSION_9550 0x400
813 815
814#define AR_SREV_5416(_ah) \ 816#define AR_SREV_5416(_ah) \
@@ -927,10 +929,18 @@
927 929
928#define AR_SREV_9565(_ah) \ 930#define AR_SREV_9565(_ah) \
929 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 931 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
930
931#define AR_SREV_9565_10(_ah) \ 932#define AR_SREV_9565_10(_ah) \
932 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ 933 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
933 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) 934 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
935#define AR_SREV_9565_101(_ah) \
936 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
937 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101))
938#define AR_SREV_9565_11(_ah) \
939 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
940 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11))
941#define AR_SREV_9565_11_OR_LATER(_ah) \
942 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
943 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11))
934 944
935#define AR_SREV_9550(_ah) \ 945#define AR_SREV_9550(_ah) \
936 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550)) 946 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
new file mode 100644
index 000000000000..57d775783ec8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -0,0 +1,264 @@
1/*
2 * Copyright (c) 2013 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
19static void ath9k_tx99_stop(struct ath_softc *sc)
20{
21 struct ath_hw *ah = sc->sc_ah;
22 struct ath_common *common = ath9k_hw_common(ah);
23
24 ath_drain_all_txq(sc);
25 ath_startrecv(sc);
26
27 ath9k_hw_set_interrupts(ah);
28 ath9k_hw_enable_interrupts(ah);
29
30 ieee80211_wake_queues(sc->hw);
31
32 kfree_skb(sc->tx99_skb);
33 sc->tx99_skb = NULL;
34 sc->tx99_state = false;
35
36 ath9k_hw_tx99_stop(sc->sc_ah);
37 ath_dbg(common, XMIT, "TX99 stopped\n");
38}
39
40static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
41{
42 static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
43 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
44 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
45 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
46 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
47 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
48 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
49 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
50 u32 len = 1200;
51 struct ieee80211_hw *hw = sc->hw;
52 struct ieee80211_hdr *hdr;
53 struct ieee80211_tx_info *tx_info;
54 struct sk_buff *skb;
55
56 skb = alloc_skb(len, GFP_KERNEL);
57 if (!skb)
58 return NULL;
59
60 skb_put(skb, len);
61
62 memset(skb->data, 0, len);
63
64 hdr = (struct ieee80211_hdr *)skb->data;
65 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
66 hdr->duration_id = 0;
67
68 memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
69 memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
70 memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
71
72 hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
73
74 tx_info = IEEE80211_SKB_CB(skb);
75 memset(tx_info, 0, sizeof(*tx_info));
76 tx_info->band = hw->conf.chandef.chan->band;
77 tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
78 tx_info->control.vif = sc->tx99_vif;
79 tx_info->control.rates[0].count = 1;
80
81 memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
82
83 return skb;
84}
85
86static void ath9k_tx99_deinit(struct ath_softc *sc)
87{
88 ath_reset(sc);
89
90 ath9k_ps_wakeup(sc);
91 ath9k_tx99_stop(sc);
92 ath9k_ps_restore(sc);
93}
94
95static int ath9k_tx99_init(struct ath_softc *sc)
96{
97 struct ieee80211_hw *hw = sc->hw;
98 struct ath_hw *ah = sc->sc_ah;
99 struct ath_common *common = ath9k_hw_common(ah);
100 struct ath_tx_control txctl;
101 int r;
102
103 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
104 ath_err(common,
105 "driver is in invalid state unable to use TX99");
106 return -EINVAL;
107 }
108
109 sc->tx99_skb = ath9k_build_tx99_skb(sc);
110 if (!sc->tx99_skb)
111 return -ENOMEM;
112
113 memset(&txctl, 0, sizeof(txctl));
114 txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
115
116 ath_reset(sc);
117
118 ath9k_ps_wakeup(sc);
119
120 ath9k_hw_disable_interrupts(ah);
121 atomic_set(&ah->intr_ref_cnt, -1);
122 ath_drain_all_txq(sc);
123 ath_stoprecv(sc);
124
125 sc->tx99_state = true;
126
127 ieee80211_stop_queues(hw);
128
129 if (sc->tx99_power == MAX_RATE_POWER + 1)
130 sc->tx99_power = MAX_RATE_POWER;
131
132 ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
133 r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
134 if (r) {
135 ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
136 return r;
137 }
138
139 ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
140 sc->tx99_power,
141 sc->tx99_power / 2);
142
143 /* We leave the harware awake as it will be chugging on */
144
145 return 0;
146}
147
148static ssize_t read_file_tx99(struct file *file, char __user *user_buf,
149 size_t count, loff_t *ppos)
150{
151 struct ath_softc *sc = file->private_data;
152 char buf[3];
153 unsigned int len;
154
155 len = sprintf(buf, "%d\n", sc->tx99_state);
156 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
157}
158
159static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
160 size_t count, loff_t *ppos)
161{
162 struct ath_softc *sc = file->private_data;
163 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
164 char buf[32];
165 bool start;
166 ssize_t len;
167 int r;
168
169 if (sc->nvifs > 1)
170 return -EOPNOTSUPP;
171
172 len = min(count, sizeof(buf) - 1);
173 if (copy_from_user(buf, user_buf, len))
174 return -EFAULT;
175
176 if (strtobool(buf, &start))
177 return -EINVAL;
178
179 if (start == sc->tx99_state) {
180 if (!start)
181 return count;
182 ath_dbg(common, XMIT, "Resetting TX99\n");
183 ath9k_tx99_deinit(sc);
184 }
185
186 if (!start) {
187 ath9k_tx99_deinit(sc);
188 return count;
189 }
190
191 r = ath9k_tx99_init(sc);
192 if (r)
193 return r;
194
195 return count;
196}
197
198static const struct file_operations fops_tx99 = {
199 .read = read_file_tx99,
200 .write = write_file_tx99,
201 .open = simple_open,
202 .owner = THIS_MODULE,
203 .llseek = default_llseek,
204};
205
206static ssize_t read_file_tx99_power(struct file *file,
207 char __user *user_buf,
208 size_t count, loff_t *ppos)
209{
210 struct ath_softc *sc = file->private_data;
211 char buf[32];
212 unsigned int len;
213
214 len = sprintf(buf, "%d (%d dBm)\n",
215 sc->tx99_power,
216 sc->tx99_power / 2);
217
218 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
219}
220
221static ssize_t write_file_tx99_power(struct file *file,
222 const char __user *user_buf,
223 size_t count, loff_t *ppos)
224{
225 struct ath_softc *sc = file->private_data;
226 int r;
227 u8 tx_power;
228
229 r = kstrtou8_from_user(user_buf, count, 0, &tx_power);
230 if (r)
231 return r;
232
233 if (tx_power > MAX_RATE_POWER)
234 return -EINVAL;
235
236 sc->tx99_power = tx_power;
237
238 ath9k_ps_wakeup(sc);
239 ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power);
240 ath9k_ps_restore(sc);
241
242 return count;
243}
244
245static const struct file_operations fops_tx99_power = {
246 .read = read_file_tx99_power,
247 .write = write_file_tx99_power,
248 .open = simple_open,
249 .owner = THIS_MODULE,
250 .llseek = default_llseek,
251};
252
253void ath9k_tx99_init_debug(struct ath_softc *sc)
254{
255 if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah))
256 return;
257
258 debugfs_create_file("tx99", S_IRUSR | S_IWUSR,
259 sc->debug.debugfs_phy, sc,
260 &fops_tx99);
261 debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR,
262 sc->debug.debugfs_phy, sc,
263 &fops_tx99_power);
264}
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 81c88dd606dc..f1cde81bb7a2 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2012 Qualcomm Atheros, Inc. 2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -14,409 +14,348 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/export.h>
18#include "ath9k.h" 17#include "ath9k.h"
19#include "reg.h"
20#include "hw-ops.h"
21 18
22const char *ath9k_hw_wow_event_to_string(u32 wow_event) 19static const struct wiphy_wowlan_support ath9k_wowlan_support = {
23{ 20 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
24 if (wow_event & AH_WOW_MAGIC_PATTERN_EN) 21 .n_patterns = MAX_NUM_USER_PATTERN,
25 return "Magic pattern"; 22 .pattern_min_len = 1,
26 if (wow_event & AH_WOW_USER_PATTERN_EN) 23 .pattern_max_len = MAX_PATTERN_SIZE,
27 return "User pattern"; 24};
28 if (wow_event & AH_WOW_LINK_CHANGE)
29 return "Link change";
30 if (wow_event & AH_WOW_BEACON_MISS)
31 return "Beacon miss";
32
33 return "unknown reason";
34}
35EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
36 25
37static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) 26static void ath9k_wow_map_triggers(struct ath_softc *sc,
27 struct cfg80211_wowlan *wowlan,
28 u32 *wow_triggers)
38{ 29{
39 struct ath_common *common = ath9k_hw_common(ah); 30 if (wowlan->disconnect)
31 *wow_triggers |= AH_WOW_LINK_CHANGE |
32 AH_WOW_BEACON_MISS;
33 if (wowlan->magic_pkt)
34 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
40 35
41 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); 36 if (wowlan->n_patterns)
37 *wow_triggers |= AH_WOW_USER_PATTERN_EN;
42 38
43 /* set rx disable bit */ 39 sc->wow_enabled = *wow_triggers;
44 REG_WRITE(ah, AR_CR, AR_CR_RXD);
45
46 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
47 ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
48 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
49 return;
50 }
51 40
52 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
53} 41}
54 42
55static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) 43static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
56{ 44{
45 struct ath_hw *ah = sc->sc_ah;
57 struct ath_common *common = ath9k_hw_common(ah); 46 struct ath_common *common = ath9k_hw_common(ah);
58 u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN]; 47 int pattern_count = 0;
59 u32 ctl[13] = {0}; 48 int i, byte_cnt;
60 u32 data_word[KAL_NUM_DATA_WORDS]; 49 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
61 u8 i; 50 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
62 u32 wow_ka_data_word0;
63
64 memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
65 memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
66
67 /* set the transmit buffer */
68 ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
69 ctl[1] = 0;
70 ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
71 ctl[4] = 0;
72 ctl[7] = (ah->txchainmask) << 2;
73 ctl[2] = 0xf << 16; /* tx_tries 0 */
74
75 for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
76 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
77
78 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
79
80 data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
81 (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
82 data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
83 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
84 data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
85 (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
86 data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
87 (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
88 data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
89 (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
90 data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
91
92 if (AR_SREV_9462_20(ah)) {
93 /* AR9462 2.0 has an extra descriptor word (time based
94 * discard) compared to other chips */
95 REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
96 wow_ka_data_word0 = AR_WOW_TXBUF(13);
97 } else {
98 wow_ka_data_word0 = AR_WOW_TXBUF(12);
99 }
100
101 for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
102 REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
103
104}
105
106void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
107 u8 *user_mask, int pattern_count,
108 int pattern_len)
109{
110 int i;
111 u32 pattern_val, mask_val;
112 u32 set, clr;
113 51
114 /* FIXME: should check count by querying the hardware capability */ 52 memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
115 if (pattern_count >= MAX_NUM_PATTERN) 53 memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
116 return;
117
118 REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
119
120 /* set the registers for pattern */
121 for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
122 memcpy(&pattern_val, user_pattern, 4);
123 REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
124 pattern_val);
125 user_pattern += 4;
126 }
127
128 /* set the registers for mask */
129 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
130 memcpy(&mask_val, user_mask, 4);
131 REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
132 user_mask += 4;
133 }
134 54
135 /* set the pattern length to be matched 55 /*
56 * Create Dissassociate / Deauthenticate packet filter
57 *
58 * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
59 * +--------------+----------+---------+--------+--------+----
60 * + Frame Control+ Duration + DA + SA + BSSID +
61 * +--------------+----------+---------+--------+--------+----
136 * 62 *
137 * AR_WOW_LENGTH1_REG1 63 * The above is the management frame format for disassociate/
138 * bit 31:24 pattern 0 length 64 * deauthenticate pattern, from this we need to match the first byte
139 * bit 23:16 pattern 1 length 65 * of 'Frame Control' and DA, SA, and BSSID fields
140 * bit 15:8 pattern 2 length 66 * (skipping 2nd byte of FC and Duration feild.
141 * bit 7:0 pattern 3 length
142 * 67 *
143 * AR_WOW_LENGTH1_REG2 68 * Disassociate pattern
144 * bit 31:24 pattern 4 length 69 * --------------------
145 * bit 23:16 pattern 5 length 70 * Frame control = 00 00 1010
146 * bit 15:8 pattern 6 length 71 * DA, SA, BSSID = x:x:x:x:x:x
147 * bit 7:0 pattern 7 length 72 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
73 * | x:x:x:x:x:x -- 22 bytes
148 * 74 *
149 * the below logic writes out the new 75 * Deauthenticate pattern
150 * pattern length for the corresponding 76 * ----------------------
151 * pattern_count, while masking out the 77 * Frame control = 00 00 1100
152 * other fields 78 * DA, SA, BSSID = x:x:x:x:x:x
79 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
80 * | x:x:x:x:x:x -- 22 bytes
153 */ 81 */
154 82
155 ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); 83 /* Create Disassociate Pattern first */
156
157 if (pattern_count < 4) {
158 /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
159 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
160 AR_WOW_LEN1_SHIFT(pattern_count);
161 clr = AR_WOW_LENGTH1_MASK(pattern_count);
162 REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
163 } else {
164 /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
165 set = (pattern_len & AR_WOW_LENGTH_MAX) <<
166 AR_WOW_LEN2_SHIFT(pattern_count);
167 clr = AR_WOW_LENGTH2_MASK(pattern_count);
168 REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
169 }
170 84
171} 85 byte_cnt = 0;
172EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
173 86
174u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) 87 /* Fill out the mask with all FF's */
175{
176 u32 wow_status = 0;
177 u32 val = 0, rval;
178 88
179 /* 89 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
180 * read the WoW status register to know 90 dis_deauth_mask[i] = 0xff;
181 * the wakeup reason
182 */
183 rval = REG_READ(ah, AR_WOW_PATTERN);
184 val = AR_WOW_STATUS(rval);
185 91
186 /* 92 /* copy the first byte of frame control field */
187 * mask only the WoW events that we have enabled. Sometimes 93 dis_deauth_pattern[byte_cnt] = 0xa0;
188 * we have spurious WoW events from the AR_WOW_PATTERN 94 byte_cnt++;
189 * register. This mask will clean it up.
190 */
191 95
192 val &= ah->wow_event_mask; 96 /* skip 2nd byte of frame control and Duration field */
193 97 byte_cnt += 3;
194 if (val) {
195 if (val & AR_WOW_MAGIC_PAT_FOUND)
196 wow_status |= AH_WOW_MAGIC_PATTERN_EN;
197 if (AR_WOW_PATTERN_FOUND(val))
198 wow_status |= AH_WOW_USER_PATTERN_EN;
199 if (val & AR_WOW_KEEP_ALIVE_FAIL)
200 wow_status |= AH_WOW_LINK_CHANGE;
201 if (val & AR_WOW_BEACON_FAIL)
202 wow_status |= AH_WOW_BEACON_MISS;
203 }
204 98
205 /* 99 /*
206 * set and clear WOW_PME_CLEAR registers for the chip to 100 * need not match the destination mac address, it can be a broadcast
207 * generate next wow signal. 101 * mac address or an unicast to this station
208 * disable D3 before accessing other registers ?
209 */ 102 */
103 byte_cnt += 6;
210 104
211 /* do we need to check the bit value 0x01000000 (7-10) ?? */ 105 /* copy the source mac address */
212 REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR, 106 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
213 AR_PMCTRL_PWR_STATE_D1D3);
214 107
215 /* 108 byte_cnt += 6;
216 * clear all events
217 */
218 REG_WRITE(ah, AR_WOW_PATTERN,
219 AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
220 109
221 /* 110 /* copy the bssid, its same as the source mac address */
222 * restore the beacon threshold to init value 111
223 */ 112 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
224 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 113
114 /* Create Disassociate pattern mask */
115
116 dis_deauth_mask[0] = 0xfe;
117 dis_deauth_mask[1] = 0x03;
118 dis_deauth_mask[2] = 0xc0;
119
120 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
225 121
122 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
123 pattern_count, byte_cnt);
124
125 pattern_count++;
226 /* 126 /*
227 * Restore the way the PCI-E reset, Power-On-Reset, external 127 * for de-authenticate pattern, only the first byte of the frame
228 * PCIE_POR_SHORT pins are tied to its original value. 128 * control field gets changed from 0xA0 to 0xC0
229 * Previously just before WoW sleep, we untie the PCI-E
230 * reset to our Chip's Power On Reset so that any PCI-E
231 * reset from the bus will not reset our chip
232 */ 129 */
233 if (ah->is_pciexpress) 130 dis_deauth_pattern[0] = 0xC0;
234 ath9k_hw_configpcipowersave(ah, false);
235 131
236 ah->wow_event_mask = 0; 132 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
133 pattern_count, byte_cnt);
237 134
238 return wow_status;
239} 135}
240EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
241 136
242void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) 137static void ath9k_wow_add_pattern(struct ath_softc *sc,
138 struct cfg80211_wowlan *wowlan)
243{ 139{
244 u32 wow_event_mask; 140 struct ath_hw *ah = sc->sc_ah;
245 u32 set, clr; 141 struct ath9k_wow_pattern *wow_pattern = NULL;
142 struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
143 int mask_len;
144 s8 i = 0;
246 145
247 /* 146 if (!wowlan->n_patterns)
248 * wow_event_mask is a mask to the AR_WOW_PATTERN register to 147 return;
249 * indicate which WoW events we have enabled. The WoW events
250 * are from the 'pattern_enable' in this function and
251 * 'pattern_count' of ath9k_hw_wow_apply_pattern()
252 */
253 wow_event_mask = ah->wow_event_mask;
254 148
255 /* 149 /*
256 * Untie Power-on-Reset from the PCI-E-Reset. When we are in 150 * Add the new user configured patterns
257 * WOW sleep, we do want the Reset from the PCI-E to disturb
258 * our hw state
259 */ 151 */
260 if (ah->is_pciexpress) { 152 for (i = 0; i < wowlan->n_patterns; i++) {
153
154 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
155
156 if (!wow_pattern)
157 return;
158
159 /*
160 * TODO: convert the generic user space pattern to
161 * appropriate chip specific/802.11 pattern.
162 */
163
164 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
165 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
166 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
167 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
168 patterns[i].pattern_len);
169 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
170 wow_pattern->pattern_len = patterns[i].pattern_len;
171
261 /* 172 /*
262 * we need to untie the internal POR (power-on-reset) 173 * just need to take care of deauth and disssoc pattern,
263 * to the external PCI-E reset. We also need to tie 174 * make sure we don't overwrite them.
264 * the PCI-E Phy reset to the PCI-E reset.
265 */ 175 */
266 set = AR_WA_RESET_EN | AR_WA_POR_SHORT; 176
267 clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE; 177 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
268 REG_RMW(ah, AR_WA, set, clr); 178 wow_pattern->mask_bytes,
179 i + 2,
180 wow_pattern->pattern_len);
181 kfree(wow_pattern);
182
269 } 183 }
270 184
271 /* 185}
272 * set the power states appropriately and enable PME
273 */
274 set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
275 AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
276 186
277 /* 187int ath9k_suspend(struct ieee80211_hw *hw,
278 * set and clear WOW_PME_CLEAR registers for the chip 188 struct cfg80211_wowlan *wowlan)
279 * to generate next wow signal. 189{
280 */ 190 struct ath_softc *sc = hw->priv;
281 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 191 struct ath_hw *ah = sc->sc_ah;
282 clr = AR_PMCTRL_WOW_PME_CLR; 192 struct ath_common *common = ath9k_hw_common(ah);
283 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); 193 u32 wow_triggers_enabled = 0;
194 int ret = 0;
284 195
285 /* 196 mutex_lock(&sc->mutex);
286 * Setup for:
287 * - beacon misses
288 * - magic pattern
289 * - keep alive timeout
290 * - pattern matching
291 */
292 197
293 /* 198 ath_cancel_work(sc);
294 * Program default values for pattern backoff, aifs/slot/KAL count, 199 ath_stop_ani(sc);
295 * beacon miss timeout, KAL timeout, etc. 200 del_timer_sync(&sc->rx_poll_timer);
296 */
297 set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
298 REG_SET_BIT(ah, AR_WOW_PATTERN, set);
299 201
300 set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | 202 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
301 AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | 203 ath_dbg(common, ANY, "Device not present\n");
302 AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); 204 ret = -EINVAL;
303 REG_SET_BIT(ah, AR_WOW_COUNT, set); 205 goto fail_wow;
206 }
304 207
305 if (pattern_enable & AH_WOW_BEACON_MISS) 208 if (WARN_ON(!wowlan)) {
306 set = AR_WOW_BEACON_TIMO; 209 ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
307 /* We are not using beacon miss, program a large value */ 210 ret = -EINVAL;
308 else 211 goto fail_wow;
309 set = AR_WOW_BEACON_TIMO_MAX; 212 }
310 213
311 REG_WRITE(ah, AR_WOW_BCN_TIMO, set); 214 if (!device_can_wakeup(sc->dev)) {
215 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
216 ret = 1;
217 goto fail_wow;
218 }
312 219
313 /* 220 /*
314 * Keep alive timo in ms except AR9280 221 * none of the sta vifs are associated
222 * and we are not currently handling multivif
223 * cases, for instance we have to seperately
224 * configure 'keep alive frame' for each
225 * STA.
315 */ 226 */
316 if (!pattern_enable)
317 set = AR_WOW_KEEP_ALIVE_NEVER;
318 else
319 set = KAL_TIMEOUT * 32;
320 227
321 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); 228 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
229 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
230 ret = 1;
231 goto fail_wow;
232 }
233
234 if (sc->nvifs > 1) {
235 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
236 ret = 1;
237 goto fail_wow;
238 }
239
240 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
241
242 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
243 wow_triggers_enabled);
244
245 ath9k_ps_wakeup(sc);
246
247 ath9k_stop_btcoex(sc);
322 248
323 /* 249 /*
324 * Keep alive delay in us. based on 'power on clock', 250 * Enable wake up on recieving disassoc/deauth
325 * therefore in usec 251 * frame by default.
326 */ 252 */
327 set = KAL_DELAY * 1000; 253 ath9k_wow_add_disassoc_deauth_pattern(sc);
328 REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); 254
255 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
256 ath9k_wow_add_pattern(sc, wowlan);
329 257
258 spin_lock_bh(&sc->sc_pcu_lock);
330 /* 259 /*
331 * Create keep alive pattern to respond to beacons 260 * To avoid false wake, we enable beacon miss interrupt only
261 * when we go to sleep. We save the current interrupt mask
262 * so we can restore it after the system wakes up
332 */ 263 */
333 ath9k_wow_create_keep_alive_pattern(ah); 264 sc->wow_intr_before_sleep = ah->imask;
265 ah->imask &= ~ATH9K_INT_GLOBAL;
266 ath9k_hw_disable_interrupts(ah);
267 ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
268 ath9k_hw_set_interrupts(ah);
269 ath9k_hw_enable_interrupts(ah);
270
271 spin_unlock_bh(&sc->sc_pcu_lock);
334 272
335 /* 273 /*
336 * Configure MAC WoW Registers 274 * we can now sync irq and kill any running tasklets, since we already
275 * disabled interrupts and not holding a spin lock
337 */ 276 */
338 set = 0; 277 synchronize_irq(sc->irq);
339 /* Send keep alive timeouts anyway */ 278 tasklet_kill(&sc->intr_tq);
340 clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
341 279
342 if (pattern_enable & AH_WOW_LINK_CHANGE) 280 ath9k_hw_wow_enable(ah, wow_triggers_enabled);
343 wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
344 else
345 set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
346 281
347 set = AR_WOW_KEEP_ALIVE_FAIL_DIS; 282 ath9k_ps_restore(sc);
348 REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); 283 ath_dbg(common, ANY, "WoW enabled in ath9k\n");
284 atomic_inc(&sc->wow_sleep_proc_intr);
349 285
350 /* 286fail_wow:
351 * we are relying on a bmiss failure. ensure we have 287 mutex_unlock(&sc->mutex);
352 * enough threshold to prevent false positives 288 return ret;
353 */ 289}
354 REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, 290
355 AR_WOW_BMISSTHRESHOLD); 291int ath9k_resume(struct ieee80211_hw *hw)
292{
293 struct ath_softc *sc = hw->priv;
294 struct ath_hw *ah = sc->sc_ah;
295 struct ath_common *common = ath9k_hw_common(ah);
296 u32 wow_status;
356 297
357 set = 0; 298 mutex_lock(&sc->mutex);
358 clr = 0;
359 299
360 if (pattern_enable & AH_WOW_BEACON_MISS) { 300 ath9k_ps_wakeup(sc);
361 set = AR_WOW_BEACON_FAIL_EN; 301
362 wow_event_mask |= AR_WOW_BEACON_FAIL; 302 spin_lock_bh(&sc->sc_pcu_lock);
363 } else { 303
364 clr = AR_WOW_BEACON_FAIL_EN; 304 ath9k_hw_disable_interrupts(ah);
305 ah->imask = sc->wow_intr_before_sleep;
306 ath9k_hw_set_interrupts(ah);
307 ath9k_hw_enable_interrupts(ah);
308
309 spin_unlock_bh(&sc->sc_pcu_lock);
310
311 wow_status = ath9k_hw_wow_wakeup(ah);
312
313 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
314 /*
315 * some devices may not pick beacon miss
316 * as the reason they woke up so we add
317 * that here for that shortcoming.
318 */
319 wow_status |= AH_WOW_BEACON_MISS;
320 atomic_dec(&sc->wow_got_bmiss_intr);
321 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
365 } 322 }
366 323
367 REG_RMW(ah, AR_WOW_BCN_EN, set, clr); 324 atomic_dec(&sc->wow_sleep_proc_intr);
368 325
369 set = 0; 326 if (wow_status) {
370 clr = 0; 327 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
371 /* 328 ath9k_hw_wow_event_to_string(wow_status), wow_status);
372 * Enable the magic packet registers
373 */
374 if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
375 set = AR_WOW_MAGIC_EN;
376 wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
377 } else {
378 clr = AR_WOW_MAGIC_EN;
379 } 329 }
380 set |= AR_WOW_MAC_INTR_EN;
381 REG_RMW(ah, AR_WOW_PATTERN, set, clr);
382 330
383 REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, 331 ath_restart_work(sc);
384 AR_WOW_PATTERN_SUPPORTED); 332 ath9k_start_btcoex(sc);
385 333
386 /* 334 ath9k_ps_restore(sc);
387 * Set the power states appropriately and enable PME 335 mutex_unlock(&sc->mutex);
388 */
389 clr = 0;
390 set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
391 AR_PMCTRL_PWR_PM_CTRL_ENA;
392 336
393 clr = AR_PCIE_PM_CTRL_ENA; 337 return 0;
394 REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); 338}
395 339
396 /* 340void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
397 * this is needed to prevent the chip waking up 341{
398 * the host within 3-4 seconds with certain 342 struct ath_softc *sc = hw->priv;
399 * platform/BIOS. The fix is to enable
400 * D1 & D3 to match original definition and
401 * also match the OTP value. Anyway this
402 * is more related to SW WOW.
403 */
404 clr = AR_PMCTRL_PWR_STATE_D1D3;
405 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
406 343
407 set = AR_PMCTRL_PWR_STATE_D1D3_REAL; 344 mutex_lock(&sc->mutex);
408 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); 345 device_init_wakeup(sc->dev, 1);
346 device_set_wakeup_enable(sc->dev, enabled);
347 mutex_unlock(&sc->mutex);
348}
409 349
410 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); 350void ath9k_init_wow(struct ieee80211_hw *hw)
351{
352 struct ath_softc *sc = hw->priv;
411 353
412 /* to bring down WOW power low margin */ 354 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
413 set = BIT(13); 355 (sc->driver_data & ATH9K_PCI_WOW) &&
414 REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); 356 device_can_wakeup(sc->dev))
415 /* HW WoW */ 357 hw->wiphy->wowlan = &ath9k_wowlan_support;
416 clr = BIT(5);
417 REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
418 358
419 ath9k_hw_set_powermode_wow_sleep(ah); 359 atomic_set(&sc->wow_sleep_proc_intr, -1);
420 ah->wow_event_mask = wow_event_mask; 360 atomic_set(&sc->wow_got_bmiss_intr, -1);
421} 361}
422EXPORT_SYMBOL(ath9k_hw_wow_enable);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 09cdbcd09739..24846d91554b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1786,6 +1786,9 @@ bool ath_drain_all_txq(struct ath_softc *sc)
1786 if (!ATH_TXQ_SETUP(sc, i)) 1786 if (!ATH_TXQ_SETUP(sc, i))
1787 continue; 1787 continue;
1788 1788
1789 if (!sc->tx.txq[i].axq_depth)
1790 continue;
1791
1789 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum)) 1792 if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
1790 npend |= BIT(i); 1793 npend |= BIT(i);
1791 } 1794 }
@@ -2749,6 +2752,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2749 } 2752 }
2750} 2753}
2751 2754
2755#ifdef CONFIG_ATH9K_TX99
2756
2752int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, 2757int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
2753 struct ath_tx_control *txctl) 2758 struct ath_tx_control *txctl)
2754{ 2759{
@@ -2791,3 +2796,5 @@ int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
2791 2796
2792 return 0; 2797 return 0;
2793} 2798}
2799
2800#endif /* CONFIG_ATH9K_TX99 */
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 1217c52ab28e..9e154732afaa 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -37,17 +37,18 @@ static int __ath_regd_init(struct ath_regulatory *reg);
37 37
38/* We enable active scan on these a case by case basis by regulatory domain */ 38/* We enable active scan on these a case by case basis by regulatory domain */
39#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 39#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
40 NL80211_RRF_PASSIVE_SCAN) 40 NL80211_RRF_NO_IR)
41#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ 41#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
42 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) 42 NL80211_RRF_NO_IR | \
43 NL80211_RRF_NO_OFDM)
43 44
44/* We allow IBSS on these on a case by case basis by regulatory domain */ 45/* We allow IBSS on these on a case by case basis by regulatory domain */
45#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\ 46#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
46 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 47 NL80211_RRF_NO_IR)
47#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\ 48#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
48 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 49 NL80211_RRF_NO_IR)
49#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\ 50#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\
50 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) 51 NL80211_RRF_NO_IR)
51 52
52#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ 53#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
53 ATH9K_2GHZ_CH12_13, \ 54 ATH9K_2GHZ_CH12_13, \
@@ -113,6 +114,87 @@ static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
113 } 114 }
114}; 115};
115 116
117static bool dynamic_country_user_possible(struct ath_regulatory *reg)
118{
119 if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
120 return true;
121
122 switch (reg->country_code) {
123 case CTRY_UNITED_STATES:
124 case CTRY_JAPAN1:
125 case CTRY_JAPAN2:
126 case CTRY_JAPAN3:
127 case CTRY_JAPAN4:
128 case CTRY_JAPAN5:
129 case CTRY_JAPAN6:
130 case CTRY_JAPAN7:
131 case CTRY_JAPAN8:
132 case CTRY_JAPAN9:
133 case CTRY_JAPAN10:
134 case CTRY_JAPAN11:
135 case CTRY_JAPAN12:
136 case CTRY_JAPAN13:
137 case CTRY_JAPAN14:
138 case CTRY_JAPAN15:
139 case CTRY_JAPAN16:
140 case CTRY_JAPAN17:
141 case CTRY_JAPAN18:
142 case CTRY_JAPAN19:
143 case CTRY_JAPAN20:
144 case CTRY_JAPAN21:
145 case CTRY_JAPAN22:
146 case CTRY_JAPAN23:
147 case CTRY_JAPAN24:
148 case CTRY_JAPAN25:
149 case CTRY_JAPAN26:
150 case CTRY_JAPAN27:
151 case CTRY_JAPAN28:
152 case CTRY_JAPAN29:
153 case CTRY_JAPAN30:
154 case CTRY_JAPAN31:
155 case CTRY_JAPAN32:
156 case CTRY_JAPAN33:
157 case CTRY_JAPAN34:
158 case CTRY_JAPAN35:
159 case CTRY_JAPAN36:
160 case CTRY_JAPAN37:
161 case CTRY_JAPAN38:
162 case CTRY_JAPAN39:
163 case CTRY_JAPAN40:
164 case CTRY_JAPAN41:
165 case CTRY_JAPAN42:
166 case CTRY_JAPAN43:
167 case CTRY_JAPAN44:
168 case CTRY_JAPAN45:
169 case CTRY_JAPAN46:
170 case CTRY_JAPAN47:
171 case CTRY_JAPAN48:
172 case CTRY_JAPAN49:
173 case CTRY_JAPAN50:
174 case CTRY_JAPAN51:
175 case CTRY_JAPAN52:
176 case CTRY_JAPAN53:
177 case CTRY_JAPAN54:
178 case CTRY_JAPAN55:
179 case CTRY_JAPAN56:
180 case CTRY_JAPAN57:
181 case CTRY_JAPAN58:
182 case CTRY_JAPAN59:
183 return false;
184 }
185
186 return true;
187}
188
189static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
190{
191 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
192 return false;
193 if (!dynamic_country_user_possible(reg))
194 return false;
195 return true;
196}
197
116static inline bool is_wwr_sku(u16 regd) 198static inline bool is_wwr_sku(u16 regd)
117{ 199{
118 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) && 200 return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
@@ -177,118 +259,139 @@ static bool ath_is_radar_freq(u16 center_freq)
177 return (center_freq >= 5260 && center_freq <= 5700); 259 return (center_freq >= 5260 && center_freq <= 5700);
178} 260}
179 261
262static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
263 struct ieee80211_channel *ch)
264{
265 const struct ieee80211_reg_rule *reg_rule;
266
267 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
268 if (IS_ERR(reg_rule))
269 return;
270
271 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
272 if (ch->flags & IEEE80211_CHAN_NO_IR)
273 ch->flags &= ~IEEE80211_CHAN_NO_IR;
274}
275
276static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
277{
278 struct ieee80211_channel *ch;
279
280 ch = ieee80211_get_channel(wiphy, center_freq);
281 if (!ch)
282 return;
283
284 ath_force_clear_no_ir_chan(wiphy, ch);
285}
286
287static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
288{
289 ch->flags |= IEEE80211_CHAN_NO_IR;
290}
291
292static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
293{
294 struct ieee80211_channel *ch;
295
296 ch = ieee80211_get_channel(wiphy, center_freq);
297 if (!ch)
298 return;
299
300 ath_force_no_ir_chan(ch);
301}
302
303static void
304__ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
305 struct ath_regulatory *reg,
306 enum nl80211_reg_initiator initiator,
307 struct ieee80211_channel *ch)
308{
309 if (ath_is_radar_freq(ch->center_freq) ||
310 (ch->flags & IEEE80211_CHAN_RADAR))
311 return;
312
313 switch (initiator) {
314 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
315 ath_force_clear_no_ir_chan(wiphy, ch);
316 break;
317 case NL80211_REGDOM_SET_BY_USER:
318 if (ath_reg_dyn_country_user_allow(reg))
319 ath_force_clear_no_ir_chan(wiphy, ch);
320 break;
321 default:
322 if (ch->beacon_found)
323 ch->flags &= ~IEEE80211_CHAN_NO_IR;
324 }
325}
326
180/* 327/*
181 * N.B: These exception rules do not apply radar freqs. 328 * These exception rules do not apply radar frequencies.
182 * 329 *
183 * - We enable adhoc (or beaconing) if allowed by 11d 330 * - We enable initiating radiation if the country IE says its fine:
184 * - We enable active scan if the channel is allowed by 11d
185 * - If no country IE has been processed and a we determine we have 331 * - If no country IE has been processed and a we determine we have
186 * received a beacon on a channel we can enable active scan and 332 * received a beacon on a channel we can enable initiating radiation.
187 * adhoc (or beaconing).
188 */ 333 */
189static void 334static void
190ath_reg_apply_beaconing_flags(struct wiphy *wiphy, 335ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
336 struct ath_regulatory *reg,
191 enum nl80211_reg_initiator initiator) 337 enum nl80211_reg_initiator initiator)
192{ 338{
193 enum ieee80211_band band; 339 enum ieee80211_band band;
194 struct ieee80211_supported_band *sband; 340 struct ieee80211_supported_band *sband;
195 const struct ieee80211_reg_rule *reg_rule;
196 struct ieee80211_channel *ch; 341 struct ieee80211_channel *ch;
197 unsigned int i; 342 unsigned int i;
198 343
199 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 344 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
200
201 if (!wiphy->bands[band]) 345 if (!wiphy->bands[band])
202 continue; 346 continue;
203
204 sband = wiphy->bands[band]; 347 sband = wiphy->bands[band];
205
206 for (i = 0; i < sband->n_channels; i++) { 348 for (i = 0; i < sband->n_channels; i++) {
207
208 ch = &sband->channels[i]; 349 ch = &sband->channels[i];
209 350 __ath_reg_apply_beaconing_flags(wiphy, reg,
210 if (ath_is_radar_freq(ch->center_freq) || 351 initiator, ch);
211 (ch->flags & IEEE80211_CHAN_RADAR))
212 continue;
213
214 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
215 reg_rule = freq_reg_info(wiphy, ch->center_freq);
216 if (IS_ERR(reg_rule))
217 continue;
218 /*
219 * If 11d had a rule for this channel ensure
220 * we enable adhoc/beaconing if it allows us to
221 * use it. Note that we would have disabled it
222 * by applying our static world regdomain by
223 * default during init, prior to calling our
224 * regulatory_hint().
225 */
226 if (!(reg_rule->flags &
227 NL80211_RRF_NO_IBSS))
228 ch->flags &=
229 ~IEEE80211_CHAN_NO_IBSS;
230 if (!(reg_rule->flags &
231 NL80211_RRF_PASSIVE_SCAN))
232 ch->flags &=
233 ~IEEE80211_CHAN_PASSIVE_SCAN;
234 } else {
235 if (ch->beacon_found)
236 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
237 IEEE80211_CHAN_PASSIVE_SCAN);
238 }
239 } 352 }
240 } 353 }
241
242} 354}
243 355
244/* Allows active scan scan on Ch 12 and 13 */ 356/**
357 * ath_reg_apply_ir_flags()
358 * @wiphy: the wiphy to use
359 * @initiator: the regulatory hint initiator
360 *
361 * If no country IE has been received always enable passive scan
362 * and no-ibss on these channels. This is only done for specific
363 * regulatory SKUs.
364 *
365 * If a country IE has been received check its rule for this
366 * channel first before enabling active scan. The passive scan
367 * would have been enforced by the initial processing of our
368 * custom regulatory domain.
369 */
245static void 370static void
246ath_reg_apply_active_scan_flags(struct wiphy *wiphy, 371ath_reg_apply_ir_flags(struct wiphy *wiphy,
247 enum nl80211_reg_initiator initiator) 372 struct ath_regulatory *reg,
373 enum nl80211_reg_initiator initiator)
248{ 374{
249 struct ieee80211_supported_band *sband; 375 struct ieee80211_supported_band *sband;
250 struct ieee80211_channel *ch;
251 const struct ieee80211_reg_rule *reg_rule;
252 376
253 sband = wiphy->bands[IEEE80211_BAND_2GHZ]; 377 sband = wiphy->bands[IEEE80211_BAND_2GHZ];
254 if (!sband) 378 if (!sband)
255 return; 379 return;
256 380
257 /* 381 switch(initiator) {
258 * If no country IE has been received always enable active scan 382 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
259 * on these channels. This is only done for specific regulatory SKUs 383 ath_force_clear_no_ir_freq(wiphy, 2467);
260 */ 384 ath_force_clear_no_ir_freq(wiphy, 2472);
261 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 385 break;
262 ch = &sband->channels[11]; /* CH 12 */ 386 case NL80211_REGDOM_SET_BY_USER:
263 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 387 if (!ath_reg_dyn_country_user_allow(reg))
264 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 388 break;
265 ch = &sband->channels[12]; /* CH 13 */ 389 ath_force_clear_no_ir_freq(wiphy, 2467);
266 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 390 ath_force_clear_no_ir_freq(wiphy, 2472);
267 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 391 break;
268 return; 392 default:
269 } 393 ath_force_no_ir_freq(wiphy, 2467);
270 394 ath_force_no_ir_freq(wiphy, 2472);
271 /*
272 * If a country IE has been received check its rule for this
273 * channel first before enabling active scan. The passive scan
274 * would have been enforced by the initial processing of our
275 * custom regulatory domain.
276 */
277
278 ch = &sband->channels[11]; /* CH 12 */
279 reg_rule = freq_reg_info(wiphy, ch->center_freq);
280 if (!IS_ERR(reg_rule)) {
281 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
282 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
283 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
284 }
285
286 ch = &sband->channels[12]; /* CH 13 */
287 reg_rule = freq_reg_info(wiphy, ch->center_freq);
288 if (!IS_ERR(reg_rule)) {
289 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
290 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
291 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
292 } 395 }
293} 396}
294 397
@@ -320,8 +423,7 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
320 */ 423 */
321 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 424 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
322 ch->flags |= IEEE80211_CHAN_RADAR | 425 ch->flags |= IEEE80211_CHAN_RADAR |
323 IEEE80211_CHAN_NO_IBSS | 426 IEEE80211_CHAN_NO_IR;
324 IEEE80211_CHAN_PASSIVE_SCAN;
325 } 427 }
326} 428}
327 429
@@ -335,12 +437,15 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy,
335 case 0x66: 437 case 0x66:
336 case 0x67: 438 case 0x67:
337 case 0x6C: 439 case 0x6C:
338 ath_reg_apply_beaconing_flags(wiphy, initiator); 440 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
339 break; 441 break;
340 case 0x68: 442 case 0x68:
341 ath_reg_apply_beaconing_flags(wiphy, initiator); 443 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
342 ath_reg_apply_active_scan_flags(wiphy, initiator); 444 ath_reg_apply_ir_flags(wiphy, reg, initiator);
343 break; 445 break;
446 default:
447 if (ath_reg_dyn_country_user_allow(reg))
448 ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
344 } 449 }
345} 450}
346 451
@@ -393,89 +498,6 @@ static void ath_reg_dyn_country(struct wiphy *wiphy,
393 reg_initiator_name(request->initiator)); 498 reg_initiator_name(request->initiator));
394} 499}
395 500
396static bool dynamic_country_user_possible(struct ath_regulatory *reg)
397{
398 if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
399 return true;
400
401 switch (reg->country_code) {
402 case CTRY_UNITED_STATES:
403 case CTRY_JAPAN1:
404 case CTRY_JAPAN2:
405 case CTRY_JAPAN3:
406 case CTRY_JAPAN4:
407 case CTRY_JAPAN5:
408 case CTRY_JAPAN6:
409 case CTRY_JAPAN7:
410 case CTRY_JAPAN8:
411 case CTRY_JAPAN9:
412 case CTRY_JAPAN10:
413 case CTRY_JAPAN11:
414 case CTRY_JAPAN12:
415 case CTRY_JAPAN13:
416 case CTRY_JAPAN14:
417 case CTRY_JAPAN15:
418 case CTRY_JAPAN16:
419 case CTRY_JAPAN17:
420 case CTRY_JAPAN18:
421 case CTRY_JAPAN19:
422 case CTRY_JAPAN20:
423 case CTRY_JAPAN21:
424 case CTRY_JAPAN22:
425 case CTRY_JAPAN23:
426 case CTRY_JAPAN24:
427 case CTRY_JAPAN25:
428 case CTRY_JAPAN26:
429 case CTRY_JAPAN27:
430 case CTRY_JAPAN28:
431 case CTRY_JAPAN29:
432 case CTRY_JAPAN30:
433 case CTRY_JAPAN31:
434 case CTRY_JAPAN32:
435 case CTRY_JAPAN33:
436 case CTRY_JAPAN34:
437 case CTRY_JAPAN35:
438 case CTRY_JAPAN36:
439 case CTRY_JAPAN37:
440 case CTRY_JAPAN38:
441 case CTRY_JAPAN39:
442 case CTRY_JAPAN40:
443 case CTRY_JAPAN41:
444 case CTRY_JAPAN42:
445 case CTRY_JAPAN43:
446 case CTRY_JAPAN44:
447 case CTRY_JAPAN45:
448 case CTRY_JAPAN46:
449 case CTRY_JAPAN47:
450 case CTRY_JAPAN48:
451 case CTRY_JAPAN49:
452 case CTRY_JAPAN50:
453 case CTRY_JAPAN51:
454 case CTRY_JAPAN52:
455 case CTRY_JAPAN53:
456 case CTRY_JAPAN54:
457 case CTRY_JAPAN55:
458 case CTRY_JAPAN56:
459 case CTRY_JAPAN57:
460 case CTRY_JAPAN58:
461 case CTRY_JAPAN59:
462 return false;
463 }
464
465 return true;
466}
467
468static void ath_reg_dyn_country_user(struct wiphy *wiphy,
469 struct ath_regulatory *reg,
470 struct regulatory_request *request)
471{
472 if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
473 return;
474 if (!dynamic_country_user_possible(reg))
475 return;
476 ath_reg_dyn_country(wiphy, reg, request);
477}
478
479void ath_reg_notifier_apply(struct wiphy *wiphy, 501void ath_reg_notifier_apply(struct wiphy *wiphy,
480 struct regulatory_request *request, 502 struct regulatory_request *request,
481 struct ath_regulatory *reg) 503 struct ath_regulatory *reg)
@@ -508,7 +530,8 @@ void ath_reg_notifier_apply(struct wiphy *wiphy,
508 case NL80211_REGDOM_SET_BY_DRIVER: 530 case NL80211_REGDOM_SET_BY_DRIVER:
509 break; 531 break;
510 case NL80211_REGDOM_SET_BY_USER: 532 case NL80211_REGDOM_SET_BY_USER:
511 ath_reg_dyn_country_user(wiphy, reg, request); 533 if (ath_reg_dyn_country_user_allow(reg))
534 ath_reg_dyn_country(wiphy, reg, request);
512 break; 535 break;
513 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 536 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
514 ath_reg_dyn_country(wiphy, reg, request); 537 ath_reg_dyn_country(wiphy, reg, request);
@@ -609,7 +632,7 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
609 const struct ieee80211_regdomain *regd; 632 const struct ieee80211_regdomain *regd;
610 633
611 wiphy->reg_notifier = reg_notifier; 634 wiphy->reg_notifier = reg_notifier;
612 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 635 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
613 636
614 if (ath_is_world_regd(reg)) { 637 if (ath_is_world_regd(reg)) {
615 /* 638 /*
@@ -617,7 +640,8 @@ ath_regd_init_wiphy(struct ath_regulatory *reg,
617 * saved on the wiphy orig_* parameters 640 * saved on the wiphy orig_* parameters
618 */ 641 */
619 regd = ath_world_regdomain(reg); 642 regd = ath_world_regdomain(reg);
620 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 643 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
644 REGULATORY_COUNTRY_IE_FOLLOW_POWER;
621 } else { 645 } else {
622 /* 646 /*
623 * This gets applied in the case of the absence of CRDA, 647 * This gets applied in the case of the absence of CRDA,
diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h
index c02dbc618724..3c2ef0c32f72 100644
--- a/drivers/net/wireless/ath/wcn36xx/hal.h
+++ b/drivers/net/wireless/ath/wcn36xx/hal.h
@@ -2644,7 +2644,7 @@ struct wcn36xx_hal_trigger_ba_rsp_candidate {
2644 struct add_ba_info ba_info[STACFG_MAX_TC]; 2644 struct add_ba_info ba_info[STACFG_MAX_TC];
2645} __packed; 2645} __packed;
2646 2646
2647struct wcn36xx_hal_trigget_ba_req_candidate { 2647struct wcn36xx_hal_trigger_ba_req_candidate {
2648 u8 sta_index; 2648 u8 sta_index;
2649 u8 tid_bitmap; 2649 u8 tid_bitmap;
2650} __packed; 2650} __packed;
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index 7839b31e4826..e64a6784079e 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -641,7 +641,8 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
641 dev_kfree_skb(skb); 641 dev_kfree_skb(skb);
642 } 642 }
643 643
644 if (changed & BSS_CHANGED_BEACON_ENABLED) { 644 if (changed & BSS_CHANGED_BEACON_ENABLED ||
645 changed & BSS_CHANGED_BEACON) {
645 wcn36xx_dbg(WCN36XX_DBG_MAC, 646 wcn36xx_dbg(WCN36XX_DBG_MAC,
646 "mac bss changed beacon enabled %d\n", 647 "mac bss changed beacon enabled %d\n",
647 bss_conf->enable_beacon); 648 bss_conf->enable_beacon);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 366339421d4f..823631cdb872 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -115,6 +115,22 @@ static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta,
115 } 115 }
116} 116}
117 117
118static void wcn36xx_smd_set_sta_default_ht_params(
119 struct wcn36xx_hal_config_sta_params *sta_params)
120{
121 sta_params->ht_capable = 1;
122 sta_params->tx_channel_width_set = 1;
123 sta_params->lsig_txop_protection = 1;
124 sta_params->max_ampdu_size = 3;
125 sta_params->max_ampdu_density = 5;
126 sta_params->max_amsdu_size = 0;
127 sta_params->sgi_20Mhz = 1;
128 sta_params->sgi_40mhz = 1;
129 sta_params->green_field_capable = 1;
130 sta_params->delayed_ba_support = 0;
131 sta_params->dsss_cck_mode_40mhz = 1;
132}
133
118static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, 134static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
119 struct ieee80211_vif *vif, 135 struct ieee80211_vif *vif,
120 struct ieee80211_sta *sta, 136 struct ieee80211_sta *sta,
@@ -172,6 +188,7 @@ static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn,
172 sizeof(priv_sta->supported_rates)); 188 sizeof(priv_sta->supported_rates));
173 } else { 189 } else {
174 wcn36xx_set_default_rates(&sta_params->supported_rates); 190 wcn36xx_set_default_rates(&sta_params->supported_rates);
191 wcn36xx_smd_set_sta_default_ht_params(sta_params);
175 } 192 }
176} 193}
177 194
@@ -1838,7 +1855,7 @@ out:
1838int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) 1855int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
1839{ 1856{
1840 struct wcn36xx_hal_trigger_ba_req_msg msg_body; 1857 struct wcn36xx_hal_trigger_ba_req_msg msg_body;
1841 struct wcn36xx_hal_trigget_ba_req_candidate *candidate; 1858 struct wcn36xx_hal_trigger_ba_req_candidate *candidate;
1842 int ret = 0; 1859 int ret = 0;
1843 1860
1844 mutex_lock(&wcn->hal_mutex); 1861 mutex_lock(&wcn->hal_mutex);
@@ -1849,7 +1866,7 @@ int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index)
1849 msg_body.header.len += sizeof(*candidate); 1866 msg_body.header.len += sizeof(*candidate);
1850 PREPARE_HAL_BUF(wcn->hal_buf, msg_body); 1867 PREPARE_HAL_BUF(wcn->hal_buf, msg_body);
1851 1868
1852 candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *) 1869 candidate = (struct wcn36xx_hal_trigger_ba_req_candidate *)
1853 (wcn->hal_buf + sizeof(msg_body)); 1870 (wcn->hal_buf + sizeof(msg_body));
1854 candidate->sta_index = sta_index; 1871 candidate->sta_index = sta_index;
1855 candidate->tid_bitmap = 1; 1872 candidate->tid_bitmap = 1;
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 58b63833e8e7..8fa5cbace5ab 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -54,7 +54,7 @@ enum wcn36xx_debug_mask {
54}; 54};
55 55
56#define wcn36xx_err(fmt, arg...) \ 56#define wcn36xx_err(fmt, arg...) \
57 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg); 57 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg)
58 58
59#define wcn36xx_warn(fmt, arg...) \ 59#define wcn36xx_warn(fmt, arg...) \
60 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) 60 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg)
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index 54e36fcb3954..fcfed6b99a62 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -4,13 +4,12 @@ config BRCMUTIL
4config BRCMSMAC 4config BRCMSMAC
5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver" 5 tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
6 depends on MAC80211 6 depends on MAC80211
7 depends on BCMA 7 depends on BCMA_POSSIBLE
8 select BCMA
8 select NEW_LEDS if BCMA_DRIVER_GPIO 9 select NEW_LEDS if BCMA_DRIVER_GPIO
9 select LEDS_CLASS if BCMA_DRIVER_GPIO 10 select LEDS_CLASS if BCMA_DRIVER_GPIO
10 select BRCMUTIL 11 select BRCMUTIL
11 select FW_LOADER 12 select FW_LOADER
12 select CRC_CCITT
13 select CRC8
14 select CORDIC 13 select CORDIC
15 ---help--- 14 ---help---
16 This module adds support for PCIe wireless adapters based on Broadcom 15 This module adds support for PCIe wireless adapters based on Broadcom
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
index 8e9b1221b32c..2082402d4b63 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile
@@ -28,7 +28,8 @@ brcmfmac-objs += \
28 fweh.o \ 28 fweh.o \
29 fwsignal.o \ 29 fwsignal.o \
30 p2p.o \ 30 p2p.o \
31 dhd_cdc.o \ 31 proto.o \
32 bcdc.o \
32 dhd_common.o \ 33 dhd_common.o \
33 dhd_linux.o \ 34 dhd_linux.o \
34 btcoex.o 35 btcoex.o
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
new file mode 100644
index 000000000000..06848e426f9a
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright (c) 2010 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/*******************************************************************************
18 * Communicates with the dongle by using dcmd codes.
19 * For certain dcmd codes, the dongle interprets string data from the host.
20 ******************************************************************************/
21
22#include <linux/types.h>
23#include <linux/netdevice.h>
24
25#include <brcmu_utils.h>
26#include <brcmu_wifi.h>
27
28#include "dhd.h"
29#include "dhd_bus.h"
30#include "fwsignal.h"
31#include "dhd_dbg.h"
32#include "tracepoint.h"
33#include "proto.h"
34#include "bcdc.h"
35
36struct brcmf_proto_bcdc_dcmd {
37 __le32 cmd; /* dongle command value */
38 __le32 len; /* lower 16: output buflen;
39 * upper 16: input buflen (excludes header) */
40 __le32 flags; /* flag defns given below */
41 __le32 status; /* status code returned from the device */
42};
43
44/* Max valid buffer size that can be sent to the dongle */
45#define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
46
47/* BCDC flag definitions */
48#define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */
49#define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
50#define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */
51#define BCDC_DCMD_IF_SHIFT 12
52#define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
53#define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
54#define BCDC_DCMD_ID(flags) \
55 (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT)
56
57/*
58 * BCDC header - Broadcom specific extension of CDC.
59 * Used on data packets to convey priority across USB.
60 */
61#define BCDC_HEADER_LEN 4
62#define BCDC_PROTO_VER 2 /* Protocol version */
63#define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
64#define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
65#define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
66#define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
67#define BCDC_PRIORITY_MASK 0x7
68#define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
69#define BCDC_FLAG2_IF_SHIFT 0
70
71#define BCDC_GET_IF_IDX(hdr) \
72 ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT))
73#define BCDC_SET_IF_IDX(hdr, idx) \
74 ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \
75 ((idx) << BCDC_FLAG2_IF_SHIFT)))
76
77/**
78 * struct brcmf_proto_bcdc_header - BCDC header format
79 *
80 * @flags: flags contain protocol and checksum info.
81 * @priority: 802.1d priority and USB flow control info (bit 4:7).
82 * @flags2: additional flags containing dongle interface index.
83 * @data_offset: start of packet data. header is following by firmware signals.
84 */
85struct brcmf_proto_bcdc_header {
86 u8 flags;
87 u8 priority;
88 u8 flags2;
89 u8 data_offset;
90};
91
92/*
93 * maximum length of firmware signal data between
94 * the BCDC header and packet data in the tx path.
95 */
96#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
97
98#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
99#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
100 * (amount of header tha might be added)
101 * plus any space that might be needed
102 * for bus alignment padding.
103 */
104#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for
105 * round off at the end of buffer
106 * Currently is SDIO
107 */
108
109struct brcmf_bcdc {
110 u16 reqid;
111 u8 bus_header[BUS_HEADER_LEN];
112 struct brcmf_proto_bcdc_dcmd msg;
113 unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
114};
115
116static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr)
117{
118 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
119 int len = le32_to_cpu(bcdc->msg.len) +
120 sizeof(struct brcmf_proto_bcdc_dcmd);
121
122 brcmf_dbg(BCDC, "Enter\n");
123
124 /* NOTE : bcdc->msg.len holds the desired length of the buffer to be
125 * returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area
126 * is actually sent to the dongle
127 */
128 if (len > BCDC_MAX_MSG_SIZE)
129 len = BCDC_MAX_MSG_SIZE;
130
131 /* Send request */
132 return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len);
133}
134
135static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
136{
137 int ret;
138 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
139
140 brcmf_dbg(BCDC, "Enter\n");
141 len += sizeof(struct brcmf_proto_bcdc_dcmd);
142 do {
143 ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg,
144 len);
145 if (ret < 0)
146 break;
147 } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id);
148
149 return ret;
150}
151
152static int
153brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
154 void *buf, uint len)
155{
156 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
157 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
158 void *info;
159 int ret = 0, retries = 0;
160 u32 id, flags;
161
162 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
163
164 memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
165
166 msg->cmd = cpu_to_le32(cmd);
167 msg->len = cpu_to_le32(len);
168 flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT);
169 flags = (flags & ~BCDC_DCMD_IF_MASK) |
170 (ifidx << BCDC_DCMD_IF_SHIFT);
171 msg->flags = cpu_to_le32(flags);
172
173 if (buf)
174 memcpy(bcdc->buf, buf, len);
175
176 ret = brcmf_proto_bcdc_msg(drvr);
177 if (ret < 0) {
178 brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
179 ret);
180 goto done;
181 }
182
183retry:
184 /* wait for interrupt and get first fragment */
185 ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
186 if (ret < 0)
187 goto done;
188
189 flags = le32_to_cpu(msg->flags);
190 id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
191
192 if ((id < bcdc->reqid) && (++retries < RETRIES))
193 goto retry;
194 if (id != bcdc->reqid) {
195 brcmf_err("%s: unexpected request id %d (expected %d)\n",
196 brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
197 ret = -EINVAL;
198 goto done;
199 }
200
201 /* Check info buffer */
202 info = (void *)&msg[1];
203
204 /* Copy info buffer */
205 if (buf) {
206 if (ret < (int)len)
207 len = ret;
208 memcpy(buf, info, len);
209 }
210
211 /* Check the ERROR flag */
212 if (flags & BCDC_DCMD_ERROR)
213 ret = le32_to_cpu(msg->status);
214
215done:
216 return ret;
217}
218
219static int
220brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
221 void *buf, uint len)
222{
223 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
224 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
225 int ret = 0;
226 u32 flags, id;
227
228 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
229
230 memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
231
232 msg->cmd = cpu_to_le32(cmd);
233 msg->len = cpu_to_le32(len);
234 flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET;
235 flags = (flags & ~BCDC_DCMD_IF_MASK) |
236 (ifidx << BCDC_DCMD_IF_SHIFT);
237 msg->flags = cpu_to_le32(flags);
238
239 if (buf)
240 memcpy(bcdc->buf, buf, len);
241
242 ret = brcmf_proto_bcdc_msg(drvr);
243 if (ret < 0)
244 goto done;
245
246 ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
247 if (ret < 0)
248 goto done;
249
250 flags = le32_to_cpu(msg->flags);
251 id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
252
253 if (id != bcdc->reqid) {
254 brcmf_err("%s: unexpected request id %d (expected %d)\n",
255 brcmf_ifname(drvr, ifidx), id, bcdc->reqid);
256 ret = -EINVAL;
257 goto done;
258 }
259
260 /* Check the ERROR flag */
261 if (flags & BCDC_DCMD_ERROR)
262 ret = le32_to_cpu(msg->status);
263
264done:
265 return ret;
266}
267
268static void
269brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
270 struct sk_buff *pktbuf)
271{
272 struct brcmf_proto_bcdc_header *h;
273
274 brcmf_dbg(BCDC, "Enter\n");
275
276 /* Push BDC header used to convey priority for buses that don't */
277 skb_push(pktbuf, BCDC_HEADER_LEN);
278
279 h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
280
281 h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT);
282 if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
283 h->flags |= BCDC_FLAG_SUM_NEEDED;
284
285 h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
286 h->flags2 = 0;
287 h->data_offset = offset;
288 BCDC_SET_IF_IDX(h, ifidx);
289 trace_brcmf_bcdchdr(pktbuf->data);
290}
291
292static int
293brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
294 struct sk_buff *pktbuf)
295{
296 struct brcmf_proto_bcdc_header *h;
297
298 brcmf_dbg(BCDC, "Enter\n");
299
300 /* Pop BCDC header used to convey priority for buses that don't */
301 if (pktbuf->len <= BCDC_HEADER_LEN) {
302 brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
303 pktbuf->len, BCDC_HEADER_LEN);
304 return -EBADE;
305 }
306
307 trace_brcmf_bcdchdr(pktbuf->data);
308 h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
309
310 *ifidx = BCDC_GET_IF_IDX(h);
311 if (*ifidx >= BRCMF_MAX_IFS) {
312 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
313 return -EBADE;
314 }
315 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
316 * events this is easy because it contains the bssidx which maps
317 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
318 * bssidx 1 is used for p2p0 and no data can be received or
319 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
320 */
321 if (*ifidx)
322 (*ifidx)++;
323
324 if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
325 BCDC_PROTO_VER) {
326 brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
327 brcmf_ifname(drvr, *ifidx), h->flags);
328 return -EBADE;
329 }
330
331 if (h->flags & BCDC_FLAG_SUM_GOOD) {
332 brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
333 brcmf_ifname(drvr, *ifidx), h->flags);
334 pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
335 }
336
337 pktbuf->priority = h->priority & BCDC_PRIORITY_MASK;
338
339 skb_pull(pktbuf, BCDC_HEADER_LEN);
340 if (do_fws)
341 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
342 else
343 skb_pull(pktbuf, h->data_offset << 2);
344
345 if (pktbuf->len == 0)
346 return -ENODATA;
347 return 0;
348}
349
350int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
351{
352 struct brcmf_bcdc *bcdc;
353
354 bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC);
355 if (!bcdc)
356 goto fail;
357
358 /* ensure that the msg buf directly follows the cdc msg struct */
359 if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
360 brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n");
361 goto fail;
362 }
363
364 drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush;
365 drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
366 drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
367 drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
368 drvr->proto->pd = bcdc;
369
370 drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
371 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
372 sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN;
373 return 0;
374
375fail:
376 kfree(bcdc);
377 return -ENOMEM;
378}
379
380void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
381{
382 kfree(drvr->proto->pd);
383 drvr->proto->pd = NULL;
384}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
new file mode 100644
index 000000000000..17e8c039ff32
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef BRCMFMAC_BCDC_H
17#define BRCMFMAC_BCDC_H
18
19
20int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
21void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
22
23
24#endif /* BRCMFMAC_BCDC_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3e10b801eee8..91651ec7f13f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -17,7 +17,6 @@
17 17
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/netdevice.h> 19#include <linux/netdevice.h>
20#include <linux/export.h>
21#include <linux/pci.h> 20#include <linux/pci.h>
22#include <linux/pci_ids.h> 21#include <linux/pci_ids.h>
23#include <linux/sched.h> 22#include <linux/sched.h>
@@ -774,7 +773,6 @@ out:
774 773
775 return ret; 774 return ret;
776} 775}
777EXPORT_SYMBOL(brcmf_sdio_probe);
778 776
779int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) 777int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
780{ 778{
@@ -791,7 +789,6 @@ int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
791 789
792 return 0; 790 return 0;
793} 791}
794EXPORT_SYMBOL(brcmf_sdio_remove);
795 792
796void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) 793void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
797{ 794{
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index abc9ceca70f3..a511c27122b8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -158,10 +158,21 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
158 } 158 }
159 } 159 }
160 160
161 if (err_ret) 161 if (err_ret) {
162 brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", 162 /*
163 rw ? "write" : "read", func, regaddr, *byte, err_ret); 163 * SleepCSR register access can fail when
164 164 * waking up the device so reduce this noise
165 * in the logs.
166 */
167 if (regaddr != SBSDIO_FUNC1_SLEEPCSR)
168 brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
169 rw ? "write" : "read", func, regaddr, *byte,
170 err_ret);
171 else
172 brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
173 rw ? "write" : "read", func, regaddr, *byte,
174 err_ret);
175 }
165 return err_ret; 176 return err_ret;
166} 177}
167 178
@@ -269,6 +280,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
269int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) 280int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
270{ 281{
271 int err_ret = 0; 282 int err_ret = 0;
283 struct mmc_host *host;
284 struct sdio_func *func;
285 uint max_blocks;
272 286
273 brcmf_dbg(SDIO, "\n"); 287 brcmf_dbg(SDIO, "\n");
274 288
@@ -290,6 +304,20 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
290 304
291 brcmf_sdioh_enablefuncs(sdiodev); 305 brcmf_sdioh_enablefuncs(sdiodev);
292 306
307 /*
308 * determine host related variables after brcmf_sdio_probe()
309 * as func->cur_blksize is properly set and F2 init has been
310 * completed successfully.
311 */
312 func = sdiodev->func[2];
313 host = func->card->host;
314 sdiodev->sg_support = host->max_segs > 1;
315 max_blocks = min_t(uint, host->max_blk_count, 511u);
316 sdiodev->max_request_size = min_t(uint, host->max_req_size,
317 max_blocks * func->cur_blksize);
318 sdiodev->max_segment_count = min_t(uint, host->max_segs,
319 SG_MAX_SINGLE_ALLOC);
320 sdiodev->max_segment_size = host->max_seg_size;
293out: 321out:
294 sdio_release_host(sdiodev->func[1]); 322 sdio_release_host(sdiodev->func[1]);
295 brcmf_dbg(SDIO, "Done\n"); 323 brcmf_dbg(SDIO, "Done\n");
@@ -318,8 +346,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
318 int err; 346 int err;
319 struct brcmf_sdio_dev *sdiodev; 347 struct brcmf_sdio_dev *sdiodev;
320 struct brcmf_bus *bus_if; 348 struct brcmf_bus *bus_if;
321 struct mmc_host *host;
322 uint max_blocks;
323 349
324 brcmf_dbg(SDIO, "Enter\n"); 350 brcmf_dbg(SDIO, "Enter\n");
325 brcmf_dbg(SDIO, "Class=%x\n", func->class); 351 brcmf_dbg(SDIO, "Class=%x\n", func->class);
@@ -367,19 +393,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
367 goto fail; 393 goto fail;
368 } 394 }
369 395
370 /*
371 * determine host related variables after brcmf_sdio_probe()
372 * as func->cur_blksize is properly set and F2 init has been
373 * completed successfully.
374 */
375 host = func->card->host;
376 sdiodev->sg_support = host->max_segs > 1;
377 max_blocks = min_t(uint, host->max_blk_count, 511u);
378 sdiodev->max_request_size = min_t(uint, host->max_req_size,
379 max_blocks * func->cur_blksize);
380 sdiodev->max_segment_count = min_t(uint, host->max_segs,
381 SG_MAX_SINGLE_ALLOC);
382 sdiodev->max_segment_size = host->max_seg_size;
383 brcmf_dbg(SDIO, "F2 init completed...\n"); 396 brcmf_dbg(SDIO, "F2 init completed...\n");
384 return 0; 397 return 0;
385 398
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 899a2ada5b82..252024bcbc3b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -25,184 +25,14 @@
25 25
26#include "fweh.h" 26#include "fweh.h"
27 27
28/*******************************************************************************
29 * IO codes that are interpreted by dongle firmware
30 ******************************************************************************/
31#define BRCMF_C_GET_VERSION 1
32#define BRCMF_C_UP 2
33#define BRCMF_C_DOWN 3
34#define BRCMF_C_SET_PROMISC 10
35#define BRCMF_C_GET_RATE 12
36#define BRCMF_C_GET_INFRA 19
37#define BRCMF_C_SET_INFRA 20
38#define BRCMF_C_GET_AUTH 21
39#define BRCMF_C_SET_AUTH 22
40#define BRCMF_C_GET_BSSID 23
41#define BRCMF_C_GET_SSID 25
42#define BRCMF_C_SET_SSID 26
43#define BRCMF_C_TERMINATED 28
44#define BRCMF_C_GET_CHANNEL 29
45#define BRCMF_C_SET_CHANNEL 30
46#define BRCMF_C_GET_SRL 31
47#define BRCMF_C_SET_SRL 32
48#define BRCMF_C_GET_LRL 33
49#define BRCMF_C_SET_LRL 34
50#define BRCMF_C_GET_RADIO 37
51#define BRCMF_C_SET_RADIO 38
52#define BRCMF_C_GET_PHYTYPE 39
53#define BRCMF_C_SET_KEY 45
54#define BRCMF_C_SET_PASSIVE_SCAN 49
55#define BRCMF_C_SCAN 50
56#define BRCMF_C_SCAN_RESULTS 51
57#define BRCMF_C_DISASSOC 52
58#define BRCMF_C_REASSOC 53
59#define BRCMF_C_SET_ROAM_TRIGGER 55
60#define BRCMF_C_SET_ROAM_DELTA 57
61#define BRCMF_C_GET_BCNPRD 75
62#define BRCMF_C_SET_BCNPRD 76
63#define BRCMF_C_GET_DTIMPRD 77
64#define BRCMF_C_SET_DTIMPRD 78
65#define BRCMF_C_SET_COUNTRY 84
66#define BRCMF_C_GET_PM 85
67#define BRCMF_C_SET_PM 86
68#define BRCMF_C_GET_CURR_RATESET 114
69#define BRCMF_C_GET_AP 117
70#define BRCMF_C_SET_AP 118
71#define BRCMF_C_GET_RSSI 127
72#define BRCMF_C_GET_WSEC 133
73#define BRCMF_C_SET_WSEC 134
74#define BRCMF_C_GET_PHY_NOISE 135
75#define BRCMF_C_GET_BSS_INFO 136
76#define BRCMF_C_GET_BANDLIST 140
77#define BRCMF_C_SET_SCB_TIMEOUT 158
78#define BRCMF_C_GET_PHYLIST 180
79#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
80#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
81#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
82#define BRCMF_C_GET_VALID_CHANNELS 217
83#define BRCMF_C_GET_KEY_PRIMARY 235
84#define BRCMF_C_SET_KEY_PRIMARY 236
85#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
86#define BRCMF_C_GET_VAR 262
87#define BRCMF_C_SET_VAR 263
88
89/* phy types (returned by WLC_GET_PHYTPE) */
90#define WLC_PHY_TYPE_A 0
91#define WLC_PHY_TYPE_B 1
92#define WLC_PHY_TYPE_G 2
93#define WLC_PHY_TYPE_N 4
94#define WLC_PHY_TYPE_LP 5
95#define WLC_PHY_TYPE_SSN 6
96#define WLC_PHY_TYPE_HT 7
97#define WLC_PHY_TYPE_LCN 8
98#define WLC_PHY_TYPE_NULL 0xf
99
100#define TOE_TX_CSUM_OL 0x00000001 28#define TOE_TX_CSUM_OL 0x00000001
101#define TOE_RX_CSUM_OL 0x00000002 29#define TOE_RX_CSUM_OL 0x00000002
102 30
103#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
104
105/* size of brcmf_scan_params not including variable length array */
106#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
107
108/* masks for channel and ssid count */
109#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
110#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
111
112/* primary (ie tx) key */
113#define BRCMF_PRIMARY_KEY (1 << 1)
114
115/* For supporting multiple interfaces */ 31/* For supporting multiple interfaces */
116#define BRCMF_MAX_IFS 16 32#define BRCMF_MAX_IFS 16
117 33
118#define DOT11_BSSTYPE_ANY 2
119#define DOT11_MAX_DEFAULT_KEYS 4 34#define DOT11_MAX_DEFAULT_KEYS 4
120 35
121#define BRCMF_ESCAN_REQ_VERSION 1
122
123#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
124
125#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
126#define BRCMF_STA_ASSOC 0x10 /* Associated */
127
128#define BRCMF_E_STATUS_SUCCESS 0
129#define BRCMF_E_STATUS_FAIL 1
130#define BRCMF_E_STATUS_TIMEOUT 2
131#define BRCMF_E_STATUS_NO_NETWORKS 3
132#define BRCMF_E_STATUS_ABORT 4
133#define BRCMF_E_STATUS_NO_ACK 5
134#define BRCMF_E_STATUS_UNSOLICITED 6
135#define BRCMF_E_STATUS_ATTEMPT 7
136#define BRCMF_E_STATUS_PARTIAL 8
137#define BRCMF_E_STATUS_NEWSCAN 9
138#define BRCMF_E_STATUS_NEWASSOC 10
139#define BRCMF_E_STATUS_11HQUIET 11
140#define BRCMF_E_STATUS_SUPPRESS 12
141#define BRCMF_E_STATUS_NOCHANS 13
142#define BRCMF_E_STATUS_CS_ABORT 15
143#define BRCMF_E_STATUS_ERROR 16
144
145#define BRCMF_E_REASON_INITIAL_ASSOC 0
146#define BRCMF_E_REASON_LOW_RSSI 1
147#define BRCMF_E_REASON_DEAUTH 2
148#define BRCMF_E_REASON_DISASSOC 3
149#define BRCMF_E_REASON_BCNS_LOST 4
150#define BRCMF_E_REASON_MINTXRATE 9
151#define BRCMF_E_REASON_TXFAIL 10
152
153#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
154#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
155#define BRCMF_E_REASON_DIRECTED_ROAM 6
156#define BRCMF_E_REASON_TSPEC_REJECTED 7
157#define BRCMF_E_REASON_BETTER_AP 8
158
159#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
160#define BRCMF_E_PRUNE_BCAST_BSSID 2
161#define BRCMF_E_PRUNE_MAC_DENY 3
162#define BRCMF_E_PRUNE_MAC_NA 4
163#define BRCMF_E_PRUNE_REG_PASSV 5
164#define BRCMF_E_PRUNE_SPCT_MGMT 6
165#define BRCMF_E_PRUNE_RADAR 7
166#define BRCMF_E_RSN_MISMATCH 8
167#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
168#define BRCMF_E_PRUNE_BASIC_RATES 10
169#define BRCMF_E_PRUNE_CIPHER_NA 12
170#define BRCMF_E_PRUNE_KNOWN_STA 13
171#define BRCMF_E_PRUNE_WDS_PEER 15
172#define BRCMF_E_PRUNE_QBSS_LOAD 16
173#define BRCMF_E_PRUNE_HOME_AP 17
174
175#define BRCMF_E_SUP_OTHER 0
176#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
177#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
178#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
179#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
180#define BRCMF_E_SUP_PW_KEY_CIPHER 5
181#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
182#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
183#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
184#define BRCMF_E_SUP_MSG3_NO_GTK 9
185#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
186#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
187#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
188#define BRCMF_E_SUP_SEND_FAIL 13
189#define BRCMF_E_SUP_DEAUTH 14
190
191#define BRCMF_E_IF_ADD 1
192#define BRCMF_E_IF_DEL 2
193#define BRCMF_E_IF_CHANGE 3
194
195#define BRCMF_E_IF_FLAG_NOIF 1
196
197#define BRCMF_E_IF_ROLE_STA 0
198#define BRCMF_E_IF_ROLE_AP 1
199#define BRCMF_E_IF_ROLE_WDS 2
200
201#define BRCMF_E_LINK_BCN_LOSS 1
202#define BRCMF_E_LINK_DISASSOC 2
203#define BRCMF_E_LINK_ASSOC_REC 3
204#define BRCMF_E_LINK_BSSCFG_DIS 4
205
206/* Small, medium and maximum buffer size for dcmd 36/* Small, medium and maximum buffer size for dcmd
207 */ 37 */
208#define BRCMF_DCMD_SMLEN 256 38#define BRCMF_DCMD_SMLEN 256
@@ -211,291 +41,10 @@
211 41
212#define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 42#define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256
213 43
214/* Pattern matching filter. Specifies an offset within received packets to 44/* Length of firmware version string stored for
215 * start matching, the pattern to match, the size of the pattern, and a bitmask 45 * ethtool driver info which uses 32 bytes as well.
216 * that indicates which bits within the pattern should be matched.
217 */
218struct brcmf_pkt_filter_pattern_le {
219 /*
220 * Offset within received packet to start pattern matching.
221 * Offset '0' is the first byte of the ethernet header.
222 */
223 __le32 offset;
224 /* Size of the pattern. Bitmask must be the same size.*/
225 __le32 size_bytes;
226 /*
227 * Variable length mask and pattern data. mask starts at offset 0.
228 * Pattern immediately follows mask.
229 */
230 u8 mask_and_pattern[1];
231};
232
233/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
234struct brcmf_pkt_filter_le {
235 __le32 id; /* Unique filter id, specified by app. */
236 __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
237 __le32 negate_match; /* Negate the result of filter matches */
238 union { /* Filter definitions */
239 struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
240 } u;
241};
242
243/* IOVAR "pkt_filter_enable" parameter. */
244struct brcmf_pkt_filter_enable_le {
245 __le32 id; /* Unique filter id */
246 __le32 enable; /* Enable/disable bool */
247};
248
249/* BSS info structure
250 * Applications MUST CHECK ie_offset field and length field to access IEs and
251 * next bss_info structure in a vector (in struct brcmf_scan_results)
252 */
253struct brcmf_bss_info_le {
254 __le32 version; /* version field */
255 __le32 length; /* byte length of data in this record,
256 * starting at version and including IEs
257 */
258 u8 BSSID[ETH_ALEN];
259 __le16 beacon_period; /* units are Kusec */
260 __le16 capability; /* Capability information */
261 u8 SSID_len;
262 u8 SSID[32];
263 struct {
264 __le32 count; /* # rates in this set */
265 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
266 } rateset; /* supported rates */
267 __le16 chanspec; /* chanspec for bss */
268 __le16 atim_window; /* units are Kusec */
269 u8 dtim_period; /* DTIM period */
270 __le16 RSSI; /* receive signal strength (in dBm) */
271 s8 phy_noise; /* noise (in dBm) */
272
273 u8 n_cap; /* BSS is 802.11N Capable */
274 /* 802.11N BSS Capabilities (based on HT_CAP_*): */
275 __le32 nbss_cap;
276 u8 ctl_ch; /* 802.11N BSS control channel number */
277 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
278 u8 flags; /* flags */
279 u8 reserved[3]; /* Reserved for expansion of BSS properties */
280 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
281
282 __le16 ie_offset; /* offset at which IEs start, from beginning */
283 __le32 ie_length; /* byte length of Information Elements */
284 __le16 SNR; /* average SNR of during frame reception */
285 /* Add new fields here */
286 /* variable length Information Elements */
287};
288
289struct brcm_rateset_le {
290 /* # rates in this set */
291 __le32 count;
292 /* rates in 500kbps units w/hi bit set if basic */
293 u8 rates[BRCMF_MAXRATES_IN_SET];
294};
295
296struct brcmf_ssid {
297 u32 SSID_len;
298 unsigned char SSID[32];
299};
300
301struct brcmf_ssid_le {
302 __le32 SSID_len;
303 unsigned char SSID[32];
304};
305
306struct brcmf_scan_params_le {
307 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
308 u8 bssid[ETH_ALEN]; /* default: bcast */
309 s8 bss_type; /* default: any,
310 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
311 */
312 u8 scan_type; /* flags, 0 use default */
313 __le32 nprobes; /* -1 use default, number of probes per channel */
314 __le32 active_time; /* -1 use default, dwell time per channel for
315 * active scanning
316 */
317 __le32 passive_time; /* -1 use default, dwell time per channel
318 * for passive scanning
319 */
320 __le32 home_time; /* -1 use default, dwell time for the
321 * home channel between channel scans
322 */
323 __le32 channel_num; /* count of channels and ssids that follow
324 *
325 * low half is count of channels in
326 * channel_list, 0 means default (use all
327 * available channels)
328 *
329 * high half is entries in struct brcmf_ssid
330 * array that follows channel_list, aligned for
331 * s32 (4 bytes) meaning an odd channel count
332 * implies a 2-byte pad between end of
333 * channel_list and first ssid
334 *
335 * if ssid count is zero, single ssid in the
336 * fixed parameter portion is assumed, otherwise
337 * ssid in the fixed portion is ignored
338 */
339 __le16 channel_list[1]; /* list of chanspecs */
340};
341
342struct brcmf_scan_results {
343 u32 buflen;
344 u32 version;
345 u32 count;
346 struct brcmf_bss_info_le bss_info_le[];
347};
348
349struct brcmf_escan_params_le {
350 __le32 version;
351 __le16 action;
352 __le16 sync_id;
353 struct brcmf_scan_params_le params_le;
354};
355
356struct brcmf_escan_result_le {
357 __le32 buflen;
358 __le32 version;
359 __le16 sync_id;
360 __le16 bss_count;
361 struct brcmf_bss_info_le bss_info_le;
362};
363
364#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
365 sizeof(struct brcmf_bss_info_le))
366
367/* used for association with a specific BSSID and chanspec list */
368struct brcmf_assoc_params_le {
369 /* 00:00:00:00:00:00: broadcast scan */
370 u8 bssid[ETH_ALEN];
371 /* 0: all available channels, otherwise count of chanspecs in
372 * chanspec_list */
373 __le32 chanspec_num;
374 /* list of chanspecs */
375 __le16 chanspec_list[1];
376};
377
378/* used for join with or without a specific bssid and channel list */
379struct brcmf_join_params {
380 struct brcmf_ssid_le ssid_le;
381 struct brcmf_assoc_params_le params_le;
382};
383
384/* scan params for extended join */
385struct brcmf_join_scan_params_le {
386 u8 scan_type; /* 0 use default, active or passive scan */
387 __le32 nprobes; /* -1 use default, nr of probes per channel */
388 __le32 active_time; /* -1 use default, dwell time per channel for
389 * active scanning
390 */
391 __le32 passive_time; /* -1 use default, dwell time per channel
392 * for passive scanning
393 */
394 __le32 home_time; /* -1 use default, dwell time for the home
395 * channel between channel scans
396 */
397};
398
399/* extended join params */
400struct brcmf_ext_join_params_le {
401 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
402 struct brcmf_join_scan_params_le scan_le;
403 struct brcmf_assoc_params_le assoc_le;
404};
405
406struct brcmf_wsec_key {
407 u32 index; /* key index */
408 u32 len; /* key length */
409 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
410 u32 pad_1[18];
411 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
412 u32 flags; /* misc flags */
413 u32 pad_2[3];
414 u32 iv_initialized; /* has IV been initialized already? */
415 u32 pad_3;
416 /* Rx IV */
417 struct {
418 u32 hi; /* upper 32 bits of IV */
419 u16 lo; /* lower 16 bits of IV */
420 } rxiv;
421 u32 pad_4[2];
422 u8 ea[ETH_ALEN]; /* per station */
423};
424
425/*
426 * dongle requires same struct as above but with fields in little endian order
427 */ 46 */
428struct brcmf_wsec_key_le { 47#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32
429 __le32 index; /* key index */
430 __le32 len; /* key length */
431 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
432 __le32 pad_1[18];
433 __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
434 __le32 flags; /* misc flags */
435 __le32 pad_2[3];
436 __le32 iv_initialized; /* has IV been initialized already? */
437 __le32 pad_3;
438 /* Rx IV */
439 struct {
440 __le32 hi; /* upper 32 bits of IV */
441 __le16 lo; /* lower 16 bits of IV */
442 } rxiv;
443 __le32 pad_4[2];
444 u8 ea[ETH_ALEN]; /* per station */
445};
446
447/* Used to get specific STA parameters */
448struct brcmf_scb_val_le {
449 __le32 val;
450 u8 ea[ETH_ALEN];
451};
452
453/* channel encoding */
454struct brcmf_channel_info_le {
455 __le32 hw_channel;
456 __le32 target_channel;
457 __le32 scan_channel;
458};
459
460struct brcmf_sta_info_le {
461 __le16 ver; /* version of this struct */
462 __le16 len; /* length in bytes of this structure */
463 __le16 cap; /* sta's advertised capabilities */
464 __le32 flags; /* flags defined below */
465 __le32 idle; /* time since data pkt rx'd from sta */
466 u8 ea[ETH_ALEN]; /* Station address */
467 __le32 count; /* # rates in this set */
468 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
469 /* w/hi bit set if basic */
470 __le32 in; /* seconds elapsed since associated */
471 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
472 __le32 tx_pkts; /* # of packets transmitted */
473 __le32 tx_failures; /* # of packets failed */
474 __le32 rx_ucast_pkts; /* # of unicast packets received */
475 __le32 rx_mcast_pkts; /* # of multicast packets received */
476 __le32 tx_rate; /* Rate of last successful tx frame */
477 __le32 rx_rate; /* Rate of last successful rx frame */
478 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
479 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
480};
481
482struct brcmf_chanspec_list {
483 __le32 count; /* # of entries */
484 __le32 element[1]; /* variable length uint32 list */
485};
486
487/*
488 * WLC_E_PROBRESP_MSG
489 * WLC_E_P2P_PROBREQ_MSG
490 * WLC_E_ACTION_FRAME_RX
491 */
492struct brcmf_rx_mgmt_data {
493 __be16 version;
494 __be16 chanspec;
495 __be32 rssi;
496 __be32 mactime;
497 __be32 rate;
498};
499 48
500/* Bus independent dongle command */ 49/* Bus independent dongle command */
501struct brcmf_dcmd { 50struct brcmf_dcmd {
@@ -535,7 +84,7 @@ struct brcmf_fws_info; /* firmware signalling info */
535struct brcmf_pub { 84struct brcmf_pub {
536 /* Linkage ponters */ 85 /* Linkage ponters */
537 struct brcmf_bus *bus_if; 86 struct brcmf_bus *bus_if;
538 struct brcmf_proto *prot; 87 struct brcmf_proto *proto;
539 struct brcmf_cfg80211_info *config; 88 struct brcmf_cfg80211_info *config;
540 89
541 /* Internal brcmf items */ 90 /* Internal brcmf items */
@@ -544,7 +93,7 @@ struct brcmf_pub {
544 u8 wme_dp; /* wme discard priority */ 93 u8 wme_dp; /* wme discard priority */
545 94
546 /* Dongle media info */ 95 /* Dongle media info */
547 unsigned long drv_version; /* Version of dongle-resident driver */ 96 char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
548 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ 97 u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
549 98
550 /* Multicast data packets sent to dongle */ 99 /* Multicast data packets sent to dongle */
@@ -566,14 +115,6 @@ struct brcmf_pub {
566#endif 115#endif
567}; 116};
568 117
569struct brcmf_if_event {
570 u8 ifidx;
571 u8 action;
572 u8 flags;
573 u8 bssidx;
574 u8 role;
575};
576
577/* forward declarations */ 118/* forward declarations */
578struct brcmf_cfg80211_vif; 119struct brcmf_cfg80211_vif;
579struct brcmf_fws_mac_descriptor; 120struct brcmf_fws_mac_descriptor;
@@ -635,16 +176,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
635/* Return pointer to interface name */ 176/* Return pointer to interface name */
636char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 177char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
637 178
638/* Query dongle */
639int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
640 void *buf, uint len);
641int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
642 void *buf, uint len);
643
644/* Remove any protocol-specific data header. */
645int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
646 struct sk_buff *rxp);
647
648int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); 179int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
649struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, 180struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
650 char *name, u8 *mac_addr); 181 char *name, u8 *mac_addr);
@@ -655,4 +186,7 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp);
655void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, 186void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp,
656 bool success); 187 bool success);
657 188
189/* Sets dongle media info (drv_version, mac address). */
190int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
191
658#endif /* _BRCMF_H_ */ 192#endif /* _BRCMF_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index a6eb09e5d46f..6a54905528be 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -34,6 +34,7 @@ struct brcmf_bus_dcmd {
34/** 34/**
35 * struct brcmf_bus_ops - bus callback operations. 35 * struct brcmf_bus_ops - bus callback operations.
36 * 36 *
37 * @preinit: execute bus/device specific dongle init commands (optional).
37 * @init: prepare for communication with dongle. 38 * @init: prepare for communication with dongle.
38 * @stop: clear pending frames, disable data flow. 39 * @stop: clear pending frames, disable data flow.
39 * @txdata: send a data frame to the dongle. When the data 40 * @txdata: send a data frame to the dongle. When the data
@@ -51,6 +52,7 @@ struct brcmf_bus_dcmd {
51 * indicated otherwise these callbacks are mandatory. 52 * indicated otherwise these callbacks are mandatory.
52 */ 53 */
53struct brcmf_bus_ops { 54struct brcmf_bus_ops {
55 int (*preinit)(struct device *dev);
54 int (*init)(struct device *dev); 56 int (*init)(struct device *dev);
55 void (*stop)(struct device *dev); 57 void (*stop)(struct device *dev);
56 int (*txdata)(struct device *dev, struct sk_buff *skb); 58 int (*txdata)(struct device *dev, struct sk_buff *skb);
@@ -85,7 +87,6 @@ struct brcmf_bus {
85 unsigned long tx_realloc; 87 unsigned long tx_realloc;
86 u32 chip; 88 u32 chip;
87 u32 chiprev; 89 u32 chiprev;
88 struct list_head dcmd_list;
89 90
90 struct brcmf_bus_ops *ops; 91 struct brcmf_bus_ops *ops;
91}; 92};
@@ -93,6 +94,13 @@ struct brcmf_bus {
93/* 94/*
94 * callback wrappers 95 * callback wrappers
95 */ 96 */
97static inline int brcmf_bus_preinit(struct brcmf_bus *bus)
98{
99 if (!bus->ops->preinit)
100 return 0;
101 return bus->ops->preinit(bus->dev);
102}
103
96static inline int brcmf_bus_init(struct brcmf_bus *bus) 104static inline int brcmf_bus_init(struct brcmf_bus *bus)
97{ 105{
98 return bus->ops->init(bus->dev); 106 return bus->ops->init(bus->dev);
@@ -139,7 +147,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt,
139void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); 147void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp);
140 148
141/* Indication from bus module regarding presence/insertion of dongle. */ 149/* Indication from bus module regarding presence/insertion of dongle. */
142int brcmf_attach(uint bus_hdrlen, struct device *dev); 150int brcmf_attach(struct device *dev);
143/* Indication from bus module regarding removal/absence of dongle */ 151/* Indication from bus module regarding removal/absence of dongle */
144void brcmf_detach(struct device *dev); 152void brcmf_detach(struct device *dev);
145/* Indication from bus module that dongle should be reset */ 153/* Indication from bus module that dongle should be reset */
@@ -151,6 +159,9 @@ void brcmf_txflowblock(struct device *dev, bool state);
151void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); 159void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
152 160
153int brcmf_bus_start(struct device *dev); 161int brcmf_bus_start(struct device *dev);
162s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data,
163 u32 len);
164void brcmf_bus_add_txhdrlen(struct device *dev, uint len);
154 165
155#ifdef CONFIG_BRCMFMAC_SDIO 166#ifdef CONFIG_BRCMFMAC_SDIO
156void brcmf_sdio_exit(void); 167void brcmf_sdio_exit(void);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
deleted file mode 100644
index dd85401063cb..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ /dev/null
@@ -1,392 +0,0 @@
1/*
2 * Copyright (c) 2010 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/*******************************************************************************
18 * Communicates with the dongle by using dcmd codes.
19 * For certain dcmd codes, the dongle interprets string data from the host.
20 ******************************************************************************/
21
22#include <linux/types.h>
23#include <linux/netdevice.h>
24
25#include <brcmu_utils.h>
26#include <brcmu_wifi.h>
27
28#include "dhd.h"
29#include "dhd_proto.h"
30#include "dhd_bus.h"
31#include "fwsignal.h"
32#include "dhd_dbg.h"
33#include "tracepoint.h"
34
35struct brcmf_proto_cdc_dcmd {
36 __le32 cmd; /* dongle command value */
37 __le32 len; /* lower 16: output buflen;
38 * upper 16: input buflen (excludes header) */
39 __le32 flags; /* flag defns given below */
40 __le32 status; /* status code returned from the device */
41};
42
43/* Max valid buffer size that can be sent to the dongle */
44#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
45
46/* CDC flag definitions */
47#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
48#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
49#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
50#define CDC_DCMD_IF_SHIFT 12
51#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
52#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
53#define CDC_DCMD_ID(flags) \
54 (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
55
56/*
57 * BDC header - Broadcom specific extension of CDC.
58 * Used on data packets to convey priority across USB.
59 */
60#define BDC_HEADER_LEN 4
61#define BDC_PROTO_VER 2 /* Protocol version */
62#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
63#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
64#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
65#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
66#define BDC_PRIORITY_MASK 0x7
67#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
68#define BDC_FLAG2_IF_SHIFT 0
69
70#define BDC_GET_IF_IDX(hdr) \
71 ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
72#define BDC_SET_IF_IDX(hdr, idx) \
73 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
74 ((idx) << BDC_FLAG2_IF_SHIFT)))
75
76/**
77 * struct brcmf_proto_bdc_header - BDC header format
78 *
79 * @flags: flags contain protocol and checksum info.
80 * @priority: 802.1d priority and USB flow control info (bit 4:7).
81 * @flags2: additional flags containing dongle interface index.
82 * @data_offset: start of packet data. header is following by firmware signals.
83 */
84struct brcmf_proto_bdc_header {
85 u8 flags;
86 u8 priority;
87 u8 flags2;
88 u8 data_offset;
89};
90
91/*
92 * maximum length of firmware signal data between
93 * the BDC header and packet data in the tx path.
94 */
95#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
96
97#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
98#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
99 * (amount of header tha might be added)
100 * plus any space that might be needed
101 * for bus alignment padding.
102 */
103#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for
104 * round off at the end of buffer
105 * Currently is SDIO
106 */
107
108struct brcmf_proto {
109 u16 reqid;
110 u8 bus_header[BUS_HEADER_LEN];
111 struct brcmf_proto_cdc_dcmd msg;
112 unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
113};
114
115static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
116{
117 struct brcmf_proto *prot = drvr->prot;
118 int len = le32_to_cpu(prot->msg.len) +
119 sizeof(struct brcmf_proto_cdc_dcmd);
120
121 brcmf_dbg(CDC, "Enter\n");
122
123 /* NOTE : cdc->msg.len holds the desired length of the buffer to be
124 * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
125 * is actually sent to the dongle
126 */
127 if (len > CDC_MAX_MSG_SIZE)
128 len = CDC_MAX_MSG_SIZE;
129
130 /* Send request */
131 return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len);
132}
133
134static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
135{
136 int ret;
137 struct brcmf_proto *prot = drvr->prot;
138
139 brcmf_dbg(CDC, "Enter\n");
140 len += sizeof(struct brcmf_proto_cdc_dcmd);
141 do {
142 ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg,
143 len);
144 if (ret < 0)
145 break;
146 } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
147
148 return ret;
149}
150
151int
152brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
153 void *buf, uint len)
154{
155 struct brcmf_proto *prot = drvr->prot;
156 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
157 void *info;
158 int ret = 0, retries = 0;
159 u32 id, flags;
160
161 brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
162
163 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
164
165 msg->cmd = cpu_to_le32(cmd);
166 msg->len = cpu_to_le32(len);
167 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
168 flags = (flags & ~CDC_DCMD_IF_MASK) |
169 (ifidx << CDC_DCMD_IF_SHIFT);
170 msg->flags = cpu_to_le32(flags);
171
172 if (buf)
173 memcpy(prot->buf, buf, len);
174
175 ret = brcmf_proto_cdc_msg(drvr);
176 if (ret < 0) {
177 brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n",
178 ret);
179 goto done;
180 }
181
182retry:
183 /* wait for interrupt and get first fragment */
184 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
185 if (ret < 0)
186 goto done;
187
188 flags = le32_to_cpu(msg->flags);
189 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
190
191 if ((id < prot->reqid) && (++retries < RETRIES))
192 goto retry;
193 if (id != prot->reqid) {
194 brcmf_err("%s: unexpected request id %d (expected %d)\n",
195 brcmf_ifname(drvr, ifidx), id, prot->reqid);
196 ret = -EINVAL;
197 goto done;
198 }
199
200 /* Check info buffer */
201 info = (void *)&msg[1];
202
203 /* Copy info buffer */
204 if (buf) {
205 if (ret < (int)len)
206 len = ret;
207 memcpy(buf, info, len);
208 }
209
210 /* Check the ERROR flag */
211 if (flags & CDC_DCMD_ERROR)
212 ret = le32_to_cpu(msg->status);
213
214done:
215 return ret;
216}
217
218int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
219 void *buf, uint len)
220{
221 struct brcmf_proto *prot = drvr->prot;
222 struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
223 int ret = 0;
224 u32 flags, id;
225
226 brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len);
227
228 memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
229
230 msg->cmd = cpu_to_le32(cmd);
231 msg->len = cpu_to_le32(len);
232 flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
233 flags = (flags & ~CDC_DCMD_IF_MASK) |
234 (ifidx << CDC_DCMD_IF_SHIFT);
235 msg->flags = cpu_to_le32(flags);
236
237 if (buf)
238 memcpy(prot->buf, buf, len);
239
240 ret = brcmf_proto_cdc_msg(drvr);
241 if (ret < 0)
242 goto done;
243
244 ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
245 if (ret < 0)
246 goto done;
247
248 flags = le32_to_cpu(msg->flags);
249 id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
250
251 if (id != prot->reqid) {
252 brcmf_err("%s: unexpected request id %d (expected %d)\n",
253 brcmf_ifname(drvr, ifidx), id, prot->reqid);
254 ret = -EINVAL;
255 goto done;
256 }
257
258 /* Check the ERROR flag */
259 if (flags & CDC_DCMD_ERROR)
260 ret = le32_to_cpu(msg->status);
261
262done:
263 return ret;
264}
265
266static bool pkt_sum_needed(struct sk_buff *skb)
267{
268 return skb->ip_summed == CHECKSUM_PARTIAL;
269}
270
271static void pkt_set_sum_good(struct sk_buff *skb, bool x)
272{
273 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
274}
275
276void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
277 struct sk_buff *pktbuf)
278{
279 struct brcmf_proto_bdc_header *h;
280
281 brcmf_dbg(CDC, "Enter\n");
282
283 /* Push BDC header used to convey priority for buses that don't */
284 skb_push(pktbuf, BDC_HEADER_LEN);
285
286 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
287
288 h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
289 if (pkt_sum_needed(pktbuf))
290 h->flags |= BDC_FLAG_SUM_NEEDED;
291
292 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
293 h->flags2 = 0;
294 h->data_offset = offset;
295 BDC_SET_IF_IDX(h, ifidx);
296 trace_brcmf_bdchdr(pktbuf->data);
297}
298
299int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
300 struct sk_buff *pktbuf)
301{
302 struct brcmf_proto_bdc_header *h;
303
304 brcmf_dbg(CDC, "Enter\n");
305
306 /* Pop BDC header used to convey priority for buses that don't */
307
308 if (pktbuf->len <= BDC_HEADER_LEN) {
309 brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
310 pktbuf->len, BDC_HEADER_LEN);
311 return -EBADE;
312 }
313
314 trace_brcmf_bdchdr(pktbuf->data);
315 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
316
317 *ifidx = BDC_GET_IF_IDX(h);
318 if (*ifidx >= BRCMF_MAX_IFS) {
319 brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
320 return -EBADE;
321 }
322 /* The ifidx is the idx to map to matching netdev/ifp. When receiving
323 * events this is easy because it contains the bssidx which maps
324 * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
325 * bssidx 1 is used for p2p0 and no data can be received or
326 * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
327 */
328 if (*ifidx)
329 (*ifidx)++;
330
331 if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
332 BDC_PROTO_VER) {
333 brcmf_err("%s: non-BDC packet received, flags 0x%x\n",
334 brcmf_ifname(drvr, *ifidx), h->flags);
335 return -EBADE;
336 }
337
338 if (h->flags & BDC_FLAG_SUM_GOOD) {
339 brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
340 brcmf_ifname(drvr, *ifidx), h->flags);
341 pkt_set_sum_good(pktbuf, true);
342 }
343
344 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
345
346 skb_pull(pktbuf, BDC_HEADER_LEN);
347 if (do_fws)
348 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
349 else
350 skb_pull(pktbuf, h->data_offset << 2);
351
352 if (pktbuf->len == 0)
353 return -ENODATA;
354 return 0;
355}
356
357int brcmf_proto_attach(struct brcmf_pub *drvr)
358{
359 struct brcmf_proto *cdc;
360
361 cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
362 if (!cdc)
363 goto fail;
364
365 /* ensure that the msg buf directly follows the cdc msg struct */
366 if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
367 brcmf_err("struct brcmf_proto is not correctly defined\n");
368 goto fail;
369 }
370
371 drvr->prot = cdc;
372 drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
373 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
374 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
375 return 0;
376
377fail:
378 kfree(cdc);
379 return -ENOMEM;
380}
381
382/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
383void brcmf_proto_detach(struct brcmf_pub *drvr)
384{
385 kfree(drvr->prot);
386 drvr->prot = NULL;
387}
388
389void brcmf_proto_stop(struct brcmf_pub *drvr)
390{
391 /* Nothing to do for CDC */
392}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 9431af2465f3..548dbb5542c6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -21,9 +21,9 @@
21#include <brcmu_utils.h> 21#include <brcmu_utils.h>
22#include "dhd.h" 22#include "dhd.h"
23#include "dhd_bus.h" 23#include "dhd_bus.h"
24#include "dhd_proto.h"
25#include "dhd_dbg.h" 24#include "dhd_dbg.h"
26#include "fwil.h" 25#include "fwil.h"
26#include "fwil_types.h"
27#include "tracepoint.h" 27#include "tracepoint.h"
28 28
29#define PKTFILTER_BUF_SIZE 128 29#define PKTFILTER_BUF_SIZE 128
@@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
257 u8 buf[BRCMF_DCMD_SMLEN]; 257 u8 buf[BRCMF_DCMD_SMLEN];
258 char *ptr; 258 char *ptr;
259 s32 err; 259 s32 err;
260 struct brcmf_bus_dcmd *cmdlst;
261 struct list_head *cur, *q;
262 260
263 /* retreive mac address */ 261 /* retreive mac address */
264 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, 262 err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
@@ -281,9 +279,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
281 } 279 }
282 ptr = (char *)buf; 280 ptr = (char *)buf;
283 strsep(&ptr, "\n"); 281 strsep(&ptr, "\n");
282
284 /* Print fw version info */ 283 /* Print fw version info */
285 brcmf_err("Firmware version = %s\n", buf); 284 brcmf_err("Firmware version = %s\n", buf);
286 285
286 /* locate firmware version number for ethtool */
287 ptr = strrchr(buf, ' ') + 1;
288 strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
289
287 /* 290 /*
288 * Setup timeout if Beacons are lost and roam is off to report 291 * Setup timeout if Beacons are lost and roam is off to report
289 * link down 292 * link down
@@ -342,17 +345,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
342 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, 345 brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER,
343 0, true); 346 0, true);
344 347
345 /* set bus specific command if there is any */ 348 /* do bus specific preinit here */
346 list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { 349 err = brcmf_bus_preinit(ifp->drvr->bus_if);
347 cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list);
348 if (cmdlst->name && cmdlst->param && cmdlst->param_len) {
349 brcmf_fil_iovar_data_set(ifp, cmdlst->name,
350 cmdlst->param,
351 cmdlst->param_len);
352 }
353 list_del(cur);
354 kfree(cmdlst);
355 }
356done: 350done:
357 return err; 351 return err;
358} 352}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
index 0f9e9057e7dd..03fe8aca4d32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c
@@ -22,7 +22,6 @@
22#include "dhd.h" 22#include "dhd.h"
23#include "dhd_bus.h" 23#include "dhd_bus.h"
24#include "dhd_dbg.h" 24#include "dhd_dbg.h"
25#include "tracepoint.h"
26 25
27static struct dentry *root_folder; 26static struct dentry *root_folder;
28 27
@@ -42,6 +41,40 @@ void brcmf_debugfs_exit(void)
42 root_folder = NULL; 41 root_folder = NULL;
43} 42}
44 43
44static
45ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data,
46 size_t count, loff_t *ppos)
47{
48 struct brcmf_pub *drvr = f->private_data;
49 struct brcmf_bus *bus = drvr->bus_if;
50 char buf[40];
51 int res;
52
53 /* only allow read from start */
54 if (*ppos > 0)
55 return 0;
56
57 res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n",
58 bus->chip, bus->chip, bus->chiprev);
59 return simple_read_from_buffer(data, count, ppos, buf, res);
60}
61
62static const struct file_operations brcmf_debugfs_chipinfo_ops = {
63 .owner = THIS_MODULE,
64 .open = simple_open,
65 .read = brcmf_debugfs_chipinfo_read
66};
67
68static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr)
69{
70 struct dentry *dentry = drvr->dbgfs_dir;
71
72 if (!IS_ERR_OR_NULL(dentry))
73 debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr,
74 &brcmf_debugfs_chipinfo_ops);
75 return 0;
76}
77
45int brcmf_debugfs_attach(struct brcmf_pub *drvr) 78int brcmf_debugfs_attach(struct brcmf_pub *drvr)
46{ 79{
47 struct device *dev = drvr->bus_if->dev; 80 struct device *dev = drvr->bus_if->dev;
@@ -50,6 +83,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr)
50 return -ENODEV; 83 return -ENODEV;
51 84
52 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); 85 drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
86 brcmf_debugfs_create_chipinfo(drvr);
53 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); 87 return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
54} 88}
55 89
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index 0af1f5dc583a..ef52ed7abc69 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -33,7 +33,7 @@
33#define BRCMF_USB_VAL 0x00002000 33#define BRCMF_USB_VAL 0x00002000
34#define BRCMF_SCAN_VAL 0x00004000 34#define BRCMF_SCAN_VAL 0x00004000
35#define BRCMF_CONN_VAL 0x00008000 35#define BRCMF_CONN_VAL 0x00008000
36#define BRCMF_CDC_VAL 0x00010000 36#define BRCMF_BCDC_VAL 0x00010000
37#define BRCMF_SDIO_VAL 0x00020000 37#define BRCMF_SDIO_VAL 0x00020000
38 38
39/* set default print format */ 39/* set default print format */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 64e9cff241b9..bce0b8e511fd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -24,13 +24,13 @@
24 24
25#include "dhd.h" 25#include "dhd.h"
26#include "dhd_bus.h" 26#include "dhd_bus.h"
27#include "dhd_proto.h"
28#include "dhd_dbg.h" 27#include "dhd_dbg.h"
29#include "fwil_types.h" 28#include "fwil_types.h"
30#include "p2p.h" 29#include "p2p.h"
31#include "wl_cfg80211.h" 30#include "wl_cfg80211.h"
32#include "fwil.h" 31#include "fwil.h"
33#include "fwsignal.h" 32#include "fwsignal.h"
33#include "proto.h"
34 34
35MODULE_AUTHOR("Broadcom Corporation"); 35MODULE_AUTHOR("Broadcom Corporation");
36MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); 36MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
@@ -592,28 +592,6 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
592 return &ifp->stats; 592 return &ifp->stats;
593} 593}
594 594
595/*
596 * Set current toe component enables in toe_ol iovar,
597 * and set toe global enable iovar
598 */
599static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
600{
601 s32 err;
602
603 err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
604 if (err < 0) {
605 brcmf_err("Setting toe_ol failed, %d\n", err);
606 return err;
607 }
608
609 err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
610 if (err < 0)
611 brcmf_err("Setting toe failed, %d\n", err);
612
613 return err;
614
615}
616
617static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 595static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
618 struct ethtool_drvinfo *info) 596 struct ethtool_drvinfo *info)
619{ 597{
@@ -621,8 +599,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
621 struct brcmf_pub *drvr = ifp->drvr; 599 struct brcmf_pub *drvr = ifp->drvr;
622 600
623 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); 601 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
624 snprintf(info->version, sizeof(info->version), "%lu", 602 snprintf(info->version, sizeof(info->version), "n/a");
625 drvr->drv_version); 603 strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version));
626 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev), 604 strlcpy(info->bus_info, dev_name(drvr->bus_if->dev),
627 sizeof(info->bus_info)); 605 sizeof(info->bus_info));
628} 606}
@@ -631,124 +609,6 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
631 .get_drvinfo = brcmf_ethtool_get_drvinfo, 609 .get_drvinfo = brcmf_ethtool_get_drvinfo,
632}; 610};
633 611
634static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
635{
636 struct brcmf_pub *drvr = ifp->drvr;
637 struct ethtool_drvinfo info;
638 char drvname[sizeof(info.driver)];
639 u32 cmd;
640 struct ethtool_value edata;
641 u32 toe_cmpnt, csum_dir;
642 int ret;
643
644 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
645
646 /* all ethtool calls start with a cmd word */
647 if (copy_from_user(&cmd, uaddr, sizeof(u32)))
648 return -EFAULT;
649
650 switch (cmd) {
651 case ETHTOOL_GDRVINFO:
652 /* Copy out any request driver name */
653 if (copy_from_user(&info, uaddr, sizeof(info)))
654 return -EFAULT;
655 strncpy(drvname, info.driver, sizeof(info.driver));
656 drvname[sizeof(info.driver) - 1] = '\0';
657
658 /* clear struct for return */
659 memset(&info, 0, sizeof(info));
660 info.cmd = cmd;
661
662 /* if requested, identify ourselves */
663 if (strcmp(drvname, "?dhd") == 0) {
664 sprintf(info.driver, "dhd");
665 strcpy(info.version, BRCMF_VERSION_STR);
666 }
667 /* report dongle driver type */
668 else
669 sprintf(info.driver, "wl");
670
671 sprintf(info.version, "%lu", drvr->drv_version);
672 if (copy_to_user(uaddr, &info, sizeof(info)))
673 return -EFAULT;
674 brcmf_dbg(TRACE, "given %*s, returning %s\n",
675 (int)sizeof(drvname), drvname, info.driver);
676 break;
677
678 /* Get toe offload components from dongle */
679 case ETHTOOL_GRXCSUM:
680 case ETHTOOL_GTXCSUM:
681 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
682 if (ret < 0)
683 return ret;
684
685 csum_dir =
686 (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
687
688 edata.cmd = cmd;
689 edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
690
691 if (copy_to_user(uaddr, &edata, sizeof(edata)))
692 return -EFAULT;
693 break;
694
695 /* Set toe offload components in dongle */
696 case ETHTOOL_SRXCSUM:
697 case ETHTOOL_STXCSUM:
698 if (copy_from_user(&edata, uaddr, sizeof(edata)))
699 return -EFAULT;
700
701 /* Read the current settings, update and write back */
702 ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
703 if (ret < 0)
704 return ret;
705
706 csum_dir =
707 (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
708
709 if (edata.data != 0)
710 toe_cmpnt |= csum_dir;
711 else
712 toe_cmpnt &= ~csum_dir;
713
714 ret = brcmf_toe_set(ifp, toe_cmpnt);
715 if (ret < 0)
716 return ret;
717
718 /* If setting TX checksum mode, tell Linux the new mode */
719 if (cmd == ETHTOOL_STXCSUM) {
720 if (edata.data)
721 ifp->ndev->features |= NETIF_F_IP_CSUM;
722 else
723 ifp->ndev->features &= ~NETIF_F_IP_CSUM;
724 }
725
726 break;
727
728 default:
729 return -EOPNOTSUPP;
730 }
731
732 return 0;
733}
734
735static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
736 int cmd)
737{
738 struct brcmf_if *ifp = netdev_priv(ndev);
739 struct brcmf_pub *drvr = ifp->drvr;
740
741 brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd);
742
743 if (!drvr->iflist[ifp->bssidx])
744 return -1;
745
746 if (cmd == SIOCETHTOOL)
747 return brcmf_ethtool(ifp, ifr->ifr_data);
748
749 return -EOPNOTSUPP;
750}
751
752static int brcmf_netdev_stop(struct net_device *ndev) 612static int brcmf_netdev_stop(struct net_device *ndev)
753{ 613{
754 struct brcmf_if *ifp = netdev_priv(ndev); 614 struct brcmf_if *ifp = netdev_priv(ndev);
@@ -769,7 +629,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
769 struct brcmf_pub *drvr = ifp->drvr; 629 struct brcmf_pub *drvr = ifp->drvr;
770 struct brcmf_bus *bus_if = drvr->bus_if; 630 struct brcmf_bus *bus_if = drvr->bus_if;
771 u32 toe_ol; 631 u32 toe_ol;
772 s32 ret = 0;
773 632
774 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); 633 brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx);
775 634
@@ -788,21 +647,20 @@ static int brcmf_netdev_open(struct net_device *ndev)
788 else 647 else
789 ndev->features &= ~NETIF_F_IP_CSUM; 648 ndev->features &= ~NETIF_F_IP_CSUM;
790 649
791 /* Allow transmit calls */
792 netif_start_queue(ndev);
793 if (brcmf_cfg80211_up(ndev)) { 650 if (brcmf_cfg80211_up(ndev)) {
794 brcmf_err("failed to bring up cfg80211\n"); 651 brcmf_err("failed to bring up cfg80211\n");
795 return -1; 652 return -EIO;
796 } 653 }
797 654
798 return ret; 655 /* Allow transmit calls */
656 netif_start_queue(ndev);
657 return 0;
799} 658}
800 659
801static const struct net_device_ops brcmf_netdev_ops_pri = { 660static const struct net_device_ops brcmf_netdev_ops_pri = {
802 .ndo_open = brcmf_netdev_open, 661 .ndo_open = brcmf_netdev_open,
803 .ndo_stop = brcmf_netdev_stop, 662 .ndo_stop = brcmf_netdev_stop,
804 .ndo_get_stats = brcmf_netdev_get_stats, 663 .ndo_get_stats = brcmf_netdev_get_stats,
805 .ndo_do_ioctl = brcmf_netdev_ioctl_entry,
806 .ndo_start_xmit = brcmf_netdev_start_xmit, 664 .ndo_start_xmit = brcmf_netdev_start_xmit,
807 .ndo_set_mac_address = brcmf_netdev_set_mac_address, 665 .ndo_set_mac_address = brcmf_netdev_set_mac_address,
808 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list 666 .ndo_set_rx_mode = brcmf_netdev_set_multicast_list
@@ -868,13 +726,6 @@ static int brcmf_net_p2p_stop(struct net_device *ndev)
868 return brcmf_cfg80211_down(ndev); 726 return brcmf_cfg80211_down(ndev);
869} 727}
870 728
871static int brcmf_net_p2p_do_ioctl(struct net_device *ndev,
872 struct ifreq *ifr, int cmd)
873{
874 brcmf_dbg(TRACE, "Enter\n");
875 return 0;
876}
877
878static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb, 729static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
879 struct net_device *ndev) 730 struct net_device *ndev)
880{ 731{
@@ -887,7 +738,6 @@ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb,
887static const struct net_device_ops brcmf_netdev_ops_p2p = { 738static const struct net_device_ops brcmf_netdev_ops_p2p = {
888 .ndo_open = brcmf_net_p2p_open, 739 .ndo_open = brcmf_net_p2p_open,
889 .ndo_stop = brcmf_net_p2p_stop, 740 .ndo_stop = brcmf_net_p2p_stop,
890 .ndo_do_ioctl = brcmf_net_p2p_do_ioctl,
891 .ndo_start_xmit = brcmf_net_p2p_start_xmit 741 .ndo_start_xmit = brcmf_net_p2p_start_xmit
892}; 742};
893 743
@@ -1016,7 +866,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx)
1016 } 866 }
1017} 867}
1018 868
1019int brcmf_attach(uint bus_hdrlen, struct device *dev) 869int brcmf_attach(struct device *dev)
1020{ 870{
1021 struct brcmf_pub *drvr = NULL; 871 struct brcmf_pub *drvr = NULL;
1022 int ret = 0; 872 int ret = 0;
@@ -1031,7 +881,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
1031 mutex_init(&drvr->proto_block); 881 mutex_init(&drvr->proto_block);
1032 882
1033 /* Link to bus module */ 883 /* Link to bus module */
1034 drvr->hdrlen = bus_hdrlen; 884 drvr->hdrlen = 0;
1035 drvr->bus_if = dev_get_drvdata(dev); 885 drvr->bus_if = dev_get_drvdata(dev);
1036 drvr->bus_if->drvr = drvr; 886 drvr->bus_if->drvr = drvr;
1037 887
@@ -1048,8 +898,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)
1048 /* attach firmware event handler */ 898 /* attach firmware event handler */
1049 brcmf_fweh_attach(drvr); 899 brcmf_fweh_attach(drvr);
1050 900
1051 INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);
1052
1053 return ret; 901 return ret;
1054 902
1055fail: 903fail:
@@ -1138,14 +986,21 @@ fail:
1138 return 0; 986 return 0;
1139} 987}
1140 988
989void brcmf_bus_add_txhdrlen(struct device *dev, uint len)
990{
991 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
992 struct brcmf_pub *drvr = bus_if->drvr;
993
994 if (drvr) {
995 drvr->hdrlen += len;
996 }
997}
998
1141static void brcmf_bus_detach(struct brcmf_pub *drvr) 999static void brcmf_bus_detach(struct brcmf_pub *drvr)
1142{ 1000{
1143 brcmf_dbg(TRACE, "Enter\n"); 1001 brcmf_dbg(TRACE, "Enter\n");
1144 1002
1145 if (drvr) { 1003 if (drvr) {
1146 /* Stop the protocol module */
1147 brcmf_proto_stop(drvr);
1148
1149 /* Stop the bus module */ 1004 /* Stop the bus module */
1150 brcmf_bus_stop(drvr->bus_if); 1005 brcmf_bus_stop(drvr->bus_if);
1151 } 1006 }
@@ -1186,8 +1041,7 @@ void brcmf_detach(struct device *dev)
1186 1041
1187 brcmf_bus_detach(drvr); 1042 brcmf_bus_detach(drvr);
1188 1043
1189 if (drvr->prot) 1044 brcmf_proto_detach(drvr);
1190 brcmf_proto_detach(drvr);
1191 1045
1192 brcmf_fws_deinit(drvr); 1046 brcmf_fws_deinit(drvr);
1193 1047
@@ -1196,6 +1050,14 @@ void brcmf_detach(struct device *dev)
1196 kfree(drvr); 1050 kfree(drvr);
1197} 1051}
1198 1052
1053s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len)
1054{
1055 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
1056 struct brcmf_if *ifp = bus_if->drvr->iflist[0];
1057
1058 return brcmf_fil_iovar_data_set(ifp, name, data, len);
1059}
1060
1199static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp) 1061static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp)
1200{ 1062{
1201 return atomic_read(&ifp->pend_8021x_cnt); 1063 return atomic_read(&ifp->pend_8021x_cnt);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
deleted file mode 100644
index 53c6e710f2cb..000000000000
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ /dev/null
@@ -1,42 +0,0 @@
1/*
2 * Copyright (c) 2010 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 _BRCMF_PROTO_H_
18#define _BRCMF_PROTO_H_
19
20/*
21 * Exported from the brcmf protocol module (brcmf_cdc)
22 */
23
24/* Linkage, sets prot link and updates hdrlen in pub */
25int brcmf_proto_attach(struct brcmf_pub *drvr);
26
27/* Unlink, frees allocated protocol memory (including brcmf_proto) */
28void brcmf_proto_detach(struct brcmf_pub *drvr);
29
30/* Stop protocol: sync w/dongle state. */
31void brcmf_proto_stop(struct brcmf_pub *drvr);
32
33/* Add any protocol-specific data header.
34 * Caller must reserve prot_hdrlen prepend space.
35 */
36void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset,
37 struct sk_buff *txp);
38
39/* Sets dongle media info (drv_version, mac address). */
40int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
41
42#endif /* _BRCMF_PROTO_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index b02953c4ade7..0f95f3e79c10 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -32,6 +32,7 @@
32#include <linux/debugfs.h> 32#include <linux/debugfs.h>
33#include <linux/vmalloc.h> 33#include <linux/vmalloc.h>
34#include <linux/platform_data/brcmfmac-sdio.h> 34#include <linux/platform_data/brcmfmac-sdio.h>
35#include <linux/moduleparam.h>
35#include <asm/unaligned.h> 36#include <asm/unaligned.h>
36#include <defs.h> 37#include <defs.h>
37#include <brcmu_wifi.h> 38#include <brcmu_wifi.h>
@@ -110,6 +111,8 @@ struct rte_console {
110#define BRCMF_TXBOUND 20 /* Default for max tx frames in 111#define BRCMF_TXBOUND 20 /* Default for max tx frames in
111 one scheduling */ 112 one scheduling */
112 113
114#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
115
113#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ 116#define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */
114 117
115#define MEMBLOCK 2048 /* Block size used for downloading 118#define MEMBLOCK 2048 /* Block size used for downloading
@@ -360,6 +363,8 @@ struct brcmf_sdio_hdrinfo {
360 u16 len_left; 363 u16 len_left;
361 u16 len_nxtfrm; 364 u16 len_nxtfrm;
362 u8 dat_offset; 365 u8 dat_offset;
366 bool lastfrm;
367 u16 tail_pad;
363}; 368};
364 369
365/* misc chip info needed by some of the routines */ 370/* misc chip info needed by some of the routines */
@@ -384,7 +389,7 @@ struct brcmf_sdio {
384 u8 tx_seq; /* Transmit sequence number (next) */ 389 u8 tx_seq; /* Transmit sequence number (next) */
385 u8 tx_max; /* Maximum transmit sequence allowed */ 390 u8 tx_max; /* Maximum transmit sequence allowed */
386 391
387 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; 392 u8 *hdrbuf; /* buffer for handling rx frame */
388 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ 393 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
389 u8 rx_seq; /* Receive sequence number (expected) */ 394 u8 rx_seq; /* Receive sequence number (expected) */
390 struct brcmf_sdio_hdrinfo cur_read; 395 struct brcmf_sdio_hdrinfo cur_read;
@@ -455,6 +460,10 @@ struct brcmf_sdio {
455 bool sleeping; /* SDIO bus sleeping */ 460 bool sleeping; /* SDIO bus sleeping */
456 461
457 u8 tx_hdrlen; /* sdio bus header length for tx packet */ 462 u8 tx_hdrlen; /* sdio bus header length for tx packet */
463 bool txglom; /* host tx glomming enable flag */
464 struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */
465 u16 head_align; /* buffer pointer alignment */
466 u16 sgentry_align; /* scatter-gather buffer alignment */
458}; 467};
459 468
460/* clkstate */ 469/* clkstate */
@@ -479,6 +488,10 @@ static const uint max_roundup = 512;
479 488
480#define ALIGNMENT 4 489#define ALIGNMENT 4
481 490
491static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
492module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0);
493MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
494
482enum brcmf_sdio_frmtype { 495enum brcmf_sdio_frmtype {
483 BRCMF_SDIO_FT_NORMAL, 496 BRCMF_SDIO_FT_NORMAL,
484 BRCMF_SDIO_FT_SUPER, 497 BRCMF_SDIO_FT_SUPER,
@@ -499,6 +512,8 @@ enum brcmf_sdio_frmtype {
499#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" 512#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
500#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" 513#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
501#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" 514#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
515#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
516#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
502 517
503MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); 518MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
504MODULE_FIRMWARE(BCM43143_NVRAM_NAME); 519MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
@@ -514,6 +529,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
514MODULE_FIRMWARE(BCM4334_NVRAM_NAME); 529MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
515MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); 530MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
516MODULE_FIRMWARE(BCM4335_NVRAM_NAME); 531MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
532MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
533MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
517 534
518struct brcmf_firmware_names { 535struct brcmf_firmware_names {
519 u32 chipid; 536 u32 chipid;
@@ -537,7 +554,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
537 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, 554 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
538 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, 555 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
539 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, 556 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
540 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) } 557 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
558 { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }
541}; 559};
542 560
543 561
@@ -1097,10 +1115,18 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1097 * host and WiFi dongle which contains information needed for SDIO core and 1115 * host and WiFi dongle which contains information needed for SDIO core and
1098 * firmware 1116 * firmware
1099 * 1117 *
1100 * It consists of 2 parts: hw header and software header 1118 * It consists of 3 parts: hardware header, hardware extension header and
1119 * software header
1101 * hardware header (frame tag) - 4 bytes 1120 * hardware header (frame tag) - 4 bytes
1102 * Byte 0~1: Frame length 1121 * Byte 0~1: Frame length
1103 * Byte 2~3: Checksum, bit-wise inverse of frame length 1122 * Byte 2~3: Checksum, bit-wise inverse of frame length
1123 * hardware extension header - 8 bytes
1124 * Tx glom mode only, N/A for Rx or normal Tx
1125 * Byte 0~1: Packet length excluding hw frame tag
1126 * Byte 2: Reserved
1127 * Byte 3: Frame flags, bit 0: last frame indication
1128 * Byte 4~5: Reserved
1129 * Byte 6~7: Tail padding length
1104 * software header - 8 bytes 1130 * software header - 8 bytes
1105 * Byte 0: Rx/Tx sequence number 1131 * Byte 0: Rx/Tx sequence number
1106 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag 1132 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
@@ -1111,6 +1137,7 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1111 * Byte 6~7: Reserved 1137 * Byte 6~7: Reserved
1112 */ 1138 */
1113#define SDPCM_HWHDR_LEN 4 1139#define SDPCM_HWHDR_LEN 4
1140#define SDPCM_HWEXT_LEN 8
1114#define SDPCM_SWHDR_LEN 8 1141#define SDPCM_SWHDR_LEN 8
1115#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN) 1142#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
1116/* software header */ 1143/* software header */
@@ -1147,7 +1174,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1147 u8 rx_seq, fc, tx_seq_max; 1174 u8 rx_seq, fc, tx_seq_max;
1148 u32 swheader; 1175 u32 swheader;
1149 1176
1150 trace_brcmf_sdpcm_hdr(false, header); 1177 trace_brcmf_sdpcm_hdr(SDPCM_RX, header);
1151 1178
1152 /* hw header */ 1179 /* hw header */
1153 len = get_unaligned_le16(header); 1180 len = get_unaligned_le16(header);
@@ -1260,25 +1287,34 @@ static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length)
1260static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, 1287static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
1261 struct brcmf_sdio_hdrinfo *hd_info) 1288 struct brcmf_sdio_hdrinfo *hd_info)
1262{ 1289{
1263 u32 sw_header; 1290 u32 hdrval;
1291 u8 hdr_offset;
1264 1292
1265 brcmf_sdio_update_hwhdr(header, hd_info->len); 1293 brcmf_sdio_update_hwhdr(header, hd_info->len);
1266 1294 hdr_offset = SDPCM_HWHDR_LEN;
1267 sw_header = bus->tx_seq; 1295
1268 sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & 1296 if (bus->txglom) {
1269 SDPCM_CHANNEL_MASK; 1297 hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24);
1270 sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & 1298 *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
1271 SDPCM_DOFFSET_MASK; 1299 hdrval = (u16)hd_info->tail_pad << 16;
1272 *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); 1300 *(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval);
1273 *(((__le32 *)header) + 2) = 0; 1301 hdr_offset += SDPCM_HWEXT_LEN;
1274 trace_brcmf_sdpcm_hdr(true, header); 1302 }
1303
1304 hdrval = hd_info->seq_num;
1305 hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
1306 SDPCM_CHANNEL_MASK;
1307 hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
1308 SDPCM_DOFFSET_MASK;
1309 *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval);
1310 *(((__le32 *)(header + hdr_offset)) + 1) = 0;
1311 trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header);
1275} 1312}
1276 1313
1277static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1314static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1278{ 1315{
1279 u16 dlen, totlen; 1316 u16 dlen, totlen;
1280 u8 *dptr, num = 0; 1317 u8 *dptr, num = 0;
1281 u32 align = 0;
1282 u16 sublen; 1318 u16 sublen;
1283 struct sk_buff *pfirst, *pnext; 1319 struct sk_buff *pfirst, *pnext;
1284 1320
@@ -1293,11 +1329,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1293 brcmf_dbg(SDIO, "start: glomd %p glom %p\n", 1329 brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
1294 bus->glomd, skb_peek(&bus->glom)); 1330 bus->glomd, skb_peek(&bus->glom));
1295 1331
1296 if (bus->sdiodev->pdata)
1297 align = bus->sdiodev->pdata->sd_sgentry_align;
1298 if (align < 4)
1299 align = 4;
1300
1301 /* If there's a descriptor, generate the packet chain */ 1332 /* If there's a descriptor, generate the packet chain */
1302 if (bus->glomd) { 1333 if (bus->glomd) {
1303 pfirst = pnext = NULL; 1334 pfirst = pnext = NULL;
@@ -1321,9 +1352,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1321 pnext = NULL; 1352 pnext = NULL;
1322 break; 1353 break;
1323 } 1354 }
1324 if (sublen % align) { 1355 if (sublen % bus->sgentry_align) {
1325 brcmf_err("sublen %d not multiple of %d\n", 1356 brcmf_err("sublen %d not multiple of %d\n",
1326 sublen, align); 1357 sublen, bus->sgentry_align);
1327 } 1358 }
1328 totlen += sublen; 1359 totlen += sublen;
1329 1360
@@ -1336,7 +1367,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1336 } 1367 }
1337 1368
1338 /* Allocate/chain packet for next subframe */ 1369 /* Allocate/chain packet for next subframe */
1339 pnext = brcmu_pkt_buf_get_skb(sublen + align); 1370 pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align);
1340 if (pnext == NULL) { 1371 if (pnext == NULL) {
1341 brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n", 1372 brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
1342 num, sublen); 1373 num, sublen);
@@ -1345,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1345 skb_queue_tail(&bus->glom, pnext); 1376 skb_queue_tail(&bus->glom, pnext);
1346 1377
1347 /* Adhere to start alignment requirements */ 1378 /* Adhere to start alignment requirements */
1348 pkt_align(pnext, sublen, align); 1379 pkt_align(pnext, sublen, bus->sgentry_align);
1349 } 1380 }
1350 1381
1351 /* If all allocations succeeded, save packet chain 1382 /* If all allocations succeeded, save packet chain
@@ -1549,9 +1580,9 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1549 goto done; 1580 goto done;
1550 1581
1551 rbuf = bus->rxbuf; 1582 rbuf = bus->rxbuf;
1552 pad = ((unsigned long)rbuf % BRCMF_SDALIGN); 1583 pad = ((unsigned long)rbuf % bus->head_align);
1553 if (pad) 1584 if (pad)
1554 rbuf += (BRCMF_SDALIGN - pad); 1585 rbuf += (bus->head_align - pad);
1555 1586
1556 /* Copy the already-read portion over */ 1587 /* Copy the already-read portion over */
1557 memcpy(buf, hdr, BRCMF_FIRSTREAD); 1588 memcpy(buf, hdr, BRCMF_FIRSTREAD);
@@ -1565,14 +1596,10 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
1565 if ((pad <= bus->roundup) && (pad < bus->blocksize) && 1596 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
1566 ((len + pad) < bus->sdiodev->bus_if->maxctl)) 1597 ((len + pad) < bus->sdiodev->bus_if->maxctl))
1567 rdlen += pad; 1598 rdlen += pad;
1568 } else if (rdlen % BRCMF_SDALIGN) { 1599 } else if (rdlen % bus->head_align) {
1569 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); 1600 rdlen += bus->head_align - (rdlen % bus->head_align);
1570 } 1601 }
1571 1602
1572 /* Satisfy length-alignment requirements */
1573 if (rdlen & (ALIGNMENT - 1))
1574 rdlen = roundup(rdlen, ALIGNMENT);
1575
1576 /* Drop if the read is too big or it exceeds our maximum */ 1603 /* Drop if the read is too big or it exceeds our maximum */
1577 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { 1604 if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) {
1578 brcmf_err("%d-byte control read exceeds %d-byte buffer\n", 1605 brcmf_err("%d-byte control read exceeds %d-byte buffer\n",
@@ -1637,8 +1664,8 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
1637 if (*pad <= bus->roundup && *pad < bus->blocksize && 1664 if (*pad <= bus->roundup && *pad < bus->blocksize &&
1638 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ) 1665 *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ)
1639 *rdlen += *pad; 1666 *rdlen += *pad;
1640 } else if (*rdlen % BRCMF_SDALIGN) { 1667 } else if (*rdlen % bus->head_align) {
1641 *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN); 1668 *rdlen += bus->head_align - (*rdlen % bus->head_align);
1642 } 1669 }
1643} 1670}
1644 1671
@@ -1726,7 +1753,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1726 brcmf_pad(bus, &pad, &rd->len_left); 1753 brcmf_pad(bus, &pad, &rd->len_left);
1727 1754
1728 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read + 1755 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read +
1729 BRCMF_SDALIGN); 1756 bus->head_align);
1730 if (!pkt) { 1757 if (!pkt) {
1731 /* Give up on data, request rtx of events */ 1758 /* Give up on data, request rtx of events */
1732 brcmf_err("brcmu_pkt_buf_get_skb failed\n"); 1759 brcmf_err("brcmu_pkt_buf_get_skb failed\n");
@@ -1736,7 +1763,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1736 continue; 1763 continue;
1737 } 1764 }
1738 skb_pull(pkt, head_read); 1765 skb_pull(pkt, head_read);
1739 pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); 1766 pkt_align(pkt, rd->len_left, bus->head_align);
1740 1767
1741 ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1768 ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1742 SDIO_FUNC_2, F2SYNC, pkt); 1769 SDIO_FUNC_2, F2SYNC, pkt);
@@ -1871,6 +1898,29 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
1871 return; 1898 return;
1872} 1899}
1873 1900
1901static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
1902{
1903 u16 head_pad;
1904 u8 *dat_buf;
1905
1906 dat_buf = (u8 *)(pkt->data);
1907
1908 /* Check head padding */
1909 head_pad = ((unsigned long)dat_buf % bus->head_align);
1910 if (head_pad) {
1911 if (skb_headroom(pkt) < head_pad) {
1912 bus->sdiodev->bus_if->tx_realloc++;
1913 head_pad = 0;
1914 if (skb_cow(pkt, head_pad))
1915 return -ENOMEM;
1916 }
1917 skb_push(pkt, head_pad);
1918 dat_buf = (u8 *)(pkt->data);
1919 memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
1920 }
1921 return head_pad;
1922}
1923
1874/** 1924/**
1875 * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for 1925 * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
1876 * bus layer usage. 1926 * bus layer usage.
@@ -1880,32 +1930,40 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
1880/* bit mask of data length chopped from the previous packet */ 1930/* bit mask of data length chopped from the previous packet */
1881#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff 1931#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff
1882 1932
1883static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, 1933static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
1884 struct sk_buff_head *pktq, 1934 struct sk_buff_head *pktq,
1885 struct sk_buff *pkt, uint chan) 1935 struct sk_buff *pkt, u16 total_len)
1886{ 1936{
1937 struct brcmf_sdio_dev *sdiodev;
1887 struct sk_buff *pkt_pad; 1938 struct sk_buff *pkt_pad;
1888 u16 tail_pad, tail_chop, sg_align; 1939 u16 tail_pad, tail_chop, chain_pad;
1889 unsigned int blksize; 1940 unsigned int blksize;
1890 u8 *dat_buf; 1941 bool lastfrm;
1891 int ntail; 1942 int ntail, ret;
1892 1943
1944 sdiodev = bus->sdiodev;
1893 blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; 1945 blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
1894 sg_align = 4;
1895 if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
1896 sg_align = sdiodev->pdata->sd_sgentry_align;
1897 /* sg entry alignment should be a divisor of block size */ 1946 /* sg entry alignment should be a divisor of block size */
1898 WARN_ON(blksize % sg_align); 1947 WARN_ON(blksize % bus->sgentry_align);
1899 1948
1900 /* Check tail padding */ 1949 /* Check tail padding */
1901 pkt_pad = NULL; 1950 lastfrm = skb_queue_is_last(pktq, pkt);
1902 tail_chop = pkt->len % sg_align; 1951 tail_pad = 0;
1903 tail_pad = sg_align - tail_chop; 1952 tail_chop = pkt->len % bus->sgentry_align;
1904 tail_pad += blksize - (pkt->len + tail_pad) % blksize; 1953 if (tail_chop)
1954 tail_pad = bus->sgentry_align - tail_chop;
1955 chain_pad = (total_len + tail_pad) % blksize;
1956 if (lastfrm && chain_pad)
1957 tail_pad += blksize - chain_pad;
1905 if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { 1958 if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) {
1906 pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); 1959 pkt_pad = bus->txglom_sgpad;
1960 if (pkt_pad == NULL)
1961 brcmu_pkt_buf_get_skb(tail_pad + tail_chop);
1907 if (pkt_pad == NULL) 1962 if (pkt_pad == NULL)
1908 return -ENOMEM; 1963 return -ENOMEM;
1964 ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad);
1965 if (unlikely(ret < 0))
1966 return ret;
1909 memcpy(pkt_pad->data, 1967 memcpy(pkt_pad->data,
1910 pkt->data + pkt->len - tail_chop, 1968 pkt->data + pkt->len - tail_chop,
1911 tail_chop); 1969 tail_chop);
@@ -1920,14 +1978,10 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev,
1920 return -ENOMEM; 1978 return -ENOMEM;
1921 if (skb_linearize(pkt)) 1979 if (skb_linearize(pkt))
1922 return -ENOMEM; 1980 return -ENOMEM;
1923 dat_buf = (u8 *)(pkt->data);
1924 __skb_put(pkt, tail_pad); 1981 __skb_put(pkt, tail_pad);
1925 } 1982 }
1926 1983
1927 if (pkt_pad) 1984 return tail_pad;
1928 return pkt->len + tail_chop;
1929 else
1930 return pkt->len - tail_pad;
1931} 1985}
1932 1986
1933/** 1987/**
@@ -1946,58 +2000,66 @@ static int
1946brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, 2000brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
1947 uint chan) 2001 uint chan)
1948{ 2002{
1949 u16 head_pad, head_align; 2003 u16 head_pad, total_len;
1950 struct sk_buff *pkt_next; 2004 struct sk_buff *pkt_next;
1951 u8 *dat_buf; 2005 u8 txseq;
1952 int err; 2006 int ret;
1953 struct brcmf_sdio_hdrinfo hd_info = {0}; 2007 struct brcmf_sdio_hdrinfo hd_info = {0};
1954 2008
1955 /* SDIO ADMA requires at least 32 bit alignment */ 2009 txseq = bus->tx_seq;
1956 head_align = 4; 2010 total_len = 0;
1957 if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) 2011 skb_queue_walk(pktq, pkt_next) {
1958 head_align = bus->sdiodev->pdata->sd_head_align; 2012 /* alignment packet inserted in previous
2013 * loop cycle can be skipped as it is
2014 * already properly aligned and does not
2015 * need an sdpcm header.
2016 */
2017 if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
2018 continue;
1959 2019
1960 pkt_next = pktq->next; 2020 /* align packet data pointer */
1961 dat_buf = (u8 *)(pkt_next->data); 2021 ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next);
2022 if (ret < 0)
2023 return ret;
2024 head_pad = (u16)ret;
2025 if (head_pad)
2026 memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen);
1962 2027
1963 /* Check head padding */ 2028 total_len += pkt_next->len;
1964 head_pad = ((unsigned long)dat_buf % head_align);
1965 if (head_pad) {
1966 if (skb_headroom(pkt_next) < head_pad) {
1967 bus->sdiodev->bus_if->tx_realloc++;
1968 head_pad = 0;
1969 if (skb_cow(pkt_next, head_pad))
1970 return -ENOMEM;
1971 }
1972 skb_push(pkt_next, head_pad);
1973 dat_buf = (u8 *)(pkt_next->data);
1974 memset(dat_buf, 0, head_pad + bus->tx_hdrlen);
1975 }
1976 2029
1977 if (bus->sdiodev->sg_support && pktq->qlen > 1) {
1978 err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq,
1979 pkt_next, chan);
1980 if (err < 0)
1981 return err;
1982 hd_info.len = (u16)err;
1983 } else {
1984 hd_info.len = pkt_next->len; 2030 hd_info.len = pkt_next->len;
1985 } 2031 hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next);
1986 2032 if (bus->txglom && pktq->qlen > 1) {
1987 hd_info.channel = chan; 2033 ret = brcmf_sdio_txpkt_prep_sg(bus, pktq,
1988 hd_info.dat_offset = head_pad + bus->tx_hdrlen; 2034 pkt_next, total_len);
1989 2035 if (ret < 0)
1990 /* Now fill the header */ 2036 return ret;
1991 brcmf_sdio_hdpack(bus, dat_buf, &hd_info); 2037 hd_info.tail_pad = (u16)ret;
1992 2038 total_len += (u16)ret;
1993 if (BRCMF_BYTES_ON() && 2039 }
1994 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
1995 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
1996 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n");
1997 else if (BRCMF_HDRS_ON())
1998 brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen,
1999 "Tx Header:\n");
2000 2040
2041 hd_info.channel = chan;
2042 hd_info.dat_offset = head_pad + bus->tx_hdrlen;
2043 hd_info.seq_num = txseq++;
2044
2045 /* Now fill the header */
2046 brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info);
2047
2048 if (BRCMF_BYTES_ON() &&
2049 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
2050 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
2051 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len,
2052 "Tx Frame:\n");
2053 else if (BRCMF_HDRS_ON())
2054 brcmf_dbg_hex_dump(true, pkt_next,
2055 head_pad + bus->tx_hdrlen,
2056 "Tx Header:\n");
2057 }
2058 /* Hardware length tag of the first packet should be total
2059 * length of the chain (including padding)
2060 */
2061 if (bus->txglom)
2062 brcmf_sdio_update_hwhdr(pktq->next->data, total_len);
2001 return 0; 2063 return 0;
2002} 2064}
2003 2065
@@ -2015,6 +2077,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2015{ 2077{
2016 u8 *hdr; 2078 u8 *hdr;
2017 u32 dat_offset; 2079 u32 dat_offset;
2080 u16 tail_pad;
2018 u32 dummy_flags, chop_len; 2081 u32 dummy_flags, chop_len;
2019 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2082 struct sk_buff *pkt_next, *tmp, *pkt_prev;
2020 2083
@@ -2024,42 +2087,42 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2024 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2087 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
2025 if (chop_len) { 2088 if (chop_len) {
2026 pkt_prev = pkt_next->prev; 2089 pkt_prev = pkt_next->prev;
2027 memcpy(pkt_prev->data + pkt_prev->len,
2028 pkt_next->data, chop_len);
2029 skb_put(pkt_prev, chop_len); 2090 skb_put(pkt_prev, chop_len);
2030 } 2091 }
2031 __skb_unlink(pkt_next, pktq); 2092 __skb_unlink(pkt_next, pktq);
2032 brcmu_pkt_buf_free_skb(pkt_next); 2093 brcmu_pkt_buf_free_skb(pkt_next);
2033 } else { 2094 } else {
2034 hdr = pkt_next->data + SDPCM_HWHDR_LEN; 2095 hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN;
2035 dat_offset = le32_to_cpu(*(__le32 *)hdr); 2096 dat_offset = le32_to_cpu(*(__le32 *)hdr);
2036 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> 2097 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >>
2037 SDPCM_DOFFSET_SHIFT; 2098 SDPCM_DOFFSET_SHIFT;
2038 skb_pull(pkt_next, dat_offset); 2099 skb_pull(pkt_next, dat_offset);
2100 if (bus->txglom) {
2101 tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2));
2102 skb_trim(pkt_next, pkt_next->len - tail_pad);
2103 }
2039 } 2104 }
2040 } 2105 }
2041} 2106}
2042 2107
2043/* Writes a HW/SW header into the packet and sends it. */ 2108/* Writes a HW/SW header into the packet and sends it. */
2044/* Assumes: (a) header space already there, (b) caller holds lock */ 2109/* Assumes: (a) header space already there, (b) caller holds lock */
2045static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, 2110static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2046 uint chan) 2111 uint chan)
2047{ 2112{
2048 int ret; 2113 int ret;
2049 int i; 2114 int i;
2050 struct sk_buff_head localq; 2115 struct sk_buff *pkt_next, *tmp;
2051 2116
2052 brcmf_dbg(TRACE, "Enter\n"); 2117 brcmf_dbg(TRACE, "Enter\n");
2053 2118
2054 __skb_queue_head_init(&localq); 2119 ret = brcmf_sdio_txpkt_prep(bus, pktq, chan);
2055 __skb_queue_tail(&localq, pkt);
2056 ret = brcmf_sdio_txpkt_prep(bus, &localq, chan);
2057 if (ret) 2120 if (ret)
2058 goto done; 2121 goto done;
2059 2122
2060 sdio_claim_host(bus->sdiodev->func[1]); 2123 sdio_claim_host(bus->sdiodev->func[1]);
2061 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, 2124 ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
2062 SDIO_FUNC_2, F2SYNC, &localq); 2125 SDIO_FUNC_2, F2SYNC, pktq);
2063 bus->sdcnt.f2txdata++; 2126 bus->sdcnt.f2txdata++;
2064 2127
2065 if (ret < 0) { 2128 if (ret < 0) {
@@ -2083,42 +2146,56 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
2083 if ((hi == 0) && (lo == 0)) 2146 if ((hi == 0) && (lo == 0))
2084 break; 2147 break;
2085 } 2148 }
2086
2087 } 2149 }
2088 sdio_release_host(bus->sdiodev->func[1]); 2150 sdio_release_host(bus->sdiodev->func[1]);
2089 if (ret == 0)
2090 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2091 2151
2092done: 2152done:
2093 brcmf_sdio_txpkt_postp(bus, &localq); 2153 brcmf_sdio_txpkt_postp(bus, pktq);
2094 __skb_dequeue_tail(&localq); 2154 if (ret == 0)
2095 brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); 2155 bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP;
2156 skb_queue_walk_safe(pktq, pkt_next, tmp) {
2157 __skb_unlink(pkt_next, pktq);
2158 brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0);
2159 }
2096 return ret; 2160 return ret;
2097} 2161}
2098 2162
2099static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) 2163static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2100{ 2164{
2101 struct sk_buff *pkt; 2165 struct sk_buff *pkt;
2166 struct sk_buff_head pktq;
2102 u32 intstatus = 0; 2167 u32 intstatus = 0;
2103 int ret = 0, prec_out; 2168 int ret = 0, prec_out, i;
2104 uint cnt = 0; 2169 uint cnt = 0;
2105 u8 tx_prec_map; 2170 u8 tx_prec_map, pkt_num;
2106 2171
2107 brcmf_dbg(TRACE, "Enter\n"); 2172 brcmf_dbg(TRACE, "Enter\n");
2108 2173
2109 tx_prec_map = ~bus->flowcontrol; 2174 tx_prec_map = ~bus->flowcontrol;
2110 2175
2111 /* Send frames until the limit or some other event */ 2176 /* Send frames until the limit or some other event */
2112 for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) { 2177 for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
2178 pkt_num = 1;
2179 __skb_queue_head_init(&pktq);
2180 if (bus->txglom)
2181 pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
2182 brcmf_sdio_txglomsz);
2183 pkt_num = min_t(u32, pkt_num,
2184 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol));
2113 spin_lock_bh(&bus->txqlock); 2185 spin_lock_bh(&bus->txqlock);
2114 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); 2186 for (i = 0; i < pkt_num; i++) {
2115 if (pkt == NULL) { 2187 pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map,
2116 spin_unlock_bh(&bus->txqlock); 2188 &prec_out);
2117 break; 2189 if (pkt == NULL)
2190 break;
2191 __skb_queue_tail(&pktq, pkt);
2118 } 2192 }
2119 spin_unlock_bh(&bus->txqlock); 2193 spin_unlock_bh(&bus->txqlock);
2194 if (i == 0)
2195 break;
2120 2196
2121 ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL); 2197 ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
2198 cnt += i;
2122 2199
2123 /* In poll mode, need to check for other events */ 2200 /* In poll mode, need to check for other events */
2124 if (!bus->intr && cnt) { 2201 if (!bus->intr && cnt) {
@@ -2665,7 +2742,7 @@ static int
2665brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) 2742brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2666{ 2743{
2667 u8 *frame; 2744 u8 *frame;
2668 u16 len; 2745 u16 len, pad;
2669 uint retries = 0; 2746 uint retries = 0;
2670 u8 doff = 0; 2747 u8 doff = 0;
2671 int ret = -1; 2748 int ret = -1;
@@ -2681,28 +2758,26 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2681 len = (msglen += bus->tx_hdrlen); 2758 len = (msglen += bus->tx_hdrlen);
2682 2759
2683 /* Add alignment padding (optional for ctl frames) */ 2760 /* Add alignment padding (optional for ctl frames) */
2684 doff = ((unsigned long)frame % BRCMF_SDALIGN); 2761 doff = ((unsigned long)frame % bus->head_align);
2685 if (doff) { 2762 if (doff) {
2686 frame -= doff; 2763 frame -= doff;
2687 len += doff; 2764 len += doff;
2688 msglen += doff; 2765 msglen += doff;
2689 memset(frame, 0, doff + bus->tx_hdrlen); 2766 memset(frame, 0, doff + bus->tx_hdrlen);
2690 } 2767 }
2691 /* precondition: doff < BRCMF_SDALIGN */ 2768 /* precondition: doff < bus->head_align */
2692 doff += bus->tx_hdrlen; 2769 doff += bus->tx_hdrlen;
2693 2770
2694 /* Round send length to next SDIO block */ 2771 /* Round send length to next SDIO block */
2772 pad = 0;
2695 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { 2773 if (bus->roundup && bus->blocksize && (len > bus->blocksize)) {
2696 u16 pad = bus->blocksize - (len % bus->blocksize); 2774 pad = bus->blocksize - (len % bus->blocksize);
2697 if ((pad <= bus->roundup) && (pad < bus->blocksize)) 2775 if ((pad > bus->roundup) || (pad >= bus->blocksize))
2698 len += pad; 2776 pad = 0;
2699 } else if (len % BRCMF_SDALIGN) { 2777 } else if (len % bus->head_align) {
2700 len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); 2778 pad = bus->head_align - (len % bus->head_align);
2701 } 2779 }
2702 2780 len += pad;
2703 /* Satisfy length-alignment requirements */
2704 if (len & (ALIGNMENT - 1))
2705 len = roundup(len, ALIGNMENT);
2706 2781
2707 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ 2782 /* precondition: IS_ALIGNED((unsigned long)frame, 2) */
2708 2783
@@ -2714,8 +2789,14 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2714 hd_info.len = (u16)msglen; 2789 hd_info.len = (u16)msglen;
2715 hd_info.channel = SDPCM_CONTROL_CHANNEL; 2790 hd_info.channel = SDPCM_CONTROL_CHANNEL;
2716 hd_info.dat_offset = doff; 2791 hd_info.dat_offset = doff;
2792 hd_info.seq_num = bus->tx_seq;
2793 hd_info.lastfrm = true;
2794 hd_info.tail_pad = pad;
2717 brcmf_sdio_hdpack(bus, frame, &hd_info); 2795 brcmf_sdio_hdpack(bus, frame, &hd_info);
2718 2796
2797 if (bus->txglom)
2798 brcmf_sdio_update_hwhdr(frame, len);
2799
2719 if (!data_ok(bus)) { 2800 if (!data_ok(bus)) {
2720 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", 2801 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
2721 bus->tx_max, bus->tx_seq); 2802 bus->tx_max, bus->tx_seq);
@@ -3425,6 +3506,65 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
3425 return ret; 3506 return ret;
3426} 3507}
3427 3508
3509static int brcmf_sdbrcm_bus_preinit(struct device *dev)
3510{
3511 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
3512 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
3513 struct brcmf_sdio *bus = sdiodev->bus;
3514 uint pad_size;
3515 u32 value;
3516 u8 idx;
3517 int err;
3518
3519 /* the commands below use the terms tx and rx from
3520 * a device perspective, ie. bus:txglom affects the
3521 * bus transfers from device to host.
3522 */
3523 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
3524 if (bus->ci->c_inf[idx].rev < 12) {
3525 /* for sdio core rev < 12, disable txgloming */
3526 value = 0;
3527 err = brcmf_iovar_data_set(dev, "bus:txglom", &value,
3528 sizeof(u32));
3529 } else {
3530 /* otherwise, set txglomalign */
3531 value = 4;
3532 if (sdiodev->pdata)
3533 value = sdiodev->pdata->sd_sgentry_align;
3534 /* SDIO ADMA requires at least 32 bit alignment */
3535 value = max_t(u32, value, 4);
3536 err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
3537 sizeof(u32));
3538 }
3539
3540 if (err < 0)
3541 goto done;
3542
3543 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
3544 if (sdiodev->sg_support) {
3545 bus->txglom = false;
3546 value = 1;
3547 pad_size = bus->sdiodev->func[2]->cur_blksize << 1;
3548 bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size);
3549 if (!bus->txglom_sgpad)
3550 brcmf_err("allocating txglom padding skb failed, reduced performance\n");
3551
3552 err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom",
3553 &value, sizeof(u32));
3554 if (err < 0) {
3555 /* bus:rxglom is allowed to fail */
3556 err = 0;
3557 } else {
3558 bus->txglom = true;
3559 bus->tx_hdrlen += SDPCM_HWEXT_LEN;
3560 }
3561 }
3562 brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen);
3563
3564done:
3565 return err;
3566}
3567
3428static int brcmf_sdbrcm_bus_init(struct device *dev) 3568static int brcmf_sdbrcm_bus_init(struct device *dev)
3429{ 3569{
3430 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 3570 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -3673,7 +3813,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus)
3673 if (bus->sdiodev->bus_if->maxctl) { 3813 if (bus->sdiodev->bus_if->maxctl) {
3674 bus->rxblen = 3814 bus->rxblen =
3675 roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), 3815 roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN),
3676 ALIGNMENT) + BRCMF_SDALIGN; 3816 ALIGNMENT) + bus->head_align;
3677 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); 3817 bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC);
3678 if (!(bus->rxbuf)) 3818 if (!(bus->rxbuf))
3679 return false; 3819 return false;
@@ -3774,9 +3914,13 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
3774 3914
3775 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); 3915 brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
3776 3916
3917 /* allocate header buffer */
3918 bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL);
3919 if (!bus->hdrbuf)
3920 return false;
3777 /* Locate an appropriately-aligned portion of hdrbuf */ 3921 /* Locate an appropriately-aligned portion of hdrbuf */
3778 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], 3922 bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0],
3779 BRCMF_SDALIGN); 3923 bus->head_align);
3780 3924
3781 /* Set the poll and/or interrupt flags */ 3925 /* Set the poll and/or interrupt flags */
3782 bus->intr = true; 3926 bus->intr = true;
@@ -3895,8 +4039,9 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3895 brcmf_sdbrcm_release_dongle(bus); 4039 brcmf_sdbrcm_release_dongle(bus);
3896 } 4040 }
3897 4041
4042 brcmu_pkt_buf_free_skb(bus->txglom_sgpad);
3898 brcmf_sdbrcm_release_malloc(bus); 4043 brcmf_sdbrcm_release_malloc(bus);
3899 4044 kfree(bus->hdrbuf);
3900 kfree(bus); 4045 kfree(bus);
3901 } 4046 }
3902 4047
@@ -3905,6 +4050,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3905 4050
3906static struct brcmf_bus_ops brcmf_sdio_bus_ops = { 4051static struct brcmf_bus_ops brcmf_sdio_bus_ops = {
3907 .stop = brcmf_sdbrcm_bus_stop, 4052 .stop = brcmf_sdbrcm_bus_stop,
4053 .preinit = brcmf_sdbrcm_bus_preinit,
3908 .init = brcmf_sdbrcm_bus_init, 4054 .init = brcmf_sdbrcm_bus_init,
3909 .txdata = brcmf_sdbrcm_bus_txdata, 4055 .txdata = brcmf_sdbrcm_bus_txdata,
3910 .txctl = brcmf_sdbrcm_bus_txctl, 4056 .txctl = brcmf_sdbrcm_bus_txctl,
@@ -3916,10 +4062,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3916{ 4062{
3917 int ret; 4063 int ret;
3918 struct brcmf_sdio *bus; 4064 struct brcmf_sdio *bus;
3919 struct brcmf_bus_dcmd *dlst;
3920 u32 dngl_txglom;
3921 u32 txglomalign = 0;
3922 u8 idx;
3923 4065
3924 brcmf_dbg(TRACE, "Enter\n"); 4066 brcmf_dbg(TRACE, "Enter\n");
3925 4067
@@ -3939,6 +4081,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3939 bus->txminmax = BRCMF_TXMINMAX; 4081 bus->txminmax = BRCMF_TXMINMAX;
3940 bus->tx_seq = SDPCM_SEQ_WRAP - 1; 4082 bus->tx_seq = SDPCM_SEQ_WRAP - 1;
3941 4083
4084 /* platform specific configuration:
4085 * alignments must be at least 4 bytes for ADMA
4086 */
4087 bus->head_align = ALIGNMENT;
4088 bus->sgentry_align = ALIGNMENT;
4089 if (sdiodev->pdata) {
4090 if (sdiodev->pdata->sd_head_align > ALIGNMENT)
4091 bus->head_align = sdiodev->pdata->sd_head_align;
4092 if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
4093 bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
4094 }
4095
3942 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 4096 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3943 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 4097 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
3944 if (bus->brcmf_wq == NULL) { 4098 if (bus->brcmf_wq == NULL) {
@@ -3983,7 +4137,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3983 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; 4137 bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN;
3984 4138
3985 /* Attach to the common layer, reserve hdr space */ 4139 /* Attach to the common layer, reserve hdr space */
3986 ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev); 4140 ret = brcmf_attach(bus->sdiodev->dev);
3987 if (ret != 0) { 4141 if (ret != 0) {
3988 brcmf_err("brcmf_attach failed\n"); 4142 brcmf_err("brcmf_attach failed\n");
3989 goto fail; 4143 goto fail;
@@ -4003,30 +4157,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4003 brcmf_sdio_debugfs_create(bus); 4157 brcmf_sdio_debugfs_create(bus);
4004 brcmf_dbg(INFO, "completed!!\n"); 4158 brcmf_dbg(INFO, "completed!!\n");
4005 4159
4006 /* sdio bus core specific dcmd */
4007 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
4008 dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL);
4009 if (dlst) {
4010 if (bus->ci->c_inf[idx].rev < 12) {
4011 /* for sdio core rev < 12, disable txgloming */
4012 dngl_txglom = 0;
4013 dlst->name = "bus:txglom";
4014 dlst->param = (char *)&dngl_txglom;
4015 dlst->param_len = sizeof(u32);
4016 } else {
4017 /* otherwise, set txglomalign */
4018 if (sdiodev->pdata)
4019 txglomalign = sdiodev->pdata->sd_sgentry_align;
4020 /* SDIO ADMA requires at least 32 bit alignment */
4021 if (txglomalign < 4)
4022 txglomalign = 4;
4023 dlst->name = "bus:txglomalign";
4024 dlst->param = (char *)&txglomalign;
4025 dlst->param_len = sizeof(u32);
4026 }
4027 list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list);
4028 }
4029
4030 /* if firmware path present try to download and bring up bus */ 4160 /* if firmware path present try to download and bring up bus */
4031 ret = brcmf_bus_start(bus->sdiodev->dev); 4161 ret = brcmf_bus_start(bus->sdiodev->dev);
4032 if (ret != 0) { 4162 if (ret != 0) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index 14bc24dc5bae..51b53a73d074 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -122,6 +122,52 @@ enum brcmf_fweh_event_code {
122#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 122#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
123#define BRCMF_EVENT_MSG_GROUP 0x04 123#define BRCMF_EVENT_MSG_GROUP 0x04
124 124
125/* status field values in struct brcmf_event_msg */
126#define BRCMF_E_STATUS_SUCCESS 0
127#define BRCMF_E_STATUS_FAIL 1
128#define BRCMF_E_STATUS_TIMEOUT 2
129#define BRCMF_E_STATUS_NO_NETWORKS 3
130#define BRCMF_E_STATUS_ABORT 4
131#define BRCMF_E_STATUS_NO_ACK 5
132#define BRCMF_E_STATUS_UNSOLICITED 6
133#define BRCMF_E_STATUS_ATTEMPT 7
134#define BRCMF_E_STATUS_PARTIAL 8
135#define BRCMF_E_STATUS_NEWSCAN 9
136#define BRCMF_E_STATUS_NEWASSOC 10
137#define BRCMF_E_STATUS_11HQUIET 11
138#define BRCMF_E_STATUS_SUPPRESS 12
139#define BRCMF_E_STATUS_NOCHANS 13
140#define BRCMF_E_STATUS_CS_ABORT 15
141#define BRCMF_E_STATUS_ERROR 16
142
143/* reason field values in struct brcmf_event_msg */
144#define BRCMF_E_REASON_INITIAL_ASSOC 0
145#define BRCMF_E_REASON_LOW_RSSI 1
146#define BRCMF_E_REASON_DEAUTH 2
147#define BRCMF_E_REASON_DISASSOC 3
148#define BRCMF_E_REASON_BCNS_LOST 4
149#define BRCMF_E_REASON_MINTXRATE 9
150#define BRCMF_E_REASON_TXFAIL 10
151
152#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4
153#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
154#define BRCMF_E_REASON_DIRECTED_ROAM 6
155#define BRCMF_E_REASON_TSPEC_REJECTED 7
156#define BRCMF_E_REASON_BETTER_AP 8
157
158/* action field values for brcmf_ifevent */
159#define BRCMF_E_IF_ADD 1
160#define BRCMF_E_IF_DEL 2
161#define BRCMF_E_IF_CHANGE 3
162
163/* flag field values for brcmf_ifevent */
164#define BRCMF_E_IF_FLAG_NOIF 1
165
166/* role field values for brcmf_ifevent */
167#define BRCMF_E_IF_ROLE_STA 0
168#define BRCMF_E_IF_ROLE_AP 1
169#define BRCMF_E_IF_ROLE_WDS 2
170
125/** 171/**
126 * definitions for event packet validation. 172 * definitions for event packet validation.
127 */ 173 */
@@ -160,6 +206,14 @@ struct brcmf_event_msg {
160 u8 bsscfgidx; 206 u8 bsscfgidx;
161}; 207};
162 208
209struct brcmf_if_event {
210 u8 ifidx;
211 u8 action;
212 u8 flags;
213 u8 bssidx;
214 u8 role;
215};
216
163typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, 217typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
164 const struct brcmf_event_msg *evtmsg, 218 const struct brcmf_event_msg *evtmsg,
165 void *data); 219 void *data);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 04f395930d86..b72d3395499a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -27,6 +27,7 @@
27#include "dhd_dbg.h" 27#include "dhd_dbg.h"
28#include "tracepoint.h" 28#include "tracepoint.h"
29#include "fwil.h" 29#include "fwil.h"
30#include "proto.h"
30 31
31 32
32#define MAX_HEX_DUMP_LEN 64 33#define MAX_HEX_DUMP_LEN 64
@@ -46,11 +47,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
46 if (data != NULL) 47 if (data != NULL)
47 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 48 len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
48 if (set) 49 if (set)
49 err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data, 50 err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
50 len);
51 else 51 else
52 err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data, 52 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
53 len);
54 53
55 if (err >= 0) 54 if (err >= 0)
56 err = 0; 55 err = 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
index 16eb8202fb1e..77eae86e55c2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
@@ -17,6 +17,67 @@
17#ifndef _fwil_h_ 17#ifndef _fwil_h_
18#define _fwil_h_ 18#define _fwil_h_
19 19
20/*******************************************************************************
21 * Dongle command codes that are interpreted by firmware
22 ******************************************************************************/
23#define BRCMF_C_GET_VERSION 1
24#define BRCMF_C_UP 2
25#define BRCMF_C_DOWN 3
26#define BRCMF_C_SET_PROMISC 10
27#define BRCMF_C_GET_RATE 12
28#define BRCMF_C_GET_INFRA 19
29#define BRCMF_C_SET_INFRA 20
30#define BRCMF_C_GET_AUTH 21
31#define BRCMF_C_SET_AUTH 22
32#define BRCMF_C_GET_BSSID 23
33#define BRCMF_C_GET_SSID 25
34#define BRCMF_C_SET_SSID 26
35#define BRCMF_C_TERMINATED 28
36#define BRCMF_C_GET_CHANNEL 29
37#define BRCMF_C_SET_CHANNEL 30
38#define BRCMF_C_GET_SRL 31
39#define BRCMF_C_SET_SRL 32
40#define BRCMF_C_GET_LRL 33
41#define BRCMF_C_SET_LRL 34
42#define BRCMF_C_GET_RADIO 37
43#define BRCMF_C_SET_RADIO 38
44#define BRCMF_C_GET_PHYTYPE 39
45#define BRCMF_C_SET_KEY 45
46#define BRCMF_C_SET_PASSIVE_SCAN 49
47#define BRCMF_C_SCAN 50
48#define BRCMF_C_SCAN_RESULTS 51
49#define BRCMF_C_DISASSOC 52
50#define BRCMF_C_REASSOC 53
51#define BRCMF_C_SET_ROAM_TRIGGER 55
52#define BRCMF_C_SET_ROAM_DELTA 57
53#define BRCMF_C_GET_BCNPRD 75
54#define BRCMF_C_SET_BCNPRD 76
55#define BRCMF_C_GET_DTIMPRD 77
56#define BRCMF_C_SET_DTIMPRD 78
57#define BRCMF_C_SET_COUNTRY 84
58#define BRCMF_C_GET_PM 85
59#define BRCMF_C_SET_PM 86
60#define BRCMF_C_GET_CURR_RATESET 114
61#define BRCMF_C_GET_AP 117
62#define BRCMF_C_SET_AP 118
63#define BRCMF_C_GET_RSSI 127
64#define BRCMF_C_GET_WSEC 133
65#define BRCMF_C_SET_WSEC 134
66#define BRCMF_C_GET_PHY_NOISE 135
67#define BRCMF_C_GET_BSS_INFO 136
68#define BRCMF_C_GET_BANDLIST 140
69#define BRCMF_C_SET_SCB_TIMEOUT 158
70#define BRCMF_C_GET_PHYLIST 180
71#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
72#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
73#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
74#define BRCMF_C_GET_VALID_CHANNELS 217
75#define BRCMF_C_GET_KEY_PRIMARY 235
76#define BRCMF_C_SET_KEY_PRIMARY 236
77#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
78#define BRCMF_C_GET_VAR 262
79#define BRCMF_C_SET_VAR 263
80
20s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 81s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
21s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); 82s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len);
22s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); 83s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index ecabb04f33c3..af17a5bc8b83 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -29,6 +29,24 @@
29#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 29#define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004
30#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 30#define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008
31 31
32#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */
33#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002
34
35#define BRCMF_STA_ASSOC 0x10 /* Associated */
36
37/* size of brcmf_scan_params not including variable length array */
38#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
39
40/* masks for channel and ssid count */
41#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
42#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
43
44/* primary (ie tx) key */
45#define BRCMF_PRIMARY_KEY (1 << 1)
46#define DOT11_BSSTYPE_ANY 2
47#define BRCMF_ESCAN_REQ_VERSION 1
48
49#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
32 50
33enum brcmf_fil_p2p_if_types { 51enum brcmf_fil_p2p_if_types {
34 BRCMF_FIL_P2P_IF_CLIENT, 52 BRCMF_FIL_P2P_IF_CLIENT,
@@ -90,4 +108,290 @@ enum brcmf_tdls_manual_ep_ops {
90 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6 108 BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6
91}; 109};
92 110
111/* Pattern matching filter. Specifies an offset within received packets to
112 * start matching, the pattern to match, the size of the pattern, and a bitmask
113 * that indicates which bits within the pattern should be matched.
114 */
115struct brcmf_pkt_filter_pattern_le {
116 /*
117 * Offset within received packet to start pattern matching.
118 * Offset '0' is the first byte of the ethernet header.
119 */
120 __le32 offset;
121 /* Size of the pattern. Bitmask must be the same size.*/
122 __le32 size_bytes;
123 /*
124 * Variable length mask and pattern data. mask starts at offset 0.
125 * Pattern immediately follows mask.
126 */
127 u8 mask_and_pattern[1];
128};
129
130/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
131struct brcmf_pkt_filter_le {
132 __le32 id; /* Unique filter id, specified by app. */
133 __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
134 __le32 negate_match; /* Negate the result of filter matches */
135 union { /* Filter definitions */
136 struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
137 } u;
138};
139
140/* IOVAR "pkt_filter_enable" parameter. */
141struct brcmf_pkt_filter_enable_le {
142 __le32 id; /* Unique filter id */
143 __le32 enable; /* Enable/disable bool */
144};
145
146/* BSS info structure
147 * Applications MUST CHECK ie_offset field and length field to access IEs and
148 * next bss_info structure in a vector (in struct brcmf_scan_results)
149 */
150struct brcmf_bss_info_le {
151 __le32 version; /* version field */
152 __le32 length; /* byte length of data in this record,
153 * starting at version and including IEs
154 */
155 u8 BSSID[ETH_ALEN];
156 __le16 beacon_period; /* units are Kusec */
157 __le16 capability; /* Capability information */
158 u8 SSID_len;
159 u8 SSID[32];
160 struct {
161 __le32 count; /* # rates in this set */
162 u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
163 } rateset; /* supported rates */
164 __le16 chanspec; /* chanspec for bss */
165 __le16 atim_window; /* units are Kusec */
166 u8 dtim_period; /* DTIM period */
167 __le16 RSSI; /* receive signal strength (in dBm) */
168 s8 phy_noise; /* noise (in dBm) */
169
170 u8 n_cap; /* BSS is 802.11N Capable */
171 /* 802.11N BSS Capabilities (based on HT_CAP_*): */
172 __le32 nbss_cap;
173 u8 ctl_ch; /* 802.11N BSS control channel number */
174 __le32 reserved32[1]; /* Reserved for expansion of BSS properties */
175 u8 flags; /* flags */
176 u8 reserved[3]; /* Reserved for expansion of BSS properties */
177 u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
178
179 __le16 ie_offset; /* offset at which IEs start, from beginning */
180 __le32 ie_length; /* byte length of Information Elements */
181 __le16 SNR; /* average SNR of during frame reception */
182 /* Add new fields here */
183 /* variable length Information Elements */
184};
185
186struct brcm_rateset_le {
187 /* # rates in this set */
188 __le32 count;
189 /* rates in 500kbps units w/hi bit set if basic */
190 u8 rates[BRCMF_MAXRATES_IN_SET];
191};
192
193struct brcmf_ssid {
194 u32 SSID_len;
195 unsigned char SSID[32];
196};
197
198struct brcmf_ssid_le {
199 __le32 SSID_len;
200 unsigned char SSID[32];
201};
202
203struct brcmf_scan_params_le {
204 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
205 u8 bssid[ETH_ALEN]; /* default: bcast */
206 s8 bss_type; /* default: any,
207 * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
208 */
209 u8 scan_type; /* flags, 0 use default */
210 __le32 nprobes; /* -1 use default, number of probes per channel */
211 __le32 active_time; /* -1 use default, dwell time per channel for
212 * active scanning
213 */
214 __le32 passive_time; /* -1 use default, dwell time per channel
215 * for passive scanning
216 */
217 __le32 home_time; /* -1 use default, dwell time for the
218 * home channel between channel scans
219 */
220 __le32 channel_num; /* count of channels and ssids that follow
221 *
222 * low half is count of channels in
223 * channel_list, 0 means default (use all
224 * available channels)
225 *
226 * high half is entries in struct brcmf_ssid
227 * array that follows channel_list, aligned for
228 * s32 (4 bytes) meaning an odd channel count
229 * implies a 2-byte pad between end of
230 * channel_list and first ssid
231 *
232 * if ssid count is zero, single ssid in the
233 * fixed parameter portion is assumed, otherwise
234 * ssid in the fixed portion is ignored
235 */
236 __le16 channel_list[1]; /* list of chanspecs */
237};
238
239struct brcmf_scan_results {
240 u32 buflen;
241 u32 version;
242 u32 count;
243 struct brcmf_bss_info_le bss_info_le[];
244};
245
246struct brcmf_escan_params_le {
247 __le32 version;
248 __le16 action;
249 __le16 sync_id;
250 struct brcmf_scan_params_le params_le;
251};
252
253struct brcmf_escan_result_le {
254 __le32 buflen;
255 __le32 version;
256 __le16 sync_id;
257 __le16 bss_count;
258 struct brcmf_bss_info_le bss_info_le;
259};
260
261#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
262 sizeof(struct brcmf_bss_info_le))
263
264/* used for association with a specific BSSID and chanspec list */
265struct brcmf_assoc_params_le {
266 /* 00:00:00:00:00:00: broadcast scan */
267 u8 bssid[ETH_ALEN];
268 /* 0: all available channels, otherwise count of chanspecs in
269 * chanspec_list */
270 __le32 chanspec_num;
271 /* list of chanspecs */
272 __le16 chanspec_list[1];
273};
274
275/* used for join with or without a specific bssid and channel list */
276struct brcmf_join_params {
277 struct brcmf_ssid_le ssid_le;
278 struct brcmf_assoc_params_le params_le;
279};
280
281/* scan params for extended join */
282struct brcmf_join_scan_params_le {
283 u8 scan_type; /* 0 use default, active or passive scan */
284 __le32 nprobes; /* -1 use default, nr of probes per channel */
285 __le32 active_time; /* -1 use default, dwell time per channel for
286 * active scanning
287 */
288 __le32 passive_time; /* -1 use default, dwell time per channel
289 * for passive scanning
290 */
291 __le32 home_time; /* -1 use default, dwell time for the home
292 * channel between channel scans
293 */
294};
295
296/* extended join params */
297struct brcmf_ext_join_params_le {
298 struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */
299 struct brcmf_join_scan_params_le scan_le;
300 struct brcmf_assoc_params_le assoc_le;
301};
302
303struct brcmf_wsec_key {
304 u32 index; /* key index */
305 u32 len; /* key length */
306 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
307 u32 pad_1[18];
308 u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
309 u32 flags; /* misc flags */
310 u32 pad_2[3];
311 u32 iv_initialized; /* has IV been initialized already? */
312 u32 pad_3;
313 /* Rx IV */
314 struct {
315 u32 hi; /* upper 32 bits of IV */
316 u16 lo; /* lower 16 bits of IV */
317 } rxiv;
318 u32 pad_4[2];
319 u8 ea[ETH_ALEN]; /* per station */
320};
321
322/*
323 * dongle requires same struct as above but with fields in little endian order
324 */
325struct brcmf_wsec_key_le {
326 __le32 index; /* key index */
327 __le32 len; /* key length */
328 u8 data[WLAN_MAX_KEY_LEN]; /* key data */
329 __le32 pad_1[18];
330 __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
331 __le32 flags; /* misc flags */
332 __le32 pad_2[3];
333 __le32 iv_initialized; /* has IV been initialized already? */
334 __le32 pad_3;
335 /* Rx IV */
336 struct {
337 __le32 hi; /* upper 32 bits of IV */
338 __le16 lo; /* lower 16 bits of IV */
339 } rxiv;
340 __le32 pad_4[2];
341 u8 ea[ETH_ALEN]; /* per station */
342};
343
344/* Used to get specific STA parameters */
345struct brcmf_scb_val_le {
346 __le32 val;
347 u8 ea[ETH_ALEN];
348};
349
350/* channel encoding */
351struct brcmf_channel_info_le {
352 __le32 hw_channel;
353 __le32 target_channel;
354 __le32 scan_channel;
355};
356
357struct brcmf_sta_info_le {
358 __le16 ver; /* version of this struct */
359 __le16 len; /* length in bytes of this structure */
360 __le16 cap; /* sta's advertised capabilities */
361 __le32 flags; /* flags defined below */
362 __le32 idle; /* time since data pkt rx'd from sta */
363 u8 ea[ETH_ALEN]; /* Station address */
364 __le32 count; /* # rates in this set */
365 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
366 /* w/hi bit set if basic */
367 __le32 in; /* seconds elapsed since associated */
368 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
369 __le32 tx_pkts; /* # of packets transmitted */
370 __le32 tx_failures; /* # of packets failed */
371 __le32 rx_ucast_pkts; /* # of unicast packets received */
372 __le32 rx_mcast_pkts; /* # of multicast packets received */
373 __le32 tx_rate; /* Rate of last successful tx frame */
374 __le32 rx_rate; /* Rate of last successful rx frame */
375 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
376 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
377};
378
379struct brcmf_chanspec_list {
380 __le32 count; /* # of entries */
381 __le32 element[1]; /* variable length uint32 list */
382};
383
384/*
385 * WLC_E_PROBRESP_MSG
386 * WLC_E_P2P_PROBREQ_MSG
387 * WLC_E_ACTION_FRAME_RX
388 */
389struct brcmf_rx_mgmt_data {
390 __be16 version;
391 __be16 chanspec;
392 __be32 rssi;
393 __be32 mactime;
394 __be32 rate;
395};
396
93#endif /* FWIL_TYPES_H_ */ 397#endif /* FWIL_TYPES_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index d0cd0bf95c5a..e9bdfdb95d8f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -27,7 +27,6 @@
27#include <brcmu_utils.h> 27#include <brcmu_utils.h>
28#include <brcmu_wifi.h> 28#include <brcmu_wifi.h>
29#include "dhd.h" 29#include "dhd.h"
30#include "dhd_proto.h"
31#include "dhd_dbg.h" 30#include "dhd_dbg.h"
32#include "dhd_bus.h" 31#include "dhd_bus.h"
33#include "fwil.h" 32#include "fwil.h"
@@ -36,6 +35,7 @@
36#include "fwsignal.h" 35#include "fwsignal.h"
37#include "p2p.h" 36#include "p2p.h"
38#include "wl_cfg80211.h" 37#include "wl_cfg80211.h"
38#include "proto.h"
39 39
40/** 40/**
41 * DOC: Firmware Signalling 41 * DOC: Firmware Signalling
@@ -105,6 +105,7 @@ static struct {
105}; 105};
106#undef BRCMF_FWS_TLV_DEF 106#undef BRCMF_FWS_TLV_DEF
107 107
108
108static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) 109static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
109{ 110{
110 int i; 111 int i;
@@ -123,6 +124,12 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
123#endif /* DEBUG */ 124#endif /* DEBUG */
124 125
125/* 126/*
127 * The PKTTAG tlv has additional bytes when firmware-signalling
128 * mode has REUSESEQ flag set.
129 */
130#define BRCMF_FWS_TYPE_SEQ_LEN 2
131
132/*
126 * flags used to enable tlv signalling from firmware. 133 * flags used to enable tlv signalling from firmware.
127 */ 134 */
128#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001 135#define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001
@@ -147,8 +154,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id)
147#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 154#define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01
148#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 155#define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02
149 156
150#define BRCMF_FWS_RET_OK_NOSCHEDULE 0 157#define BRCMF_FWS_RET_OK_NOSCHEDULE 0
151#define BRCMF_FWS_RET_OK_SCHEDULE 1 158#define BRCMF_FWS_RET_OK_SCHEDULE 1
159
160#define BRCMF_FWS_MODE_REUSESEQ_SHIFT 3 /* seq reuse */
161#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val) ((x) = \
162 ((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \
163 (((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT))
164#define BRCMF_FWS_MODE_GET_REUSESEQ(x) \
165 (((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1)
152 166
153/** 167/**
154 * enum brcmf_fws_skb_state - indicates processing state of skb. 168 * enum brcmf_fws_skb_state - indicates processing state of skb.
@@ -171,6 +185,7 @@ enum brcmf_fws_skb_state {
171 * @bus_flags: 2 bytes reserved for bus specific parameters 185 * @bus_flags: 2 bytes reserved for bus specific parameters
172 * @if_flags: holds interface index and packet related flags. 186 * @if_flags: holds interface index and packet related flags.
173 * @htod: host to device packet identifier (used in PKTTAG tlv). 187 * @htod: host to device packet identifier (used in PKTTAG tlv).
188 * @htod_seq: this 16-bit is original seq number for every suppress packet.
174 * @state: transmit state of the packet. 189 * @state: transmit state of the packet.
175 * @mac: descriptor related to destination for this packet. 190 * @mac: descriptor related to destination for this packet.
176 * 191 *
@@ -181,6 +196,7 @@ struct brcmf_skbuff_cb {
181 u16 bus_flags; 196 u16 bus_flags;
182 u16 if_flags; 197 u16 if_flags;
183 u32 htod; 198 u32 htod;
199 u16 htod_seq;
184 enum brcmf_fws_skb_state state; 200 enum brcmf_fws_skb_state state;
185 struct brcmf_fws_mac_descriptor *mac; 201 struct brcmf_fws_mac_descriptor *mac;
186}; 202};
@@ -257,6 +273,22 @@ struct brcmf_skbuff_cb {
257 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ 273 BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \
258 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) 274 BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT)
259 275
276#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK 0x2000
277#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT 13
278#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK 0x1000
279#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT 12
280#define BRCMF_SKB_HTOD_SEQ_NR_MASK 0x0fff
281#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT 0
282
283#define brcmf_skb_htod_seq_set_field(skb, field, value) \
284 brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \
285 BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
286 BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value))
287#define brcmf_skb_htod_seq_get_field(skb, field) \
288 brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \
289 BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \
290 BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT)
291
260#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000 292#define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000
261#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31 293#define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31
262#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000 294#define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000
@@ -265,8 +297,8 @@ struct brcmf_skbuff_cb {
265#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24 297#define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24
266#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00 298#define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00
267#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8 299#define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8
268#define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF 300#define BRCMF_FWS_TXSTAT_FREERUN_MASK 0x000000FF
269#define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0 301#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT 0
270 302
271#define brcmf_txstatus_get_field(txs, field) \ 303#define brcmf_txstatus_get_field(txs, field) \
272 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ 304 brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \
@@ -443,6 +475,7 @@ struct brcmf_fws_info {
443 unsigned long borrow_defer_timestamp; 475 unsigned long borrow_defer_timestamp;
444 bool bus_flow_blocked; 476 bool bus_flow_blocked;
445 bool creditmap_received; 477 bool creditmap_received;
478 u8 mode;
446}; 479};
447 480
448/* 481/*
@@ -812,13 +845,16 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
812 u16 data_offset = 0; 845 u16 data_offset = 0;
813 u8 fillers; 846 u8 fillers;
814 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); 847 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
848 __le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq);
815 849
816 brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n", 850 brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n",
817 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX), 851 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
818 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); 852 (le32_to_cpu(pkttag) >> 8) & 0xffff,
853 brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq);
819 if (entry->send_tim_signal) 854 if (entry->send_tim_signal)
820 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 855 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
821 856 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
857 data_offset += BRCMF_FWS_TYPE_SEQ_LEN;
822 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ 858 /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */
823 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN; 859 data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN;
824 fillers = round_up(data_offset, 4) - data_offset; 860 fillers = round_up(data_offset, 4) - data_offset;
@@ -830,7 +866,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
830 wlh[0] = BRCMF_FWS_TYPE_PKTTAG; 866 wlh[0] = BRCMF_FWS_TYPE_PKTTAG;
831 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN; 867 wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN;
832 memcpy(&wlh[2], &pkttag, sizeof(pkttag)); 868 memcpy(&wlh[2], &pkttag, sizeof(pkttag));
833 wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2; 869 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
870 wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN;
871 memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq,
872 sizeof(pktseq));
873 }
874 wlh += wlh[1] + 2;
834 875
835 if (entry->send_tim_signal) { 876 if (entry->send_tim_signal) {
836 entry->send_tim_signal = 0; 877 entry->send_tim_signal = 0;
@@ -875,6 +916,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
875 /* create a dummy packet and sent that. The traffic */ 916 /* create a dummy packet and sent that. The traffic */
876 /* bitmap info will automatically be attached to that packet */ 917 /* bitmap info will automatically be attached to that packet */
877 len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 + 918 len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 +
919 BRCMF_FWS_TYPE_SEQ_LEN +
878 BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 + 920 BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 +
879 4 + fws->drvr->hdrlen; 921 4 + fws->drvr->hdrlen;
880 skb = brcmu_pkt_buf_get_skb(len); 922 skb = brcmu_pkt_buf_get_skb(len);
@@ -884,6 +926,8 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws,
884 skcb = brcmf_skbcb(skb); 926 skcb = brcmf_skbcb(skb);
885 skcb->mac = entry; 927 skcb->mac = entry;
886 skcb->state = BRCMF_FWS_SKBSTATE_TIM; 928 skcb->state = BRCMF_FWS_SKBSTATE_TIM;
929 skcb->htod = 0;
930 skcb->htod_seq = 0;
887 bus = fws->drvr->bus_if; 931 bus = fws->drvr->bus_if;
888 err = brcmf_fws_hdrpush(fws, skb); 932 err = brcmf_fws_hdrpush(fws, skb);
889 if (err == 0) { 933 if (err == 0) {
@@ -1172,8 +1216,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
1172{ 1216{
1173 int prec = 2 * fifo; 1217 int prec = 2 * fifo;
1174 u32 *qfull_stat = &fws->stats.delayq_full_error; 1218 u32 *qfull_stat = &fws->stats.delayq_full_error;
1175
1176 struct brcmf_fws_mac_descriptor *entry; 1219 struct brcmf_fws_mac_descriptor *entry;
1220 struct pktq *pq;
1221 struct sk_buff_head *queue;
1222 struct sk_buff *p_head;
1223 struct sk_buff *p_tail;
1224 u32 fr_new;
1225 u32 fr_compare;
1177 1226
1178 entry = brcmf_skbcb(p)->mac; 1227 entry = brcmf_skbcb(p)->mac;
1179 if (entry == NULL) { 1228 if (entry == NULL) {
@@ -1185,9 +1234,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws,
1185 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { 1234 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
1186 prec += 1; 1235 prec += 1;
1187 qfull_stat = &fws->stats.supprq_full_error; 1236 qfull_stat = &fws->stats.supprq_full_error;
1188 }
1189 1237
1190 if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { 1238 /* Fix out of order delivery of frames. Dont assume frame */
1239 /* can be inserted at the end, but look for correct position */
1240 pq = &entry->psq;
1241 if (pktq_full(pq) || pktq_pfull(pq, prec)) {
1242 *qfull_stat += 1;
1243 return -ENFILE;
1244 }
1245 queue = &pq->q[prec].skblist;
1246
1247 p_head = skb_peek(queue);
1248 p_tail = skb_peek_tail(queue);
1249 fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN);
1250
1251 while (p_head != p_tail) {
1252 fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
1253 FREERUN);
1254 /* be sure to handle wrap of 256 */
1255 if (((fr_new > fr_compare) &&
1256 ((fr_new - fr_compare) < 128)) ||
1257 ((fr_new < fr_compare) &&
1258 ((fr_compare - fr_new) > 128)))
1259 break;
1260 p_tail = skb_queue_prev(queue, p_tail);
1261 }
1262 /* Position found. Determine what to do */
1263 if (p_tail == NULL) {
1264 /* empty list */
1265 __skb_queue_tail(queue, p);
1266 } else {
1267 fr_compare = brcmf_skb_htod_tag_get_field(p_tail,
1268 FREERUN);
1269 if (((fr_new > fr_compare) &&
1270 ((fr_new - fr_compare) < 128)) ||
1271 ((fr_new < fr_compare) &&
1272 ((fr_compare - fr_new) > 128))) {
1273 /* After tail */
1274 __skb_queue_after(queue, p_tail, p);
1275 } else {
1276 /* Before tail */
1277 __skb_insert(p, p_tail->prev, p_tail, queue);
1278 }
1279 }
1280
1281 /* Complete the counters and statistics */
1282 pq->len++;
1283 if (pq->hi_prec < prec)
1284 pq->hi_prec = (u8) prec;
1285 } else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) {
1191 *qfull_stat += 1; 1286 *qfull_stat += 1;
1192 return -ENFILE; 1287 return -ENFILE;
1193 } 1288 }
@@ -1277,7 +1372,8 @@ done:
1277} 1372}
1278 1373
1279static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, 1374static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1280 struct sk_buff *skb, u32 genbit) 1375 struct sk_buff *skb, u32 genbit,
1376 u16 seq)
1281{ 1377{
1282 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 1378 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1283 u32 hslot; 1379 u32 hslot;
@@ -1298,6 +1394,14 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1298 1394
1299 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1395 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1300 if (ret == 0) 1396 if (ret == 0)
1397 brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
1398 brcmf_skbcb(skb)->htod_seq = seq;
1399 if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
1400 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
1401 brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
1402 } else {
1403 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
1404 }
1301 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, 1405 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
1302 skb); 1406 skb);
1303 if (ret != 0) { 1407 if (ret != 0) {
@@ -1317,7 +1421,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1317 1421
1318static int 1422static int
1319brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, 1423brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1320 u32 genbit) 1424 u32 genbit, u16 seq)
1321{ 1425{
1322 u32 fifo; 1426 u32 fifo;
1323 int ret; 1427 int ret;
@@ -1360,8 +1464,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1360 if (entry->suppressed && entry->suppr_transit_count) 1464 if (entry->suppressed && entry->suppr_transit_count)
1361 entry->suppr_transit_count--; 1465 entry->suppr_transit_count--;
1362 1466
1363 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, 1467 brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
1364 skcb->htod); 1468 skcb->htod, seq);
1365 1469
1366 /* pick up the implicit credit from this packet */ 1470 /* pick up the implicit credit from this packet */
1367 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO); 1471 fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
@@ -1374,7 +1478,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1374 brcmf_fws_macdesc_return_req_credit(skb); 1478 brcmf_fws_macdesc_return_req_credit(skb);
1375 1479
1376 if (!remove_from_hanger) 1480 if (!remove_from_hanger)
1377 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit); 1481 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit,
1482 seq);
1378 1483
1379 if (remove_from_hanger || ret) 1484 if (remove_from_hanger || ret)
1380 brcmf_txfinalize(fws->drvr, skb, true); 1485 brcmf_txfinalize(fws->drvr, skb, true);
@@ -1406,10 +1511,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1406static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1511static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1407{ 1512{
1408 __le32 status_le; 1513 __le32 status_le;
1514 __le16 seq_le;
1409 u32 status; 1515 u32 status;
1410 u32 hslot; 1516 u32 hslot;
1411 u32 genbit; 1517 u32 genbit;
1412 u8 flags; 1518 u8 flags;
1519 u16 seq;
1413 1520
1414 fws->stats.txs_indicate++; 1521 fws->stats.txs_indicate++;
1415 memcpy(&status_le, data, sizeof(status_le)); 1522 memcpy(&status_le, data, sizeof(status_le));
@@ -1417,9 +1524,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1417 flags = brcmf_txstatus_get_field(status, FLAGS); 1524 flags = brcmf_txstatus_get_field(status, FLAGS);
1418 hslot = brcmf_txstatus_get_field(status, HSLOT); 1525 hslot = brcmf_txstatus_get_field(status, HSLOT);
1419 genbit = brcmf_txstatus_get_field(status, GENERATION); 1526 genbit = brcmf_txstatus_get_field(status, GENERATION);
1527 if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
1528 memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
1529 sizeof(seq_le));
1530 seq = le16_to_cpu(seq_le);
1531 } else {
1532 seq = 0;
1533 }
1420 1534
1421 brcmf_fws_lock(fws); 1535 brcmf_fws_lock(fws);
1422 brcmf_fws_txs_process(fws, flags, hslot, genbit); 1536 brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
1423 brcmf_fws_unlock(fws); 1537 brcmf_fws_unlock(fws);
1424 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1538 return BRCMF_FWS_RET_OK_NOSCHEDULE;
1425} 1539}
@@ -1610,8 +1724,8 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1610 struct brcmf_fws_mac_descriptor *entry = skcb->mac; 1724 struct brcmf_fws_mac_descriptor *entry = skcb->mac;
1611 u8 flags; 1725 u8 flags;
1612 1726
1613 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1727 if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED)
1614 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1728 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
1615 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; 1729 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
1616 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { 1730 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
1617 /* 1731 /*
@@ -1652,7 +1766,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1652 fws->stats.rollback_failed++; 1766 fws->stats.rollback_failed++;
1653 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1767 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1654 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, 1768 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
1655 hslot, 0); 1769 hslot, 0, 0);
1656 } else { 1770 } else {
1657 fws->stats.rollback_success++; 1771 fws->stats.rollback_success++;
1658 brcmf_fws_return_credits(fws, fifo, 1); 1772 brcmf_fws_return_credits(fws, fifo, 1);
@@ -1732,6 +1846,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
1732 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1846 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1733 int rc, hslot; 1847 int rc, hslot;
1734 1848
1849 skcb->htod = 0;
1850 skcb->htod_seq = 0;
1735 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); 1851 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1736 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); 1852 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1737 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]); 1853 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
@@ -1908,6 +2024,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
1908 struct brcmf_fws_info *fws; 2024 struct brcmf_fws_info *fws;
1909 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; 2025 u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
1910 int rc; 2026 int rc;
2027 u32 mode;
1911 2028
1912 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); 2029 drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL);
1913 if (!drvr->fws) { 2030 if (!drvr->fws) {
@@ -1966,6 +2083,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
1966 if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) 2083 if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
1967 brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); 2084 brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
1968 2085
2086 /* Enable seq number reuse, if supported */
2087 if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
2088 if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
2089 mode = 0;
2090 BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
2091 if (brcmf_fil_iovar_int_set(drvr->iflist[0],
2092 "wlfc_mode", mode) == 0) {
2093 BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
2094 }
2095 }
2096 }
2097
1969 brcmf_fws_hanger_init(&fws->hanger); 2098 brcmf_fws_hanger_init(&fws->hanger);
1970 brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0); 2099 brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0);
1971 brcmf_fws_macdesc_set_name(fws, &fws->desc.other); 2100 brcmf_fws_macdesc_set_name(fws, &fws->desc.other);
@@ -2022,7 +2151,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb)
2022 } 2151 }
2023 brcmf_fws_lock(fws); 2152 brcmf_fws_lock(fws);
2024 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 2153 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
2025 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0); 2154 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
2026 brcmf_fws_unlock(fws); 2155 brcmf_fws_unlock(fws);
2027} 2156}
2028 2157
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
index 4a2293041821..d31803607259 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,
812 struct ieee80211_channel *chan = request->channels[i]; 812 struct ieee80211_channel *chan = request->channels[i];
813 813
814 if (chan->flags & (IEEE80211_CHAN_RADAR | 814 if (chan->flags & (IEEE80211_CHAN_RADAR |
815 IEEE80211_CHAN_PASSIVE_SCAN)) 815 IEEE80211_CHAN_NO_IR))
816 continue; 816 continue;
817 817
818 chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, 818 chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
new file mode 100644
index 000000000000..87eb2bd4c072
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18 #include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/netdevice.h>
21
22#include <brcmu_wifi.h>
23#include "dhd.h"
24#include "dhd_dbg.h"
25#include "proto.h"
26#include "bcdc.h"
27
28
29int brcmf_proto_attach(struct brcmf_pub *drvr)
30{
31 struct brcmf_proto *proto;
32
33 proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
34 if (!proto)
35 goto fail;
36
37 drvr->proto = proto;
38 /* BCDC protocol is only protocol supported for the moment */
39 if (brcmf_proto_bcdc_attach(drvr))
40 goto fail;
41
42 if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) ||
43 (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) {
44 brcmf_err("Not all proto handlers have been installed\n");
45 goto fail;
46 }
47 return 0;
48
49fail:
50 kfree(proto);
51 drvr->proto = NULL;
52 return -ENOMEM;
53}
54
55void brcmf_proto_detach(struct brcmf_pub *drvr)
56{
57 if (drvr->proto) {
58 brcmf_proto_bcdc_detach(drvr);
59 kfree(drvr->proto);
60 drvr->proto = NULL;
61 }
62}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
new file mode 100644
index 000000000000..8de1b3bce228
--- /dev/null
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) 2013 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16#ifndef BRCMFMAC_PROTO_H
17#define BRCMFMAC_PROTO_H
18
19struct brcmf_proto {
20 void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset,
21 struct sk_buff *skb);
22 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
23 struct sk_buff *skb);
24 int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
25 void *buf, uint len);
26 int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
27 uint len);
28 void *pd;
29};
30
31
32int brcmf_proto_attach(struct brcmf_pub *drvr);
33void brcmf_proto_detach(struct brcmf_pub *drvr);
34
35static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
36 u8 offset, struct sk_buff *skb)
37{
38 drvr->proto->hdrpush(drvr, ifidx, offset, skb);
39}
40static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
41 u8 *ifidx, struct sk_buff *skb)
42{
43 return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
44}
45static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
46 uint cmd, void *buf, uint len)
47{
48 return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
49}
50static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
51 uint cmd, void *buf, uint len)
52{
53 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
54}
55
56
57#endif /* BRCMFMAC_PROTO_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
index 3c67529b9074..4d7d51f95716 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h
@@ -89,7 +89,7 @@ TRACE_EVENT(brcmf_hexdump,
89 TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len) 89 TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len)
90); 90);
91 91
92TRACE_EVENT(brcmf_bdchdr, 92TRACE_EVENT(brcmf_bcdchdr,
93 TP_PROTO(void *data), 93 TP_PROTO(void *data),
94 TP_ARGS(data), 94 TP_ARGS(data),
95 TP_STRUCT__entry( 95 TP_STRUCT__entry(
@@ -107,24 +107,35 @@ TRACE_EVENT(brcmf_bdchdr,
107 memcpy(__get_dynamic_array(signal), 107 memcpy(__get_dynamic_array(signal),
108 (u8 *)data + 4, __entry->siglen); 108 (u8 *)data + 4, __entry->siglen);
109 ), 109 ),
110 TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) 110 TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen)
111); 111);
112 112
113#ifndef SDPCM_RX
114#define SDPCM_RX 0
115#endif
116#ifndef SDPCM_TX
117#define SDPCM_TX 1
118#endif
119#ifndef SDPCM_GLOM
120#define SDPCM_GLOM 2
121#endif
122
113TRACE_EVENT(brcmf_sdpcm_hdr, 123TRACE_EVENT(brcmf_sdpcm_hdr,
114 TP_PROTO(bool tx, void *data), 124 TP_PROTO(u8 dir, void *data),
115 TP_ARGS(tx, data), 125 TP_ARGS(dir, data),
116 TP_STRUCT__entry( 126 TP_STRUCT__entry(
117 __field(u8, tx) 127 __field(u8, dir)
118 __field(u16, len) 128 __field(u16, len)
119 __array(u8, hdr, 12) 129 __dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12)
120 ), 130 ),
121 TP_fast_assign( 131 TP_fast_assign(
122 memcpy(__entry->hdr, data, 12); 132 memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12);
123 __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8); 133 __entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8);
124 __entry->tx = tx ? 1 : 0; 134 __entry->dir = dir;
125 ), 135 ),
126 TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX", 136 TP_printk("sdpcm: %s len %u, seq %d",
127 __entry->len, __entry->hdr[4]) 137 __entry->dir == SDPCM_RX ? "RX" : "TX",
138 __entry->len, ((u8 *)__get_dynamic_array(hdr))[4])
128); 139);
129 140
130#ifdef CONFIG_BRCM_TRACING 141#ifdef CONFIG_BRCM_TRACING
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 422f44c63175..51c4de054b15 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1255 bus->chiprev = bus_pub->chiprev; 1255 bus->chiprev = bus_pub->chiprev;
1256 1256
1257 /* Attach to the common driver interface */ 1257 /* Attach to the common driver interface */
1258 ret = brcmf_attach(0, dev); 1258 ret = brcmf_attach(dev);
1259 if (ret) { 1259 if (ret) {
1260 brcmf_err("brcmf_attach failed\n"); 1260 brcmf_err("brcmf_attach failed\n");
1261 goto fail; 1261 goto fail;
@@ -1454,7 +1454,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
1454 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1454 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
1455 1455
1456 brcmf_dbg(USB, "Enter\n"); 1456 brcmf_dbg(USB, "Enter\n");
1457 if (!brcmf_attach(0, devinfo->dev)) 1457 if (!brcmf_attach(devinfo->dev))
1458 return brcmf_bus_start(&usb->dev); 1458 return brcmf_bus_start(&usb->dev);
1459 1459
1460 return 0; 1460 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 571f013cebbb..3966fe0fcfd9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -202,9 +202,9 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = {
202 202
203/* This is to override regulatory domains defined in cfg80211 module (reg.c) 203/* This is to override regulatory domains defined in cfg80211 module (reg.c)
204 * By default world regulatory domain defined in reg.c puts the flags 204 * By default world regulatory domain defined in reg.c puts the flags
205 * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for 205 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206 * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't 206 * With respect to these flags, wpa_supplicant doesn't * start p2p
207 * start p2p operations on 5GHz channels. All the changes in world regulatory 207 * operations on 5GHz channels. All the changes in world regulatory
208 * domain are to be done here. 208 * domain are to be done here.
209 */ 209 */
210static const struct ieee80211_regdomain brcmf_regdom = { 210static const struct ieee80211_regdomain brcmf_regdom = {
@@ -2556,8 +2556,8 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2556 ch_bss.band == ch_bss_info_le.band && 2556 ch_bss.band == ch_bss_info_le.band &&
2557 bss_info_le->SSID_len == bss->SSID_len && 2557 bss_info_le->SSID_len == bss->SSID_len &&
2558 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { 2558 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2559 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == 2559 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2560 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) { 2560 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2561 s16 bss_rssi = le16_to_cpu(bss->RSSI); 2561 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2562 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI); 2562 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2563 2563
@@ -2566,13 +2566,13 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2566 */ 2566 */
2567 if (bss_info_rssi > bss_rssi) 2567 if (bss_info_rssi > bss_rssi)
2568 bss->RSSI = bss_info_le->RSSI; 2568 bss->RSSI = bss_info_le->RSSI;
2569 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) && 2569 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2570 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) { 2570 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2571 /* preserve the on-channel rssi measurement 2571 /* preserve the on-channel rssi measurement
2572 * if the new measurement is off channel 2572 * if the new measurement is off channel
2573 */ 2573 */
2574 bss->RSSI = bss_info_le->RSSI; 2574 bss->RSSI = bss_info_le->RSSI;
2575 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL; 2575 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2576 } 2576 }
2577 return 1; 2577 return 1;
2578 } 2578 }
@@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3973 3973
3974static int 3974static int
3975brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3975brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3976 struct ieee80211_channel *chan, bool offchan, 3976 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3977 unsigned int wait, const u8 *buf, size_t len,
3978 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3979{ 3977{
3980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 3978 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3979 struct ieee80211_channel *chan = params->chan;
3980 const u8 *buf = params->buf;
3981 size_t len = params->len;
3981 const struct ieee80211_mgmt *mgmt; 3982 const struct ieee80211_mgmt *mgmt;
3982 struct brcmf_cfg80211_vif *vif; 3983 struct brcmf_cfg80211_vif *vif;
3983 s32 err = 0; 3984 s32 err = 0;
@@ -4341,7 +4342,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4341 wiphy->max_remain_on_channel_duration = 5000; 4342 wiphy->max_remain_on_channel_duration = 5000;
4342 brcmf_wiphy_pno_params(wiphy); 4343 brcmf_wiphy_pno_params(wiphy);
4343 brcmf_dbg(INFO, "Registering custom regulatory\n"); 4344 brcmf_dbg(INFO, "Registering custom regulatory\n");
4344 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 4345 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4345 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); 4346 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4346 err = wiphy_register(wiphy); 4347 err = wiphy_register(wiphy);
4347 if (err < 0) { 4348 if (err < 0) {
@@ -5197,10 +5198,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5197 if (channel & WL_CHAN_RADAR) 5198 if (channel & WL_CHAN_RADAR)
5198 band_chan_arr[index].flags |= 5199 band_chan_arr[index].flags |=
5199 (IEEE80211_CHAN_RADAR | 5200 (IEEE80211_CHAN_RADAR |
5200 IEEE80211_CHAN_NO_IBSS); 5201 IEEE80211_CHAN_NO_IR);
5201 if (channel & WL_CHAN_PASSIVE) 5202 if (channel & WL_CHAN_PASSIVE)
5202 band_chan_arr[index].flags |= 5203 band_chan_arr[index].flags |=
5203 IEEE80211_CHAN_PASSIVE_SCAN; 5204 IEEE80211_CHAN_NO_IR;
5204 } 5205 }
5205 } 5206 }
5206 if (!update) 5207 if (!update)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
index cc87926f5055..635ae034c7e5 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c
@@ -59,23 +59,18 @@
59 59
60#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) 60#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
61#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ 61#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
62 NL80211_RRF_PASSIVE_SCAN | \ 62 NL80211_RRF_NO_IR)
63 NL80211_RRF_NO_IBSS)
64 63
65#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ 64#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
66 NL80211_RRF_PASSIVE_SCAN | \ 65 NL80211_RRF_NO_IR)
67 NL80211_RRF_NO_IBSS)
68#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ 66#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
69 NL80211_RRF_PASSIVE_SCAN | \
70 NL80211_RRF_DFS | \ 67 NL80211_RRF_DFS | \
71 NL80211_RRF_NO_IBSS) 68 NL80211_RRF_NO_IR)
72#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ 69#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
73 NL80211_RRF_PASSIVE_SCAN | \
74 NL80211_RRF_DFS | \ 70 NL80211_RRF_DFS | \
75 NL80211_RRF_NO_IBSS) 71 NL80211_RRF_NO_IR)
76#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ 72#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
77 NL80211_RRF_PASSIVE_SCAN | \ 73 NL80211_RRF_NO_IR)
78 NL80211_RRF_NO_IBSS)
79 74
80static const struct ieee80211_regdomain brcms_regdom_x2 = { 75static const struct ieee80211_regdomain brcms_regdom_x2 = {
81 .n_reg_rules = 6, 76 .n_reg_rules = 6,
@@ -395,7 +390,7 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec,
395 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); 390 brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false);
396 391
397 brcms_b_set_chanspec(wlc->hw, chanspec, 392 brcms_b_set_chanspec(wlc->hw, chanspec,
398 !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), 393 !!(ch->flags & IEEE80211_CHAN_NO_IR),
399 &txpwr); 394 &txpwr);
400} 395}
401 396
@@ -657,8 +652,8 @@ static void brcms_reg_apply_radar_flags(struct wiphy *wiphy)
657 */ 652 */
658 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 653 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
659 ch->flags |= IEEE80211_CHAN_RADAR | 654 ch->flags |= IEEE80211_CHAN_RADAR |
660 IEEE80211_CHAN_NO_IBSS | 655 IEEE80211_CHAN_NO_IR |
661 IEEE80211_CHAN_PASSIVE_SCAN; 656 IEEE80211_CHAN_NO_IR;
662 } 657 }
663} 658}
664 659
@@ -684,18 +679,15 @@ brcms_reg_apply_beaconing_flags(struct wiphy *wiphy,
684 continue; 679 continue;
685 680
686 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 681 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
687 rule = freq_reg_info(wiphy, ch->center_freq); 682 rule = freq_reg_info(wiphy,
683 MHZ_TO_KHZ(ch->center_freq));
688 if (IS_ERR(rule)) 684 if (IS_ERR(rule))
689 continue; 685 continue;
690 686
691 if (!(rule->flags & NL80211_RRF_NO_IBSS)) 687 if (!(rule->flags & NL80211_RRF_NO_IR))
692 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 688 ch->flags &= ~IEEE80211_CHAN_NO_IR;
693 if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN))
694 ch->flags &=
695 ~IEEE80211_CHAN_PASSIVE_SCAN;
696 } else if (ch->beacon_found) { 689 } else if (ch->beacon_found) {
697 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 690 ch->flags &= ~IEEE80211_CHAN_NO_IR;
698 IEEE80211_CHAN_PASSIVE_SCAN);
699 } 691 }
700 } 692 }
701 } 693 }
@@ -775,8 +767,8 @@ void brcms_c_regd_init(struct brcms_c_info *wlc)
775 } 767 }
776 768
777 wlc->wiphy->reg_notifier = brcms_reg_notifier; 769 wlc->wiphy->reg_notifier = brcms_reg_notifier;
778 wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 770 wlc->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
779 WIPHY_FLAG_STRICT_REGULATORY; 771 REGULATORY_STRICT_REG;
780 wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); 772 wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain);
781 brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); 773 brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER);
782} 774}
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index edc5d105ff98..e71ce8c842a2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -125,13 +125,13 @@ static struct ieee80211_channel brcms_2ghz_chantable[] = {
125 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), 125 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
126 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), 126 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
127 CHAN2GHZ(12, 2467, 127 CHAN2GHZ(12, 2467,
128 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 128 IEEE80211_CHAN_NO_IR |
129 IEEE80211_CHAN_NO_HT40PLUS), 129 IEEE80211_CHAN_NO_HT40PLUS),
130 CHAN2GHZ(13, 2472, 130 CHAN2GHZ(13, 2472,
131 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 131 IEEE80211_CHAN_NO_IR |
132 IEEE80211_CHAN_NO_HT40PLUS), 132 IEEE80211_CHAN_NO_HT40PLUS),
133 CHAN2GHZ(14, 2484, 133 CHAN2GHZ(14, 2484,
134 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | 134 IEEE80211_CHAN_NO_IR |
135 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | 135 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS |
136 IEEE80211_CHAN_NO_OFDM) 136 IEEE80211_CHAN_NO_OFDM)
137}; 137};
@@ -144,51 +144,51 @@ static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
144 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), 144 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
145 /* UNII-2 */ 145 /* UNII-2 */
146 CHAN5GHZ(52, 146 CHAN5GHZ(52,
147 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 147 IEEE80211_CHAN_RADAR |
148 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 148 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
149 CHAN5GHZ(56, 149 CHAN5GHZ(56,
150 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 150 IEEE80211_CHAN_RADAR |
151 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 151 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
152 CHAN5GHZ(60, 152 CHAN5GHZ(60,
153 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 153 IEEE80211_CHAN_RADAR |
154 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 154 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
155 CHAN5GHZ(64, 155 CHAN5GHZ(64,
156 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 156 IEEE80211_CHAN_RADAR |
157 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 157 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
158 /* MID */ 158 /* MID */
159 CHAN5GHZ(100, 159 CHAN5GHZ(100,
160 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 160 IEEE80211_CHAN_RADAR |
161 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 161 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
162 CHAN5GHZ(104, 162 CHAN5GHZ(104,
163 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 163 IEEE80211_CHAN_RADAR |
164 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 164 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
165 CHAN5GHZ(108, 165 CHAN5GHZ(108,
166 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 166 IEEE80211_CHAN_RADAR |
167 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 167 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
168 CHAN5GHZ(112, 168 CHAN5GHZ(112,
169 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 169 IEEE80211_CHAN_RADAR |
170 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 170 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
171 CHAN5GHZ(116, 171 CHAN5GHZ(116,
172 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 172 IEEE80211_CHAN_RADAR |
173 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 173 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
174 CHAN5GHZ(120, 174 CHAN5GHZ(120,
175 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 175 IEEE80211_CHAN_RADAR |
176 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 176 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
177 CHAN5GHZ(124, 177 CHAN5GHZ(124,
178 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 178 IEEE80211_CHAN_RADAR |
179 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 179 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
180 CHAN5GHZ(128, 180 CHAN5GHZ(128,
181 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 181 IEEE80211_CHAN_RADAR |
182 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 182 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
183 CHAN5GHZ(132, 183 CHAN5GHZ(132,
184 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 184 IEEE80211_CHAN_RADAR |
185 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), 185 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS),
186 CHAN5GHZ(136, 186 CHAN5GHZ(136,
187 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 187 IEEE80211_CHAN_RADAR |
188 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), 188 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS),
189 CHAN5GHZ(140, 189 CHAN5GHZ(140,
190 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | 190 IEEE80211_CHAN_RADAR |
191 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | 191 IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS |
192 IEEE80211_CHAN_NO_HT40MINUS), 192 IEEE80211_CHAN_NO_HT40MINUS),
193 /* UNII-3 */ 193 /* UNII-3 */
194 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), 194 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index ebdcdf44f155..d3acc85932a5 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -108,9 +108,9 @@ static irqreturn_t cw1200_gpio_irq(int irq, void *dev_id)
108 struct hwbus_priv *self = dev_id; 108 struct hwbus_priv *self = dev_id;
109 109
110 if (self->core) { 110 if (self->core) {
111 sdio_claim_host(self->func); 111 cw1200_sdio_lock(self);
112 cw1200_irq_handler(self->core); 112 cw1200_irq_handler(self->core);
113 sdio_release_host(self->func); 113 cw1200_sdio_unlock(self);
114 return IRQ_HANDLED; 114 return IRQ_HANDLED;
115 } else { 115 } else {
116 return IRQ_NONE; 116 return IRQ_NONE;
diff --git a/drivers/net/wireless/cw1200/scan.c b/drivers/net/wireless/cw1200/scan.c
index ee3c19037aac..9afcd4ce3368 100644
--- a/drivers/net/wireless/cw1200/scan.c
+++ b/drivers/net/wireless/cw1200/scan.c
@@ -173,8 +173,9 @@ void cw1200_scan_work(struct work_struct *work)
173 cw1200_set_pm(priv, &priv->powersave_mode); 173 cw1200_set_pm(priv, &priv->powersave_mode);
174 174
175 if (priv->scan.status < 0) 175 if (priv->scan.status < 0)
176 wiphy_dbg(priv->hw->wiphy, "[SCAN] Scan failed (%d).\n", 176 wiphy_warn(priv->hw->wiphy,
177 priv->scan.status); 177 "[SCAN] Scan failed (%d).\n",
178 priv->scan.status);
178 else if (priv->scan.req) 179 else if (priv->scan.req)
179 wiphy_dbg(priv->hw->wiphy, 180 wiphy_dbg(priv->hw->wiphy,
180 "[SCAN] Scan completed.\n"); 181 "[SCAN] Scan completed.\n");
@@ -197,9 +198,9 @@ void cw1200_scan_work(struct work_struct *work)
197 if ((*it)->band != first->band) 198 if ((*it)->band != first->band)
198 break; 199 break;
199 if (((*it)->flags ^ first->flags) & 200 if (((*it)->flags ^ first->flags) &
200 IEEE80211_CHAN_PASSIVE_SCAN) 201 IEEE80211_CHAN_NO_IR)
201 break; 202 break;
202 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 203 if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
203 (*it)->max_power != first->max_power) 204 (*it)->max_power != first->max_power)
204 break; 205 break;
205 } 206 }
@@ -210,7 +211,7 @@ void cw1200_scan_work(struct work_struct *work)
210 else 211 else
211 scan.max_tx_rate = WSM_TRANSMIT_RATE_1; 212 scan.max_tx_rate = WSM_TRANSMIT_RATE_1;
212 scan.num_probes = 213 scan.num_probes =
213 (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2; 214 (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2;
214 scan.num_ssids = priv->scan.n_ssids; 215 scan.num_ssids = priv->scan.n_ssids;
215 scan.ssids = &priv->scan.ssids[0]; 216 scan.ssids = &priv->scan.ssids[0];
216 scan.num_channels = it - priv->scan.curr; 217 scan.num_channels = it - priv->scan.curr;
@@ -233,7 +234,7 @@ void cw1200_scan_work(struct work_struct *work)
233 } 234 }
234 for (i = 0; i < scan.num_channels; ++i) { 235 for (i = 0; i < scan.num_channels; ++i) {
235 scan.ch[i].number = priv->scan.curr[i]->hw_value; 236 scan.ch[i].number = priv->scan.curr[i]->hw_value;
236 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 237 if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) {
237 scan.ch[i].min_chan_time = 50; 238 scan.ch[i].min_chan_time = 50;
238 scan.ch[i].max_chan_time = 100; 239 scan.ch[i].max_chan_time = 100;
239 } else { 240 } else {
@@ -241,7 +242,7 @@ void cw1200_scan_work(struct work_struct *work)
241 scan.ch[i].max_chan_time = 25; 242 scan.ch[i].max_chan_time = 25;
242 } 243 }
243 } 244 }
244 if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 245 if (!(first->flags & IEEE80211_CHAN_NO_IR) &&
245 priv->scan.output_power != first->max_power) { 246 priv->scan.output_power != first->max_power) {
246 priv->scan.output_power = first->max_power; 247 priv->scan.output_power = first->max_power;
247 wsm_set_output_power(priv, 248 wsm_set_output_power(priv,
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index f8ab193009cd..3aba49259ef1 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1930,10 +1930,10 @@ static int ipw2100_wdev_init(struct net_device *dev)
1930 bg_band->channels[i].max_power = geo->bg[i].max_power; 1930 bg_band->channels[i].max_power = geo->bg[i].max_power;
1931 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 1931 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
1932 bg_band->channels[i].flags |= 1932 bg_band->channels[i].flags |=
1933 IEEE80211_CHAN_PASSIVE_SCAN; 1933 IEEE80211_CHAN_NO_IR;
1934 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 1934 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
1935 bg_band->channels[i].flags |= 1935 bg_band->channels[i].flags |=
1936 IEEE80211_CHAN_NO_IBSS; 1936 IEEE80211_CHAN_NO_IR;
1937 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 1937 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
1938 bg_band->channels[i].flags |= 1938 bg_band->channels[i].flags |=
1939 IEEE80211_CHAN_RADAR; 1939 IEEE80211_CHAN_RADAR;
@@ -6362,7 +6362,6 @@ out:
6362 &ipw2100_attribute_group); 6362 &ipw2100_attribute_group);
6363 6363
6364 free_libipw(dev, 0); 6364 free_libipw(dev, 0);
6365 pci_set_drvdata(pci_dev, NULL);
6366 } 6365 }
6367 6366
6368 pci_iounmap(pci_dev, ioaddr); 6367 pci_iounmap(pci_dev, ioaddr);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 81903e33d5b1..9244b3661d34 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11472,10 +11472,10 @@ static int ipw_wdev_init(struct net_device *dev)
11472 bg_band->channels[i].max_power = geo->bg[i].max_power; 11472 bg_band->channels[i].max_power = geo->bg[i].max_power;
11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11473 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11474 bg_band->channels[i].flags |= 11474 bg_band->channels[i].flags |=
11475 IEEE80211_CHAN_PASSIVE_SCAN; 11475 IEEE80211_CHAN_NO_IR;
11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) 11476 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
11477 bg_band->channels[i].flags |= 11477 bg_band->channels[i].flags |=
11478 IEEE80211_CHAN_NO_IBSS; 11478 IEEE80211_CHAN_NO_IR;
11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) 11479 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
11480 bg_band->channels[i].flags |= 11480 bg_band->channels[i].flags |=
11481 IEEE80211_CHAN_RADAR; 11481 IEEE80211_CHAN_RADAR;
@@ -11511,10 +11511,10 @@ static int ipw_wdev_init(struct net_device *dev)
11511 a_band->channels[i].max_power = geo->a[i].max_power; 11511 a_band->channels[i].max_power = geo->a[i].max_power;
11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) 11512 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
11513 a_band->channels[i].flags |= 11513 a_band->channels[i].flags |=
11514 IEEE80211_CHAN_PASSIVE_SCAN; 11514 IEEE80211_CHAN_NO_IR;
11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) 11515 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
11516 a_band->channels[i].flags |= 11516 a_band->channels[i].flags |=
11517 IEEE80211_CHAN_NO_IBSS; 11517 IEEE80211_CHAN_NO_IR;
11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) 11518 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
11519 a_band->channels[i].flags |= 11519 a_band->channels[i].flags |=
11520 IEEE80211_CHAN_RADAR; 11520 IEEE80211_CHAN_RADAR;
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index dea3b50d68b9..0487461ae4da 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -1595,7 +1595,7 @@ il3945_get_channels_for_scan(struct il_priv *il, enum ieee80211_band band,
1595 * and use long active_dwell time. 1595 * and use long active_dwell time.
1596 */ 1596 */
1597 if (!is_active || il_is_channel_passive(ch_info) || 1597 if (!is_active || il_is_channel_passive(ch_info) ||
1598 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { 1598 (chan->flags & IEEE80211_CHAN_NO_IR)) {
1599 scan_ch->type = 0; /* passive */ 1599 scan_ch->type = 0; /* passive */
1600 if (IL_UCODE_API(il->ucode_ver) == 1) 1600 if (IL_UCODE_API(il->ucode_ver) == 1)
1601 scan_ch->active_dwell = 1601 scan_ch->active_dwell =
@@ -2396,8 +2396,7 @@ __il3945_up(struct il_priv *il)
2396 clear_bit(S_RFKILL, &il->status); 2396 clear_bit(S_RFKILL, &il->status);
2397 else { 2397 else {
2398 set_bit(S_RFKILL, &il->status); 2398 set_bit(S_RFKILL, &il->status);
2399 IL_WARN("Radio disabled by HW RF Kill switch\n"); 2399 return -ERFKILL;
2400 return -ENODEV;
2401 } 2400 }
2402 2401
2403 _il_wr(il, CSR_INT, 0xFFFFFFFF); 2402 _il_wr(il, CSR_INT, 0xFFFFFFFF);
@@ -3575,9 +3574,9 @@ il3945_setup_mac(struct il_priv *il)
3575 hw->wiphy->interface_modes = 3574 hw->wiphy->interface_modes =
3576 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 3575 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
3577 3576
3578 hw->wiphy->flags |= 3577 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
3579 WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 3578 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
3580 WIPHY_FLAG_IBSS_RSN; 3579 REGULATORY_DISABLE_BEACON_HINTS;
3581 3580
3582 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; 3581 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3583 3582
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 3982ab76f375..43f488a8cda2 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -805,7 +805,7 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
805 } 805 }
806 806
807 if (!is_active || il_is_channel_passive(ch_info) || 807 if (!is_active || il_is_channel_passive(ch_info) ||
808 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 808 (chan->flags & IEEE80211_CHAN_NO_IR))
809 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 809 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
810 else 810 else
811 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 811 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -5778,9 +5778,9 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
5778 hw->wiphy->interface_modes = 5778 hw->wiphy->interface_modes =
5779 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 5779 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
5780 5780
5781 hw->wiphy->flags |= 5781 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
5782 WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | 5782 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
5783 WIPHY_FLAG_IBSS_RSN; 5783 REGULATORY_DISABLE_BEACON_HINTS;
5784 5784
5785 /* 5785 /*
5786 * For now, disable PS by default because it affects 5786 * For now, disable PS by default because it affects
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index b03e22ef5462..a27b14cfeaec 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -3445,10 +3445,10 @@ il_init_geos(struct il_priv *il)
3445 3445
3446 if (il_is_channel_valid(ch)) { 3446 if (il_is_channel_valid(ch)) {
3447 if (!(ch->flags & EEPROM_CHANNEL_IBSS)) 3447 if (!(ch->flags & EEPROM_CHANNEL_IBSS))
3448 geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; 3448 geo_ch->flags |= IEEE80211_CHAN_NO_IR;
3449 3449
3450 if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) 3450 if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
3451 geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 3451 geo_ch->flags |= IEEE80211_CHAN_NO_IR;
3452 3452
3453 if (ch->flags & EEPROM_CHANNEL_RADAR) 3453 if (ch->flags & EEPROM_CHANNEL_RADAR)
3454 geo_ch->flags |= IEEE80211_CHAN_RADAR; 3454 geo_ch->flags |= IEEE80211_CHAN_RADAR;
diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c
index eff26501d60a..3a487a3bb5de 100644
--- a/drivers/net/wireless/iwlegacy/debug.c
+++ b/drivers/net/wireless/iwlegacy/debug.c
@@ -567,12 +567,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
567 flags & IEEE80211_CHAN_RADAR ? 567 flags & IEEE80211_CHAN_RADAR ?
568 " (IEEE 802.11h required)" : "", 568 " (IEEE 802.11h required)" : "",
569 ((channels[i]. 569 ((channels[i].
570 flags & IEEE80211_CHAN_NO_IBSS) || 570 flags & IEEE80211_CHAN_NO_IR) ||
571 (channels[i]. 571 (channels[i].
572 flags & IEEE80211_CHAN_RADAR)) ? "" : 572 flags & IEEE80211_CHAN_RADAR)) ? "" :
573 ", IBSS", 573 ", IBSS",
574 channels[i]. 574 channels[i].
575 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 575 flags & IEEE80211_CHAN_NO_IR ?
576 "passive only" : "active/passive"); 576 "passive only" : "active/passive");
577 } 577 }
578 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ); 578 supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
@@ -594,12 +594,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
594 flags & IEEE80211_CHAN_RADAR ? 594 flags & IEEE80211_CHAN_RADAR ?
595 " (IEEE 802.11h required)" : "", 595 " (IEEE 802.11h required)" : "",
596 ((channels[i]. 596 ((channels[i].
597 flags & IEEE80211_CHAN_NO_IBSS) || 597 flags & IEEE80211_CHAN_NO_IR) ||
598 (channels[i]. 598 (channels[i].
599 flags & IEEE80211_CHAN_RADAR)) ? "" : 599 flags & IEEE80211_CHAN_RADAR)) ? "" :
600 ", IBSS", 600 ", IBSS",
601 channels[i]. 601 channels[i].
602 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 602 flags & IEEE80211_CHAN_NO_IR ?
603 "passive only" : "active/passive"); 603 "passive only" : "active/passive");
604 } 604 }
605 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 605 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
index d94f8ab15004..f69301e505ee 100644
--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c
@@ -352,12 +352,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
352 channels[i].max_power, 352 channels[i].max_power,
353 channels[i].flags & IEEE80211_CHAN_RADAR ? 353 channels[i].flags & IEEE80211_CHAN_RADAR ?
354 " (IEEE 802.11h required)" : "", 354 " (IEEE 802.11h required)" : "",
355 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 355 ((channels[i].flags & IEEE80211_CHAN_NO_IR)
356 || (channels[i].flags & 356 || (channels[i].flags &
357 IEEE80211_CHAN_RADAR)) ? "" : 357 IEEE80211_CHAN_RADAR)) ? "" :
358 ", IBSS", 358 ", IBSS",
359 channels[i].flags & 359 channels[i].flags &
360 IEEE80211_CHAN_PASSIVE_SCAN ? 360 IEEE80211_CHAN_NO_IR ?
361 "passive only" : "active/passive"); 361 "passive only" : "active/passive");
362 } 362 }
363 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 363 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
@@ -375,12 +375,12 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
375 channels[i].max_power, 375 channels[i].max_power,
376 channels[i].flags & IEEE80211_CHAN_RADAR ? 376 channels[i].flags & IEEE80211_CHAN_RADAR ?
377 " (IEEE 802.11h required)" : "", 377 " (IEEE 802.11h required)" : "",
378 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 378 ((channels[i].flags & IEEE80211_CHAN_NO_IR)
379 || (channels[i].flags & 379 || (channels[i].flags &
380 IEEE80211_CHAN_RADAR)) ? "" : 380 IEEE80211_CHAN_RADAR)) ? "" :
381 ", IBSS", 381 ", IBSS",
382 channels[i].flags & 382 channels[i].flags &
383 IEEE80211_CHAN_PASSIVE_SCAN ? 383 IEEE80211_CHAN_NO_IR ?
384 "passive only" : "active/passive"); 384 "passive only" : "active/passive");
385 } 385 }
386 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 386 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index cae4d3182e33..217f1ca321a0 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -155,9 +155,9 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
155 ARRAY_SIZE(iwlagn_iface_combinations_dualmode); 155 ARRAY_SIZE(iwlagn_iface_combinations_dualmode);
156 } 156 }
157 157
158 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 158 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
159 WIPHY_FLAG_DISABLE_BEACON_HINTS | 159 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
160 WIPHY_FLAG_IBSS_RSN; 160 REGULATORY_DISABLE_BEACON_HINTS;
161 161
162#ifdef CONFIG_PM_SLEEP 162#ifdef CONFIG_PM_SLEEP
163 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && 163 if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
diff --git a/drivers/net/wireless/iwlwifi/dvm/scan.c b/drivers/net/wireless/iwlwifi/dvm/scan.c
index 35e0ee8b4e5b..928f8640a0a7 100644
--- a/drivers/net/wireless/iwlwifi/dvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/dvm/scan.c
@@ -544,7 +544,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
544 channel = chan->hw_value; 544 channel = chan->hw_value;
545 scan_ch->channel = cpu_to_le16(channel); 545 scan_ch->channel = cpu_to_le16(channel);
546 546
547 if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) 547 if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR))
548 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; 548 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
549 else 549 else
550 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; 550 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 4c887f365908..f4a6d317a023 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -614,10 +614,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
614 channel->flags = IEEE80211_CHAN_NO_HT40; 614 channel->flags = IEEE80211_CHAN_NO_HT40;
615 615
616 if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) 616 if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS))
617 channel->flags |= IEEE80211_CHAN_NO_IBSS; 617 channel->flags |= IEEE80211_CHAN_NO_IR;
618 618
619 if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) 619 if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE))
620 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 620 channel->flags |= IEEE80211_CHAN_NO_IR;
621 621
622 if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) 622 if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR)
623 channel->flags |= IEEE80211_CHAN_RADAR; 623 channel->flags |= IEEE80211_CHAN_RADAR;
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index b76a9a8fc0b3..2fab203d3027 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -223,10 +223,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
223 channel->flags |= IEEE80211_CHAN_NO_160MHZ; 223 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
224 224
225 if (!(ch_flags & NVM_CHANNEL_IBSS)) 225 if (!(ch_flags & NVM_CHANNEL_IBSS))
226 channel->flags |= IEEE80211_CHAN_NO_IBSS; 226 channel->flags |= IEEE80211_CHAN_NO_IR;
227 227
228 if (!(ch_flags & NVM_CHANNEL_ACTIVE)) 228 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
229 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; 229 channel->flags |= IEEE80211_CHAN_NO_IR;
230 230
231 if (ch_flags & NVM_CHANNEL_RADAR) 231 if (ch_flags & NVM_CHANNEL_RADAR)
232 channel->flags |= IEEE80211_CHAN_RADAR; 232 channel->flags |= IEEE80211_CHAN_RADAR;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 74bc2c8af06d..b56c989ad784 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -199,9 +199,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) 199 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 200 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
201 201
202 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 202 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
203 WIPHY_FLAG_DISABLE_BEACON_HINTS | 203 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
204 WIPHY_FLAG_IBSS_RSN; 204 REGULATORY_DISABLE_BEACON_HINTS;
205 205
206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 206 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
207 hw->wiphy->n_iface_combinations = 207 hw->wiphy->n_iface_combinations =
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index dff7592e1ff8..e0cd100b40cd 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -192,7 +192,7 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd,
192 for (i = 0; i < cmd->channel_count; i++) { 192 for (i = 0; i < cmd->channel_count; i++) {
193 chan->channel = cpu_to_le16(req->channels[i]->hw_value); 193 chan->channel = cpu_to_le16(req->channels[i]->hw_value);
194 chan->type = cpu_to_le32(type); 194 chan->type = cpu_to_le32(type);
195 if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) 195 if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR)
196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); 196 chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE);
197 chan->active_dwell = cpu_to_le16(active_dwell); 197 chan->active_dwell = cpu_to_le16(active_dwell);
198 chan->passive_dwell = cpu_to_le16(passive_dwell); 198 chan->passive_dwell = cpu_to_le16(passive_dwell);
@@ -642,7 +642,7 @@ static void iwl_build_channel_cfg(struct iwl_mvm *mvm,
642 channels->iter_count[index] = cpu_to_le16(1); 642 channels->iter_count[index] = cpu_to_le16(1);
643 channels->iter_interval[index] = 0; 643 channels->iter_interval[index] = 0;
644 644
645 if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) 645 if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR))
646 channels->type[index] |= 646 channels->type[index] |=
647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); 647 cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE);
648 648
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 991238afd1b6..58c6ee5de98f 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -849,7 +849,7 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card)
849 card->started = true; 849 card->started = true;
850 /* Tell PM core that we don't need the card to be 850 /* Tell PM core that we don't need the card to be
851 * powered now */ 851 * powered now */
852 pm_runtime_put_noidle(&func->dev); 852 pm_runtime_put(&func->dev);
853 } 853 }
854 } 854 }
855 855
@@ -907,8 +907,8 @@ static int if_sdio_power_on(struct if_sdio_card *card)
907 sdio_release_host(func); 907 sdio_release_host(func);
908 ret = if_sdio_prog_firmware(card); 908 ret = if_sdio_prog_firmware(card);
909 if (ret) { 909 if (ret) {
910 sdio_disable_func(func); 910 sdio_claim_host(func);
911 return ret; 911 goto disable;
912 } 912 }
913 913
914 return 0; 914 return 0;
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 83669151bb82..f11728a866ff 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -93,7 +93,6 @@ static void free_if_spi_card(struct if_spi_card *card)
93 list_del(&packet->list); 93 list_del(&packet->list);
94 kfree(packet); 94 kfree(packet);
95 } 95 }
96 spi_set_drvdata(card->spi, NULL);
97 kfree(card); 96 kfree(card);
98} 97}
99 98
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index c72438bb2faf..9c0cc8ded021 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -159,7 +159,7 @@ static const struct ieee80211_regdomain hwsim_world_regdom_custom_02 = {
159 .reg_rules = { 159 .reg_rules = {
160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0), 160 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0),
161 REG_RULE(5725-10, 5850+10, 40, 0, 30, 161 REG_RULE(5725-10, 5850+10, 40, 0, 30,
162 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 162 NL80211_RRF_NO_IR),
163 } 163 }
164}; 164};
165 165
@@ -353,7 +353,6 @@ struct mac80211_hwsim_data {
353 } ps; 353 } ps;
354 bool ps_poll_pending; 354 bool ps_poll_pending;
355 struct dentry *debugfs; 355 struct dentry *debugfs;
356 struct dentry *debugfs_ps;
357 356
358 struct sk_buff_head pending; /* packets pending */ 357 struct sk_buff_head pending; /* packets pending */
359 /* 358 /*
@@ -362,7 +361,6 @@ struct mac80211_hwsim_data {
362 * radio can be in more then one group. 361 * radio can be in more then one group.
363 */ 362 */
364 u64 group; 363 u64 group;
365 struct dentry *debugfs_group;
366 364
367 int power_level; 365 int power_level;
368 366
@@ -1493,7 +1491,7 @@ static void hw_scan_work(struct work_struct *work)
1493 req->channels[hwsim->scan_chan_idx]->center_freq); 1491 req->channels[hwsim->scan_chan_idx]->center_freq);
1494 1492
1495 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; 1493 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
1496 if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || 1494 if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR ||
1497 !req->n_ssids) { 1495 !req->n_ssids) {
1498 dwell = 120; 1496 dwell = 120;
1499 } else { 1497 } else {
@@ -1742,9 +1740,7 @@ static void mac80211_hwsim_free(void)
1742 spin_unlock_bh(&hwsim_radio_lock); 1740 spin_unlock_bh(&hwsim_radio_lock);
1743 1741
1744 list_for_each_entry_safe(data, tmpdata, &tmplist, list) { 1742 list_for_each_entry_safe(data, tmpdata, &tmplist, list) {
1745 debugfs_remove(data->debugfs_group); 1743 debugfs_remove_recursive(data->debugfs);
1746 debugfs_remove(data->debugfs_ps);
1747 debugfs_remove(data->debugfs);
1748 ieee80211_unregister_hw(data->hw); 1744 ieee80211_unregister_hw(data->hw);
1749 device_release_driver(data->dev); 1745 device_release_driver(data->dev);
1750 device_unregister(data->dev); 1746 device_unregister(data->dev);
@@ -1901,6 +1897,17 @@ static int hwsim_fops_ps_write(void *dat, u64 val)
1901DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write, 1897DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
1902 "%llu\n"); 1898 "%llu\n");
1903 1899
1900static int hwsim_write_simulate_radar(void *dat, u64 val)
1901{
1902 struct mac80211_hwsim_data *data = dat;
1903
1904 ieee80211_radar_detected(data->hw);
1905
1906 return 0;
1907}
1908
1909DEFINE_SIMPLE_ATTRIBUTE(hwsim_simulate_radar, NULL,
1910 hwsim_write_simulate_radar, "%llu\n");
1904 1911
1905static int hwsim_fops_group_read(void *dat, u64 *val) 1912static int hwsim_fops_group_read(void *dat, u64 *val)
1906{ 1913{
@@ -2201,11 +2208,28 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = {
2201 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, 2208 { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
2202}; 2209};
2203 2210
2204static struct ieee80211_iface_combination hwsim_if_comb = { 2211static const struct ieee80211_iface_limit hwsim_if_dfs_limits[] = {
2205 .limits = hwsim_if_limits, 2212 { .max = 8, .types = BIT(NL80211_IFTYPE_AP) },
2206 .n_limits = ARRAY_SIZE(hwsim_if_limits), 2213};
2207 .max_interfaces = 2048, 2214
2208 .num_different_channels = 1, 2215static struct ieee80211_iface_combination hwsim_if_comb[] = {
2216 {
2217 .limits = hwsim_if_limits,
2218 .n_limits = ARRAY_SIZE(hwsim_if_limits),
2219 .max_interfaces = 2048,
2220 .num_different_channels = 1,
2221 },
2222 {
2223 .limits = hwsim_if_dfs_limits,
2224 .n_limits = ARRAY_SIZE(hwsim_if_dfs_limits),
2225 .max_interfaces = 8,
2226 .num_different_channels = 1,
2227 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
2228 BIT(NL80211_CHAN_WIDTH_20) |
2229 BIT(NL80211_CHAN_WIDTH_40) |
2230 BIT(NL80211_CHAN_WIDTH_80) |
2231 BIT(NL80211_CHAN_WIDTH_160),
2232 }
2209}; 2233};
2210 2234
2211static int __init init_mac80211_hwsim(void) 2235static int __init init_mac80211_hwsim(void)
@@ -2223,7 +2247,7 @@ static int __init init_mac80211_hwsim(void)
2223 return -EINVAL; 2247 return -EINVAL;
2224 2248
2225 if (channels > 1) { 2249 if (channels > 1) {
2226 hwsim_if_comb.num_different_channels = channels; 2250 hwsim_if_comb[0].num_different_channels = channels;
2227 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; 2251 mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan;
2228 mac80211_hwsim_ops.cancel_hw_scan = 2252 mac80211_hwsim_ops.cancel_hw_scan =
2229 mac80211_hwsim_cancel_hw_scan; 2253 mac80211_hwsim_cancel_hw_scan;
@@ -2303,13 +2327,15 @@ static int __init init_mac80211_hwsim(void)
2303 hw->wiphy->n_addresses = 2; 2327 hw->wiphy->n_addresses = 2;
2304 hw->wiphy->addresses = data->addresses; 2328 hw->wiphy->addresses = data->addresses;
2305 2329
2306 hw->wiphy->iface_combinations = &hwsim_if_comb; 2330 hw->wiphy->iface_combinations = hwsim_if_comb;
2307 hw->wiphy->n_iface_combinations = 1; 2331 hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
2308 2332
2309 if (channels > 1) { 2333 if (channels > 1) {
2310 hw->wiphy->max_scan_ssids = 255; 2334 hw->wiphy->max_scan_ssids = 255;
2311 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; 2335 hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
2312 hw->wiphy->max_remain_on_channel_duration = 1000; 2336 hw->wiphy->max_remain_on_channel_duration = 1000;
2337 /* For channels > 1 DFS is not allowed */
2338 hw->wiphy->n_iface_combinations = 1;
2313 } 2339 }
2314 2340
2315 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); 2341 INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
@@ -2333,7 +2359,8 @@ static int __init init_mac80211_hwsim(void)
2333 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 2359 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2334 IEEE80211_HW_AMPDU_AGGREGATION | 2360 IEEE80211_HW_AMPDU_AGGREGATION |
2335 IEEE80211_HW_WANT_MONITOR_VIF | 2361 IEEE80211_HW_WANT_MONITOR_VIF |
2336 IEEE80211_HW_QUEUE_CONTROL; 2362 IEEE80211_HW_QUEUE_CONTROL |
2363 IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
2337 if (rctbl) 2364 if (rctbl)
2338 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE; 2365 hw->flags |= IEEE80211_HW_SUPPORTS_RC_TABLE;
2339 2366
@@ -2393,6 +2420,7 @@ static int __init init_mac80211_hwsim(void)
2393 sband->vht_cap.cap = 2420 sband->vht_cap.cap =
2394 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 2421 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
2395 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | 2422 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
2423 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
2396 IEEE80211_VHT_CAP_RXLDPC | 2424 IEEE80211_VHT_CAP_RXLDPC |
2397 IEEE80211_VHT_CAP_SHORT_GI_80 | 2425 IEEE80211_VHT_CAP_SHORT_GI_80 |
2398 IEEE80211_VHT_CAP_SHORT_GI_160 | 2426 IEEE80211_VHT_CAP_SHORT_GI_160 |
@@ -2435,46 +2463,53 @@ static int __init init_mac80211_hwsim(void)
2435 break; 2463 break;
2436 case HWSIM_REGTEST_WORLD_ROAM: 2464 case HWSIM_REGTEST_WORLD_ROAM:
2437 if (i == 0) { 2465 if (i == 0) {
2438 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2466 hw->wiphy->regulatory_flags |=
2467 REGULATORY_CUSTOM_REG;
2439 wiphy_apply_custom_regulatory(hw->wiphy, 2468 wiphy_apply_custom_regulatory(hw->wiphy,
2440 &hwsim_world_regdom_custom_01); 2469 &hwsim_world_regdom_custom_01);
2441 } 2470 }
2442 break; 2471 break;
2443 case HWSIM_REGTEST_CUSTOM_WORLD: 2472 case HWSIM_REGTEST_CUSTOM_WORLD:
2444 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2473 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
2445 wiphy_apply_custom_regulatory(hw->wiphy, 2474 wiphy_apply_custom_regulatory(hw->wiphy,
2446 &hwsim_world_regdom_custom_01); 2475 &hwsim_world_regdom_custom_01);
2447 break; 2476 break;
2448 case HWSIM_REGTEST_CUSTOM_WORLD_2: 2477 case HWSIM_REGTEST_CUSTOM_WORLD_2:
2449 if (i == 0) { 2478 if (i == 0) {
2450 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2479 hw->wiphy->regulatory_flags |=
2480 REGULATORY_CUSTOM_REG;
2451 wiphy_apply_custom_regulatory(hw->wiphy, 2481 wiphy_apply_custom_regulatory(hw->wiphy,
2452 &hwsim_world_regdom_custom_01); 2482 &hwsim_world_regdom_custom_01);
2453 } else if (i == 1) { 2483 } else if (i == 1) {
2454 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2484 hw->wiphy->regulatory_flags |=
2485 REGULATORY_CUSTOM_REG;
2455 wiphy_apply_custom_regulatory(hw->wiphy, 2486 wiphy_apply_custom_regulatory(hw->wiphy,
2456 &hwsim_world_regdom_custom_02); 2487 &hwsim_world_regdom_custom_02);
2457 } 2488 }
2458 break; 2489 break;
2459 case HWSIM_REGTEST_STRICT_ALL: 2490 case HWSIM_REGTEST_STRICT_ALL:
2460 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2491 hw->wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
2461 break; 2492 break;
2462 case HWSIM_REGTEST_STRICT_FOLLOW: 2493 case HWSIM_REGTEST_STRICT_FOLLOW:
2463 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG: 2494 case HWSIM_REGTEST_STRICT_AND_DRIVER_REG:
2464 if (i == 0) 2495 if (i == 0)
2465 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2496 hw->wiphy->regulatory_flags |=
2497 REGULATORY_STRICT_REG;
2466 break; 2498 break;
2467 case HWSIM_REGTEST_ALL: 2499 case HWSIM_REGTEST_ALL:
2468 if (i == 0) { 2500 if (i == 0) {
2469 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2501 hw->wiphy->regulatory_flags |=
2502 REGULATORY_CUSTOM_REG;
2470 wiphy_apply_custom_regulatory(hw->wiphy, 2503 wiphy_apply_custom_regulatory(hw->wiphy,
2471 &hwsim_world_regdom_custom_01); 2504 &hwsim_world_regdom_custom_01);
2472 } else if (i == 1) { 2505 } else if (i == 1) {
2473 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 2506 hw->wiphy->regulatory_flags |=
2507 REGULATORY_CUSTOM_REG;
2474 wiphy_apply_custom_regulatory(hw->wiphy, 2508 wiphy_apply_custom_regulatory(hw->wiphy,
2475 &hwsim_world_regdom_custom_02); 2509 &hwsim_world_regdom_custom_02);
2476 } else if (i == 4) 2510 } else if (i == 4)
2477 hw->wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY; 2511 hw->wiphy->regulatory_flags |=
2512 REGULATORY_STRICT_REG;
2478 break; 2513 break;
2479 default: 2514 default:
2480 break; 2515 break;
@@ -2541,16 +2576,18 @@ static int __init init_mac80211_hwsim(void)
2541 2576
2542 data->debugfs = debugfs_create_dir("hwsim", 2577 data->debugfs = debugfs_create_dir("hwsim",
2543 hw->wiphy->debugfsdir); 2578 hw->wiphy->debugfsdir);
2544 data->debugfs_ps = debugfs_create_file("ps", 0666, 2579 debugfs_create_file("ps", 0666, data->debugfs, data,
2545 data->debugfs, data, 2580 &hwsim_fops_ps);
2546 &hwsim_fops_ps); 2581 debugfs_create_file("group", 0666, data->debugfs, data,
2547 data->debugfs_group = debugfs_create_file("group", 0666, 2582 &hwsim_fops_group);
2548 data->debugfs, data, 2583 if (channels == 1)
2549 &hwsim_fops_group); 2584 debugfs_create_file("dfs_simulate_radar", 0222,
2585 data->debugfs,
2586 data, &hwsim_simulate_radar);
2550 2587
2551 tasklet_hrtimer_init(&data->beacon_timer, 2588 tasklet_hrtimer_init(&data->beacon_timer,
2552 mac80211_hwsim_beacon, 2589 mac80211_hwsim_beacon,
2553 CLOCK_REALTIME, HRTIMER_MODE_ABS); 2590 CLOCK_MONOTONIC_RAW, HRTIMER_MODE_ABS);
2554 2591
2555 list_add_tail(&data->list, &hwsim_radios); 2592 list_add_tail(&data->list, &hwsim_radios);
2556 } 2593 }
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index aeaea0e3b4c4..d9b7330c902f 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -50,24 +50,24 @@ static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0), 50 REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
51 /* Channel 12 - 13 */ 51 /* Channel 12 - 13 */
52 REG_RULE(2467-10, 2472+10, 20, 3, 20, 52 REG_RULE(2467-10, 2472+10, 20, 3, 20,
53 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 53 NL80211_RRF_NO_IR),
54 /* Channel 14 */ 54 /* Channel 14 */
55 REG_RULE(2484-10, 2484+10, 20, 3, 20, 55 REG_RULE(2484-10, 2484+10, 20, 3, 20,
56 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 56 NL80211_RRF_NO_IR |
57 NL80211_RRF_NO_OFDM), 57 NL80211_RRF_NO_OFDM),
58 /* Channel 36 - 48 */ 58 /* Channel 36 - 48 */
59 REG_RULE(5180-10, 5240+10, 40, 3, 20, 59 REG_RULE(5180-10, 5240+10, 40, 3, 20,
60 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 60 NL80211_RRF_NO_IR),
61 /* Channel 149 - 165 */ 61 /* Channel 149 - 165 */
62 REG_RULE(5745-10, 5825+10, 40, 3, 20, 62 REG_RULE(5745-10, 5825+10, 40, 3, 20,
63 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), 63 NL80211_RRF_NO_IR),
64 /* Channel 52 - 64 */ 64 /* Channel 52 - 64 */
65 REG_RULE(5260-10, 5320+10, 40, 3, 30, 65 REG_RULE(5260-10, 5320+10, 40, 3, 30,
66 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 66 NL80211_RRF_NO_IR |
67 NL80211_RRF_DFS), 67 NL80211_RRF_DFS),
68 /* Channel 100 - 140 */ 68 /* Channel 100 - 140 */
69 REG_RULE(5500-10, 5700+10, 40, 3, 30, 69 REG_RULE(5500-10, 5700+10, 40, 3, 30,
70 NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | 70 NL80211_RRF_NO_IR |
71 NL80211_RRF_DFS), 71 NL80211_RRF_DFS),
72 } 72 }
73}; 73};
@@ -184,10 +184,10 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len)
184 */ 184 */
185static int 185static int
186mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 186mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
187 struct ieee80211_channel *chan, bool offchan, 187 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
188 unsigned int wait, const u8 *buf, size_t len,
189 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
190{ 188{
189 const u8 *buf = params->buf;
190 size_t len = params->len;
191 struct sk_buff *skb; 191 struct sk_buff *skb;
192 u16 pkt_len; 192 u16 pkt_len;
193 const struct ieee80211_mgmt *mgmt; 193 const struct ieee80211_mgmt *mgmt;
@@ -1968,7 +1968,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1968 user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1968 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1969 user_scan_cfg->chan_list[i].radio_type = chan->band; 1969 user_scan_cfg->chan_list[i].radio_type = chan->band;
1970 1970
1971 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1971 if (chan->flags & IEEE80211_CHAN_NO_IR)
1972 user_scan_cfg->chan_list[i].scan_type = 1972 user_scan_cfg->chan_list[i].scan_type =
1973 MWIFIEX_SCAN_TYPE_PASSIVE; 1973 MWIFIEX_SCAN_TYPE_PASSIVE;
1974 else 1974 else
@@ -2702,9 +2702,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2702 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 2702 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
2703 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 2703 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
2704 WIPHY_FLAG_AP_UAPSD | 2704 WIPHY_FLAG_AP_UAPSD |
2705 WIPHY_FLAG_CUSTOM_REGULATORY |
2706 WIPHY_FLAG_STRICT_REGULATORY |
2707 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 2705 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
2706 wiphy->regulatory_flags |=
2707 REGULATORY_CUSTOM_REG |
2708 REGULATORY_STRICT_REG;
2708 2709
2709 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2710 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
2710 2711
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 8cf7d50a7603..0ed06646f19a 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -515,14 +515,14 @@ mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
515 scan_chan_list[chan_idx].max_scan_time = 515 scan_chan_list[chan_idx].max_scan_time =
516 cpu_to_le16((u16) user_scan_in-> 516 cpu_to_le16((u16) user_scan_in->
517 chan_list[0].scan_time); 517 chan_list[0].scan_time);
518 else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 518 else if (ch->flags & IEEE80211_CHAN_NO_IR)
519 scan_chan_list[chan_idx].max_scan_time = 519 scan_chan_list[chan_idx].max_scan_time =
520 cpu_to_le16(adapter->passive_scan_time); 520 cpu_to_le16(adapter->passive_scan_time);
521 else 521 else
522 scan_chan_list[chan_idx].max_scan_time = 522 scan_chan_list[chan_idx].max_scan_time =
523 cpu_to_le16(adapter->active_scan_time); 523 cpu_to_le16(adapter->active_scan_time);
524 524
525 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 525 if (ch->flags & IEEE80211_CHAN_NO_IR)
526 scan_chan_list[chan_idx].chan_scan_mode_bitmap 526 scan_chan_list[chan_idx].chan_scan_mode_bitmap
527 |= MWIFIEX_PASSIVE_SCAN; 527 |= MWIFIEX_PASSIVE_SCAN;
528 else 528 else
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 2675ca7f8d14..551194605aa7 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -338,8 +338,7 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
338 if (!data_buf) 338 if (!data_buf)
339 return -1; 339 return -1;
340 340
341 pg_tlv_hdr = (struct mwifiex_types_power_group *) 341 pg_tlv_hdr = (struct mwifiex_types_power_group *)((u8 *)data_buf);
342 ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg));
343 pg = (struct mwifiex_power_group *) 342 pg = (struct mwifiex_power_group *)
344 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); 343 ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group));
345 length = le16_to_cpu(pg_tlv_hdr->length); 344 length = le16_to_cpu(pg_tlv_hdr->length);
@@ -383,19 +382,25 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
383 struct mwifiex_types_power_group *pg_tlv_hdr; 382 struct mwifiex_types_power_group *pg_tlv_hdr;
384 struct mwifiex_power_group *pg; 383 struct mwifiex_power_group *pg;
385 u16 action = le16_to_cpu(txp_cfg->action); 384 u16 action = le16_to_cpu(txp_cfg->action);
385 u16 tlv_buf_left;
386 386
387 switch (action) { 387 pg_tlv_hdr = (struct mwifiex_types_power_group *)
388 case HostCmd_ACT_GEN_GET: 388 ((u8 *)txp_cfg +
389 pg_tlv_hdr = (struct mwifiex_types_power_group *) 389 sizeof(struct host_cmd_ds_txpwr_cfg));
390 ((u8 *) txp_cfg +
391 sizeof(struct host_cmd_ds_txpwr_cfg));
392 390
393 pg = (struct mwifiex_power_group *) 391 pg = (struct mwifiex_power_group *)
394 ((u8 *) pg_tlv_hdr + 392 ((u8 *)pg_tlv_hdr +
395 sizeof(struct mwifiex_types_power_group)); 393 sizeof(struct mwifiex_types_power_group));
396 394
395 tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*txp_cfg);
396 if (tlv_buf_left <
397 le16_to_cpu(pg_tlv_hdr->length) + sizeof(*pg_tlv_hdr))
398 return 0;
399
400 switch (action) {
401 case HostCmd_ACT_GEN_GET:
397 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 402 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
398 mwifiex_get_power_level(priv, txp_cfg); 403 mwifiex_get_power_level(priv, pg_tlv_hdr);
399 404
400 priv->tx_power_level = (u16) pg->power_min; 405 priv->tx_power_level = (u16) pg->power_min;
401 break; 406 break;
@@ -404,14 +409,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
404 if (!le32_to_cpu(txp_cfg->mode)) 409 if (!le32_to_cpu(txp_cfg->mode))
405 break; 410 break;
406 411
407 pg_tlv_hdr = (struct mwifiex_types_power_group *)
408 ((u8 *) txp_cfg +
409 sizeof(struct host_cmd_ds_txpwr_cfg));
410
411 pg = (struct mwifiex_power_group *)
412 ((u8 *) pg_tlv_hdr +
413 sizeof(struct mwifiex_types_power_group));
414
415 if (pg->power_max == pg->power_min) 412 if (pg->power_max == pg->power_min)
416 priv->tx_power_level = (u16) pg->power_min; 413 priv->tx_power_level = (u16) pg->power_min;
417 break; 414 break;
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index e05d9b4c8317..7fa2898d0619 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -914,7 +914,6 @@ islpci_setup(struct pci_dev *pdev)
914 do_islpci_free_memory: 914 do_islpci_free_memory:
915 islpci_free_memory(priv); 915 islpci_free_memory(priv);
916 do_free_netdev: 916 do_free_netdev:
917 pci_set_drvdata(pdev, NULL);
918 free_netdev(ndev); 917 free_netdev(ndev);
919 priv = NULL; 918 priv = NULL;
920 return NULL; 919 return NULL;
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c
index 9e68e0cb718e..d7b9e6376424 100644
--- a/drivers/net/wireless/prism54/islpci_hotplug.c
+++ b/drivers/net/wireless/prism54/islpci_hotplug.c
@@ -199,7 +199,6 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
199 do_unregister_netdev: 199 do_unregister_netdev:
200 unregister_netdev(ndev); 200 unregister_netdev(ndev);
201 islpci_free_memory(priv); 201 islpci_free_memory(priv);
202 pci_set_drvdata(pdev, NULL);
203 free_netdev(ndev); 202 free_netdev(ndev);
204 priv = NULL; 203 priv = NULL;
205 do_pci_clear_mwi: 204 do_pci_clear_mwi:
@@ -247,7 +246,6 @@ prism54_remove(struct pci_dev *pdev)
247 /* free the PCI memory and unmap the remapped page */ 246 /* free the PCI memory and unmap the remapped page */
248 islpci_free_memory(priv); 247 islpci_free_memory(priv);
249 248
250 pci_set_drvdata(pdev, NULL);
251 free_netdev(ndev); 249 free_netdev(ndev);
252 priv = NULL; 250 priv = NULL;
253 251
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 776aff3678ff..5ee5b296ad28 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -5462,15 +5462,14 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
5462 5462
5463 rt2800_bbp_write(rt2x00dev, 68, 0x0b); 5463 rt2800_bbp_write(rt2x00dev, 68, 0x0b);
5464 5464
5465 rt2800_bbp_write(rt2x00dev, 69, 0x12); 5465 rt2800_bbp_write(rt2x00dev, 69, 0x0d);
5466 rt2800_bbp_write(rt2x00dev, 70, 0x06);
5466 rt2800_bbp_write(rt2x00dev, 73, 0x13); 5467 rt2800_bbp_write(rt2x00dev, 73, 0x13);
5467 rt2800_bbp_write(rt2x00dev, 75, 0x46); 5468 rt2800_bbp_write(rt2x00dev, 75, 0x46);
5468 rt2800_bbp_write(rt2x00dev, 76, 0x28); 5469 rt2800_bbp_write(rt2x00dev, 76, 0x28);
5469 5470
5470 rt2800_bbp_write(rt2x00dev, 77, 0x59); 5471 rt2800_bbp_write(rt2x00dev, 77, 0x59);
5471 5472
5472 rt2800_bbp_write(rt2x00dev, 70, 0x0a);
5473
5474 rt2800_bbp_write(rt2x00dev, 79, 0x13); 5473 rt2800_bbp_write(rt2x00dev, 79, 0x13);
5475 rt2800_bbp_write(rt2x00dev, 80, 0x05); 5474 rt2800_bbp_write(rt2x00dev, 80, 0x05);
5476 rt2800_bbp_write(rt2x00dev, 81, 0x33); 5475 rt2800_bbp_write(rt2x00dev, 81, 0x33);
@@ -5513,6 +5512,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
5513 if (rt2x00_rt(rt2x00dev, RT5392)) { 5512 if (rt2x00_rt(rt2x00dev, RT5392)) {
5514 rt2800_bbp_write(rt2x00dev, 134, 0xd0); 5513 rt2800_bbp_write(rt2x00dev, 134, 0xd0);
5515 rt2800_bbp_write(rt2x00dev, 135, 0xf6); 5514 rt2800_bbp_write(rt2x00dev, 135, 0xf6);
5515 rt2800_bbp_write(rt2x00dev, 148, 0x84);
5516 } 5516 }
5517 5517
5518 rt2800_disable_unused_dac_adc(rt2x00dev); 5518 rt2800_disable_unused_dac_adc(rt2x00dev);
@@ -6453,7 +6453,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6453 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 6453 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
6454 rt2800_rfcsr_write(rt2x00dev, 10, 0x53); 6454 rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
6455 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); 6455 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
6456 rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); 6456 rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
6457 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); 6457 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
6458 rt2800_rfcsr_write(rt2x00dev, 14, 0x00); 6458 rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
6459 rt2800_rfcsr_write(rt2x00dev, 15, 0x00); 6459 rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
@@ -6466,7 +6466,8 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6466 rt2800_rfcsr_write(rt2x00dev, 22, 0x20); 6466 rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
6467 rt2800_rfcsr_write(rt2x00dev, 23, 0x00); 6467 rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
6468 rt2800_rfcsr_write(rt2x00dev, 24, 0x00); 6468 rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
6469 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6469 if (rt2x00_is_usb(rt2x00dev) &&
6470 rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
6470 rt2800_rfcsr_write(rt2x00dev, 25, 0x80); 6471 rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
6471 else 6472 else
6472 rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); 6473 rt2800_rfcsr_write(rt2x00dev, 25, 0xc0);
@@ -6486,10 +6487,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6486 rt2800_rfcsr_write(rt2x00dev, 38, 0x85); 6487 rt2800_rfcsr_write(rt2x00dev, 38, 0x85);
6487 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); 6488 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
6488 6489
6489 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6490 rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
6490 rt2800_rfcsr_write(rt2x00dev, 40, 0x0b);
6491 else
6492 rt2800_rfcsr_write(rt2x00dev, 40, 0x4b);
6493 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); 6491 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
6494 rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); 6492 rt2800_rfcsr_write(rt2x00dev, 42, 0xd2);
6495 rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); 6493 rt2800_rfcsr_write(rt2x00dev, 43, 0x9a);
@@ -6510,16 +6508,26 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
6510 rt2800_rfcsr_write(rt2x00dev, 53, 0x84); 6508 rt2800_rfcsr_write(rt2x00dev, 53, 0x84);
6511 rt2800_rfcsr_write(rt2x00dev, 54, 0x78); 6509 rt2800_rfcsr_write(rt2x00dev, 54, 0x78);
6512 rt2800_rfcsr_write(rt2x00dev, 55, 0x44); 6510 rt2800_rfcsr_write(rt2x00dev, 55, 0x44);
6513 rt2800_rfcsr_write(rt2x00dev, 56, 0x22); 6511 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F))
6512 rt2800_rfcsr_write(rt2x00dev, 56, 0x42);
6513 else
6514 rt2800_rfcsr_write(rt2x00dev, 56, 0x22);
6514 rt2800_rfcsr_write(rt2x00dev, 57, 0x80); 6515 rt2800_rfcsr_write(rt2x00dev, 57, 0x80);
6515 rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); 6516 rt2800_rfcsr_write(rt2x00dev, 58, 0x7f);
6516 rt2800_rfcsr_write(rt2x00dev, 59, 0x8f); 6517 rt2800_rfcsr_write(rt2x00dev, 59, 0x8f);
6517 6518
6518 rt2800_rfcsr_write(rt2x00dev, 60, 0x45); 6519 rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
6519 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) 6520 if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
6520 rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); 6521 if (rt2x00_is_usb(rt2x00dev))
6521 else 6522 rt2800_rfcsr_write(rt2x00dev, 61, 0xd1);
6522 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); 6523 else
6524 rt2800_rfcsr_write(rt2x00dev, 61, 0xd5);
6525 } else {
6526 if (rt2x00_is_usb(rt2x00dev))
6527 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
6528 else
6529 rt2800_rfcsr_write(rt2x00dev, 61, 0xb5);
6530 }
6523 rt2800_rfcsr_write(rt2x00dev, 62, 0x00); 6531 rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
6524 rt2800_rfcsr_write(rt2x00dev, 63, 0x00); 6532 rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
6525 6533
@@ -6602,7 +6610,6 @@ static void rt2800_init_rfcsr_5592(struct rt2x00_dev *rt2x00dev)
6602 6610
6603 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F); 6611 rt2800_rfcsr_write(rt2x00dev, 1, 0x3F);
6604 rt2800_rfcsr_write(rt2x00dev, 3, 0x08); 6612 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
6605 rt2800_rfcsr_write(rt2x00dev, 3, 0x08);
6606 rt2800_rfcsr_write(rt2x00dev, 5, 0x10); 6613 rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
6607 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4); 6614 rt2800_rfcsr_write(rt2x00dev, 6, 0xE4);
6608 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 6615 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 25da20e7e1f3..af721831dcbc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -156,8 +156,6 @@ exit_release_regions:
156exit_disable_device: 156exit_disable_device:
157 pci_disable_device(pci_dev); 157 pci_disable_device(pci_dev);
158 158
159 pci_set_drvdata(pci_dev, NULL);
160
161 return retval; 159 return retval;
162} 160}
163EXPORT_SYMBOL_GPL(rt2x00pci_probe); 161EXPORT_SYMBOL_GPL(rt2x00pci_probe);
@@ -177,7 +175,6 @@ void rt2x00pci_remove(struct pci_dev *pci_dev)
177 /* 175 /*
178 * Free the PCI device data. 176 * Free the PCI device data.
179 */ 177 */
180 pci_set_drvdata(pci_dev, NULL);
181 pci_disable_device(pci_dev); 178 pci_disable_device(pci_dev);
182 pci_release_regions(pci_dev); 179 pci_release_regions(pci_dev);
183} 180}
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 9a6edb0c014e..ec9aa5b67381 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -416,7 +416,7 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev)
416 struct rtl8187_rx_info *info; 416 struct rtl8187_rx_info *info;
417 int ret = 0; 417 int ret = 0;
418 418
419 while (skb_queue_len(&priv->rx_queue) < 16) { 419 while (skb_queue_len(&priv->rx_queue) < 32) {
420 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); 420 skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL);
421 if (!skb) { 421 if (!skb) {
422 ret = -ENOMEM; 422 ret = -ENOMEM;
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c
index ff784072fb42..fcf9b621918c 100644
--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -1437,7 +1437,8 @@ void rtl_watchdog_wq_callback(void *data)
1437 /* if we can't recv beacon for 6s, we should 1437 /* if we can't recv beacon for 6s, we should
1438 * reconnect this AP 1438 * reconnect this AP
1439 */ 1439 */
1440 if (rtlpriv->link_info.roam_times >= 3) { 1440 if ((rtlpriv->link_info.roam_times >= 3) &&
1441 !is_zero_ether_addr(rtlpriv->mac80211.bssid)) {
1441 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1442 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1442 "AP off, try to reconnect now\n"); 1443 "AP off, try to reconnect now\n");
1443 rtlpriv->link_info.roam_times = 0; 1444 rtlpriv->link_info.roam_times = 0;
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 210ce7cd94d8..2d337a0c3df0 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -46,10 +46,20 @@ void rtl_fw_cb(const struct firmware *firmware, void *context)
46 "Firmware callback routine entered!\n"); 46 "Firmware callback routine entered!\n");
47 complete(&rtlpriv->firmware_loading_complete); 47 complete(&rtlpriv->firmware_loading_complete);
48 if (!firmware) { 48 if (!firmware) {
49 if (rtlpriv->cfg->alt_fw_name) {
50 err = request_firmware(&firmware,
51 rtlpriv->cfg->alt_fw_name,
52 rtlpriv->io.dev);
53 pr_info("Loading alternative firmware %s\n",
54 rtlpriv->cfg->alt_fw_name);
55 if (!err)
56 goto found_alt;
57 }
49 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); 58 pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
50 rtlpriv->max_fw_size = 0; 59 rtlpriv->max_fw_size = 0;
51 return; 60 return;
52 } 61 }
62found_alt:
53 if (firmware->size > rtlpriv->max_fw_size) { 63 if (firmware->size > rtlpriv->max_fw_size) {
54 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 64 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
55 "Firmware is too big!\n"); 65 "Firmware is too big!\n");
@@ -184,6 +194,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw,
184 rtlpriv->cfg->maps 194 rtlpriv->cfg->maps
185 [RTL_IBSS_INT_MASKS]); 195 [RTL_IBSS_INT_MASKS]);
186 } 196 }
197 mac->link_state = MAC80211_LINKED;
187 break; 198 break;
188 case NL80211_IFTYPE_ADHOC: 199 case NL80211_IFTYPE_ADHOC:
189 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, 200 RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 0f494444bcd1..8707d1a94995 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -688,8 +688,6 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb,
688 rtlpriv->stats.rxbytesunicast += skb->len; 688 rtlpriv->stats.rxbytesunicast += skb->len;
689 } 689 }
690 690
691 rtl_is_special_data(hw, skb, false);
692
693 if (ieee80211_is_data(fc)) { 691 if (ieee80211_is_data(fc)) {
694 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 692 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
695 693
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c
index d7d0d4948b01..a4eb9b271438 100644
--- a/drivers/net/wireless/rtlwifi/regd.c
+++ b/drivers/net/wireless/rtlwifi/regd.c
@@ -59,30 +59,26 @@ static struct country_code_to_enum_rd allCountries[] = {
59 */ 59 */
60#define RTL819x_2GHZ_CH12_13 \ 60#define RTL819x_2GHZ_CH12_13 \
61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ 61 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
62 NL80211_RRF_PASSIVE_SCAN) 62 NL80211_RRF_NO_IR)
63 63
64#define RTL819x_2GHZ_CH14 \ 64#define RTL819x_2GHZ_CH14 \
65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \ 65 REG_RULE(2484-10, 2484+10, 40, 0, 20, \
66 NL80211_RRF_PASSIVE_SCAN | \ 66 NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)
67 NL80211_RRF_NO_OFDM)
68 67
69/* 5G chan 36 - chan 64*/ 68/* 5G chan 36 - chan 64*/
70#define RTL819x_5GHZ_5150_5350 \ 69#define RTL819x_5GHZ_5150_5350 \
71 REG_RULE(5150-10, 5350+10, 40, 0, 30, \ 70 REG_RULE(5150-10, 5350+10, 40, 0, 30, \
72 NL80211_RRF_PASSIVE_SCAN | \ 71 NL80211_RRF_NO_IR)
73 NL80211_RRF_NO_IBSS)
74 72
75/* 5G chan 100 - chan 165*/ 73/* 5G chan 100 - chan 165*/
76#define RTL819x_5GHZ_5470_5850 \ 74#define RTL819x_5GHZ_5470_5850 \
77 REG_RULE(5470-10, 5850+10, 40, 0, 30, \ 75 REG_RULE(5470-10, 5850+10, 40, 0, 30, \
78 NL80211_RRF_PASSIVE_SCAN | \ 76 NL80211_RRF_NO_IR)
79 NL80211_RRF_NO_IBSS)
80 77
81/* 5G chan 149 - chan 165*/ 78/* 5G chan 149 - chan 165*/
82#define RTL819x_5GHZ_5725_5850 \ 79#define RTL819x_5GHZ_5725_5850 \
83 REG_RULE(5725-10, 5850+10, 40, 0, 30, \ 80 REG_RULE(5725-10, 5850+10, 40, 0, 30, \
84 NL80211_RRF_PASSIVE_SCAN | \ 81 NL80211_RRF_NO_IR)
85 NL80211_RRF_NO_IBSS)
86 82
87#define RTL819x_5GHZ_ALL \ 83#define RTL819x_5GHZ_ALL \
88 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) 84 (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
@@ -172,7 +168,8 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
172 (ch->flags & IEEE80211_CHAN_RADAR)) 168 (ch->flags & IEEE80211_CHAN_RADAR))
173 continue; 169 continue;
174 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 170 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
175 reg_rule = freq_reg_info(wiphy, ch->center_freq); 171 reg_rule = freq_reg_info(wiphy,
172 MHZ_TO_KHZ(ch->center_freq));
176 if (IS_ERR(reg_rule)) 173 if (IS_ERR(reg_rule))
177 continue; 174 continue;
178 175
@@ -185,16 +182,11 @@ static void _rtl_reg_apply_beaconing_flags(struct wiphy *wiphy,
185 *regulatory_hint(). 182 *regulatory_hint().
186 */ 183 */
187 184
188 if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) 185 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
189 ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 186 ch->flags &= ~IEEE80211_CHAN_NO_IR;
190 if (!(reg_rule->
191 flags & NL80211_RRF_PASSIVE_SCAN))
192 ch->flags &=
193 ~IEEE80211_CHAN_PASSIVE_SCAN;
194 } else { 187 } else {
195 if (ch->beacon_found) 188 if (ch->beacon_found)
196 ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 189 ch->flags &= ~IEEE80211_CHAN_NO_IR;
197 IEEE80211_CHAN_PASSIVE_SCAN);
198 } 190 }
199 } 191 }
200 } 192 }
@@ -219,11 +211,11 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
219 */ 211 */
220 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 212 if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
221 ch = &sband->channels[11]; /* CH 12 */ 213 ch = &sband->channels[11]; /* CH 12 */
222 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 214 if (ch->flags & IEEE80211_CHAN_NO_IR)
223 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 215 ch->flags &= ~IEEE80211_CHAN_NO_IR;
224 ch = &sband->channels[12]; /* CH 13 */ 216 ch = &sband->channels[12]; /* CH 13 */
225 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 217 if (ch->flags & IEEE80211_CHAN_NO_IR)
226 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 218 ch->flags &= ~IEEE80211_CHAN_NO_IR;
227 return; 219 return;
228 } 220 }
229 221
@@ -235,19 +227,19 @@ static void _rtl_reg_apply_active_scan_flags(struct wiphy *wiphy,
235 */ 227 */
236 228
237 ch = &sband->channels[11]; /* CH 12 */ 229 ch = &sband->channels[11]; /* CH 12 */
238 reg_rule = freq_reg_info(wiphy, ch->center_freq); 230 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
239 if (!IS_ERR(reg_rule)) { 231 if (!IS_ERR(reg_rule)) {
240 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 232 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
241 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 233 if (ch->flags & IEEE80211_CHAN_NO_IR)
242 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 234 ch->flags &= ~IEEE80211_CHAN_NO_IR;
243 } 235 }
244 236
245 ch = &sband->channels[12]; /* CH 13 */ 237 ch = &sband->channels[12]; /* CH 13 */
246 reg_rule = freq_reg_info(wiphy, ch->center_freq); 238 reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
247 if (!IS_ERR(reg_rule)) { 239 if (!IS_ERR(reg_rule)) {
248 if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) 240 if (!(reg_rule->flags & NL80211_RRF_NO_IR))
249 if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) 241 if (ch->flags & IEEE80211_CHAN_NO_IR)
250 ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 242 ch->flags &= ~IEEE80211_CHAN_NO_IR;
251 } 243 }
252} 244}
253 245
@@ -284,8 +276,7 @@ static void _rtl_reg_apply_radar_flags(struct wiphy *wiphy)
284 */ 276 */
285 if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 277 if (!(ch->flags & IEEE80211_CHAN_DISABLED))
286 ch->flags |= IEEE80211_CHAN_RADAR | 278 ch->flags |= IEEE80211_CHAN_RADAR |
287 IEEE80211_CHAN_NO_IBSS | 279 IEEE80211_CHAN_NO_IR;
288 IEEE80211_CHAN_PASSIVE_SCAN;
289 } 280 }
290} 281}
291 282
@@ -354,9 +345,9 @@ static int _rtl_regd_init_wiphy(struct rtl_regulatory *reg,
354 345
355 wiphy->reg_notifier = reg_notifier; 346 wiphy->reg_notifier = reg_notifier;
356 347
357 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; 348 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
358 wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY; 349 wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
359 wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS; 350 wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
360 351
361 regd = _rtl_regdomain_select(reg); 352 regd = _rtl_regdomain_select(reg);
362 wiphy_apply_custom_regulatory(wiphy, regd); 353 wiphy_apply_custom_regulatory(wiphy, regd);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
index 21a5cf060677..a6184b6e1d57 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/dm.c
@@ -1078,7 +1078,7 @@ static void rtl88e_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
1078 rtldm->swing_flag_ofdm = true; 1078 rtldm->swing_flag_ofdm = true;
1079 } 1079 }
1080 1080
1081 if (rtldm->swing_idx_cck != rtldm->swing_idx_cck) { 1081 if (rtldm->swing_idx_cck_cur != rtldm->swing_idx_cck) {
1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck; 1082 rtldm->swing_idx_cck_cur = rtldm->swing_idx_cck;
1083 rtldm->swing_flag_cck = true; 1083 rtldm->swing_flag_cck = true;
1084 } 1084 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
index e9caa5d4cff0..fd7e4a7c94de 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
@@ -158,6 +158,42 @@ static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
158 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} 158 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
159}; 159};
160 160
161static u32 power_index_reg[6] = {0xc90, 0xc91, 0xc92, 0xc98, 0xc99, 0xc9a};
162
163void dm_restorepowerindex(struct ieee80211_hw *hw)
164{
165 struct rtl_priv *rtlpriv = rtl_priv(hw);
166 u8 index;
167
168 for (index = 0; index < 6; index++)
169 rtl_write_byte(rtlpriv, power_index_reg[index],
170 rtlpriv->dm.powerindex_backup[index]);
171}
172EXPORT_SYMBOL_GPL(dm_restorepowerindex);
173
174void dm_writepowerindex(struct ieee80211_hw *hw, u8 value)
175{
176 struct rtl_priv *rtlpriv = rtl_priv(hw);
177 u8 index;
178
179 for (index = 0; index < 6; index++)
180 rtl_write_byte(rtlpriv, power_index_reg[index], value);
181}
182EXPORT_SYMBOL_GPL(dm_writepowerindex);
183
184void dm_savepowerindex(struct ieee80211_hw *hw)
185{
186 struct rtl_priv *rtlpriv = rtl_priv(hw);
187 u8 index;
188 u8 tmp;
189
190 for (index = 0; index < 6; index++) {
191 tmp = rtl_read_byte(rtlpriv, power_index_reg[index]);
192 rtlpriv->dm.powerindex_backup[index] = tmp;
193 }
194}
195EXPORT_SYMBOL_GPL(dm_savepowerindex);
196
161static void rtl92c_dm_diginit(struct ieee80211_hw *hw) 197static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
162{ 198{
163 struct rtl_priv *rtlpriv = rtl_priv(hw); 199 struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -180,7 +216,12 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
180 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; 216 dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX;
181 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; 217 dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN;
182 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; 218 dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX;
183 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 219 dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_LowRssi;
220
221 dm_digtable->forbidden_igi = DM_DIG_MIN;
222 dm_digtable->large_fa_hit = 0;
223 dm_digtable->recover_cnt = 0;
224 dm_digtable->dig_dynamic_min = 0x25;
184} 225}
185 226
186static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 227static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
@@ -206,7 +247,9 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
206 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; 247 rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
207 } 248 }
208 249
209 return (u8) rssi_val_min; 250 if (rssi_val_min > 100)
251 rssi_val_min = 100;
252 return (u8)rssi_val_min;
210} 253}
211 254
212static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 255static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
@@ -224,9 +267,17 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
224 267
225 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); 268 ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
226 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 269 falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
270
271 ret_value = rtl_get_bbreg(hw, ROFDM0_FRAMESYNC, MASKDWORD);
272 falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff);
273 falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16);
274
227 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 275 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
228 falsealm_cnt->cnt_rate_illegal + 276 falsealm_cnt->cnt_rate_illegal +
229 falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; 277 falsealm_cnt->cnt_crc8_fail +
278 falsealm_cnt->cnt_mcs_fail +
279 falsealm_cnt->cnt_fast_fsync_fail +
280 falsealm_cnt->cnt_sb_search_fail;
230 281
231 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); 282 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
232 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); 283 ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
@@ -271,12 +322,14 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
271 value_igi++; 322 value_igi++;
272 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) 323 else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
273 value_igi += 2; 324 value_igi += 2;
325
274 if (value_igi > DM_DIG_FA_UPPER) 326 if (value_igi > DM_DIG_FA_UPPER)
275 value_igi = DM_DIG_FA_UPPER; 327 value_igi = DM_DIG_FA_UPPER;
276 else if (value_igi < DM_DIG_FA_LOWER) 328 else if (value_igi < DM_DIG_FA_LOWER)
277 value_igi = DM_DIG_FA_LOWER; 329 value_igi = DM_DIG_FA_LOWER;
330
278 if (rtlpriv->falsealm_cnt.cnt_all > 10000) 331 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
279 value_igi = 0x32; 332 value_igi = DM_DIG_FA_UPPER;
280 333
281 dm_digtable->cur_igvalue = value_igi; 334 dm_digtable->cur_igvalue = value_igi;
282 rtl92c_dm_write_dig(hw); 335 rtl92c_dm_write_dig(hw);
@@ -286,32 +339,80 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
286{ 339{
287 struct rtl_priv *rtlpriv = rtl_priv(hw); 340 struct rtl_priv *rtlpriv = rtl_priv(hw);
288 struct dig_t *digtable = &rtlpriv->dm_digtable; 341 struct dig_t *digtable = &rtlpriv->dm_digtable;
342 u32 isbt;
343
344 /* modify DIG lower bound, deal with abnorally large false alarm */
345 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
346 digtable->large_fa_hit++;
347 if (digtable->forbidden_igi < digtable->cur_igvalue) {
348 digtable->forbidden_igi = digtable->cur_igvalue;
349 digtable->large_fa_hit = 1;
350 }
289 351
290 if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { 352 if (digtable->large_fa_hit >= 3) {
291 if ((digtable->back_val - 2) < digtable->back_range_min) 353 if ((digtable->forbidden_igi + 1) >
292 digtable->back_val = digtable->back_range_min; 354 digtable->rx_gain_max)
293 else 355 digtable->rx_gain_min = digtable->rx_gain_max;
294 digtable->back_val -= 2; 356 else
295 } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { 357 digtable->rx_gain_min = (digtable->forbidden_igi + 1);
296 if ((digtable->back_val + 2) > digtable->back_range_max) 358 digtable->recover_cnt = 3600; /* 3600=2hr */
297 digtable->back_val = digtable->back_range_max; 359 }
298 else 360 } else {
299 digtable->back_val += 2; 361 /* Recovery mechanism for IGI lower bound */
362 if (digtable->recover_cnt != 0) {
363 digtable->recover_cnt--;
364 } else {
365 if (digtable->large_fa_hit == 0) {
366 if ((digtable->forbidden_igi-1) < DM_DIG_MIN) {
367 digtable->forbidden_igi = DM_DIG_MIN;
368 digtable->rx_gain_min = DM_DIG_MIN;
369 } else {
370 digtable->forbidden_igi--;
371 digtable->rx_gain_min = digtable->forbidden_igi + 1;
372 }
373 } else if (digtable->large_fa_hit == 3) {
374 digtable->large_fa_hit = 0;
375 }
376 }
377 }
378 if (rtlpriv->falsealm_cnt.cnt_all < 250) {
379 isbt = rtl_read_byte(rtlpriv, 0x4fd) & 0x01;
380
381 if (!isbt) {
382 if (rtlpriv->falsealm_cnt.cnt_all >
383 digtable->fa_lowthresh) {
384 if ((digtable->back_val - 2) <
385 digtable->back_range_min)
386 digtable->back_val = digtable->back_range_min;
387 else
388 digtable->back_val -= 2;
389 } else if (rtlpriv->falsealm_cnt.cnt_all <
390 digtable->fa_lowthresh) {
391 if ((digtable->back_val + 2) >
392 digtable->back_range_max)
393 digtable->back_val = digtable->back_range_max;
394 else
395 digtable->back_val += 2;
396 }
397 } else {
398 digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
399 }
400 } else {
401 /* Adjust initial gain by false alarm */
402 if (rtlpriv->falsealm_cnt.cnt_all > 1000)
403 digtable->cur_igvalue = digtable->pre_igvalue + 2;
404 else if (rtlpriv->falsealm_cnt.cnt_all > 750)
405 digtable->cur_igvalue = digtable->pre_igvalue + 1;
406 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
407 digtable->cur_igvalue = digtable->pre_igvalue - 1;
300 } 408 }
301 409
302 if ((digtable->rssi_val_min + 10 - digtable->back_val) > 410 /* Check initial gain by upper/lower bound */
303 digtable->rx_gain_max) 411 if (digtable->cur_igvalue > digtable->rx_gain_max)
304 digtable->cur_igvalue = digtable->rx_gain_max; 412 digtable->cur_igvalue = digtable->rx_gain_max;
305 else if ((digtable->rssi_val_min + 10 -
306 digtable->back_val) < digtable->rx_gain_min)
307 digtable->cur_igvalue = digtable->rx_gain_min;
308 else
309 digtable->cur_igvalue = digtable->rssi_val_min + 10 -
310 digtable->back_val;
311 413
312 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 414 if (digtable->cur_igvalue < digtable->rx_gain_min)
313 "rssi_val_min = %x back_val %x\n", 415 digtable->cur_igvalue = digtable->rx_gain_min;
314 digtable->rssi_val_min, digtable->back_val);
315 416
316 rtl92c_dm_write_dig(hw); 417 rtl92c_dm_write_dig(hw);
317} 418}
@@ -329,7 +430,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
329 multi_sta = true; 430 multi_sta = true;
330 431
331 if (!multi_sta || 432 if (!multi_sta ||
332 dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 433 dm_digtable->cursta_cstate == DIG_STA_DISCONNECT) {
333 initialized = false; 434 initialized = false;
334 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 435 dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
335 return; 436 return;
@@ -375,7 +476,6 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
375 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, 476 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
376 "presta_cstate = %x, cursta_cstate = %x\n", 477 "presta_cstate = %x, cursta_cstate = %x\n",
377 dm_digtable->presta_cstate, dm_digtable->cursta_cstate); 478 dm_digtable->presta_cstate, dm_digtable->cursta_cstate);
378
379 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || 479 if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
380 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || 480 dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
381 dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 481 dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
@@ -383,6 +483,8 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
383 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 483 if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
384 dm_digtable->rssi_val_min = 484 dm_digtable->rssi_val_min =
385 rtl92c_dm_initial_gain_min_pwdb(hw); 485 rtl92c_dm_initial_gain_min_pwdb(hw);
486 if (dm_digtable->rssi_val_min > 100)
487 dm_digtable->rssi_val_min = 100;
386 rtl92c_dm_ctrl_initgain_by_rssi(hw); 488 rtl92c_dm_ctrl_initgain_by_rssi(hw);
387 } 489 }
388 } else { 490 } else {
@@ -398,11 +500,12 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
398static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 500static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
399{ 501{
400 struct rtl_priv *rtlpriv = rtl_priv(hw); 502 struct rtl_priv *rtlpriv = rtl_priv(hw);
401 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
402 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 503 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
403 504
404 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 505 if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
405 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); 506 dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
507 if (dm_digtable->rssi_val_min > 100)
508 dm_digtable->rssi_val_min = 100;
406 509
407 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { 510 if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
408 if (dm_digtable->rssi_val_min <= 25) 511 if (dm_digtable->rssi_val_min <= 25)
@@ -424,48 +527,14 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
424 } 527 }
425 528
426 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 529 if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
427 if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { 530 if ((dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) ||
428 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) 531 (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_MAX))
429 dm_digtable->cur_cck_fa_state = 532 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x83);
430 CCK_FA_STAGE_High; 533 else
431 else
432 dm_digtable->cur_cck_fa_state = CCK_FA_STAGE_Low;
433
434 if (dm_digtable->pre_cck_fa_state !=
435 dm_digtable->cur_cck_fa_state) {
436 if (dm_digtable->cur_cck_fa_state ==
437 CCK_FA_STAGE_Low)
438 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
439 0x83);
440 else
441 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
442 0xcd);
443
444 dm_digtable->pre_cck_fa_state =
445 dm_digtable->cur_cck_fa_state;
446 }
447
448 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
449
450 if (IS_92C_SERIAL(rtlhal->version))
451 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
452 MASKBYTE2, 0xd7);
453 } else {
454 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 534 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
455 rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
456 535
457 if (IS_92C_SERIAL(rtlhal->version))
458 rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
459 MASKBYTE2, 0xd3);
460 }
461 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; 536 dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
462 } 537 }
463
464 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n",
465 dm_digtable->cur_cck_pd_state);
466
467 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n",
468 IS_92C_SERIAL(rtlhal->version));
469} 538}
470 539
471static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) 540static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
@@ -482,6 +551,8 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
482 else 551 else
483 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; 552 dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
484 553
554 dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT;
555
485 rtl92c_dm_initial_gain_sta(hw); 556 rtl92c_dm_initial_gain_sta(hw);
486 rtl92c_dm_initial_gain_multi_sta(hw); 557 rtl92c_dm_initial_gain_multi_sta(hw);
487 rtl92c_dm_cck_packet_detection_thresh(hw); 558 rtl92c_dm_cck_packet_detection_thresh(hw);
@@ -493,23 +564,26 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
493static void rtl92c_dm_dig(struct ieee80211_hw *hw) 564static void rtl92c_dm_dig(struct ieee80211_hw *hw)
494{ 565{
495 struct rtl_priv *rtlpriv = rtl_priv(hw); 566 struct rtl_priv *rtlpriv = rtl_priv(hw);
496 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
497 567
498 if (rtlpriv->dm.dm_initialgain_enable == false) 568 if (rtlpriv->dm.dm_initialgain_enable == false)
499 return; 569 return;
500 if (dm_digtable->dig_enable_flag == false) 570 if (!rtlpriv->dm.dm_flag & DYNAMIC_FUNC_DIG)
501 return; 571 return;
502 572
503 rtl92c_dm_ctrl_initgain_by_twoport(hw); 573 rtl92c_dm_ctrl_initgain_by_twoport(hw);
504
505} 574}
506 575
507static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) 576static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
508{ 577{
509 struct rtl_priv *rtlpriv = rtl_priv(hw); 578 struct rtl_priv *rtlpriv = rtl_priv(hw);
510 579
511 rtlpriv->dm.dynamic_txpower_enable = false; 580 if (rtlpriv->rtlhal.interface == INTF_USB &&
512 581 rtlpriv->rtlhal.board_type & 0x1) {
582 dm_savepowerindex(hw);
583 rtlpriv->dm.dynamic_txpower_enable = true;
584 } else {
585 rtlpriv->dm.dynamic_txpower_enable = false;
586 }
513 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; 587 rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
514 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 588 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
515} 589}
@@ -524,9 +598,14 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
524 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, 598 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
525 dm_digtable->back_val); 599 dm_digtable->back_val);
526 600
527 dm_digtable->cur_igvalue += 2; 601 if (rtlpriv->rtlhal.interface == INTF_USB &&
528 if (dm_digtable->cur_igvalue > 0x3f) 602 !dm_digtable->dig_enable_flag) {
529 dm_digtable->cur_igvalue = 0x3f; 603 dm_digtable->pre_igvalue = 0x17;
604 return;
605 }
606 dm_digtable->cur_igvalue -= 1;
607 if (dm_digtable->cur_igvalue < DM_DIG_MIN)
608 dm_digtable->cur_igvalue = DM_DIG_MIN;
530 609
531 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { 610 if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
532 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, 611 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
@@ -536,11 +615,47 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
536 615
537 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; 616 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
538 } 617 }
618 RT_TRACE(rtlpriv, COMP_DIG, DBG_WARNING,
619 "dig values 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
620 dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
621 dm_digtable->rssi_val_min, dm_digtable->back_val,
622 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min,
623 dm_digtable->large_fa_hit, dm_digtable->forbidden_igi);
539} 624}
540EXPORT_SYMBOL(rtl92c_dm_write_dig); 625EXPORT_SYMBOL(rtl92c_dm_write_dig);
541 626
542static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) 627static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
543{ 628{
629 struct rtl_priv *rtlpriv = rtl_priv(hw);
630 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
631 long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
632
633 if (mac->link_state != MAC80211_LINKED)
634 return;
635
636 if (mac->opmode == NL80211_IFTYPE_ADHOC ||
637 mac->opmode == NL80211_IFTYPE_AP) {
638 /* TODO: Handle ADHOC and AP Mode */
639 }
640
641 if (tmpentry_max_pwdb != 0)
642 rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb;
643 else
644 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
645
646 if (tmpentry_min_pwdb != 0xff)
647 rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb;
648 else
649 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
650
651/* TODO:
652 * if (mac->opmode == NL80211_IFTYPE_STATION) {
653 * if (rtlpriv->rtlhal.fw_ready) {
654 * u32 param = (u32)(rtlpriv->dm.undec_sm_pwdb << 16);
655 * rtl8192c_set_rssi_cmd(hw, param);
656 * }
657 * }
658 */
544} 659}
545 660
546void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) 661void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
@@ -750,6 +865,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
750 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; 865 rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
751 rtlpriv->dm.cck_index = cck_index_old; 866 rtlpriv->dm.cck_index = cck_index_old;
752 } 867 }
868 /* Handle USB High PA boards */
753 869
754 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? 870 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
755 (thermalvalue - rtlpriv->dm.thermalvalue) : 871 (thermalvalue - rtlpriv->dm.thermalvalue) :
@@ -1140,22 +1256,22 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1140{ 1256{
1141 struct rtl_priv *rtlpriv = rtl_priv(hw); 1257 struct rtl_priv *rtlpriv = rtl_priv(hw);
1142 struct ps_t *dm_pstable = &rtlpriv->dm_pstable; 1258 struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
1143 static u8 initialize;
1144 static u32 reg_874, reg_c70, reg_85c, reg_a74;
1145 1259
1146 if (initialize == 0) { 1260 if (!rtlpriv->reg_init) {
1147 reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1261 rtlpriv->reg_874 = (rtl_get_bbreg(hw,
1148 MASKDWORD) & 0x1CC000) >> 14; 1262 RFPGA0_XCD_RFINTERFACESW,
1263 MASKDWORD) & 0x1CC000) >> 14;
1149 1264
1150 reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, 1265 rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1151 MASKDWORD) & BIT(3)) >> 3; 1266 MASKDWORD) & BIT(3)) >> 3;
1152 1267
1153 reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 1268 rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1154 MASKDWORD) & 0xFF000000) >> 24; 1269 MASKDWORD) & 0xFF000000) >> 24;
1155 1270
1156 reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; 1271 rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) &
1272 0xF000) >> 12;
1157 1273
1158 initialize = 1; 1274 rtlpriv->reg_init = true;
1159 } 1275 }
1160 1276
1161 if (!bforce_in_normal) { 1277 if (!bforce_in_normal) {
@@ -1192,12 +1308,12 @@ void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1192 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); 1308 rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1193 } else { 1309 } else {
1194 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 1310 rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1195 0x1CC000, reg_874); 1311 0x1CC000, rtlpriv->reg_874);
1196 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 1312 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1197 reg_c70); 1313 rtlpriv->reg_c70);
1198 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, 1314 rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1199 reg_85c); 1315 rtlpriv->reg_85c);
1200 rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); 1316 rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74);
1201 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); 1317 rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1202 } 1318 }
1203 1319
@@ -1213,6 +1329,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1213 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1329 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1214 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1330 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1215 1331
1332 /* Determine the minimum RSSI */
1216 if (((mac->link_state == MAC80211_NOLINK)) && 1333 if (((mac->link_state == MAC80211_NOLINK)) &&
1217 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 1334 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
1218 dm_pstable->rssi_val_min = 0; 1335 dm_pstable->rssi_val_min = 0;
@@ -1241,6 +1358,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1241 dm_pstable->rssi_val_min); 1358 dm_pstable->rssi_val_min);
1242 } 1359 }
1243 1360
1361 /* Power Saving for 92C */
1244 if (IS_92C_SERIAL(rtlhal->version)) 1362 if (IS_92C_SERIAL(rtlhal->version))
1245 ;/* rtl92c_dm_1r_cca(hw); */ 1363 ;/* rtl92c_dm_1r_cca(hw); */
1246 else 1364 else
@@ -1252,12 +1370,23 @@ void rtl92c_dm_init(struct ieee80211_hw *hw)
1252 struct rtl_priv *rtlpriv = rtl_priv(hw); 1370 struct rtl_priv *rtlpriv = rtl_priv(hw);
1253 1371
1254 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 1372 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1373 rtlpriv->dm.dm_flag = DYNAMIC_FUNC_DISABLE | DYNAMIC_FUNC_DIG;
1374 rtlpriv->dm.undec_sm_pwdb = -1;
1375 rtlpriv->dm.undec_sm_cck = -1;
1376 rtlpriv->dm.dm_initialgain_enable = true;
1255 rtl92c_dm_diginit(hw); 1377 rtl92c_dm_diginit(hw);
1378
1379 rtlpriv->dm.dm_flag |= HAL_DM_HIPWR_DISABLE;
1256 rtl92c_dm_init_dynamic_txpower(hw); 1380 rtl92c_dm_init_dynamic_txpower(hw);
1381
1257 rtl92c_dm_init_edca_turbo(hw); 1382 rtl92c_dm_init_edca_turbo(hw);
1258 rtl92c_dm_init_rate_adaptive_mask(hw); 1383 rtl92c_dm_init_rate_adaptive_mask(hw);
1384 rtlpriv->dm.dm_flag |= DYNAMIC_FUNC_SS;
1259 rtl92c_dm_initialize_txpower_tracking(hw); 1385 rtl92c_dm_initialize_txpower_tracking(hw);
1260 rtl92c_dm_init_dynamic_bb_powersaving(hw); 1386 rtl92c_dm_init_dynamic_bb_powersaving(hw);
1387
1388 rtlpriv->dm.ofdm_pkt_cnt = 0;
1389 rtlpriv->dm.dm_rssi_sel = RSSI_DEFAULT;
1261} 1390}
1262EXPORT_SYMBOL(rtl92c_dm_init); 1391EXPORT_SYMBOL(rtl92c_dm_init);
1263 1392
@@ -1308,7 +1437,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1308 } 1437 }
1309 1438
1310 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { 1439 if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
1311 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; 1440 rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2;
1312 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 1441 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1313 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); 1442 "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
1314 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && 1443 } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
@@ -1328,8 +1457,16 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1328 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 1457 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
1329 rtlphy->current_channel); 1458 rtlphy->current_channel);
1330 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 1459 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1460 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1461 TXHIGHPWRLEVEL_NORMAL)
1462 dm_restorepowerindex(hw);
1463 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1464 TXHIGHPWRLEVEL_LEVEL1)
1465 dm_writepowerindex(hw, 0x14);
1466 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
1467 TXHIGHPWRLEVEL_LEVEL2)
1468 dm_writepowerindex(hw, 0x10);
1331 } 1469 }
1332
1333 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 1470 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
1334} 1471}
1335 1472
@@ -1400,12 +1537,6 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
1400 else 1537 else
1401 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); 1538 curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
1402 1539
1403 /* Set Tx Power according to BT status. */
1404 if (undec_sm_pwdb >= 30)
1405 curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW;
1406 else if (undec_sm_pwdb < 25)
1407 curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
1408
1409 /* Check BT state related to BT_Idle in B/G mode. */ 1540 /* Check BT state related to BT_Idle in B/G mode. */
1410 if (undec_sm_pwdb < 15) 1541 if (undec_sm_pwdb < 15)
1411 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; 1542 curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
index 518e208c0180..4f232a063636 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
@@ -91,6 +91,17 @@
91#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 91#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74
92#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 92#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67
93 93
94#define DYNAMIC_FUNC_DISABLE 0x0
95#define DYNAMIC_FUNC_DIG BIT(0)
96#define DYNAMIC_FUNC_HP BIT(1)
97#define DYNAMIC_FUNC_SS BIT(2) /*Tx Power Tracking*/
98#define DYNAMIC_FUNC_BT BIT(3)
99#define DYNAMIC_FUNC_ANT_DIV BIT(4)
100
101#define RSSI_CCK 0
102#define RSSI_OFDM 1
103#define RSSI_DEFAULT 2
104
94struct swat_t { 105struct swat_t {
95 u8 failure_cnt; 106 u8 failure_cnt;
96 u8 try_flag; 107 u8 try_flag;
@@ -167,5 +178,8 @@ void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
167void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); 178void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
168void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); 179void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
169void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw); 180void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
181void dm_savepowerindex(struct ieee80211_hw *hw);
182void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
183void dm_restorepowerindex(struct ieee80211_hw *hw);
170 184
171#endif 185#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index 0c0e78263a66..9e32ac8a4425 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -1147,6 +1147,12 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1147 0x522, 0x550, 0x551, 0x040 1147 0x522, 0x550, 0x551, 0x040
1148 }; 1148 };
1149 1149
1150 u32 iqk_bb_reg_92C[9] = {
1151 0xc04, 0xc08, 0x874, 0xb68,
1152 0xb6c, 0x870, 0x860, 0x864,
1153 0x800
1154 };
1155
1150 const u32 retrycount = 2; 1156 const u32 retrycount = 2;
1151 1157
1152 if (t == 0) { 1158 if (t == 0) {
@@ -1157,6 +1163,8 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1157 rtlphy->adda_backup, 16); 1163 rtlphy->adda_backup, 16);
1158 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, 1164 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg,
1159 rtlphy->iqk_mac_backup); 1165 rtlphy->iqk_mac_backup);
1166 _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg_92C,
1167 rtlphy->iqk_bb_backup, 9);
1160 } 1168 }
1161 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); 1169 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t);
1162 if (t == 0) { 1170 if (t == 0) {
@@ -1167,14 +1175,18 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1167 1175
1168 if (!rtlphy->rfpi_enable) 1176 if (!rtlphy->rfpi_enable)
1169 _rtl92c_phy_pi_mode_switch(hw, true); 1177 _rtl92c_phy_pi_mode_switch(hw, true);
1170 if (t == 0) { 1178
1171 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 1179 rtl_set_bbreg(hw, 0x800, BIT(24), 0x0);
1172 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 1180
1173 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1174 }
1175 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 1181 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1176 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 1182 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1177 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 1183 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1184
1185 rtl_set_bbreg(hw, 0x870, BIT(10), 0x1);
1186 rtl_set_bbreg(hw, 0x870, BIT(26), 0x1);
1187 rtl_set_bbreg(hw, 0x860, BIT(10), 0x0);
1188 rtl_set_bbreg(hw, 0x864, BIT(10), 0x0);
1189
1178 if (is2t) { 1190 if (is2t) {
1179 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1191 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1180 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 1192 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
@@ -1239,13 +1251,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1239 0x3FF0000) >> 16; 1251 0x3FF0000) >> 16;
1240 } 1252 }
1241 } 1253 }
1242 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); 1254
1243 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1244 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1245 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 1255 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1246 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 1256
1247 if (is2t)
1248 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1249 if (t != 0) { 1257 if (t != 0) {
1250 if (!rtlphy->rfpi_enable) 1258 if (!rtlphy->rfpi_enable)
1251 _rtl92c_phy_pi_mode_switch(hw, false); 1259 _rtl92c_phy_pi_mode_switch(hw, false);
@@ -1253,6 +1261,15 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw,
1253 rtlphy->adda_backup, 16); 1261 rtlphy->adda_backup, 16);
1254 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, 1262 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg,
1255 rtlphy->iqk_mac_backup); 1263 rtlphy->iqk_mac_backup);
1264 _rtl92c_phy_reload_adda_registers(hw, iqk_bb_reg_92C,
1265 rtlphy->iqk_bb_backup, 9);
1266
1267 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1268 if (is2t)
1269 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1270
1271 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1272 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1256 } 1273 }
1257} 1274}
1258 1275
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
index 16a0b9e59acf..c16209a336ea 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c
@@ -101,6 +101,15 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw)
101 "PHY_SetTxPowerLevel8192S() Channel = %d\n", 101 "PHY_SetTxPowerLevel8192S() Channel = %d\n",
102 rtlphy->current_channel); 102 rtlphy->current_channel);
103 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 103 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
104 if (rtlpriv->dm.dynamic_txhighpower_lvl ==
105 TXHIGHPWRLEVEL_NORMAL)
106 dm_restorepowerindex(hw);
107 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
108 TXHIGHPWRLEVEL_LEVEL1)
109 dm_writepowerindex(hw, 0x14);
110 else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
111 TXHIGHPWRLEVEL_LEVEL2)
112 dm_writepowerindex(hw, 0x10);
104 } 113 }
105 114
106 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 115 rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
index d947e7d350bb..fafa6bac2a3f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h
@@ -30,3 +30,6 @@
30#include "../rtl8192ce/dm.h" 30#include "../rtl8192ce/dm.h"
31 31
32void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw); 32void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw);
33void dm_savepowerindex(struct ieee80211_hw *hw);
34void dm_writepowerindex(struct ieee80211_hw *hw, u8 value);
35void dm_restorepowerindex(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 189ba124a8c6..468bf73cc883 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1022,7 +1022,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1022 if (ppsc->rfpwr_state == ERFON) { 1022 if (ppsc->rfpwr_state == ERFON) {
1023 rtl92c_phy_set_rfpath_switch(hw, 1); 1023 rtl92c_phy_set_rfpath_switch(hw, 1);
1024 if (iqk_initialized) { 1024 if (iqk_initialized) {
1025 rtl92c_phy_iq_calibrate(hw, false); 1025 rtl92c_phy_iq_calibrate(hw, true);
1026 } else { 1026 } else {
1027 rtl92c_phy_iq_calibrate(hw, false); 1027 rtl92c_phy_iq_calibrate(hw, false);
1028 iqk_initialized = true; 1028 iqk_initialized = true;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
index 34e56308301e..0c09240eadcc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
@@ -120,6 +120,7 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
120 struct rtl_priv *rtlpriv = rtl_priv(hw); 120 struct rtl_priv *rtlpriv = rtl_priv(hw);
121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 121 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
122 u16 regval; 122 u16 regval;
123 u32 regval32;
123 u8 b_reg_hwparafile = 1; 124 u8 b_reg_hwparafile = 1;
124 125
125 _rtl92c_phy_init_bb_rf_register_definition(hw); 126 _rtl92c_phy_init_bb_rf_register_definition(hw);
@@ -135,8 +136,11 @@ bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
135 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) { 136 } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) {
136 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | 137 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
137 FEN_BB_GLB_RSTn | FEN_BBRSTB); 138 FEN_BB_GLB_RSTn | FEN_BBRSTB);
138 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
139 } 139 }
140 regval32 = rtl_read_dword(rtlpriv, 0x87c);
141 rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
142 if (IS_HARDWARE_TYPE_8192CU(rtlhal))
143 rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
140 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 144 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
141 if (b_reg_hwparafile == 1) 145 if (b_reg_hwparafile == 1)
142 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); 146 rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
index 2119313a737b..b878d56d2f4d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
@@ -85,17 +85,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
85 if (mac->act_scanning) { 85 if (mac->act_scanning) {
86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f; 86 tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f; 87 tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
88 if (turbo_scanoff) { 88 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
89 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 89 tx_agc[idx1] = ppowerlevel[idx1] |
90 tx_agc[idx1] = ppowerlevel[idx1] | 90 (ppowerlevel[idx1] << 8) |
91 (ppowerlevel[idx1] << 8) | 91 (ppowerlevel[idx1] << 16) |
92 (ppowerlevel[idx1] << 16) | 92 (ppowerlevel[idx1] << 24);
93 (ppowerlevel[idx1] << 24); 93 if (rtlhal->interface == INTF_USB) {
94 if (rtlhal->interface == INTF_USB) { 94 if (tx_agc[idx1] > 0x20 &&
95 if (tx_agc[idx1] > 0x20 && 95 rtlefuse->external_pa)
96 rtlefuse->external_pa) 96 tx_agc[idx1] = 0x20;
97 tx_agc[idx1] = 0x20;
98 }
99 } 97 }
100 } 98 }
101 } else { 99 } else {
@@ -107,7 +105,7 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
107 TXHIGHPWRLEVEL_LEVEL2) { 105 TXHIGHPWRLEVEL_LEVEL2) {
108 tx_agc[RF90_PATH_A] = 0x00000000; 106 tx_agc[RF90_PATH_A] = 0x00000000;
109 tx_agc[RF90_PATH_B] = 0x00000000; 107 tx_agc[RF90_PATH_B] = 0x00000000;
110 } else{ 108 } else {
111 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { 109 for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
112 tx_agc[idx1] = ppowerlevel[idx1] | 110 tx_agc[idx1] = ppowerlevel[idx1] |
113 (ppowerlevel[idx1] << 8) | 111 (ppowerlevel[idx1] << 8) |
@@ -373,7 +371,12 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw,
373 regoffset == RTXAGC_B_MCS07_MCS04) 371 regoffset == RTXAGC_B_MCS07_MCS04)
374 regoffset = 0xc98; 372 regoffset = 0xc98;
375 for (i = 0; i < 3; i++) { 373 for (i = 0; i < 3; i++) {
376 writeVal = (writeVal > 6) ? (writeVal - 6) : 0; 374 if (i != 2)
375 writeVal = (writeVal > 8) ?
376 (writeVal - 8) : 0;
377 else
378 writeVal = (writeVal > 6) ?
379 (writeVal - 6) : 0;
377 rtl_write_byte(rtlpriv, (u32)(regoffset + i), 380 rtl_write_byte(rtlpriv, (u32)(regoffset + i),
378 (u8)writeVal); 381 (u8)writeVal);
379 } 382 }
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 9936de716ad5..8501954cfb44 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -50,6 +50,9 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); 51MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
52MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); 52MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
53MODULE_FIRMWARE("rtlwifi/rtl8192cufw_A.bin");
54MODULE_FIRMWARE("rtlwifi/rtl8192cufw_B.bin");
55MODULE_FIRMWARE("rtlwifi/rtl8192cufw_TMSC.bin");
53 56
54static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) 57static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
55{ 58{
@@ -69,14 +72,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
69 "Can't alloc buffer for fw\n"); 72 "Can't alloc buffer for fw\n");
70 return 1; 73 return 1;
71 } 74 }
72 75 if (IS_VENDOR_UMC_A_CUT(rtlpriv->rtlhal.version) &&
76 !IS_92C_SERIAL(rtlpriv->rtlhal.version)) {
77 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_A.bin";
78 } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlpriv->rtlhal.version)) {
79 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_B.bin";
80 } else {
81 rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cufw_TMSC.bin";
82 }
83 /* provide name of alternative file */
84 rtlpriv->cfg->alt_fw_name = "rtlwifi/rtl8192cufw.bin";
73 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); 85 pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
74 rtlpriv->max_fw_size = 0x4000; 86 rtlpriv->max_fw_size = 0x4000;
75 err = request_firmware_nowait(THIS_MODULE, 1, 87 err = request_firmware_nowait(THIS_MODULE, 1,
76 rtlpriv->cfg->fw_name, rtlpriv->io.dev, 88 rtlpriv->cfg->fw_name, rtlpriv->io.dev,
77 GFP_KERNEL, hw, rtl_fw_cb); 89 GFP_KERNEL, hw, rtl_fw_cb);
78
79
80 return err; 90 return err;
81} 91}
82 92
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
index 966be519edb8..7903c154de00 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c
@@ -36,7 +36,7 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
36 0x804, 0x00000003, 36 0x804, 0x00000003,
37 0x808, 0x0000fc00, 37 0x808, 0x0000fc00,
38 0x80c, 0x0000000a, 38 0x80c, 0x0000000a,
39 0x810, 0x10005388, 39 0x810, 0x10000330,
40 0x814, 0x020c3d10, 40 0x814, 0x020c3d10,
41 0x818, 0x02200385, 41 0x818, 0x02200385,
42 0x81c, 0x00000000, 42 0x81c, 0x00000000,
@@ -110,22 +110,22 @@ u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = {
110 0xc44, 0x000100b7, 110 0xc44, 0x000100b7,
111 0xc48, 0xec020107, 111 0xc48, 0xec020107,
112 0xc4c, 0x007f037f, 112 0xc4c, 0x007f037f,
113 0xc50, 0x6954341e, 113 0xc50, 0x69543420,
114 0xc54, 0x43bc0094, 114 0xc54, 0x43bc0094,
115 0xc58, 0x6954341e, 115 0xc58, 0x69543420,
116 0xc5c, 0x433c0094, 116 0xc5c, 0x433c0094,
117 0xc60, 0x00000000, 117 0xc60, 0x00000000,
118 0xc64, 0x5116848b, 118 0xc64, 0x5116848b,
119 0xc68, 0x47c00bff, 119 0xc68, 0x47c00bff,
120 0xc6c, 0x00000036, 120 0xc6c, 0x00000036,
121 0xc70, 0x2c7f000d, 121 0xc70, 0x2c7f000d,
122 0xc74, 0x0186115b, 122 0xc74, 0x2186115b,
123 0xc78, 0x0000001f, 123 0xc78, 0x0000001f,
124 0xc7c, 0x00b99612, 124 0xc7c, 0x00b99612,
125 0xc80, 0x40000100, 125 0xc80, 0x40000100,
126 0xc84, 0x20f60000, 126 0xc84, 0x20f60000,
127 0xc88, 0x40000100, 127 0xc88, 0x40000100,
128 0xc8c, 0x20200000, 128 0xc8c, 0xa0e40000,
129 0xc90, 0x00121820, 129 0xc90, 0x00121820,
130 0xc94, 0x00000000, 130 0xc94, 0x00000000,
131 0xc98, 0x00121820, 131 0xc98, 0x00121820,
@@ -226,7 +226,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
226 0x804, 0x00000001, 226 0x804, 0x00000001,
227 0x808, 0x0000fc00, 227 0x808, 0x0000fc00,
228 0x80c, 0x0000000a, 228 0x80c, 0x0000000a,
229 0x810, 0x10005388, 229 0x810, 0x10000330,
230 0x814, 0x020c3d10, 230 0x814, 0x020c3d10,
231 0x818, 0x02200385, 231 0x818, 0x02200385,
232 0x81c, 0x00000000, 232 0x81c, 0x00000000,
@@ -300,9 +300,9 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
300 0xc44, 0x000100b7, 300 0xc44, 0x000100b7,
301 0xc48, 0xec020107, 301 0xc48, 0xec020107,
302 0xc4c, 0x007f037f, 302 0xc4c, 0x007f037f,
303 0xc50, 0x6954341e, 303 0xc50, 0x69543420,
304 0xc54, 0x43bc0094, 304 0xc54, 0x43bc0094,
305 0xc58, 0x6954341e, 305 0xc58, 0x69543420,
306 0xc5c, 0x433c0094, 306 0xc5c, 0x433c0094,
307 0xc60, 0x00000000, 307 0xc60, 0x00000000,
308 0xc64, 0x5116848b, 308 0xc64, 0x5116848b,
@@ -340,7 +340,7 @@ u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = {
340 0xce4, 0x00000000, 340 0xce4, 0x00000000,
341 0xce8, 0x37644302, 341 0xce8, 0x37644302,
342 0xcec, 0x2f97d40c, 342 0xcec, 0x2f97d40c,
343 0xd00, 0x00080740, 343 0xd00, 0x00000740,
344 0xd04, 0x00020401, 344 0xd04, 0x00020401,
345 0xd08, 0x0000907f, 345 0xd08, 0x0000907f,
346 0xd0c, 0x20010201, 346 0xd0c, 0x20010201,
@@ -633,17 +633,17 @@ u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = {
633 0x012, 0x00071000, 633 0x012, 0x00071000,
634 0x012, 0x000b0000, 634 0x012, 0x000b0000,
635 0x012, 0x000fc000, 635 0x012, 0x000fc000,
636 0x013, 0x000287af, 636 0x013, 0x000287b3,
637 0x013, 0x000244b7, 637 0x013, 0x000244b7,
638 0x013, 0x000204ab, 638 0x013, 0x000204ab,
639 0x013, 0x0001c49f, 639 0x013, 0x0001c49f,
640 0x013, 0x00018493, 640 0x013, 0x00018493,
641 0x013, 0x00014297, 641 0x013, 0x0001429b,
642 0x013, 0x00010295, 642 0x013, 0x00010299,
643 0x013, 0x0000c298, 643 0x013, 0x0000c29c,
644 0x013, 0x0000819c, 644 0x013, 0x000081a0,
645 0x013, 0x000040a8, 645 0x013, 0x000040ac,
646 0x013, 0x0000001c, 646 0x013, 0x00000020,
647 0x014, 0x0001944c, 647 0x014, 0x0001944c,
648 0x014, 0x00059444, 648 0x014, 0x00059444,
649 0x014, 0x0009944c, 649 0x014, 0x0009944c,
@@ -932,10 +932,10 @@ u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = {
932 0x608, 0x0000000e, 932 0x608, 0x0000000e,
933 0x609, 0x0000002a, 933 0x609, 0x0000002a,
934 0x652, 0x00000020, 934 0x652, 0x00000020,
935 0x63c, 0x0000000a, 935 0x63c, 0x00000008,
936 0x63d, 0x0000000e, 936 0x63d, 0x00000008,
937 0x63e, 0x0000000a, 937 0x63e, 0x0000000c,
938 0x63f, 0x0000000e, 938 0x63f, 0x0000000c,
939 0x66e, 0x00000005, 939 0x66e, 0x00000005,
940 0x700, 0x00000021, 940 0x700, 0x00000021,
941 0x701, 0x00000043, 941 0x701, 0x00000043,
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c
index 8ed31744a054..4f083fc1d360 100644
--- a/drivers/net/wireless/rtlwifi/stats.c
+++ b/drivers/net/wireless/rtlwifi/stats.c
@@ -176,6 +176,7 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
176 struct rtl_sta_info *drv_priv = NULL; 176 struct rtl_sta_info *drv_priv = NULL;
177 struct ieee80211_sta *sta = NULL; 177 struct ieee80211_sta *sta = NULL;
178 long undec_sm_pwdb; 178 long undec_sm_pwdb;
179 long undec_sm_cck;
179 180
180 rcu_read_lock(); 181 rcu_read_lock();
181 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) 182 if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
@@ -185,12 +186,16 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
185 if (sta) { 186 if (sta) {
186 drv_priv = (struct rtl_sta_info *) sta->drv_priv; 187 drv_priv = (struct rtl_sta_info *) sta->drv_priv;
187 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; 188 undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb;
189 undec_sm_cck = drv_priv->rssi_stat.undec_sm_cck;
188 } else { 190 } else {
189 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; 191 undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
192 undec_sm_cck = rtlpriv->dm.undec_sm_cck;
190 } 193 }
191 194
192 if (undec_sm_pwdb < 0) 195 if (undec_sm_pwdb < 0)
193 undec_sm_pwdb = pstatus->rx_pwdb_all; 196 undec_sm_pwdb = pstatus->rx_pwdb_all;
197 if (undec_sm_cck < 0)
198 undec_sm_cck = pstatus->rx_pwdb_all;
194 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { 199 if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) {
195 undec_sm_pwdb = (((undec_sm_pwdb) * 200 undec_sm_pwdb = (((undec_sm_pwdb) *
196 (RX_SMOOTH_FACTOR - 1)) + 201 (RX_SMOOTH_FACTOR - 1)) +
@@ -200,6 +205,15 @@ static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus)
200 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + 205 undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) +
201 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); 206 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
202 } 207 }
208 if (pstatus->rx_pwdb_all > (u32) undec_sm_cck) {
209 undec_sm_cck = (((undec_sm_pwdb) *
210 (RX_SMOOTH_FACTOR - 1)) +
211 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
212 undec_sm_cck = undec_sm_cck + 1;
213 } else {
214 undec_sm_pwdb = (((undec_sm_cck) * (RX_SMOOTH_FACTOR - 1)) +
215 (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
216 }
203 217
204 if (sta) { 218 if (sta) {
205 drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; 219 drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb;
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 6e2b5c5c83c8..4933f02ce1d5 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -475,14 +475,14 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw,
475 rtlpriv->stats.rxbytesunicast += skb->len; 475 rtlpriv->stats.rxbytesunicast += skb->len;
476 } 476 }
477 477
478 rtl_is_special_data(hw, skb, false);
479
480 if (ieee80211_is_data(fc)) { 478 if (ieee80211_is_data(fc)) {
481 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 479 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
482 480
483 if (unicast) 481 if (unicast)
484 rtlpriv->link_info.num_rx_inperiod++; 482 rtlpriv->link_info.num_rx_inperiod++;
485 } 483 }
484 /* static bcn for roaming */
485 rtl_beacon_statistic(hw, skb);
486 } 486 }
487} 487}
488 488
@@ -517,8 +517,6 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw,
517 rtlpriv->stats.rxbytesunicast += skb->len; 517 rtlpriv->stats.rxbytesunicast += skb->len;
518 } 518 }
519 519
520 rtl_is_special_data(hw, skb, false);
521
522 if (ieee80211_is_data(fc)) { 520 if (ieee80211_is_data(fc)) {
523 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); 521 rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX);
524 522
@@ -553,7 +551,7 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
553 } 551 }
554} 552}
555 553
556#define __RX_SKB_MAX_QUEUED 32 554#define __RX_SKB_MAX_QUEUED 64
557 555
558static void _rtl_rx_work(unsigned long param) 556static void _rtl_rx_work(unsigned long param)
559{ 557{
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 0c65386fa30d..8c647391bedf 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -1033,6 +1033,7 @@ struct rtl_ht_agg {
1033 1033
1034struct rssi_sta { 1034struct rssi_sta {
1035 long undec_sm_pwdb; 1035 long undec_sm_pwdb;
1036 long undec_sm_cck;
1036}; 1037};
1037 1038
1038struct rtl_tid_data { 1039struct rtl_tid_data {
@@ -1323,8 +1324,10 @@ struct fast_ant_training {
1323struct rtl_dm { 1324struct rtl_dm {
1324 /*PHY status for Dynamic Management */ 1325 /*PHY status for Dynamic Management */
1325 long entry_min_undec_sm_pwdb; 1326 long entry_min_undec_sm_pwdb;
1327 long undec_sm_cck;
1326 long undec_sm_pwdb; /*out dm */ 1328 long undec_sm_pwdb; /*out dm */
1327 long entry_max_undec_sm_pwdb; 1329 long entry_max_undec_sm_pwdb;
1330 s32 ofdm_pkt_cnt;
1328 bool dm_initialgain_enable; 1331 bool dm_initialgain_enable;
1329 bool dynamic_txpower_enable; 1332 bool dynamic_txpower_enable;
1330 bool current_turbo_edca; 1333 bool current_turbo_edca;
@@ -1339,6 +1342,7 @@ struct rtl_dm {
1339 bool inform_fw_driverctrldm; 1342 bool inform_fw_driverctrldm;
1340 bool current_mrc_switch; 1343 bool current_mrc_switch;
1341 u8 txpowercount; 1344 u8 txpowercount;
1345 u8 powerindex_backup[6];
1342 1346
1343 u8 thermalvalue_rxgain; 1347 u8 thermalvalue_rxgain;
1344 u8 thermalvalue_iqk; 1348 u8 thermalvalue_iqk;
@@ -1350,7 +1354,9 @@ struct rtl_dm {
1350 bool done_txpower; 1354 bool done_txpower;
1351 u8 dynamic_txhighpower_lvl; /*Tx high power level */ 1355 u8 dynamic_txhighpower_lvl; /*Tx high power level */
1352 u8 dm_flag; /*Indicate each dynamic mechanism's status. */ 1356 u8 dm_flag; /*Indicate each dynamic mechanism's status. */
1357 u8 dm_flag_tmp;
1353 u8 dm_type; 1358 u8 dm_type;
1359 u8 dm_rssi_sel;
1354 u8 txpower_track_control; 1360 u8 txpower_track_control;
1355 bool interrupt_migration; 1361 bool interrupt_migration;
1356 bool disable_tx_int; 1362 bool disable_tx_int;
@@ -1804,6 +1810,7 @@ struct rtl_hal_cfg {
1804 bool write_readback; 1810 bool write_readback;
1805 char *name; 1811 char *name;
1806 char *fw_name; 1812 char *fw_name;
1813 char *alt_fw_name;
1807 struct rtl_hal_ops *ops; 1814 struct rtl_hal_ops *ops;
1808 struct rtl_mod_params *mod_params; 1815 struct rtl_mod_params *mod_params;
1809 struct rtl_hal_usbint_cfg *usb_interface_cfg; 1816 struct rtl_hal_usbint_cfg *usb_interface_cfg;
@@ -1948,6 +1955,7 @@ struct dig_t {
1948 u8 pre_ccastate; 1955 u8 pre_ccastate;
1949 u8 cur_ccasate; 1956 u8 cur_ccasate;
1950 u8 large_fa_hit; 1957 u8 large_fa_hit;
1958 u8 dig_dynamic_min;
1951 u8 forbidden_igi; 1959 u8 forbidden_igi;
1952 u8 dig_state; 1960 u8 dig_state;
1953 u8 dig_highpwrstate; 1961 u8 dig_highpwrstate;
@@ -2028,22 +2036,15 @@ struct rtl_priv {
2028 struct dig_t dm_digtable; 2036 struct dig_t dm_digtable;
2029 struct ps_t dm_pstable; 2037 struct ps_t dm_pstable;
2030 2038
2031 /* section shared by individual drivers */ 2039 u32 reg_874;
2032 union { 2040 u32 reg_c70;
2033 struct { /* data buffer pointer for USB reads */ 2041 u32 reg_85c;
2034 __le32 *usb_data; 2042 u32 reg_a74;
2035 int usb_data_index; 2043 bool reg_init; /* true if regs saved */
2036 bool initialized; 2044 bool bt_operation_on;
2037 }; 2045 __le32 *usb_data;
2038 struct { /* section for 8723ae */ 2046 int usb_data_index;
2039 bool reg_init; /* true if regs saved */ 2047 bool initialized;
2040 u32 reg_874;
2041 u32 reg_c70;
2042 u32 reg_85c;
2043 u32 reg_a74;
2044 bool bt_operation_on;
2045 };
2046 };
2047 bool enter_ps; /* true when entering PS */ 2048 bool enter_ps; /* true when entering PS */
2048 u8 rate_mask[5]; 2049 u8 rate_mask[5];
2049 2050
diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c
index db6430c1a084..374268d5ac6a 100644
--- a/drivers/net/wireless/ti/wl1251/acx.c
+++ b/drivers/net/wireless/ti/wl1251/acx.c
@@ -18,10 +18,8 @@ int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod,
18 wl1251_debug(DEBUG_ACX, "acx frame rates"); 18 wl1251_debug(DEBUG_ACX, "acx frame rates");
19 19
20 rates = kzalloc(sizeof(*rates), GFP_KERNEL); 20 rates = kzalloc(sizeof(*rates), GFP_KERNEL);
21 if (!rates) { 21 if (!rates)
22 ret = -ENOMEM; 22 return -ENOMEM;
23 goto out;
24 }
25 23
26 rates->tx_ctrl_frame_rate = ctrl_rate; 24 rates->tx_ctrl_frame_rate = ctrl_rate;
27 rates->tx_ctrl_frame_mod = ctrl_mod; 25 rates->tx_ctrl_frame_mod = ctrl_mod;
@@ -49,10 +47,8 @@ int wl1251_acx_station_id(struct wl1251 *wl)
49 wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); 47 wl1251_debug(DEBUG_ACX, "acx dot11_station_id");
50 48
51 mac = kzalloc(sizeof(*mac), GFP_KERNEL); 49 mac = kzalloc(sizeof(*mac), GFP_KERNEL);
52 if (!mac) { 50 if (!mac)
53 ret = -ENOMEM; 51 return -ENOMEM;
54 goto out;
55 }
56 52
57 for (i = 0; i < ETH_ALEN; i++) 53 for (i = 0; i < ETH_ALEN; i++)
58 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; 54 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
@@ -74,10 +70,8 @@ int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
74 wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); 70 wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
75 71
76 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); 72 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
77 if (!default_key) { 73 if (!default_key)
78 ret = -ENOMEM; 74 return -ENOMEM;
79 goto out;
80 }
81 75
82 default_key->id = key_id; 76 default_key->id = key_id;
83 77
@@ -104,10 +98,8 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event,
104 wl1251_debug(DEBUG_ACX, "acx wake up conditions"); 98 wl1251_debug(DEBUG_ACX, "acx wake up conditions");
105 99
106 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); 100 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
107 if (!wake_up) { 101 if (!wake_up)
108 ret = -ENOMEM; 102 return -ENOMEM;
109 goto out;
110 }
111 103
112 wake_up->wake_up_event = wake_up_event; 104 wake_up->wake_up_event = wake_up_event;
113 wake_up->listen_interval = listen_interval; 105 wake_up->listen_interval = listen_interval;
@@ -132,16 +124,13 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth)
132 wl1251_debug(DEBUG_ACX, "acx sleep auth"); 124 wl1251_debug(DEBUG_ACX, "acx sleep auth");
133 125
134 auth = kzalloc(sizeof(*auth), GFP_KERNEL); 126 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
135 if (!auth) { 127 if (!auth)
136 ret = -ENOMEM; 128 return -ENOMEM;
137 goto out;
138 }
139 129
140 auth->sleep_auth = sleep_auth; 130 auth->sleep_auth = sleep_auth;
141 131
142 ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); 132 ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
143 133
144out:
145 kfree(auth); 134 kfree(auth);
146 return ret; 135 return ret;
147} 136}
@@ -154,10 +143,8 @@ int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
154 wl1251_debug(DEBUG_ACX, "acx fw rev"); 143 wl1251_debug(DEBUG_ACX, "acx fw rev");
155 144
156 rev = kzalloc(sizeof(*rev), GFP_KERNEL); 145 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
157 if (!rev) { 146 if (!rev)
158 ret = -ENOMEM; 147 return -ENOMEM;
159 goto out;
160 }
161 148
162 ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); 149 ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
163 if (ret < 0) { 150 if (ret < 0) {
@@ -191,10 +178,8 @@ int wl1251_acx_tx_power(struct wl1251 *wl, int power)
191 return -EINVAL; 178 return -EINVAL;
192 179
193 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 180 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
194 if (!acx) { 181 if (!acx)
195 ret = -ENOMEM; 182 return -ENOMEM;
196 goto out;
197 }
198 183
199 acx->current_tx_power = power * 10; 184 acx->current_tx_power = power * 10;
200 185
@@ -217,10 +202,8 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl)
217 wl1251_debug(DEBUG_ACX, "acx feature cfg"); 202 wl1251_debug(DEBUG_ACX, "acx feature cfg");
218 203
219 feature = kzalloc(sizeof(*feature), GFP_KERNEL); 204 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
220 if (!feature) { 205 if (!feature)
221 ret = -ENOMEM; 206 return -ENOMEM;
222 goto out;
223 }
224 207
225 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 208 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
226 feature->data_flow_options = 0; 209 feature->data_flow_options = 0;
@@ -261,10 +244,8 @@ int wl1251_acx_data_path_params(struct wl1251 *wl,
261 wl1251_debug(DEBUG_ACX, "acx data path params"); 244 wl1251_debug(DEBUG_ACX, "acx data path params");
262 245
263 params = kzalloc(sizeof(*params), GFP_KERNEL); 246 params = kzalloc(sizeof(*params), GFP_KERNEL);
264 if (!params) { 247 if (!params)
265 ret = -ENOMEM; 248 return -ENOMEM;
266 goto out;
267 }
268 249
269 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; 250 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
270 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; 251 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
@@ -309,10 +290,8 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time)
309 wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); 290 wl1251_debug(DEBUG_ACX, "acx rx msdu life time");
310 291
311 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 292 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
312 if (!acx) { 293 if (!acx)
313 ret = -ENOMEM; 294 return -ENOMEM;
314 goto out;
315 }
316 295
317 acx->lifetime = life_time; 296 acx->lifetime = life_time;
318 ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME, 297 ret = wl1251_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
@@ -335,10 +314,8 @@ int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter)
335 wl1251_debug(DEBUG_ACX, "acx rx config"); 314 wl1251_debug(DEBUG_ACX, "acx rx config");
336 315
337 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); 316 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
338 if (!rx_config) { 317 if (!rx_config)
339 ret = -ENOMEM; 318 return -ENOMEM;
340 goto out;
341 }
342 319
343 rx_config->config_options = config; 320 rx_config->config_options = config;
344 rx_config->filter_options = filter; 321 rx_config->filter_options = filter;
@@ -363,10 +340,8 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl)
363 wl1251_debug(DEBUG_ACX, "acx data pd threshold"); 340 wl1251_debug(DEBUG_ACX, "acx data pd threshold");
364 341
365 pd = kzalloc(sizeof(*pd), GFP_KERNEL); 342 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
366 if (!pd) { 343 if (!pd)
367 ret = -ENOMEM; 344 return -ENOMEM;
368 goto out;
369 }
370 345
371 /* FIXME: threshold value not set */ 346 /* FIXME: threshold value not set */
372 347
@@ -389,10 +364,8 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time)
389 wl1251_debug(DEBUG_ACX, "acx slot"); 364 wl1251_debug(DEBUG_ACX, "acx slot");
390 365
391 slot = kzalloc(sizeof(*slot), GFP_KERNEL); 366 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
392 if (!slot) { 367 if (!slot)
393 ret = -ENOMEM; 368 return -ENOMEM;
394 goto out;
395 }
396 369
397 slot->wone_index = STATION_WONE_INDEX; 370 slot->wone_index = STATION_WONE_INDEX;
398 slot->slot_time = slot_time; 371 slot->slot_time = slot_time;
@@ -416,10 +389,8 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl)
416 wl1251_debug(DEBUG_ACX, "acx group address tbl"); 389 wl1251_debug(DEBUG_ACX, "acx group address tbl");
417 390
418 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 391 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
419 if (!acx) { 392 if (!acx)
420 ret = -ENOMEM; 393 return -ENOMEM;
421 goto out;
422 }
423 394
424 /* MAC filtering */ 395 /* MAC filtering */
425 acx->enabled = 0; 396 acx->enabled = 0;
@@ -444,10 +415,8 @@ int wl1251_acx_service_period_timeout(struct wl1251 *wl)
444 int ret; 415 int ret;
445 416
446 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); 417 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
447 if (!rx_timeout) { 418 if (!rx_timeout)
448 ret = -ENOMEM; 419 return -ENOMEM;
449 goto out;
450 }
451 420
452 wl1251_debug(DEBUG_ACX, "acx service period timeout"); 421 wl1251_debug(DEBUG_ACX, "acx service period timeout");
453 422
@@ -475,10 +444,8 @@ int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold)
475 wl1251_debug(DEBUG_ACX, "acx rts threshold"); 444 wl1251_debug(DEBUG_ACX, "acx rts threshold");
476 445
477 rts = kzalloc(sizeof(*rts), GFP_KERNEL); 446 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
478 if (!rts) { 447 if (!rts)
479 ret = -ENOMEM; 448 return -ENOMEM;
480 goto out;
481 }
482 449
483 rts->threshold = rts_threshold; 450 rts->threshold = rts_threshold;
484 451
@@ -501,10 +468,8 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter)
501 wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); 468 wl1251_debug(DEBUG_ACX, "acx beacon filter opt");
502 469
503 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); 470 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
504 if (!beacon_filter) { 471 if (!beacon_filter)
505 ret = -ENOMEM; 472 return -ENOMEM;
506 goto out;
507 }
508 473
509 beacon_filter->enable = enable_filter; 474 beacon_filter->enable = enable_filter;
510 beacon_filter->max_num_beacons = 0; 475 beacon_filter->max_num_beacons = 0;
@@ -530,10 +495,8 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl)
530 wl1251_debug(DEBUG_ACX, "acx beacon filter table"); 495 wl1251_debug(DEBUG_ACX, "acx beacon filter table");
531 496
532 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); 497 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
533 if (!ie_table) { 498 if (!ie_table)
534 ret = -ENOMEM; 499 return -ENOMEM;
535 goto out;
536 }
537 500
538 /* configure default beacon pass-through rules */ 501 /* configure default beacon pass-through rules */
539 ie_table->num_ie = 1; 502 ie_table->num_ie = 1;
@@ -560,10 +523,8 @@ int wl1251_acx_conn_monit_params(struct wl1251 *wl)
560 wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); 523 wl1251_debug(DEBUG_ACX, "acx connection monitor parameters");
561 524
562 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 525 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
563 if (!acx) { 526 if (!acx)
564 ret = -ENOMEM; 527 return -ENOMEM;
565 goto out;
566 }
567 528
568 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD; 529 acx->synch_fail_thold = SYNCH_FAIL_DEFAULT_THRESHOLD;
569 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT; 530 acx->bss_lose_timeout = NO_BEACON_DEFAULT_TIMEOUT;
@@ -589,10 +550,8 @@ int wl1251_acx_sg_enable(struct wl1251 *wl)
589 wl1251_debug(DEBUG_ACX, "acx sg enable"); 550 wl1251_debug(DEBUG_ACX, "acx sg enable");
590 551
591 pta = kzalloc(sizeof(*pta), GFP_KERNEL); 552 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
592 if (!pta) { 553 if (!pta)
593 ret = -ENOMEM; 554 return -ENOMEM;
594 goto out;
595 }
596 555
597 pta->enable = SG_ENABLE; 556 pta->enable = SG_ENABLE;
598 557
@@ -615,10 +574,8 @@ int wl1251_acx_sg_cfg(struct wl1251 *wl)
615 wl1251_debug(DEBUG_ACX, "acx sg cfg"); 574 wl1251_debug(DEBUG_ACX, "acx sg cfg");
616 575
617 param = kzalloc(sizeof(*param), GFP_KERNEL); 576 param = kzalloc(sizeof(*param), GFP_KERNEL);
618 if (!param) { 577 if (!param)
619 ret = -ENOMEM; 578 return -ENOMEM;
620 goto out;
621 }
622 579
623 /* BT-WLAN coext parameters */ 580 /* BT-WLAN coext parameters */
624 param->min_rate = RATE_INDEX_24MBPS; 581 param->min_rate = RATE_INDEX_24MBPS;
@@ -669,10 +626,8 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
669 wl1251_debug(DEBUG_ACX, "acx cca threshold"); 626 wl1251_debug(DEBUG_ACX, "acx cca threshold");
670 627
671 detection = kzalloc(sizeof(*detection), GFP_KERNEL); 628 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
672 if (!detection) { 629 if (!detection)
673 ret = -ENOMEM; 630 return -ENOMEM;
674 goto out;
675 }
676 631
677 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 632 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
678 detection->tx_energy_detection = 0; 633 detection->tx_energy_detection = 0;
@@ -682,7 +637,6 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl)
682 if (ret < 0) 637 if (ret < 0)
683 wl1251_warning("failed to set cca threshold: %d", ret); 638 wl1251_warning("failed to set cca threshold: %d", ret);
684 639
685out:
686 kfree(detection); 640 kfree(detection);
687 return ret; 641 return ret;
688} 642}
@@ -695,10 +649,8 @@ int wl1251_acx_bcn_dtim_options(struct wl1251 *wl)
695 wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); 649 wl1251_debug(DEBUG_ACX, "acx bcn dtim options");
696 650
697 bb = kzalloc(sizeof(*bb), GFP_KERNEL); 651 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
698 if (!bb) { 652 if (!bb)
699 ret = -ENOMEM; 653 return -ENOMEM;
700 goto out;
701 }
702 654
703 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 655 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
704 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; 656 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
@@ -724,10 +676,8 @@ int wl1251_acx_aid(struct wl1251 *wl, u16 aid)
724 wl1251_debug(DEBUG_ACX, "acx aid"); 676 wl1251_debug(DEBUG_ACX, "acx aid");
725 677
726 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); 678 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
727 if (!acx_aid) { 679 if (!acx_aid)
728 ret = -ENOMEM; 680 return -ENOMEM;
729 goto out;
730 }
731 681
732 acx_aid->aid = aid; 682 acx_aid->aid = aid;
733 683
@@ -750,10 +700,8 @@ int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask)
750 wl1251_debug(DEBUG_ACX, "acx event mbox mask"); 700 wl1251_debug(DEBUG_ACX, "acx event mbox mask");
751 701
752 mask = kzalloc(sizeof(*mask), GFP_KERNEL); 702 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
753 if (!mask) { 703 if (!mask)
754 ret = -ENOMEM; 704 return -ENOMEM;
755 goto out;
756 }
757 705
758 /* high event mask is unused */ 706 /* high event mask is unused */
759 mask->high_event_mask = 0xffffffff; 707 mask->high_event_mask = 0xffffffff;
@@ -805,10 +753,8 @@ int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble)
805 wl1251_debug(DEBUG_ACX, "acx_set_preamble"); 753 wl1251_debug(DEBUG_ACX, "acx_set_preamble");
806 754
807 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 755 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
808 if (!acx) { 756 if (!acx)
809 ret = -ENOMEM; 757 return -ENOMEM;
810 goto out;
811 }
812 758
813 acx->preamble = preamble; 759 acx->preamble = preamble;
814 760
@@ -832,10 +778,8 @@ int wl1251_acx_cts_protect(struct wl1251 *wl,
832 wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); 778 wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect");
833 779
834 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 780 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
835 if (!acx) { 781 if (!acx)
836 ret = -ENOMEM; 782 return -ENOMEM;
837 goto out;
838 }
839 783
840 acx->ctsprotect = ctsprotect; 784 acx->ctsprotect = ctsprotect;
841 785
@@ -856,10 +800,8 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
856 int ret; 800 int ret;
857 801
858 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); 802 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
859 if (!tsf_info) { 803 if (!tsf_info)
860 ret = -ENOMEM; 804 return -ENOMEM;
861 goto out;
862 }
863 805
864 ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO, 806 ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
865 tsf_info, sizeof(*tsf_info)); 807 tsf_info, sizeof(*tsf_info));
@@ -900,11 +842,8 @@ int wl1251_acx_rate_policies(struct wl1251 *wl)
900 wl1251_debug(DEBUG_ACX, "acx rate policies"); 842 wl1251_debug(DEBUG_ACX, "acx rate policies");
901 843
902 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 844 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
903 845 if (!acx)
904 if (!acx) { 846 return -ENOMEM;
905 ret = -ENOMEM;
906 goto out;
907 }
908 847
909 /* configure one default (one-size-fits-all) rate class */ 848 /* configure one default (one-size-fits-all) rate class */
910 acx->rate_class_cnt = 1; 849 acx->rate_class_cnt = 1;
@@ -932,10 +871,8 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl)
932 wl1251_debug(DEBUG_ACX, "acx mem cfg"); 871 wl1251_debug(DEBUG_ACX, "acx mem cfg");
933 872
934 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); 873 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
935 if (!mem_conf) { 874 if (!mem_conf)
936 ret = -ENOMEM; 875 return -ENOMEM;
937 goto out;
938 }
939 876
940 /* memory config */ 877 /* memory config */
941 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); 878 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
@@ -979,10 +916,8 @@ int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim)
979 wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); 916 wl1251_debug(DEBUG_ACX, "acx tbtt and dtim");
980 917
981 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 918 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
982 if (!acx) { 919 if (!acx)
983 ret = -ENOMEM; 920 return -ENOMEM;
984 goto out;
985 }
986 921
987 acx->tbtt = tbtt; 922 acx->tbtt = tbtt;
988 acx->dtim = dtim; 923 acx->dtim = dtim;
@@ -1008,10 +943,8 @@ int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode,
1008 wl1251_debug(DEBUG_ACX, "acx bet enable"); 943 wl1251_debug(DEBUG_ACX, "acx bet enable");
1009 944
1010 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 945 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1011 if (!acx) { 946 if (!acx)
1012 ret = -ENOMEM; 947 return -ENOMEM;
1013 goto out;
1014 }
1015 948
1016 acx->enable = mode; 949 acx->enable = mode;
1017 acx->max_consecutive = max_consecutive; 950 acx->max_consecutive = max_consecutive;
@@ -1037,11 +970,8 @@ int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max,
1037 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); 970 "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop);
1038 971
1039 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 972 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1040 973 if (!acx)
1041 if (!acx) { 974 return -ENOMEM;
1042 ret = -ENOMEM;
1043 goto out;
1044 }
1045 975
1046 acx->ac = ac; 976 acx->ac = ac;
1047 acx->cw_min = cw_min; 977 acx->cw_min = cw_min;
@@ -1073,11 +1003,8 @@ int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue,
1073 ps_scheme, ack_policy); 1003 ps_scheme, ack_policy);
1074 1004
1075 acx = kzalloc(sizeof(*acx), GFP_KERNEL); 1005 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
1076 1006 if (!acx)
1077 if (!acx) { 1007 return -ENOMEM;
1078 ret = -ENOMEM;
1079 goto out;
1080 }
1081 1008
1082 acx->queue = queue; 1009 acx->queue = queue;
1083 acx->type = type; 1010 acx->type = type;
diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c
index 4a0bbb13806b..7541bd1a4a4b 100644
--- a/drivers/net/wireless/ti/wl12xx/scan.c
+++ b/drivers/net/wireless/ti/wl12xx/scan.c
@@ -47,7 +47,7 @@ static int wl1271_get_scan_channels(struct wl1271 *wl,
47 * In active scans, we only scan channels not 47 * In active scans, we only scan channels not
48 * marked as passive. 48 * marked as passive.
49 */ 49 */
50 (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { 50 (passive || !(flags & IEEE80211_CHAN_NO_IR))) {
51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", 51 wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
52 req->channels[i]->band, 52 req->channels[i]->band,
53 req->channels[i]->center_freq); 53 req->channels[i]->center_freq);
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index 34d9dfff2ad3..9b2ecf52449f 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1688,7 +1688,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
1688 1688
1689 if (channel->flags & (IEEE80211_CHAN_DISABLED | 1689 if (channel->flags & (IEEE80211_CHAN_DISABLED |
1690 IEEE80211_CHAN_RADAR | 1690 IEEE80211_CHAN_RADAR |
1691 IEEE80211_CHAN_PASSIVE_SCAN)) 1691 IEEE80211_CHAN_NO_IR))
1692 continue; 1692 continue;
1693 1693
1694 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch); 1694 ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch);
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 0368b9cbfb89..e9da47cead58 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -91,8 +91,7 @@ static void wl1271_reg_notify(struct wiphy *wiphy,
91 continue; 91 continue;
92 92
93 if (ch->flags & IEEE80211_CHAN_RADAR) 93 if (ch->flags & IEEE80211_CHAN_RADAR)
94 ch->flags |= IEEE80211_CHAN_NO_IBSS | 94 ch->flags |= IEEE80211_CHAN_NO_IR;
95 IEEE80211_CHAN_PASSIVE_SCAN;
96 95
97 } 96 }
98 97
diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c
index 7ed86203304b..1e3d51cd673a 100644
--- a/drivers/net/wireless/ti/wlcore/scan.c
+++ b/drivers/net/wireless/ti/wlcore/scan.c
@@ -188,16 +188,14 @@ wlcore_scan_get_channels(struct wl1271 *wl,
188 flags = req_channels[i]->flags; 188 flags = req_channels[i]->flags;
189 189
190 if (force_passive) 190 if (force_passive)
191 flags |= IEEE80211_CHAN_PASSIVE_SCAN; 191 flags |= IEEE80211_CHAN_NO_IR;
192 192
193 if ((req_channels[i]->band == band) && 193 if ((req_channels[i]->band == band) &&
194 !(flags & IEEE80211_CHAN_DISABLED) && 194 !(flags & IEEE80211_CHAN_DISABLED) &&
195 (!!(flags & IEEE80211_CHAN_RADAR) == radar) && 195 (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
196 /* if radar is set, we ignore the passive flag */ 196 /* if radar is set, we ignore the passive flag */
197 (radar || 197 (radar ||
198 !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { 198 !!(flags & IEEE80211_CHAN_NO_IR) == passive)) {
199
200
201 if (flags & IEEE80211_CHAN_RADAR) { 199 if (flags & IEEE80211_CHAN_RADAR) {
202 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; 200 channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
203 201
@@ -220,7 +218,7 @@ wlcore_scan_get_channels(struct wl1271 *wl,
220 (band == IEEE80211_BAND_2GHZ) && 218 (band == IEEE80211_BAND_2GHZ) &&
221 (channels[j].channel >= 12) && 219 (channels[j].channel >= 12) &&
222 (channels[j].channel <= 14) && 220 (channels[j].channel <= 14) &&
223 (flags & IEEE80211_CHAN_PASSIVE_SCAN) && 221 (flags & IEEE80211_CHAN_NO_IR) &&
224 !force_passive) { 222 !force_passive) {
225 /* pactive channels treated as DFS */ 223 /* pactive channels treated as DFS */
226 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; 224 channels[j].flags = SCAN_CHANNEL_FLAGS_DFS;
@@ -243,8 +241,8 @@ wlcore_scan_get_channels(struct wl1271 *wl,
243 max_dwell_time_active, 241 max_dwell_time_active,
244 flags & IEEE80211_CHAN_RADAR ? 242 flags & IEEE80211_CHAN_RADAR ?
245 ", DFS" : "", 243 ", DFS" : "",
246 flags & IEEE80211_CHAN_PASSIVE_SCAN ? 244 flags & IEEE80211_CHAN_NO_IR ?
247 ", PASSIVE" : ""); 245 ", NO-IR" : "");
248 j++; 246 j++;
249 } 247 }
250 } 248 }
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 8c3b26a21574..776cbb80d098 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1411,8 +1411,12 @@ struct ieee80211_vht_operation {
1411#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 1411#define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700
1412#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 1412#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800
1413#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 1413#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000
1414#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX 0x0000e000 1414#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13
1415#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX 0x00070000 1415#define IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK \
1416 (7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)
1417#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT 16
1418#define IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK \
1419 (7 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT)
1416#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 1420#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000
1417#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 1421#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000
1418#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 1422#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3eae46cb1acf..e9abc7b536cd 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -91,9 +91,8 @@ enum ieee80211_band {
91 * Channel flags set by the regulatory control code. 91 * Channel flags set by the regulatory control code.
92 * 92 *
93 * @IEEE80211_CHAN_DISABLED: This channel is disabled. 93 * @IEEE80211_CHAN_DISABLED: This channel is disabled.
94 * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted 94 * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes
95 * on this channel. 95 * sending probe requests or beaconing.
96 * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
97 * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. 96 * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
98 * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel 97 * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
99 * is not permitted. 98 * is not permitted.
@@ -113,8 +112,8 @@ enum ieee80211_band {
113 */ 112 */
114enum ieee80211_channel_flags { 113enum ieee80211_channel_flags {
115 IEEE80211_CHAN_DISABLED = 1<<0, 114 IEEE80211_CHAN_DISABLED = 1<<0,
116 IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, 115 IEEE80211_CHAN_NO_IR = 1<<1,
117 IEEE80211_CHAN_NO_IBSS = 1<<2, 116 /* hole at 1<<2 */
118 IEEE80211_CHAN_RADAR = 1<<3, 117 IEEE80211_CHAN_RADAR = 1<<3,
119 IEEE80211_CHAN_NO_HT40PLUS = 1<<4, 118 IEEE80211_CHAN_NO_HT40PLUS = 1<<4,
120 IEEE80211_CHAN_NO_HT40MINUS = 1<<5, 119 IEEE80211_CHAN_NO_HT40MINUS = 1<<5,
@@ -1945,6 +1944,29 @@ struct cfg80211_update_ft_ies_params {
1945}; 1944};
1946 1945
1947/** 1946/**
1947 * struct cfg80211_mgmt_tx_params - mgmt tx parameters
1948 *
1949 * This structure provides information needed to transmit a mgmt frame
1950 *
1951 * @chan: channel to use
1952 * @offchan: indicates wether off channel operation is required
1953 * @wait: duration for ROC
1954 * @buf: buffer to transmit
1955 * @len: buffer length
1956 * @no_cck: don't use cck rates for this frame
1957 * @dont_wait_for_ack: tells the low level not to wait for an ack
1958 */
1959struct cfg80211_mgmt_tx_params {
1960 struct ieee80211_channel *chan;
1961 bool offchan;
1962 unsigned int wait;
1963 const u8 *buf;
1964 size_t len;
1965 bool no_cck;
1966 bool dont_wait_for_ack;
1967};
1968
1969/**
1948 * struct cfg80211_ops - backend description for wireless configuration 1970 * struct cfg80211_ops - backend description for wireless configuration
1949 * 1971 *
1950 * This struct is registered by fullmac card drivers and/or wireless stacks 1972 * This struct is registered by fullmac card drivers and/or wireless stacks
@@ -2342,9 +2364,8 @@ struct cfg80211_ops {
2342 u64 cookie); 2364 u64 cookie);
2343 2365
2344 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, 2366 int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
2345 struct ieee80211_channel *chan, bool offchan, 2367 struct cfg80211_mgmt_tx_params *params,
2346 unsigned int wait, const u8 *buf, size_t len, 2368 u64 *cookie);
2347 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
2348 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, 2369 int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
2349 struct wireless_dev *wdev, 2370 struct wireless_dev *wdev,
2350 u64 cookie); 2371 u64 cookie);
@@ -2438,27 +2459,6 @@ struct cfg80211_ops {
2438/** 2459/**
2439 * enum wiphy_flags - wiphy capability flags 2460 * enum wiphy_flags - wiphy capability flags
2440 * 2461 *
2441 * @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device
2442 * has its own custom regulatory domain and cannot identify the
2443 * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
2444 * we will disregard the first regulatory hint (when the
2445 * initiator is %REGDOM_SET_BY_CORE).
2446 * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will
2447 * ignore regulatory domain settings until it gets its own regulatory
2448 * domain via its regulatory_hint() unless the regulatory hint is
2449 * from a country IE. After its gets its own regulatory domain it will
2450 * only allow further regulatory domain settings to further enhance
2451 * compliance. For example if channel 13 and 14 are disabled by this
2452 * regulatory domain no user regulatory domain can enable these channels
2453 * at a later time. This can be used for devices which do not have
2454 * calibration information guaranteed for frequencies or settings
2455 * outside of its regulatory domain. If used in combination with
2456 * WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings
2457 * will be followed.
2458 * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure
2459 * that passive scan flags and beaconing flags may not be lifted by
2460 * cfg80211 due to regulatory beacon hints. For more information on beacon
2461 * hints read the documenation for regulatory_hint_found_beacon()
2462 * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this 2462 * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this
2463 * wiphy at all 2463 * wiphy at all
2464 * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled 2464 * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled
@@ -2497,9 +2497,9 @@ struct cfg80211_ops {
2497 * beaconing mode (AP, IBSS, Mesh, ...). 2497 * beaconing mode (AP, IBSS, Mesh, ...).
2498 */ 2498 */
2499enum wiphy_flags { 2499enum wiphy_flags {
2500 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 2500 /* use hole at 0 */
2501 WIPHY_FLAG_STRICT_REGULATORY = BIT(1), 2501 /* use hole at 1 */
2502 WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), 2502 /* use hole at 2 */
2503 WIPHY_FLAG_NETNS_OK = BIT(3), 2503 WIPHY_FLAG_NETNS_OK = BIT(3),
2504 WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), 2504 WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4),
2505 WIPHY_FLAG_4ADDR_AP = BIT(5), 2505 WIPHY_FLAG_4ADDR_AP = BIT(5),
@@ -2721,6 +2721,8 @@ struct wiphy_coalesce_support {
2721 * @software_iftypes: bitmask of software interface types, these are not 2721 * @software_iftypes: bitmask of software interface types, these are not
2722 * subject to any restrictions since they are purely managed in SW. 2722 * subject to any restrictions since they are purely managed in SW.
2723 * @flags: wiphy flags, see &enum wiphy_flags 2723 * @flags: wiphy flags, see &enum wiphy_flags
2724 * @regulatory_flags: wiphy regulatory flags, see
2725 * &enum ieee80211_regulatory_flags
2724 * @features: features advertised to nl80211, see &enum nl80211_feature_flags. 2726 * @features: features advertised to nl80211, see &enum nl80211_feature_flags.
2725 * @bss_priv_size: each BSS struct has private data allocated with it, 2727 * @bss_priv_size: each BSS struct has private data allocated with it,
2726 * this variable determines its size 2728 * this variable determines its size
@@ -2809,7 +2811,7 @@ struct wiphy {
2809 2811
2810 u16 max_acl_mac_addrs; 2812 u16 max_acl_mac_addrs;
2811 2813
2812 u32 flags, features; 2814 u32 flags, regulatory_flags, features;
2813 2815
2814 u32 ap_sme_capa; 2816 u32 ap_sme_capa;
2815 2817
@@ -3472,6 +3474,9 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
3472 * custom regulatory domain will be trusted completely and as such previous 3474 * custom regulatory domain will be trusted completely and as such previous
3473 * default channel settings will be disregarded. If no rule is found for a 3475 * default channel settings will be disregarded. If no rule is found for a
3474 * channel on the regulatory domain the channel will be disabled. 3476 * channel on the regulatory domain the channel will be disabled.
3477 * Drivers using this for a wiphy should also set the wiphy flag
3478 * WIPHY_FLAG_CUSTOM_REGULATORY or cfg80211 will set it for the wiphy
3479 * that called this helper.
3475 */ 3480 */
3476void wiphy_apply_custom_regulatory(struct wiphy *wiphy, 3481void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
3477 const struct ieee80211_regdomain *regd); 3482 const struct ieee80211_regdomain *regd);
@@ -4146,6 +4151,7 @@ void cfg80211_radar_event(struct wiphy *wiphy,
4146/** 4151/**
4147 * cfg80211_cac_event - Channel availability check (CAC) event 4152 * cfg80211_cac_event - Channel availability check (CAC) event
4148 * @netdev: network device 4153 * @netdev: network device
4154 * @chandef: chandef for the current channel
4149 * @event: type of event 4155 * @event: type of event
4150 * @gfp: context flags 4156 * @gfp: context flags
4151 * 4157 *
@@ -4154,6 +4160,7 @@ void cfg80211_radar_event(struct wiphy *wiphy,
4154 * also by full-MAC drivers. 4160 * also by full-MAC drivers.
4155 */ 4161 */
4156void cfg80211_cac_event(struct net_device *netdev, 4162void cfg80211_cac_event(struct net_device *netdev,
4163 const struct cfg80211_chan_def *chandef,
4157 enum nl80211_radar_event event, gfp_t gfp); 4164 enum nl80211_radar_event event, gfp_t gfp);
4158 4165
4159 4166
@@ -4279,7 +4286,8 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
4279 * @dev: the device which switched channels 4286 * @dev: the device which switched channels
4280 * @chandef: the new channel definition 4287 * @chandef: the new channel definition
4281 * 4288 *
4282 * Acquires wdev_lock, so must only be called from sleepable driver context! 4289 * Caller must acquire wdev_lock, therefore must only be called from sleepable
4290 * driver context!
4283 */ 4291 */
4284void cfg80211_ch_switch_notify(struct net_device *dev, 4292void cfg80211_ch_switch_notify(struct net_device *dev,
4285 struct cfg80211_chan_def *chandef); 4293 struct cfg80211_chan_def *chandef);
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7ceed99a05bc..3cd408b326de 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -154,12 +154,14 @@ struct ieee80211_low_level_stats {
154 * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed 154 * @IEEE80211_CHANCTX_CHANGE_RADAR: radar detection flag changed
155 * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel, 155 * @IEEE80211_CHANCTX_CHANGE_CHANNEL: switched to another operating channel,
156 * this is used only with channel switching with CSA 156 * this is used only with channel switching with CSA
157 * @IEEE80211_CHANCTX_CHANGE_MIN_WIDTH: The min required channel width changed
157 */ 158 */
158enum ieee80211_chanctx_change { 159enum ieee80211_chanctx_change {
159 IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0), 160 IEEE80211_CHANCTX_CHANGE_WIDTH = BIT(0),
160 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1), 161 IEEE80211_CHANCTX_CHANGE_RX_CHAINS = BIT(1),
161 IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2), 162 IEEE80211_CHANCTX_CHANGE_RADAR = BIT(2),
162 IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3), 163 IEEE80211_CHANCTX_CHANGE_CHANNEL = BIT(3),
164 IEEE80211_CHANCTX_CHANGE_MIN_WIDTH = BIT(4),
163}; 165};
164 166
165/** 167/**
@@ -169,6 +171,7 @@ enum ieee80211_chanctx_change {
169 * that contains it is visible in mac80211 only. 171 * that contains it is visible in mac80211 only.
170 * 172 *
171 * @def: the channel definition 173 * @def: the channel definition
174 * @min_def: the minimum channel definition currently required.
172 * @rx_chains_static: The number of RX chains that must always be 175 * @rx_chains_static: The number of RX chains that must always be
173 * active on the channel to receive MIMO transmissions 176 * active on the channel to receive MIMO transmissions
174 * @rx_chains_dynamic: The number of RX chains that must be enabled 177 * @rx_chains_dynamic: The number of RX chains that must be enabled
@@ -180,6 +183,7 @@ enum ieee80211_chanctx_change {
180 */ 183 */
181struct ieee80211_chanctx_conf { 184struct ieee80211_chanctx_conf {
182 struct cfg80211_chan_def def; 185 struct cfg80211_chan_def def;
186 struct cfg80211_chan_def min_def;
183 187
184 u8 rx_chains_static, rx_chains_dynamic; 188 u8 rx_chains_static, rx_chains_dynamic;
185 189
@@ -1229,6 +1233,36 @@ struct ieee80211_key_conf {
1229}; 1233};
1230 1234
1231/** 1235/**
1236 * struct ieee80211_cipher_scheme - cipher scheme
1237 *
1238 * This structure contains a cipher scheme information defining
1239 * the secure packet crypto handling.
1240 *
1241 * @cipher: a cipher suite selector
1242 * @iftype: a cipher iftype bit mask indicating an allowed cipher usage
1243 * @hdr_len: a length of a security header used the cipher
1244 * @pn_len: a length of a packet number in the security header
1245 * @pn_off: an offset of pn from the beginning of the security header
1246 * @key_idx_off: an offset of key index byte in the security header
1247 * @key_idx_mask: a bit mask of key_idx bits
1248 * @key_idx_shift: a bit shift needed to get key_idx
1249 * key_idx value calculation:
1250 * (sec_header_base[key_idx_off] & key_idx_mask) >> key_idx_shift
1251 * @mic_len: a mic length in bytes
1252 */
1253struct ieee80211_cipher_scheme {
1254 u32 cipher;
1255 u16 iftype;
1256 u8 hdr_len;
1257 u8 pn_len;
1258 u8 pn_off;
1259 u8 key_idx_off;
1260 u8 key_idx_mask;
1261 u8 key_idx_shift;
1262 u8 mic_len;
1263};
1264
1265/**
1232 * enum set_key_cmd - key command 1266 * enum set_key_cmd - key command
1233 * 1267 *
1234 * Used with the set_key() callback in &struct ieee80211_ops, this 1268 * Used with the set_key() callback in &struct ieee80211_ops, this
@@ -1636,6 +1670,10 @@ enum ieee80211_hw_flags {
1636 * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may 1670 * @uapsd_max_sp_len: maximum number of total buffered frames the WMM AP may
1637 * deliver to a WMM STA during any Service Period triggered by the WMM STA. 1671 * deliver to a WMM STA during any Service Period triggered by the WMM STA.
1638 * Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values. 1672 * Use IEEE80211_WMM_IE_STA_QOSINFO_SP_* for correct values.
1673 *
1674 * @n_cipher_schemes: a size of an array of cipher schemes definitions.
1675 * @cipher_schemes: a pointer to an array of cipher scheme definitions
1676 * supported by HW.
1639 */ 1677 */
1640struct ieee80211_hw { 1678struct ieee80211_hw {
1641 struct ieee80211_conf conf; 1679 struct ieee80211_conf conf;
@@ -1663,6 +1701,8 @@ struct ieee80211_hw {
1663 netdev_features_t netdev_features; 1701 netdev_features_t netdev_features;
1664 u8 uapsd_queues; 1702 u8 uapsd_queues;
1665 u8 uapsd_max_sp_len; 1703 u8 uapsd_max_sp_len;
1704 u8 n_cipher_schemes;
1705 const struct ieee80211_cipher_scheme *cipher_schemes;
1666}; 1706};
1667 1707
1668/** 1708/**
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
index f17ed590d64a..c96a0b86f342 100644
--- a/include/net/regulatory.h
+++ b/include/net/regulatory.h
@@ -38,17 +38,17 @@ enum environment_cap {
38 * 38 *
39 * @rcu_head: RCU head struct used to free the request 39 * @rcu_head: RCU head struct used to free the request
40 * @wiphy_idx: this is set if this request's initiator is 40 * @wiphy_idx: this is set if this request's initiator is
41 * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This 41 * %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
42 * can be used by the wireless core to deal with conflicts 42 * can be used by the wireless core to deal with conflicts
43 * and potentially inform users of which devices specifically 43 * and potentially inform users of which devices specifically
44 * cased the conflicts. 44 * cased the conflicts.
45 * @initiator: indicates who sent this request, could be any of 45 * @initiator: indicates who sent this request, could be any of
46 * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*) 46 * of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
47 * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested 47 * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
48 * regulatory domain. We have a few special codes: 48 * regulatory domain. We have a few special codes:
49 * 00 - World regulatory domain 49 * 00 - World regulatory domain
50 * 99 - built by driver but a specific alpha2 cannot be determined 50 * 99 - built by driver but a specific alpha2 cannot be determined
51 * 98 - result of an intersection between two regulatory domains 51 * 98 - result of an intersection between two regulatory domains
52 * 97 - regulatory domain has not yet been configured 52 * 97 - regulatory domain has not yet been configured
53 * @dfs_region: If CRDA responded with a regulatory domain that requires 53 * @dfs_region: If CRDA responded with a regulatory domain that requires
54 * DFS master operation on a known DFS region (NL80211_DFS_*), 54 * DFS master operation on a known DFS region (NL80211_DFS_*),
@@ -59,8 +59,8 @@ enum environment_cap {
59 * of hint passed. This could be any of the %NL80211_USER_REG_HINT_* 59 * of hint passed. This could be any of the %NL80211_USER_REG_HINT_*
60 * types. 60 * types.
61 * @intersect: indicates whether the wireless core should intersect 61 * @intersect: indicates whether the wireless core should intersect
62 * the requested regulatory domain with the presently set regulatory 62 * the requested regulatory domain with the presently set regulatory
63 * domain. 63 * domain.
64 * @processed: indicates whether or not this requests has already been 64 * @processed: indicates whether or not this requests has already been
65 * processed. When the last request is processed it means that the 65 * processed. When the last request is processed it means that the
66 * currently regulatory domain set on cfg80211 is updated from 66 * currently regulatory domain set on cfg80211 is updated from
@@ -68,9 +68,9 @@ enum environment_cap {
68 * the last request is not yet processed we must yield until it 68 * the last request is not yet processed we must yield until it
69 * is processed before processing any new requests. 69 * is processed before processing any new requests.
70 * @country_ie_checksum: checksum of the last processed and accepted 70 * @country_ie_checksum: checksum of the last processed and accepted
71 * country IE 71 * country IE
72 * @country_ie_env: lets us know if the AP is telling us we are outdoor, 72 * @country_ie_env: lets us know if the AP is telling us we are outdoor,
73 * indoor, or if it doesn't matter 73 * indoor, or if it doesn't matter
74 * @list: used to insert into the reg_requests_list linked list 74 * @list: used to insert into the reg_requests_list linked list
75 */ 75 */
76struct regulatory_request { 76struct regulatory_request {
@@ -79,13 +79,63 @@ struct regulatory_request {
79 enum nl80211_reg_initiator initiator; 79 enum nl80211_reg_initiator initiator;
80 enum nl80211_user_reg_hint_type user_reg_hint_type; 80 enum nl80211_user_reg_hint_type user_reg_hint_type;
81 char alpha2[2]; 81 char alpha2[2];
82 u8 dfs_region; 82 enum nl80211_dfs_regions dfs_region;
83 bool intersect; 83 bool intersect;
84 bool processed; 84 bool processed;
85 enum environment_cap country_ie_env; 85 enum environment_cap country_ie_env;
86 struct list_head list; 86 struct list_head list;
87}; 87};
88 88
89/**
90 * enum ieee80211_regulatory_flags - device regulatory flags
91 *
92 * @REGULATORY_CUSTOM_REG: tells us the driver for this device
93 * has its own custom regulatory domain and cannot identify the
94 * ISO / IEC 3166 alpha2 it belongs to. When this is enabled
95 * we will disregard the first regulatory hint (when the
96 * initiator is %REGDOM_SET_BY_CORE). Drivers that use
97 * wiphy_apply_custom_regulatory() should have this flag set
98 * or the regulatory core will set it for the wiphy.
99 * @REGULATORY_STRICT_REG: tells us that the wiphy for this device
100 * has regulatory domain that it wishes to be considered as the
101 * superset for regulatory rules. After this device gets its regulatory
102 * domain programmed further regulatory hints shall only be considered
103 * for this device to enhance regulatory compliance, forcing the
104 * device to only possibly use subsets of the original regulatory
105 * rules. For example if channel 13 and 14 are disabled by this
106 * device's regulatory domain no user specified regulatory hint which
107 * has these channels enabled would enable them for this wiphy,
108 * the device's original regulatory domain will be trusted as the
109 * base. You can program the superset of regulatory rules for this
110 * wiphy with regulatory_hint() for cards programmed with an
111 * ISO3166-alpha2 country code. wiphys that use regulatory_hint()
112 * will have their wiphy->regd programmed once the regulatory
113 * domain is set, and all other regulatory hints will be ignored
114 * until their own regulatory domain gets programmed.
115 * @REGULATORY_DISABLE_BEACON_HINTS: enable this if your driver needs to
116 * ensure that passive scan flags and beaconing flags may not be lifted by
117 * cfg80211 due to regulatory beacon hints. For more information on beacon
118 * hints read the documenation for regulatory_hint_found_beacon()
119 * @REGULATORY_COUNTRY_IE_FOLLOW_POWER: for devices that have a preference
120 * that even though they may have programmed their own custom power
121 * setting prior to wiphy registration, they want to ensure their channel
122 * power settings are updated for this connection with the power settings
123 * derived from the regulatory domain. The regulatory domain used will be
124 * based on the ISO3166-alpha2 from country IE provided through
125 * regulatory_hint_country_ie()
126 * @REGULATORY_COUNTRY_IE_IGNORE: for devices that have a preference to ignore
127 * all country IE information processed by the regulatory core. This will
128 * override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will
129 * be ignored.
130 */
131enum ieee80211_regulatory_flags {
132 REGULATORY_CUSTOM_REG = BIT(0),
133 REGULATORY_STRICT_REG = BIT(1),
134 REGULATORY_DISABLE_BEACON_HINTS = BIT(2),
135 REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3),
136 REGULATORY_COUNTRY_IE_IGNORE = BIT(4),
137};
138
89struct ieee80211_freq_range { 139struct ieee80211_freq_range {
90 u32 start_freq_khz; 140 u32 start_freq_khz;
91 u32 end_freq_khz; 141 u32 end_freq_khz;
@@ -107,7 +157,7 @@ struct ieee80211_regdomain {
107 struct rcu_head rcu_head; 157 struct rcu_head rcu_head;
108 u32 n_reg_rules; 158 u32 n_reg_rules;
109 char alpha2[2]; 159 char alpha2[2];
110 u8 dfs_region; 160 enum nl80211_dfs_regions dfs_region;
111 struct ieee80211_reg_rule reg_rules[]; 161 struct ieee80211_reg_rule reg_rules[];
112}; 162};
113 163
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index f752e9821e71..129b7b087148 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -581,7 +581,14 @@
581 * operation, %NL80211_ATTR_MAC contains the peer MAC address, and 581 * operation, %NL80211_ATTR_MAC contains the peer MAC address, and
582 * %NL80211_ATTR_REASON_CODE the reason code to be used (only with 582 * %NL80211_ATTR_REASON_CODE the reason code to be used (only with
583 * %NL80211_TDLS_TEARDOWN). 583 * %NL80211_TDLS_TEARDOWN).
584 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. 584 * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The
585 * %NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be
586 * sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as
587 * 802.11 management frames, while TDLS action codes (802.11-2012
588 * 8.5.13.1) will be encapsulated and sent as data frames. The currently
589 * supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES
590 * and the currently supported TDLS actions codes are given in
591 * &enum ieee80211_tdls_actioncode.
585 * 592 *
586 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP 593 * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP
587 * (or GO) interface (i.e. hostapd) to ask for unexpected frames to 594 * (or GO) interface (i.e. hostapd) to ask for unexpected frames to
@@ -1508,6 +1515,11 @@ enum nl80211_commands {
1508 * to react to radar events, e.g. initiate a channel switch or leave the 1515 * to react to radar events, e.g. initiate a channel switch or leave the
1509 * IBSS network. 1516 * IBSS network.
1510 * 1517 *
1518 * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports
1519 * 5 MHz channel bandwidth.
1520 * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports
1521 * 10 MHz channel bandwidth.
1522 *
1511 * @NL80211_ATTR_MAX: highest attribute number currently defined 1523 * @NL80211_ATTR_MAX: highest attribute number currently defined
1512 * @__NL80211_ATTR_AFTER_LAST: internal use 1524 * @__NL80211_ATTR_AFTER_LAST: internal use
1513 */ 1525 */
@@ -1824,6 +1836,9 @@ enum nl80211_attrs {
1824 1836
1825 NL80211_ATTR_HANDLE_DFS, 1837 NL80211_ATTR_HANDLE_DFS,
1826 1838
1839 NL80211_ATTR_SUPPORT_5_MHZ,
1840 NL80211_ATTR_SUPPORT_10_MHZ,
1841
1827 /* add attributes here, update the policy in nl80211.c */ 1842 /* add attributes here, update the policy in nl80211.c */
1828 1843
1829 __NL80211_ATTR_AFTER_LAST, 1844 __NL80211_ATTR_AFTER_LAST,
@@ -2224,10 +2239,9 @@ enum nl80211_band_attr {
2224 * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz 2239 * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
2225 * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current 2240 * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current
2226 * regulatory domain. 2241 * regulatory domain.
2227 * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is 2242 * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation
2228 * permitted on this channel in current regulatory domain. 2243 * are permitted on this channel, this includes sending probe
2229 * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted 2244 * requests, or modes of operation that require beaconing.
2230 * on this channel in current regulatory domain.
2231 * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory 2245 * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory
2232 * on this channel in current regulatory domain. 2246 * on this channel in current regulatory domain.
2233 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm 2247 * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm
@@ -2254,8 +2268,8 @@ enum nl80211_frequency_attr {
2254 __NL80211_FREQUENCY_ATTR_INVALID, 2268 __NL80211_FREQUENCY_ATTR_INVALID,
2255 NL80211_FREQUENCY_ATTR_FREQ, 2269 NL80211_FREQUENCY_ATTR_FREQ,
2256 NL80211_FREQUENCY_ATTR_DISABLED, 2270 NL80211_FREQUENCY_ATTR_DISABLED,
2257 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, 2271 NL80211_FREQUENCY_ATTR_NO_IR,
2258 NL80211_FREQUENCY_ATTR_NO_IBSS, 2272 __NL80211_FREQUENCY_ATTR_NO_IBSS,
2259 NL80211_FREQUENCY_ATTR_RADAR, 2273 NL80211_FREQUENCY_ATTR_RADAR,
2260 NL80211_FREQUENCY_ATTR_MAX_TX_POWER, 2274 NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
2261 NL80211_FREQUENCY_ATTR_DFS_STATE, 2275 NL80211_FREQUENCY_ATTR_DFS_STATE,
@@ -2271,6 +2285,9 @@ enum nl80211_frequency_attr {
2271}; 2285};
2272 2286
2273#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER 2287#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER
2288#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR
2289#define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR
2290#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR
2274 2291
2275/** 2292/**
2276 * enum nl80211_bitrate_attr - bitrate attributes 2293 * enum nl80211_bitrate_attr - bitrate attributes
@@ -2413,8 +2430,9 @@ enum nl80211_sched_scan_match_attr {
2413 * @NL80211_RRF_DFS: DFS support is required to be used 2430 * @NL80211_RRF_DFS: DFS support is required to be used
2414 * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links 2431 * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links
2415 * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links 2432 * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links
2416 * @NL80211_RRF_PASSIVE_SCAN: passive scan is required 2433 * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed,
2417 * @NL80211_RRF_NO_IBSS: no IBSS is allowed 2434 * this includes probe requests or modes of operation that require
2435 * beaconing.
2418 */ 2436 */
2419enum nl80211_reg_rule_flags { 2437enum nl80211_reg_rule_flags {
2420 NL80211_RRF_NO_OFDM = 1<<0, 2438 NL80211_RRF_NO_OFDM = 1<<0,
@@ -2424,10 +2442,17 @@ enum nl80211_reg_rule_flags {
2424 NL80211_RRF_DFS = 1<<4, 2442 NL80211_RRF_DFS = 1<<4,
2425 NL80211_RRF_PTP_ONLY = 1<<5, 2443 NL80211_RRF_PTP_ONLY = 1<<5,
2426 NL80211_RRF_PTMP_ONLY = 1<<6, 2444 NL80211_RRF_PTMP_ONLY = 1<<6,
2427 NL80211_RRF_PASSIVE_SCAN = 1<<7, 2445 NL80211_RRF_NO_IR = 1<<7,
2428 NL80211_RRF_NO_IBSS = 1<<8, 2446 __NL80211_RRF_NO_IBSS = 1<<8,
2429}; 2447};
2430 2448
2449#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
2450#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR
2451#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR
2452
2453/* For backport compatibility with older userspace */
2454#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS)
2455
2431/** 2456/**
2432 * enum nl80211_dfs_regions - regulatory DFS regions 2457 * enum nl80211_dfs_regions - regulatory DFS regions
2433 * 2458 *
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 364ce0c5962f..f80e8c4c6bcd 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -133,7 +133,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
133 struct key_params *params) 133 struct key_params *params)
134{ 134{
135 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 135 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
136 struct ieee80211_local *local = sdata->local;
136 struct sta_info *sta = NULL; 137 struct sta_info *sta = NULL;
138 const struct ieee80211_cipher_scheme *cs = NULL;
137 struct ieee80211_key *key; 139 struct ieee80211_key *key;
138 int err; 140 int err;
139 141
@@ -145,22 +147,28 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
145 case WLAN_CIPHER_SUITE_WEP40: 147 case WLAN_CIPHER_SUITE_WEP40:
146 case WLAN_CIPHER_SUITE_TKIP: 148 case WLAN_CIPHER_SUITE_TKIP:
147 case WLAN_CIPHER_SUITE_WEP104: 149 case WLAN_CIPHER_SUITE_WEP104:
148 if (IS_ERR(sdata->local->wep_tx_tfm)) 150 if (IS_ERR(local->wep_tx_tfm))
149 return -EINVAL; 151 return -EINVAL;
150 break; 152 break;
153 case WLAN_CIPHER_SUITE_CCMP:
154 case WLAN_CIPHER_SUITE_AES_CMAC:
155 case WLAN_CIPHER_SUITE_GCMP:
156 break;
151 default: 157 default:
158 cs = ieee80211_cs_get(local, params->cipher, sdata->vif.type);
152 break; 159 break;
153 } 160 }
154 161
155 key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, 162 key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
156 params->key, params->seq_len, params->seq); 163 params->key, params->seq_len, params->seq,
164 cs);
157 if (IS_ERR(key)) 165 if (IS_ERR(key))
158 return PTR_ERR(key); 166 return PTR_ERR(key);
159 167
160 if (pairwise) 168 if (pairwise)
161 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; 169 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
162 170
163 mutex_lock(&sdata->local->sta_mtx); 171 mutex_lock(&local->sta_mtx);
164 172
165 if (mac_addr) { 173 if (mac_addr) {
166 if (ieee80211_vif_is_mesh(&sdata->vif)) 174 if (ieee80211_vif_is_mesh(&sdata->vif))
@@ -216,10 +224,13 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
216 break; 224 break;
217 } 225 }
218 226
227 if (sta)
228 sta->cipher_scheme = cs;
229
219 err = ieee80211_key_link(key, sdata, sta); 230 err = ieee80211_key_link(key, sdata, sta);
220 231
221 out_unlock: 232 out_unlock:
222 mutex_unlock(&sdata->local->sta_mtx); 233 mutex_unlock(&local->sta_mtx);
223 234
224 return err; 235 return err;
225} 236}
@@ -244,7 +255,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
244 goto out_unlock; 255 goto out_unlock;
245 256
246 if (pairwise) 257 if (pairwise)
247 key = key_mtx_dereference(local, sta->ptk); 258 key = key_mtx_dereference(local, sta->ptk[key_idx]);
248 else 259 else
249 key = key_mtx_dereference(local, sta->gtk[key_idx]); 260 key = key_mtx_dereference(local, sta->gtk[key_idx]);
250 } else 261 } else
@@ -291,7 +302,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
291 goto out; 302 goto out;
292 303
293 if (pairwise) 304 if (pairwise)
294 key = rcu_dereference(sta->ptk); 305 key = rcu_dereference(sta->ptk[key_idx]);
295 else if (key_idx < NUM_DEFAULT_KEYS) 306 else if (key_idx < NUM_DEFAULT_KEYS)
296 key = rcu_dereference(sta->gtk[key_idx]); 307 key = rcu_dereference(sta->gtk[key_idx]);
297 } else 308 } else
@@ -521,8 +532,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
521 STATION_INFO_PEER_PM | 532 STATION_INFO_PEER_PM |
522 STATION_INFO_NONPEER_PM; 533 STATION_INFO_NONPEER_PM;
523 534
524 sinfo->llid = le16_to_cpu(sta->llid); 535 sinfo->llid = sta->llid;
525 sinfo->plid = le16_to_cpu(sta->plid); 536 sinfo->plid = sta->plid;
526 sinfo->plink_state = sta->plink_state; 537 sinfo->plink_state = sta->plink_state;
527 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { 538 if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) {
528 sinfo->filled |= STATION_INFO_T_OFFSET; 539 sinfo->filled |= STATION_INFO_T_OFFSET;
@@ -846,7 +857,7 @@ static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata,
846 if (!resp || !resp_len) 857 if (!resp || !resp_len)
847 return 1; 858 return 1;
848 859
849 old = rtnl_dereference(sdata->u.ap.probe_resp); 860 old = sdata_dereference(sdata->u.ap.probe_resp, sdata);
850 861
851 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); 862 new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL);
852 if (!new) 863 if (!new)
@@ -870,7 +881,8 @@ int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata,
870 int size, err; 881 int size, err;
871 u32 changed = BSS_CHANGED_BEACON; 882 u32 changed = BSS_CHANGED_BEACON;
872 883
873 old = rtnl_dereference(sdata->u.ap.beacon); 884 old = sdata_dereference(sdata->u.ap.beacon, sdata);
885
874 886
875 /* Need to have a beacon head if we don't have one yet */ 887 /* Need to have a beacon head if we don't have one yet */
876 if (!params->head && !old) 888 if (!params->head && !old)
@@ -947,7 +959,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
947 BSS_CHANGED_P2P_PS; 959 BSS_CHANGED_P2P_PS;
948 int err; 960 int err;
949 961
950 old = rtnl_dereference(sdata->u.ap.beacon); 962 old = sdata_dereference(sdata->u.ap.beacon, sdata);
951 if (old) 963 if (old)
952 return -EALREADY; 964 return -EALREADY;
953 965
@@ -968,11 +980,19 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
968 */ 980 */
969 sdata->control_port_protocol = params->crypto.control_port_ethertype; 981 sdata->control_port_protocol = params->crypto.control_port_ethertype;
970 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt; 982 sdata->control_port_no_encrypt = params->crypto.control_port_no_encrypt;
983 sdata->encrypt_headroom = ieee80211_cs_headroom(sdata->local,
984 &params->crypto,
985 sdata->vif.type);
986
971 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { 987 list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) {
972 vlan->control_port_protocol = 988 vlan->control_port_protocol =
973 params->crypto.control_port_ethertype; 989 params->crypto.control_port_ethertype;
974 vlan->control_port_no_encrypt = 990 vlan->control_port_no_encrypt =
975 params->crypto.control_port_no_encrypt; 991 params->crypto.control_port_no_encrypt;
992 vlan->encrypt_headroom =
993 ieee80211_cs_headroom(sdata->local,
994 &params->crypto,
995 vlan->vif.type);
976 } 996 }
977 997
978 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 998 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
@@ -1001,7 +1021,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
1001 1021
1002 err = drv_start_ap(sdata->local, sdata); 1022 err = drv_start_ap(sdata->local, sdata);
1003 if (err) { 1023 if (err) {
1004 old = rtnl_dereference(sdata->u.ap.beacon); 1024 old = sdata_dereference(sdata->u.ap.beacon, sdata);
1025
1005 if (old) 1026 if (old)
1006 kfree_rcu(old, rcu_head); 1027 kfree_rcu(old, rcu_head);
1007 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 1028 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
@@ -1032,7 +1053,7 @@ static int ieee80211_change_beacon(struct wiphy *wiphy, struct net_device *dev,
1032 if (sdata->vif.csa_active) 1053 if (sdata->vif.csa_active)
1033 return -EBUSY; 1054 return -EBUSY;
1034 1055
1035 old = rtnl_dereference(sdata->u.ap.beacon); 1056 old = sdata_dereference(sdata->u.ap.beacon, sdata);
1036 if (!old) 1057 if (!old)
1037 return -ENOENT; 1058 return -ENOENT;
1038 1059
@@ -1050,15 +1071,18 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1050 struct ieee80211_local *local = sdata->local; 1071 struct ieee80211_local *local = sdata->local;
1051 struct beacon_data *old_beacon; 1072 struct beacon_data *old_beacon;
1052 struct probe_resp *old_probe_resp; 1073 struct probe_resp *old_probe_resp;
1074 struct cfg80211_chan_def chandef;
1053 1075
1054 old_beacon = rtnl_dereference(sdata->u.ap.beacon); 1076 old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata);
1055 if (!old_beacon) 1077 if (!old_beacon)
1056 return -ENOENT; 1078 return -ENOENT;
1057 old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); 1079 old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata);
1058 1080
1059 /* abort any running channel switch */ 1081 /* abort any running channel switch */
1060 sdata->vif.csa_active = false; 1082 sdata->vif.csa_active = false;
1061 cancel_work_sync(&sdata->csa_finalize_work); 1083 kfree(sdata->u.ap.next_beacon);
1084 sdata->u.ap.next_beacon = NULL;
1085
1062 cancel_work_sync(&sdata->u.ap.request_smps_work); 1086 cancel_work_sync(&sdata->u.ap.request_smps_work);
1063 1087
1064 /* turn off carrier for this interface and dependent VLANs */ 1088 /* turn off carrier for this interface and dependent VLANs */
@@ -1091,8 +1115,10 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1091 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 1115 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
1092 1116
1093 if (sdata->wdev.cac_started) { 1117 if (sdata->wdev.cac_started) {
1118 chandef = sdata->vif.bss_conf.chandef;
1094 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 1119 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
1095 cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, 1120 cfg80211_cac_event(sdata->dev, &chandef,
1121 NL80211_RADAR_CAC_ABORTED,
1096 GFP_KERNEL); 1122 GFP_KERNEL);
1097 } 1123 }
1098 1124
@@ -1953,7 +1979,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1953 enum ieee80211_band band; 1979 enum ieee80211_band band;
1954 u32 changed = 0; 1980 u32 changed = 0;
1955 1981
1956 if (!rtnl_dereference(sdata->u.ap.beacon)) 1982 if (!sdata_dereference(sdata->u.ap.beacon, sdata))
1957 return -ENOENT; 1983 return -ENOENT;
1958 1984
1959 band = ieee80211_get_sdata_band(sdata); 1985 band = ieee80211_get_sdata_band(sdata);
@@ -2963,27 +2989,33 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
2963 struct ieee80211_local *local = sdata->local; 2989 struct ieee80211_local *local = sdata->local;
2964 int err, changed = 0; 2990 int err, changed = 0;
2965 2991
2992 sdata_lock(sdata);
2993 /* AP might have been stopped while waiting for the lock. */
2994 if (!sdata->vif.csa_active)
2995 goto unlock;
2996
2966 if (!ieee80211_sdata_running(sdata)) 2997 if (!ieee80211_sdata_running(sdata))
2967 return; 2998 goto unlock;
2968 2999
2969 sdata->radar_required = sdata->csa_radar_required; 3000 sdata->radar_required = sdata->csa_radar_required;
2970 err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, 3001 err = ieee80211_vif_change_channel(sdata, &changed);
2971 &changed);
2972 if (WARN_ON(err < 0)) 3002 if (WARN_ON(err < 0))
2973 return; 3003 goto unlock;
2974 3004
2975 if (!local->use_chanctx) { 3005 if (!local->use_chanctx) {
2976 local->_oper_chandef = local->csa_chandef; 3006 local->_oper_chandef = sdata->csa_chandef;
2977 ieee80211_hw_config(local, 0); 3007 ieee80211_hw_config(local, 0);
2978 } 3008 }
2979 3009
2980 ieee80211_bss_info_change_notify(sdata, changed); 3010 ieee80211_bss_info_change_notify(sdata, changed);
2981 3011
3012 sdata->vif.csa_active = false;
2982 switch (sdata->vif.type) { 3013 switch (sdata->vif.type) {
2983 case NL80211_IFTYPE_AP: 3014 case NL80211_IFTYPE_AP:
2984 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); 3015 err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
2985 if (err < 0) 3016 if (err < 0)
2986 return; 3017 goto unlock;
3018
2987 changed |= err; 3019 changed |= err;
2988 kfree(sdata->u.ap.next_beacon); 3020 kfree(sdata->u.ap.next_beacon);
2989 sdata->u.ap.next_beacon = NULL; 3021 sdata->u.ap.next_beacon = NULL;
@@ -2997,20 +3029,22 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
2997 case NL80211_IFTYPE_MESH_POINT: 3029 case NL80211_IFTYPE_MESH_POINT:
2998 err = ieee80211_mesh_finish_csa(sdata); 3030 err = ieee80211_mesh_finish_csa(sdata);
2999 if (err < 0) 3031 if (err < 0)
3000 return; 3032 goto unlock;
3001 break; 3033 break;
3002#endif 3034#endif
3003 default: 3035 default:
3004 WARN_ON(1); 3036 WARN_ON(1);
3005 return; 3037 goto unlock;
3006 } 3038 }
3007 sdata->vif.csa_active = false;
3008 3039
3009 ieee80211_wake_queues_by_reason(&sdata->local->hw, 3040 ieee80211_wake_queues_by_reason(&sdata->local->hw,
3010 IEEE80211_MAX_QUEUE_MAP, 3041 IEEE80211_MAX_QUEUE_MAP,
3011 IEEE80211_QUEUE_STOP_REASON_CSA); 3042 IEEE80211_QUEUE_STOP_REASON_CSA);
3012 3043
3013 cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); 3044 cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
3045
3046unlock:
3047 sdata_unlock(sdata);
3014} 3048}
3015 3049
3016static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 3050static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
@@ -3023,6 +3057,8 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3023 struct ieee80211_if_mesh __maybe_unused *ifmsh; 3057 struct ieee80211_if_mesh __maybe_unused *ifmsh;
3024 int err, num_chanctx; 3058 int err, num_chanctx;
3025 3059
3060 lockdep_assert_held(&sdata->wdev.mtx);
3061
3026 if (!list_empty(&local->roc_list) || local->scanning) 3062 if (!list_empty(&local->roc_list) || local->scanning)
3027 return -EBUSY; 3063 return -EBUSY;
3028 3064
@@ -3143,7 +3179,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3143 IEEE80211_MAX_QUEUE_MAP, 3179 IEEE80211_MAX_QUEUE_MAP,
3144 IEEE80211_QUEUE_STOP_REASON_CSA); 3180 IEEE80211_QUEUE_STOP_REASON_CSA);
3145 3181
3146 local->csa_chandef = params->chandef; 3182 sdata->csa_chandef = params->chandef;
3147 sdata->vif.csa_active = true; 3183 sdata->vif.csa_active = true;
3148 3184
3149 ieee80211_bss_info_change_notify(sdata, err); 3185 ieee80211_bss_info_change_notify(sdata, err);
@@ -3153,26 +3189,25 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3153} 3189}
3154 3190
3155static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 3191static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3156 struct ieee80211_channel *chan, bool offchan, 3192 struct cfg80211_mgmt_tx_params *params,
3157 unsigned int wait, const u8 *buf, size_t len, 3193 u64 *cookie)
3158 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3159{ 3194{
3160 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3195 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3161 struct ieee80211_local *local = sdata->local; 3196 struct ieee80211_local *local = sdata->local;
3162 struct sk_buff *skb; 3197 struct sk_buff *skb;
3163 struct sta_info *sta; 3198 struct sta_info *sta;
3164 const struct ieee80211_mgmt *mgmt = (void *)buf; 3199 const struct ieee80211_mgmt *mgmt = (void *)params->buf;
3165 bool need_offchan = false; 3200 bool need_offchan = false;
3166 u32 flags; 3201 u32 flags;
3167 int ret; 3202 int ret;
3168 3203
3169 if (dont_wait_for_ack) 3204 if (params->dont_wait_for_ack)
3170 flags = IEEE80211_TX_CTL_NO_ACK; 3205 flags = IEEE80211_TX_CTL_NO_ACK;
3171 else 3206 else
3172 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | 3207 flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX |
3173 IEEE80211_TX_CTL_REQ_TX_STATUS; 3208 IEEE80211_TX_CTL_REQ_TX_STATUS;
3174 3209
3175 if (no_cck) 3210 if (params->no_cck)
3176 flags |= IEEE80211_TX_CTL_NO_CCK_RATE; 3211 flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
3177 3212
3178 switch (sdata->vif.type) { 3213 switch (sdata->vif.type) {
@@ -3220,7 +3255,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3220 /* configurations requiring offchan cannot work if no channel has been 3255 /* configurations requiring offchan cannot work if no channel has been
3221 * specified 3256 * specified
3222 */ 3257 */
3223 if (need_offchan && !chan) 3258 if (need_offchan && !params->chan)
3224 return -EINVAL; 3259 return -EINVAL;
3225 3260
3226 mutex_lock(&local->mtx); 3261 mutex_lock(&local->mtx);
@@ -3233,8 +3268,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3233 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3268 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3234 3269
3235 if (chanctx_conf) { 3270 if (chanctx_conf) {
3236 need_offchan = chan && (chan != chanctx_conf->def.chan); 3271 need_offchan = params->chan &&
3237 } else if (!chan) { 3272 (params->chan !=
3273 chanctx_conf->def.chan);
3274 } else if (!params->chan) {
3238 ret = -EINVAL; 3275 ret = -EINVAL;
3239 rcu_read_unlock(); 3276 rcu_read_unlock();
3240 goto out_unlock; 3277 goto out_unlock;
@@ -3244,19 +3281,19 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3244 rcu_read_unlock(); 3281 rcu_read_unlock();
3245 } 3282 }
3246 3283
3247 if (need_offchan && !offchan) { 3284 if (need_offchan && !params->offchan) {
3248 ret = -EBUSY; 3285 ret = -EBUSY;
3249 goto out_unlock; 3286 goto out_unlock;
3250 } 3287 }
3251 3288
3252 skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); 3289 skb = dev_alloc_skb(local->hw.extra_tx_headroom + params->len);
3253 if (!skb) { 3290 if (!skb) {
3254 ret = -ENOMEM; 3291 ret = -ENOMEM;
3255 goto out_unlock; 3292 goto out_unlock;
3256 } 3293 }
3257 skb_reserve(skb, local->hw.extra_tx_headroom); 3294 skb_reserve(skb, local->hw.extra_tx_headroom);
3258 3295
3259 memcpy(skb_put(skb, len), buf, len); 3296 memcpy(skb_put(skb, params->len), params->buf, params->len);
3260 3297
3261 IEEE80211_SKB_CB(skb)->flags = flags; 3298 IEEE80211_SKB_CB(skb)->flags = flags;
3262 3299
@@ -3276,8 +3313,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3276 local->hw.offchannel_tx_hw_queue; 3313 local->hw.offchannel_tx_hw_queue;
3277 3314
3278 /* This will handle all kinds of coalescing and immediate TX */ 3315 /* This will handle all kinds of coalescing and immediate TX */
3279 ret = ieee80211_start_roc_work(local, sdata, chan, 3316 ret = ieee80211_start_roc_work(local, sdata, params->chan,
3280 wait, cookie, skb, 3317 params->wait, cookie, skb,
3281 IEEE80211_ROC_TYPE_MGMT_TX); 3318 IEEE80211_ROC_TYPE_MGMT_TX);
3282 if (ret) 3319 if (ret)
3283 kfree_skb(skb); 3320 kfree_skb(skb);
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 03ba6b5c5373..a57d5d9466bc 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -9,6 +9,140 @@
9#include "ieee80211_i.h" 9#include "ieee80211_i.h"
10#include "driver-ops.h" 10#include "driver-ops.h"
11 11
12static enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta)
13{
14 switch (sta->bandwidth) {
15 case IEEE80211_STA_RX_BW_20:
16 if (sta->ht_cap.ht_supported)
17 return NL80211_CHAN_WIDTH_20;
18 else
19 return NL80211_CHAN_WIDTH_20_NOHT;
20 case IEEE80211_STA_RX_BW_40:
21 return NL80211_CHAN_WIDTH_40;
22 case IEEE80211_STA_RX_BW_80:
23 return NL80211_CHAN_WIDTH_80;
24 case IEEE80211_STA_RX_BW_160:
25 /*
26 * This applied for both 160 and 80+80. since we use
27 * the returned value to consider degradation of
28 * ctx->conf.min_def, we have to make sure to take
29 * the bigger one (NL80211_CHAN_WIDTH_160).
30 * Otherwise we might try degrading even when not
31 * needed, as the max required sta_bw returned (80+80)
32 * might be smaller than the configured bw (160).
33 */
34 return NL80211_CHAN_WIDTH_160;
35 default:
36 WARN_ON(1);
37 return NL80211_CHAN_WIDTH_20;
38 }
39}
40
41static enum nl80211_chan_width
42ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata)
43{
44 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
45 struct sta_info *sta;
46
47 rcu_read_lock();
48 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
49 if (sdata != sta->sdata &&
50 !(sta->sdata->bss && sta->sdata->bss == sdata->bss))
51 continue;
52
53 if (!sta->uploaded)
54 continue;
55
56 max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta));
57 }
58 rcu_read_unlock();
59
60 return max_bw;
61}
62
63static enum nl80211_chan_width
64ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local,
65 struct ieee80211_chanctx_conf *conf)
66{
67 struct ieee80211_sub_if_data *sdata;
68 enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT;
69
70 rcu_read_lock();
71 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
72 struct ieee80211_vif *vif = &sdata->vif;
73 enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT;
74
75 if (!ieee80211_sdata_running(sdata))
76 continue;
77
78 if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
79 continue;
80
81 switch (vif->type) {
82 case NL80211_IFTYPE_AP:
83 case NL80211_IFTYPE_AP_VLAN:
84 width = ieee80211_get_max_required_bw(sdata);
85 break;
86 case NL80211_IFTYPE_P2P_DEVICE:
87 continue;
88 case NL80211_IFTYPE_STATION:
89 case NL80211_IFTYPE_ADHOC:
90 case NL80211_IFTYPE_WDS:
91 case NL80211_IFTYPE_MESH_POINT:
92 width = vif->bss_conf.chandef.width;
93 break;
94 case NL80211_IFTYPE_UNSPECIFIED:
95 case NUM_NL80211_IFTYPES:
96 case NL80211_IFTYPE_MONITOR:
97 case NL80211_IFTYPE_P2P_CLIENT:
98 case NL80211_IFTYPE_P2P_GO:
99 WARN_ON_ONCE(1);
100 }
101 max_bw = max(max_bw, width);
102 }
103 rcu_read_unlock();
104
105 return max_bw;
106}
107
108/*
109 * recalc the min required chan width of the channel context, which is
110 * the max of min required widths of all the interfaces bound to this
111 * channel context.
112 */
113void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
114 struct ieee80211_chanctx *ctx)
115{
116 enum nl80211_chan_width max_bw;
117 struct cfg80211_chan_def min_def;
118
119 lockdep_assert_held(&local->chanctx_mtx);
120
121 /* don't optimize 5MHz, 10MHz, and radar_enabled confs */
122 if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 ||
123 ctx->conf.def.width == NL80211_CHAN_WIDTH_10 ||
124 ctx->conf.radar_enabled) {
125 ctx->conf.min_def = ctx->conf.def;
126 return;
127 }
128
129 max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf);
130
131 /* downgrade chandef up to max_bw */
132 min_def = ctx->conf.def;
133 while (min_def.width > max_bw)
134 ieee80211_chandef_downgrade(&min_def);
135
136 if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def))
137 return;
138
139 ctx->conf.min_def = min_def;
140 if (!ctx->driver_present)
141 return;
142
143 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH);
144}
145
12static void ieee80211_change_chanctx(struct ieee80211_local *local, 146static void ieee80211_change_chanctx(struct ieee80211_local *local,
13 struct ieee80211_chanctx *ctx, 147 struct ieee80211_chanctx *ctx,
14 const struct cfg80211_chan_def *chandef) 148 const struct cfg80211_chan_def *chandef)
@@ -20,6 +154,7 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
20 154
21 ctx->conf.def = *chandef; 155 ctx->conf.def = *chandef;
22 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); 156 drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
157 ieee80211_recalc_chanctx_min_def(local, ctx);
23 158
24 if (!local->use_chanctx) { 159 if (!local->use_chanctx) {
25 local->_oper_chandef = *chandef; 160 local->_oper_chandef = *chandef;
@@ -93,6 +228,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
93 ctx->conf.rx_chains_dynamic = 1; 228 ctx->conf.rx_chains_dynamic = 1;
94 ctx->mode = mode; 229 ctx->mode = mode;
95 ctx->conf.radar_enabled = ieee80211_is_radar_required(local); 230 ctx->conf.radar_enabled = ieee80211_is_radar_required(local);
231 ieee80211_recalc_chanctx_min_def(local, ctx);
96 if (!local->use_chanctx) 232 if (!local->use_chanctx)
97 local->hw.conf.radar_enabled = ctx->conf.radar_enabled; 233 local->hw.conf.radar_enabled = ctx->conf.radar_enabled;
98 234
@@ -179,6 +315,7 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
179 ctx->refcount++; 315 ctx->refcount++;
180 316
181 ieee80211_recalc_txpower(sdata); 317 ieee80211_recalc_txpower(sdata);
318 ieee80211_recalc_chanctx_min_def(local, ctx);
182 sdata->vif.bss_conf.idle = false; 319 sdata->vif.bss_conf.idle = false;
183 320
184 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && 321 if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE &&
@@ -243,6 +380,7 @@ static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
243 ieee80211_recalc_chanctx_chantype(sdata->local, ctx); 380 ieee80211_recalc_chanctx_chantype(sdata->local, ctx);
244 ieee80211_recalc_smps_chanctx(local, ctx); 381 ieee80211_recalc_smps_chanctx(local, ctx);
245 ieee80211_recalc_radar_chanctx(local, ctx); 382 ieee80211_recalc_radar_chanctx(local, ctx);
383 ieee80211_recalc_chanctx_min_def(local, ctx);
246 } 384 }
247} 385}
248 386
@@ -411,12 +549,12 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
411} 549}
412 550
413int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 551int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
414 const struct cfg80211_chan_def *chandef,
415 u32 *changed) 552 u32 *changed)
416{ 553{
417 struct ieee80211_local *local = sdata->local; 554 struct ieee80211_local *local = sdata->local;
418 struct ieee80211_chanctx_conf *conf; 555 struct ieee80211_chanctx_conf *conf;
419 struct ieee80211_chanctx *ctx; 556 struct ieee80211_chanctx *ctx;
557 const struct cfg80211_chan_def *chandef = &sdata->csa_chandef;
420 int ret; 558 int ret;
421 u32 chanctx_changed = 0; 559 u32 chanctx_changed = 0;
422 560
@@ -456,6 +594,7 @@ int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
456 ieee80211_recalc_chanctx_chantype(local, ctx); 594 ieee80211_recalc_chanctx_chantype(local, ctx);
457 ieee80211_recalc_smps_chanctx(local, ctx); 595 ieee80211_recalc_smps_chanctx(local, ctx);
458 ieee80211_recalc_radar_chanctx(local, ctx); 596 ieee80211_recalc_radar_chanctx(local, ctx);
597 ieee80211_recalc_chanctx_min_def(local, ctx);
459 598
460 ret = 0; 599 ret = 0;
461 out: 600 out:
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 5c090e41d9bb..fa16e54980a1 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -17,6 +17,172 @@
17 17
18#define DEBUGFS_FORMAT_BUFFER_SIZE 100 18#define DEBUGFS_FORMAT_BUFFER_SIZE 100
19 19
20#define TX_LATENCY_BIN_DELIMTER_C ','
21#define TX_LATENCY_BIN_DELIMTER_S ","
22#define TX_LATENCY_BINS_DISABLED "enable(bins disabled)\n"
23#define TX_LATENCY_DISABLED "disable\n"
24
25
26/*
27 * Display if Tx latency statistics & bins are enabled/disabled
28 */
29static ssize_t sta_tx_latency_stat_read(struct file *file,
30 char __user *userbuf,
31 size_t count, loff_t *ppos)
32{
33 struct ieee80211_local *local = file->private_data;
34 struct ieee80211_tx_latency_bin_ranges *tx_latency;
35 char *buf;
36 int bufsz, i, ret;
37 int pos = 0;
38
39 rcu_read_lock();
40
41 tx_latency = rcu_dereference(local->tx_latency);
42
43 if (tx_latency && tx_latency->n_ranges) {
44 bufsz = tx_latency->n_ranges * 15;
45 buf = kzalloc(bufsz, GFP_ATOMIC);
46 if (!buf)
47 goto err;
48
49 for (i = 0; i < tx_latency->n_ranges; i++)
50 pos += scnprintf(buf + pos, bufsz - pos, "%d,",
51 tx_latency->ranges[i]);
52 pos += scnprintf(buf + pos, bufsz - pos, "\n");
53 } else if (tx_latency) {
54 bufsz = sizeof(TX_LATENCY_BINS_DISABLED) + 1;
55 buf = kzalloc(bufsz, GFP_ATOMIC);
56 if (!buf)
57 goto err;
58
59 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
60 TX_LATENCY_BINS_DISABLED);
61 } else {
62 bufsz = sizeof(TX_LATENCY_DISABLED) + 1;
63 buf = kzalloc(bufsz, GFP_ATOMIC);
64 if (!buf)
65 goto err;
66
67 pos += scnprintf(buf + pos, bufsz - pos, "%s\n",
68 TX_LATENCY_DISABLED);
69 }
70
71 rcu_read_unlock();
72
73 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
74 kfree(buf);
75
76 return ret;
77err:
78 rcu_read_unlock();
79 return -ENOMEM;
80}
81
82/*
83 * Receive input from user regarding Tx latency statistics
84 * The input should indicate if Tx latency statistics and bins are
85 * enabled/disabled.
86 * If bins are enabled input should indicate the amount of different bins and
87 * their ranges. Each bin will count how many Tx frames transmitted within the
88 * appropriate latency.
89 * Legal input is:
90 * a) "enable(bins disabled)" - to enable only general statistics
91 * b) "a,b,c,d,...z" - to enable general statistics and bins, where all are
92 * numbers and a < b < c < d.. < z
93 * c) "disable" - disable all statistics
94 * NOTE: must configure Tx latency statistics bins before stations connected.
95 */
96
97static ssize_t sta_tx_latency_stat_write(struct file *file,
98 const char __user *userbuf,
99 size_t count, loff_t *ppos)
100{
101 struct ieee80211_local *local = file->private_data;
102 char buf[128] = {};
103 char *bins = buf;
104 char *token;
105 int buf_size, i, alloc_size;
106 int prev_bin = 0;
107 int n_ranges = 0;
108 int ret = count;
109 struct ieee80211_tx_latency_bin_ranges *tx_latency;
110
111 if (sizeof(buf) <= count)
112 return -EINVAL;
113 buf_size = count;
114 if (copy_from_user(buf, userbuf, buf_size))
115 return -EFAULT;
116
117 mutex_lock(&local->sta_mtx);
118
119 /* cannot change config once we have stations */
120 if (local->num_sta)
121 goto unlock;
122
123 tx_latency =
124 rcu_dereference_protected(local->tx_latency,
125 lockdep_is_held(&local->sta_mtx));
126
127 /* disable Tx statistics */
128 if (!strcmp(buf, TX_LATENCY_DISABLED)) {
129 if (!tx_latency)
130 goto unlock;
131 rcu_assign_pointer(local->tx_latency, NULL);
132 synchronize_rcu();
133 kfree(tx_latency);
134 goto unlock;
135 }
136
137 /* Tx latency already enabled */
138 if (tx_latency)
139 goto unlock;
140
141 if (strcmp(TX_LATENCY_BINS_DISABLED, buf)) {
142 /* check how many bins and between what ranges user requested */
143 token = buf;
144 while (*token != '\0') {
145 if (*token == TX_LATENCY_BIN_DELIMTER_C)
146 n_ranges++;
147 token++;
148 }
149 n_ranges++;
150 }
151
152 alloc_size = sizeof(struct ieee80211_tx_latency_bin_ranges) +
153 n_ranges * sizeof(u32);
154 tx_latency = kzalloc(alloc_size, GFP_ATOMIC);
155 if (!tx_latency) {
156 ret = -ENOMEM;
157 goto unlock;
158 }
159 tx_latency->n_ranges = n_ranges;
160 for (i = 0; i < n_ranges; i++) { /* setting bin ranges */
161 token = strsep(&bins, TX_LATENCY_BIN_DELIMTER_S);
162 sscanf(token, "%d", &tx_latency->ranges[i]);
163 /* bins values should be in ascending order */
164 if (prev_bin >= tx_latency->ranges[i]) {
165 ret = -EINVAL;
166 kfree(tx_latency);
167 goto unlock;
168 }
169 prev_bin = tx_latency->ranges[i];
170 }
171 rcu_assign_pointer(local->tx_latency, tx_latency);
172
173unlock:
174 mutex_unlock(&local->sta_mtx);
175
176 return ret;
177}
178
179static const struct file_operations stats_tx_latency_ops = {
180 .write = sta_tx_latency_stat_write,
181 .read = sta_tx_latency_stat_read,
182 .open = simple_open,
183 .llseek = generic_file_llseek,
184};
185
20int mac80211_format_buffer(char __user *userbuf, size_t count, 186int mac80211_format_buffer(char __user *userbuf, size_t count,
21 loff_t *ppos, char *fmt, ...) 187 loff_t *ppos, char *fmt, ...)
22{ 188{
@@ -315,4 +481,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
315 DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount); 481 DEBUGFS_DEVSTATS_ADD(dot11RTSFailureCount);
316 DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount); 482 DEBUGFS_DEVSTATS_ADD(dot11FCSErrorCount);
317 DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount); 483 DEBUGFS_DEVSTATS_ADD(dot11RTSSuccessCount);
484
485 DEBUGFS_DEVSTATS_ADD(tx_latency);
318} 486}
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 19c54a44ed47..80194b557a0c 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -38,6 +38,13 @@ static const struct file_operations sta_ ##name## _ops = { \
38 .llseek = generic_file_llseek, \ 38 .llseek = generic_file_llseek, \
39} 39}
40 40
41#define STA_OPS_W(name) \
42static const struct file_operations sta_ ##name## _ops = { \
43 .write = sta_##name##_write, \
44 .open = simple_open, \
45 .llseek = generic_file_llseek, \
46}
47
41#define STA_OPS_RW(name) \ 48#define STA_OPS_RW(name) \
42static const struct file_operations sta_ ##name## _ops = { \ 49static const struct file_operations sta_ ##name## _ops = { \
43 .read = sta_##name##_read, \ 50 .read = sta_##name##_read, \
@@ -388,6 +395,131 @@ static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf,
388} 395}
389STA_OPS(last_rx_rate); 396STA_OPS(last_rx_rate);
390 397
398static int
399sta_tx_latency_stat_header(struct ieee80211_tx_latency_bin_ranges *tx_latency,
400 char *buf, int pos, int bufsz)
401{
402 int i;
403 int range_count = tx_latency->n_ranges;
404 u32 *bin_ranges = tx_latency->ranges;
405
406 pos += scnprintf(buf + pos, bufsz - pos,
407 "Station\t\t\tTID\tMax\tAvg");
408 if (range_count) {
409 pos += scnprintf(buf + pos, bufsz - pos,
410 "\t<=%d", bin_ranges[0]);
411 for (i = 0; i < range_count - 1; i++)
412 pos += scnprintf(buf + pos, bufsz - pos, "\t%d-%d",
413 bin_ranges[i], bin_ranges[i+1]);
414 pos += scnprintf(buf + pos, bufsz - pos,
415 "\t%d<", bin_ranges[range_count - 1]);
416 }
417
418 pos += scnprintf(buf + pos, bufsz - pos, "\n");
419
420 return pos;
421}
422
423static int
424sta_tx_latency_stat_table(struct ieee80211_tx_latency_bin_ranges *tx_lat_range,
425 struct ieee80211_tx_latency_stat *tx_lat,
426 char *buf, int pos, int bufsz, int tid)
427{
428 u32 avg = 0;
429 int j;
430 int bin_count = tx_lat->bin_count;
431
432 pos += scnprintf(buf + pos, bufsz - pos, "\t\t\t%d", tid);
433 /* make sure you don't divide in 0 */
434 if (tx_lat->counter)
435 avg = tx_lat->sum / tx_lat->counter;
436
437 pos += scnprintf(buf + pos, bufsz - pos, "\t%d\t%d",
438 tx_lat->max, avg);
439
440 if (tx_lat_range->n_ranges && tx_lat->bins)
441 for (j = 0; j < bin_count; j++)
442 pos += scnprintf(buf + pos, bufsz - pos,
443 "\t%d", tx_lat->bins[j]);
444 pos += scnprintf(buf + pos, bufsz - pos, "\n");
445
446 return pos;
447}
448
449/*
450 * Output Tx latency statistics station && restart all statistics information
451 */
452static ssize_t sta_tx_latency_stat_read(struct file *file,
453 char __user *userbuf,
454 size_t count, loff_t *ppos)
455{
456 struct sta_info *sta = file->private_data;
457 struct ieee80211_local *local = sta->local;
458 struct ieee80211_tx_latency_bin_ranges *tx_latency;
459 char *buf;
460 int bufsz, ret, i;
461 int pos = 0;
462
463 bufsz = 20 * IEEE80211_NUM_TIDS *
464 sizeof(struct ieee80211_tx_latency_stat);
465 buf = kzalloc(bufsz, GFP_KERNEL);
466 if (!buf)
467 return -ENOMEM;
468
469 rcu_read_lock();
470
471 tx_latency = rcu_dereference(local->tx_latency);
472
473 if (!sta->tx_lat) {
474 pos += scnprintf(buf + pos, bufsz - pos,
475 "Tx latency statistics are not enabled\n");
476 goto unlock;
477 }
478
479 pos = sta_tx_latency_stat_header(tx_latency, buf, pos, bufsz);
480
481 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", sta->sta.addr);
482 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
483 pos = sta_tx_latency_stat_table(tx_latency, &sta->tx_lat[i],
484 buf, pos, bufsz, i);
485unlock:
486 rcu_read_unlock();
487
488 ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
489 kfree(buf);
490
491 return ret;
492}
493STA_OPS(tx_latency_stat);
494
495static ssize_t sta_tx_latency_stat_reset_write(struct file *file,
496 const char __user *userbuf,
497 size_t count, loff_t *ppos)
498{
499 u32 *bins;
500 int bin_count;
501 struct sta_info *sta = file->private_data;
502 int i;
503
504 if (!sta->tx_lat)
505 return -EINVAL;
506
507 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
508 bins = sta->tx_lat[i].bins;
509 bin_count = sta->tx_lat[i].bin_count;
510
511 sta->tx_lat[i].max = 0;
512 sta->tx_lat[i].sum = 0;
513 sta->tx_lat[i].counter = 0;
514
515 if (bin_count)
516 memset(bins, 0, bin_count * sizeof(u32));
517 }
518
519 return count;
520}
521STA_OPS_W(tx_latency_stat_reset);
522
391#define DEBUGFS_ADD(name) \ 523#define DEBUGFS_ADD(name) \
392 debugfs_create_file(#name, 0400, \ 524 debugfs_create_file(#name, 0400, \
393 sta->debugfs.dir, sta, &sta_ ##name## _ops); 525 sta->debugfs.dir, sta, &sta_ ##name## _ops);
@@ -441,6 +573,8 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
441 DEBUGFS_ADD(last_ack_signal); 573 DEBUGFS_ADD(last_ack_signal);
442 DEBUGFS_ADD(current_tx_rate); 574 DEBUGFS_ADD(current_tx_rate);
443 DEBUGFS_ADD(last_rx_rate); 575 DEBUGFS_ADD(last_rx_rate);
576 DEBUGFS_ADD(tx_latency_stat);
577 DEBUGFS_ADD(tx_latency_stat_reset);
444 578
445 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); 579 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets);
446 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); 580 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 27a39de89679..2eda7b13124a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -550,12 +550,12 @@ int ieee80211_ibss_finish_csa(struct ieee80211_sub_if_data *sdata)
550 capability); 550 capability);
551 /* XXX: should not really modify cfg80211 data */ 551 /* XXX: should not really modify cfg80211 data */
552 if (cbss) { 552 if (cbss) {
553 cbss->channel = sdata->local->csa_chandef.chan; 553 cbss->channel = sdata->csa_chandef.chan;
554 cfg80211_put_bss(sdata->local->hw.wiphy, cbss); 554 cfg80211_put_bss(sdata->local->hw.wiphy, cbss);
555 } 555 }
556 } 556 }
557 557
558 ifibss->chandef = sdata->local->csa_chandef; 558 ifibss->chandef = sdata->csa_chandef;
559 559
560 /* generate the beacon */ 560 /* generate the beacon */
561 err = ieee80211_ibss_csa_beacon(sdata, NULL); 561 err = ieee80211_ibss_csa_beacon(sdata, NULL);
@@ -926,7 +926,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
926 IEEE80211_MAX_QUEUE_MAP, 926 IEEE80211_MAX_QUEUE_MAP,
927 IEEE80211_QUEUE_STOP_REASON_CSA); 927 IEEE80211_QUEUE_STOP_REASON_CSA);
928 928
929 sdata->local->csa_chandef = params.chandef; 929 sdata->csa_chandef = params.chandef;
930 sdata->vif.csa_active = true; 930 sdata->vif.csa_active = true;
931 931
932 ieee80211_bss_info_change_notify(sdata, err); 932 ieee80211_bss_info_change_notify(sdata, err);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4aea4e791113..ed5bf8b4b5c2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -728,6 +728,7 @@ struct ieee80211_sub_if_data {
728 u16 sequence_number; 728 u16 sequence_number;
729 __be16 control_port_protocol; 729 __be16 control_port_protocol;
730 bool control_port_no_encrypt; 730 bool control_port_no_encrypt;
731 int encrypt_headroom;
731 732
732 struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; 733 struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
733 734
@@ -735,6 +736,7 @@ struct ieee80211_sub_if_data {
735 int csa_counter_offset_beacon; 736 int csa_counter_offset_beacon;
736 int csa_counter_offset_presp; 737 int csa_counter_offset_presp;
737 bool csa_radar_required; 738 bool csa_radar_required;
739 struct cfg80211_chan_def csa_chandef;
738 740
739 /* used to reconfigure hardware SM PS */ 741 /* used to reconfigure hardware SM PS */
740 struct work_struct recalc_smps; 742 struct work_struct recalc_smps;
@@ -811,6 +813,9 @@ static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)
811 __release(&sdata->wdev.mtx); 813 __release(&sdata->wdev.mtx);
812} 814}
813 815
816#define sdata_dereference(p, sdata) \
817 rcu_dereference_protected(p, lockdep_is_held(&sdata->wdev.mtx))
818
814static inline void 819static inline void
815sdata_assert_lock(struct ieee80211_sub_if_data *sdata) 820sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
816{ 821{
@@ -896,6 +901,24 @@ struct tpt_led_trigger {
896}; 901};
897#endif 902#endif
898 903
904/*
905 * struct ieee80211_tx_latency_bin_ranges - Tx latency statistics bins ranges
906 *
907 * Measuring Tx latency statistics. Counts how many Tx frames transmitted in a
908 * certain latency range (in Milliseconds). Each station that uses these
909 * ranges will have bins to count the amount of frames received in that range.
910 * The user can configure the ranges via debugfs.
911 * If ranges is NULL then Tx latency statistics bins are disabled for all
912 * stations.
913 *
914 * @n_ranges: number of ranges that are taken in account
915 * @ranges: the ranges that the user requested or NULL if disabled.
916 */
917struct ieee80211_tx_latency_bin_ranges {
918 int n_ranges;
919 u32 ranges[];
920};
921
899/** 922/**
900 * mac80211 scan flags - currently active scan mode 923 * mac80211 scan flags - currently active scan mode
901 * 924 *
@@ -1048,6 +1071,12 @@ struct ieee80211_local {
1048 struct timer_list sta_cleanup; 1071 struct timer_list sta_cleanup;
1049 int sta_generation; 1072 int sta_generation;
1050 1073
1074 /*
1075 * Tx latency statistics parameters for all stations.
1076 * Can enable via debugfs (NULL when disabled).
1077 */
1078 struct ieee80211_tx_latency_bin_ranges __rcu *tx_latency;
1079
1051 struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; 1080 struct sk_buff_head pending[IEEE80211_MAX_QUEUES];
1052 struct tasklet_struct tx_pending_tasklet; 1081 struct tasklet_struct tx_pending_tasklet;
1053 1082
@@ -1093,7 +1122,6 @@ struct ieee80211_local {
1093 enum mac80211_scan_state next_scan_state; 1122 enum mac80211_scan_state next_scan_state;
1094 struct delayed_work scan_work; 1123 struct delayed_work scan_work;
1095 struct ieee80211_sub_if_data __rcu *scan_sdata; 1124 struct ieee80211_sub_if_data __rcu *scan_sdata;
1096 struct cfg80211_chan_def csa_chandef;
1097 /* For backward compatibility only -- do not use */ 1125 /* For backward compatibility only -- do not use */
1098 struct cfg80211_chan_def _oper_chandef; 1126 struct cfg80211_chan_def _oper_chandef;
1099 1127
@@ -1693,6 +1721,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
1693int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata, 1721int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
1694 enum ieee80211_smps_mode smps_mode); 1722 enum ieee80211_smps_mode smps_mode);
1695void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); 1723void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata);
1724void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
1696 1725
1697size_t ieee80211_ie_split(const u8 *ies, size_t ielen, 1726size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1698 const u8 *ids, int n_ids, size_t offset); 1727 const u8 *ids, int n_ids, size_t offset);
@@ -1731,7 +1760,6 @@ ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1731/* NOTE: only use ieee80211_vif_change_channel() for channel switch */ 1760/* NOTE: only use ieee80211_vif_change_channel() for channel switch */
1732int __must_check 1761int __must_check
1733ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, 1762ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata,
1734 const struct cfg80211_chan_def *chandef,
1735 u32 *changed); 1763 u32 *changed);
1736void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1764void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1737void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); 1765void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
@@ -1742,6 +1770,8 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
1742 struct ieee80211_chanctx *chanctx); 1770 struct ieee80211_chanctx *chanctx);
1743void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, 1771void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local,
1744 struct ieee80211_chanctx *chanctx); 1772 struct ieee80211_chanctx *chanctx);
1773void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local,
1774 struct ieee80211_chanctx *ctx);
1745 1775
1746void ieee80211_dfs_cac_timer(unsigned long data); 1776void ieee80211_dfs_cac_timer(unsigned long data);
1747void ieee80211_dfs_cac_timer_work(struct work_struct *work); 1777void ieee80211_dfs_cac_timer_work(struct work_struct *work);
@@ -1750,6 +1780,15 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work);
1750int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, 1780int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
1751 struct cfg80211_csa_settings *csa_settings); 1781 struct cfg80211_csa_settings *csa_settings);
1752 1782
1783bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs);
1784bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n);
1785const struct ieee80211_cipher_scheme *
1786ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
1787 enum nl80211_iftype iftype);
1788int ieee80211_cs_headroom(struct ieee80211_local *local,
1789 struct cfg80211_crypto_settings *crypto,
1790 enum nl80211_iftype iftype);
1791
1753#ifdef CONFIG_MAC80211_NOINLINE 1792#ifdef CONFIG_MAC80211_NOINLINE
1754#define debug_noinline noinline 1793#define debug_noinline noinline
1755#else 1794#else
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 36c3a4cbcabf..7aa9f9dea9df 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -401,6 +401,8 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
401 snprintf(sdata->name, IFNAMSIZ, "%s-monitor", 401 snprintf(sdata->name, IFNAMSIZ, "%s-monitor",
402 wiphy_name(local->hw.wiphy)); 402 wiphy_name(local->hw.wiphy));
403 403
404 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
405
404 ieee80211_set_default_queues(sdata); 406 ieee80211_set_default_queues(sdata);
405 407
406 ret = drv_add_interface(local, sdata); 408 ret = drv_add_interface(local, sdata);
@@ -749,6 +751,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
749 u32 hw_reconf_flags = 0; 751 u32 hw_reconf_flags = 0;
750 int i, flushed; 752 int i, flushed;
751 struct ps_data *ps; 753 struct ps_data *ps;
754 struct cfg80211_chan_def chandef;
752 755
753 clear_bit(SDATA_STATE_RUNNING, &sdata->state); 756 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
754 757
@@ -823,11 +826,13 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
823 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 826 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
824 827
825 if (sdata->wdev.cac_started) { 828 if (sdata->wdev.cac_started) {
829 chandef = sdata->vif.bss_conf.chandef;
826 WARN_ON(local->suspended); 830 WARN_ON(local->suspended);
827 mutex_lock(&local->iflist_mtx); 831 mutex_lock(&local->iflist_mtx);
828 ieee80211_vif_release_channel(sdata); 832 ieee80211_vif_release_channel(sdata);
829 mutex_unlock(&local->iflist_mtx); 833 mutex_unlock(&local->iflist_mtx);
830 cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, 834 cfg80211_cac_event(sdata->dev, &chandef,
835 NL80211_RADAR_CAC_ABORTED,
831 GFP_KERNEL); 836 GFP_KERNEL);
832 } 837 }
833 838
@@ -1036,7 +1041,6 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
1036 */ 1041 */
1037static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) 1042static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
1038{ 1043{
1039 int flushed;
1040 int i; 1044 int i;
1041 1045
1042 /* free extra data */ 1046 /* free extra data */
@@ -1050,9 +1054,6 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
1050 1054
1051 if (ieee80211_vif_is_mesh(&sdata->vif)) 1055 if (ieee80211_vif_is_mesh(&sdata->vif))
1052 mesh_rmc_free(sdata); 1056 mesh_rmc_free(sdata);
1053
1054 flushed = sta_info_flush(sdata);
1055 WARN_ON(flushed);
1056} 1057}
1057 1058
1058static void ieee80211_uninit(struct net_device *dev) 1059static void ieee80211_uninit(struct net_device *dev)
@@ -1270,6 +1271,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
1270 1271
1271 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); 1272 sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE);
1272 sdata->control_port_no_encrypt = false; 1273 sdata->control_port_no_encrypt = false;
1274 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
1273 1275
1274 sdata->noack_map = 0; 1276 sdata->noack_map = 0;
1275 1277
@@ -1685,6 +1687,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
1685 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; 1687 sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
1686 sdata->user_power_level = local->user_power_level; 1688 sdata->user_power_level = local->user_power_level;
1687 1689
1690 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
1691
1688 /* setup type-dependent data */ 1692 /* setup type-dependent data */
1689 ieee80211_setup_sdata(sdata, type); 1693 ieee80211_setup_sdata(sdata, type);
1690 1694
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 3e51dd7d98b3..e568d98167d0 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -260,25 +260,29 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
260 int idx; 260 int idx;
261 bool defunikey, defmultikey, defmgmtkey; 261 bool defunikey, defmultikey, defmgmtkey;
262 262
263 /* caller must provide at least one old/new */
264 if (WARN_ON(!new && !old))
265 return;
266
263 if (new) 267 if (new)
264 list_add_tail(&new->list, &sdata->key_list); 268 list_add_tail(&new->list, &sdata->key_list);
265 269
266 if (sta && pairwise) { 270 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
267 rcu_assign_pointer(sta->ptk, new);
268 } else if (sta) {
269 if (old)
270 idx = old->conf.keyidx;
271 else
272 idx = new->conf.keyidx;
273 rcu_assign_pointer(sta->gtk[idx], new);
274 } else {
275 WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
276 271
277 if (old) 272 if (old)
278 idx = old->conf.keyidx; 273 idx = old->conf.keyidx;
279 else 274 else
280 idx = new->conf.keyidx; 275 idx = new->conf.keyidx;
281 276
277 if (sta) {
278 if (pairwise) {
279 rcu_assign_pointer(sta->ptk[idx], new);
280 sta->ptk_idx = idx;
281 } else {
282 rcu_assign_pointer(sta->gtk[idx], new);
283 sta->gtk_idx = idx;
284 }
285 } else {
282 defunikey = old && 286 defunikey = old &&
283 old == key_mtx_dereference(sdata->local, 287 old == key_mtx_dereference(sdata->local,
284 sdata->default_unicast_key); 288 sdata->default_unicast_key);
@@ -312,9 +316,11 @@ static void ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
312 list_del(&old->list); 316 list_del(&old->list);
313} 317}
314 318
315struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 319struct ieee80211_key *
316 const u8 *key_data, 320ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
317 size_t seq_len, const u8 *seq) 321 const u8 *key_data,
322 size_t seq_len, const u8 *seq,
323 const struct ieee80211_cipher_scheme *cs)
318{ 324{
319 struct ieee80211_key *key; 325 struct ieee80211_key *key;
320 int i, j, err; 326 int i, j, err;
@@ -393,6 +399,18 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
393 return ERR_PTR(err); 399 return ERR_PTR(err);
394 } 400 }
395 break; 401 break;
402 default:
403 if (cs) {
404 size_t len = (seq_len > MAX_PN_LEN) ?
405 MAX_PN_LEN : seq_len;
406
407 key->conf.iv_len = cs->hdr_len;
408 key->conf.icv_len = cs->mic_len;
409 for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
410 for (j = 0; j < len; j++)
411 key->u.gen.rx_pn[i][j] =
412 seq[len - j - 1];
413 }
396 } 414 }
397 memcpy(key->conf.key, key_data, key_len); 415 memcpy(key->conf.key, key_data, key_len);
398 INIT_LIST_HEAD(&key->list); 416 INIT_LIST_HEAD(&key->list);
@@ -475,7 +493,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
475 mutex_lock(&sdata->local->key_mtx); 493 mutex_lock(&sdata->local->key_mtx);
476 494
477 if (sta && pairwise) 495 if (sta && pairwise)
478 old_key = key_mtx_dereference(sdata->local, sta->ptk); 496 old_key = key_mtx_dereference(sdata->local, sta->ptk[idx]);
479 else if (sta) 497 else if (sta)
480 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); 498 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]);
481 else 499 else
@@ -625,8 +643,10 @@ void ieee80211_free_sta_keys(struct ieee80211_local *local,
625 list_add(&key->list, &keys); 643 list_add(&key->list, &keys);
626 } 644 }
627 645
628 key = key_mtx_dereference(local, sta->ptk); 646 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
629 if (key) { 647 key = key_mtx_dereference(local, sta->ptk[i]);
648 if (!key)
649 continue;
630 ieee80211_key_replace(key->sdata, key->sta, 650 ieee80211_key_replace(key->sdata, key->sta,
631 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, 651 key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE,
632 key, NULL); 652 key, NULL);
@@ -877,7 +897,7 @@ ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
877 897
878 key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx, 898 key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx,
879 keyconf->keylen, keyconf->key, 899 keyconf->keylen, keyconf->key,
880 0, NULL); 900 0, NULL, NULL);
881 if (IS_ERR(key)) 901 if (IS_ERR(key))
882 return ERR_CAST(key); 902 return ERR_CAST(key);
883 903
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index aaae0ed37004..0aebb889caba 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -18,6 +18,7 @@
18 18
19#define NUM_DEFAULT_KEYS 4 19#define NUM_DEFAULT_KEYS 4
20#define NUM_DEFAULT_MGMT_KEYS 2 20#define NUM_DEFAULT_MGMT_KEYS 2
21#define MAX_PN_LEN 16
21 22
22struct ieee80211_local; 23struct ieee80211_local;
23struct ieee80211_sub_if_data; 24struct ieee80211_sub_if_data;
@@ -93,6 +94,10 @@ struct ieee80211_key {
93 u32 replays; /* dot11RSNAStatsCMACReplays */ 94 u32 replays; /* dot11RSNAStatsCMACReplays */
94 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ 95 u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
95 } aes_cmac; 96 } aes_cmac;
97 struct {
98 /* generic cipher scheme */
99 u8 rx_pn[IEEE80211_NUM_TIDS + 1][MAX_PN_LEN];
100 } gen;
96 } u; 101 } u;
97 102
98 /* number of times this key has been used */ 103 /* number of times this key has been used */
@@ -113,9 +118,11 @@ struct ieee80211_key {
113 struct ieee80211_key_conf conf; 118 struct ieee80211_key_conf conf;
114}; 119};
115 120
116struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, 121struct ieee80211_key *
117 const u8 *key_data, 122ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
118 size_t seq_len, const u8 *seq); 123 const u8 *key_data,
124 size_t seq_len, const u8 *seq,
125 const struct ieee80211_cipher_scheme *cs);
119/* 126/*
120 * Insert a key into data structures (sdata, sta if necessary) 127 * Insert a key into data structures (sdata, sta if necessary)
121 * to make it used, free old key. On failure, also free the new key. 128 * to make it used, free old key. On failure, also free the new key.
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 7d1c3ac48ed9..fa34cd2344b9 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -651,15 +651,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
651} 651}
652EXPORT_SYMBOL(ieee80211_alloc_hw); 652EXPORT_SYMBOL(ieee80211_alloc_hw);
653 653
654int ieee80211_register_hw(struct ieee80211_hw *hw) 654static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
655{ 655{
656 struct ieee80211_local *local = hw_to_local(hw); 656 bool have_wep = !(IS_ERR(local->wep_tx_tfm) ||
657 int result, i; 657 IS_ERR(local->wep_rx_tfm));
658 enum ieee80211_band band; 658 bool have_mfp = local->hw.flags & IEEE80211_HW_MFP_CAPABLE;
659 int channels, max_bitrates; 659 const struct ieee80211_cipher_scheme *cs = local->hw.cipher_schemes;
660 bool supp_ht, supp_vht; 660 int n_suites = 0, r = 0, w = 0;
661 netdev_features_t feature_whitelist; 661 u32 *suites;
662 struct cfg80211_chan_def dflt_chandef = {};
663 static const u32 cipher_suites[] = { 662 static const u32 cipher_suites[] = {
664 /* keep WEP first, it may be removed below */ 663 /* keep WEP first, it may be removed below */
665 WLAN_CIPHER_SUITE_WEP40, 664 WLAN_CIPHER_SUITE_WEP40,
@@ -671,6 +670,93 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
671 WLAN_CIPHER_SUITE_AES_CMAC 670 WLAN_CIPHER_SUITE_AES_CMAC
672 }; 671 };
673 672
673 /* Driver specifies the ciphers, we have nothing to do... */
674 if (local->hw.wiphy->cipher_suites && have_wep)
675 return 0;
676
677 /* Set up cipher suites if driver relies on mac80211 cipher defs */
678 if (!local->hw.wiphy->cipher_suites && !cs) {
679 local->hw.wiphy->cipher_suites = cipher_suites;
680 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
681
682 if (!have_mfp)
683 local->hw.wiphy->n_cipher_suites--;
684
685 if (!have_wep) {
686 local->hw.wiphy->cipher_suites += 2;
687 local->hw.wiphy->n_cipher_suites -= 2;
688 }
689
690 return 0;
691 }
692
693 if (!local->hw.wiphy->cipher_suites) {
694 /*
695 * Driver specifies cipher schemes only
696 * We start counting ciphers defined by schemes, TKIP and CCMP
697 */
698 n_suites = local->hw.n_cipher_schemes + 2;
699
700 /* check if we have WEP40 and WEP104 */
701 if (have_wep)
702 n_suites += 2;
703
704 /* check if we have AES_CMAC */
705 if (have_mfp)
706 n_suites++;
707
708 suites = kmalloc(sizeof(u32) * n_suites, GFP_KERNEL);
709 if (!suites)
710 return -ENOMEM;
711
712 suites[w++] = WLAN_CIPHER_SUITE_CCMP;
713 suites[w++] = WLAN_CIPHER_SUITE_TKIP;
714
715 if (have_wep) {
716 suites[w++] = WLAN_CIPHER_SUITE_WEP40;
717 suites[w++] = WLAN_CIPHER_SUITE_WEP104;
718 }
719
720 if (have_mfp)
721 suites[w++] = WLAN_CIPHER_SUITE_AES_CMAC;
722
723 for (r = 0; r < local->hw.n_cipher_schemes; r++)
724 suites[w++] = cs[r].cipher;
725 } else {
726 /* Driver provides cipher suites, but we need to exclude WEP */
727 suites = kmemdup(local->hw.wiphy->cipher_suites,
728 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
729 GFP_KERNEL);
730 if (!suites)
731 return -ENOMEM;
732
733 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
734 u32 suite = local->hw.wiphy->cipher_suites[r];
735
736 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
737 suite == WLAN_CIPHER_SUITE_WEP104)
738 continue;
739 suites[w++] = suite;
740 }
741 }
742
743 local->hw.wiphy->cipher_suites = suites;
744 local->hw.wiphy->n_cipher_suites = w;
745 local->wiphy_ciphers_allocated = true;
746
747 return 0;
748}
749
750int ieee80211_register_hw(struct ieee80211_hw *hw)
751{
752 struct ieee80211_local *local = hw_to_local(hw);
753 int result, i;
754 enum ieee80211_band band;
755 int channels, max_bitrates;
756 bool supp_ht, supp_vht;
757 netdev_features_t feature_whitelist;
758 struct cfg80211_chan_def dflt_chandef = {};
759
674 if (hw->flags & IEEE80211_HW_QUEUE_CONTROL && 760 if (hw->flags & IEEE80211_HW_QUEUE_CONTROL &&
675 (local->hw.offchannel_tx_hw_queue == IEEE80211_INVAL_HW_QUEUE || 761 (local->hw.offchannel_tx_hw_queue == IEEE80211_INVAL_HW_QUEUE ||
676 local->hw.offchannel_tx_hw_queue >= local->hw.queues)) 762 local->hw.offchannel_tx_hw_queue >= local->hw.queues))
@@ -851,43 +937,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
851 if (local->hw.wiphy->max_scan_ie_len) 937 if (local->hw.wiphy->max_scan_ie_len)
852 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; 938 local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
853 939
854 /* Set up cipher suites unless driver already did */ 940 WARN_ON(!ieee80211_cs_list_valid(local->hw.cipher_schemes,
855 if (!local->hw.wiphy->cipher_suites) { 941 local->hw.n_cipher_schemes));
856 local->hw.wiphy->cipher_suites = cipher_suites; 942
857 local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 943 result = ieee80211_init_cipher_suites(local);
858 if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) 944 if (result < 0)
859 local->hw.wiphy->n_cipher_suites--; 945 goto fail_wiphy_register;
860 }
861 if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) {
862 if (local->hw.wiphy->cipher_suites == cipher_suites) {
863 local->hw.wiphy->cipher_suites += 2;
864 local->hw.wiphy->n_cipher_suites -= 2;
865 } else {
866 u32 *suites;
867 int r, w = 0;
868
869 /* Filter out WEP */
870
871 suites = kmemdup(
872 local->hw.wiphy->cipher_suites,
873 sizeof(u32) * local->hw.wiphy->n_cipher_suites,
874 GFP_KERNEL);
875 if (!suites) {
876 result = -ENOMEM;
877 goto fail_wiphy_register;
878 }
879 for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) {
880 u32 suite = local->hw.wiphy->cipher_suites[r];
881 if (suite == WLAN_CIPHER_SUITE_WEP40 ||
882 suite == WLAN_CIPHER_SUITE_WEP104)
883 continue;
884 suites[w++] = suite;
885 }
886 local->hw.wiphy->cipher_suites = suites;
887 local->hw.wiphy->n_cipher_suites = w;
888 local->wiphy_ciphers_allocated = true;
889 }
890 }
891 946
892 if (!local->ops->remain_on_channel) 947 if (!local->ops->remain_on_channel)
893 local->hw.wiphy->max_remain_on_channel_duration = 5000; 948 local->hw.wiphy->max_remain_on_channel_duration = 5000;
@@ -1090,6 +1145,8 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1090 ieee80211_free_ack_frame, NULL); 1145 ieee80211_free_ack_frame, NULL);
1091 idr_destroy(&local->ack_status_frames); 1146 idr_destroy(&local->ack_status_frames);
1092 1147
1148 kfree(rcu_access_pointer(local->tx_latency));
1149
1093 wiphy_free(local->hw.wiphy); 1150 wiphy_free(local->hw.wiphy);
1094} 1151}
1095EXPORT_SYMBOL(ieee80211_free_hw); 1152EXPORT_SYMBOL(ieee80211_free_hw);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index ba105257d03f..89df62b2b689 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -674,8 +674,6 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
674 rcu_read_lock(); 674 rcu_read_lock();
675 csa = rcu_dereference(ifmsh->csa); 675 csa = rcu_dereference(ifmsh->csa);
676 if (csa) { 676 if (csa) {
677 __le16 pre_value;
678
679 pos = skb_put(skb, 13); 677 pos = skb_put(skb, 13);
680 memset(pos, 0, 13); 678 memset(pos, 0, 13);
681 *pos++ = WLAN_EID_CHANNEL_SWITCH; 679 *pos++ = WLAN_EID_CHANNEL_SWITCH;
@@ -697,8 +695,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
697 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; 695 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
698 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); 696 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos);
699 pos += 2; 697 pos += 2;
700 pre_value = cpu_to_le16(ifmsh->pre_value); 698 put_unaligned_le16(ifmsh->pre_value, pos);
701 memcpy(pos, &pre_value, 2);
702 pos += 2; 699 pos += 2;
703 } 700 }
704 rcu_read_unlock(); 701 rcu_read_unlock();
@@ -964,7 +961,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
964 IEEE80211_MAX_QUEUE_MAP, 961 IEEE80211_MAX_QUEUE_MAP,
965 IEEE80211_QUEUE_STOP_REASON_CSA); 962 IEEE80211_QUEUE_STOP_REASON_CSA);
966 963
967 sdata->local->csa_chandef = params.chandef; 964 sdata->csa_chandef = params.chandef;
968 sdata->vif.csa_active = true; 965 sdata->vif.csa_active = true;
969 966
970 ieee80211_bss_info_change_notify(sdata, err); 967 ieee80211_bss_info_change_notify(sdata, err);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 2bc7fd2f787d..f39a19f9090f 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -215,8 +215,6 @@ int mesh_rmc_check(struct ieee80211_sub_if_data *sdata,
215bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 215bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
216 struct ieee802_11_elems *ie); 216 struct ieee802_11_elems *ie);
217void mesh_ids_set_default(struct ieee80211_if_mesh *mesh); 217void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
218void mesh_mgmt_ies_add(struct ieee80211_sub_if_data *sdata,
219 struct sk_buff *skb);
220int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, 218int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
221 struct sk_buff *skb); 219 struct sk_buff *skb);
222int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, 220int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata,
@@ -303,8 +301,8 @@ void mesh_mpath_table_grow(void);
303void mesh_mpp_table_grow(void); 301void mesh_mpp_table_grow(void);
304/* Mesh paths */ 302/* Mesh paths */
305int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 303int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
306 u8 ttl, const u8 *target, __le32 target_sn, 304 u8 ttl, const u8 *target, u32 target_sn,
307 __le16 target_rcode, const u8 *ra); 305 u16 target_rcode, const u8 *ra);
308void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 306void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
309void mesh_path_flush_pending(struct mesh_path *mpath); 307void mesh_path_flush_pending(struct mesh_path *mpath);
310void mesh_path_tx_pending(struct mesh_path *mpath); 308void mesh_path_tx_pending(struct mesh_path *mpath);
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 486819cd02cd..f9514685d45a 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -102,12 +102,11 @@ enum mpath_frame_type {
102static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 102static const u8 broadcast_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
103 103
104static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, 104static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
105 const u8 *orig_addr, __le32 orig_sn, 105 const u8 *orig_addr, u32 orig_sn,
106 u8 target_flags, const u8 *target, 106 u8 target_flags, const u8 *target,
107 __le32 target_sn, const u8 *da, 107 u32 target_sn, const u8 *da,
108 u8 hop_count, u8 ttl, 108 u8 hop_count, u8 ttl,
109 __le32 lifetime, __le32 metric, 109 u32 lifetime, u32 metric, u32 preq_id,
110 __le32 preq_id,
111 struct ieee80211_sub_if_data *sdata) 110 struct ieee80211_sub_if_data *sdata)
112{ 111{
113 struct ieee80211_local *local = sdata->local; 112 struct ieee80211_local *local = sdata->local;
@@ -167,33 +166,33 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
167 if (action == MPATH_PREP) { 166 if (action == MPATH_PREP) {
168 memcpy(pos, target, ETH_ALEN); 167 memcpy(pos, target, ETH_ALEN);
169 pos += ETH_ALEN; 168 pos += ETH_ALEN;
170 memcpy(pos, &target_sn, 4); 169 put_unaligned_le32(target_sn, pos);
171 pos += 4; 170 pos += 4;
172 } else { 171 } else {
173 if (action == MPATH_PREQ) { 172 if (action == MPATH_PREQ) {
174 memcpy(pos, &preq_id, 4); 173 put_unaligned_le32(preq_id, pos);
175 pos += 4; 174 pos += 4;
176 } 175 }
177 memcpy(pos, orig_addr, ETH_ALEN); 176 memcpy(pos, orig_addr, ETH_ALEN);
178 pos += ETH_ALEN; 177 pos += ETH_ALEN;
179 memcpy(pos, &orig_sn, 4); 178 put_unaligned_le32(orig_sn, pos);
180 pos += 4; 179 pos += 4;
181 } 180 }
182 memcpy(pos, &lifetime, 4); /* interval for RANN */ 181 put_unaligned_le32(lifetime, pos); /* interval for RANN */
183 pos += 4; 182 pos += 4;
184 memcpy(pos, &metric, 4); 183 put_unaligned_le32(metric, pos);
185 pos += 4; 184 pos += 4;
186 if (action == MPATH_PREQ) { 185 if (action == MPATH_PREQ) {
187 *pos++ = 1; /* destination count */ 186 *pos++ = 1; /* destination count */
188 *pos++ = target_flags; 187 *pos++ = target_flags;
189 memcpy(pos, target, ETH_ALEN); 188 memcpy(pos, target, ETH_ALEN);
190 pos += ETH_ALEN; 189 pos += ETH_ALEN;
191 memcpy(pos, &target_sn, 4); 190 put_unaligned_le32(target_sn, pos);
192 pos += 4; 191 pos += 4;
193 } else if (action == MPATH_PREP) { 192 } else if (action == MPATH_PREP) {
194 memcpy(pos, orig_addr, ETH_ALEN); 193 memcpy(pos, orig_addr, ETH_ALEN);
195 pos += ETH_ALEN; 194 pos += ETH_ALEN;
196 memcpy(pos, &orig_sn, 4); 195 put_unaligned_le32(orig_sn, pos);
197 pos += 4; 196 pos += 4;
198 } 197 }
199 198
@@ -239,8 +238,8 @@ static void prepare_frame_for_deferred_tx(struct ieee80211_sub_if_data *sdata,
239 * frame directly but add it to the pending queue instead. 238 * frame directly but add it to the pending queue instead.
240 */ 239 */
241int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 240int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
242 u8 ttl, const u8 *target, __le32 target_sn, 241 u8 ttl, const u8 *target, u32 target_sn,
243 __le16 target_rcode, const u8 *ra) 242 u16 target_rcode, const u8 *ra)
244{ 243{
245 struct ieee80211_local *local = sdata->local; 244 struct ieee80211_local *local = sdata->local;
246 struct sk_buff *skb; 245 struct sk_buff *skb;
@@ -254,13 +253,13 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
254 return -EAGAIN; 253 return -EAGAIN;
255 254
256 skb = dev_alloc_skb(local->tx_headroom + 255 skb = dev_alloc_skb(local->tx_headroom +
257 IEEE80211_ENCRYPT_HEADROOM + 256 sdata->encrypt_headroom +
258 IEEE80211_ENCRYPT_TAILROOM + 257 IEEE80211_ENCRYPT_TAILROOM +
259 hdr_len + 258 hdr_len +
260 2 + 15 /* PERR IE */); 259 2 + 15 /* PERR IE */);
261 if (!skb) 260 if (!skb)
262 return -1; 261 return -1;
263 skb_reserve(skb, local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM); 262 skb_reserve(skb, local->tx_headroom + sdata->encrypt_headroom);
264 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 263 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
265 memset(mgmt, 0, hdr_len); 264 memset(mgmt, 0, hdr_len);
266 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 265 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
@@ -293,9 +292,9 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata,
293 pos++; 292 pos++;
294 memcpy(pos, target, ETH_ALEN); 293 memcpy(pos, target, ETH_ALEN);
295 pos += ETH_ALEN; 294 pos += ETH_ALEN;
296 memcpy(pos, &target_sn, 4); 295 put_unaligned_le32(target_sn, pos);
297 pos += 4; 296 pos += 4;
298 memcpy(pos, &target_rcode, 2); 297 put_unaligned_le16(target_rcode, pos);
299 298
300 /* see note in function header */ 299 /* see note in function header */
301 prepare_frame_for_deferred_tx(sdata, skb); 300 prepare_frame_for_deferred_tx(sdata, skb);
@@ -592,10 +591,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
592 if (ttl != 0) { 591 if (ttl != 0) {
593 mhwmp_dbg(sdata, "replying to the PREQ\n"); 592 mhwmp_dbg(sdata, "replying to the PREQ\n");
594 mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, 593 mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr,
595 cpu_to_le32(orig_sn), 0, target_addr, 594 orig_sn, 0, target_addr,
596 cpu_to_le32(target_sn), mgmt->sa, 0, ttl, 595 target_sn, mgmt->sa, 0, ttl,
597 cpu_to_le32(lifetime), cpu_to_le32(metric), 596 lifetime, metric, 0, sdata);
598 0, sdata);
599 } else { 597 } else {
600 ifmsh->mshstats.dropped_frames_ttl++; 598 ifmsh->mshstats.dropped_frames_ttl++;
601 } 599 }
@@ -625,11 +623,9 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
625 } 623 }
626 624
627 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 625 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
628 cpu_to_le32(orig_sn), target_flags, target_addr, 626 orig_sn, target_flags, target_addr,
629 cpu_to_le32(target_sn), da, 627 target_sn, da, hopcount, ttl, lifetime,
630 hopcount, ttl, cpu_to_le32(lifetime), 628 metric, preq_id, sdata);
631 cpu_to_le32(metric), cpu_to_le32(preq_id),
632 sdata);
633 if (!is_multicast_ether_addr(da)) 629 if (!is_multicast_ether_addr(da))
634 ifmsh->mshstats.fwded_unicast++; 630 ifmsh->mshstats.fwded_unicast++;
635 else 631 else
@@ -695,11 +691,9 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
695 target_sn = PREP_IE_TARGET_SN(prep_elem); 691 target_sn = PREP_IE_TARGET_SN(prep_elem);
696 orig_sn = PREP_IE_ORIG_SN(prep_elem); 692 orig_sn = PREP_IE_ORIG_SN(prep_elem);
697 693
698 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 694 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, orig_sn, 0,
699 cpu_to_le32(orig_sn), 0, target_addr, 695 target_addr, target_sn, next_hop, hopcount,
700 cpu_to_le32(target_sn), next_hop, hopcount, 696 ttl, lifetime, metric, 0, sdata);
701 ttl, cpu_to_le32(lifetime), cpu_to_le32(metric),
702 0, sdata);
703 rcu_read_unlock(); 697 rcu_read_unlock();
704 698
705 sdata->u.mesh.mshstats.fwded_unicast++; 699 sdata->u.mesh.mshstats.fwded_unicast++;
@@ -750,8 +744,7 @@ static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
750 if (!ifmsh->mshcfg.dot11MeshForwarding) 744 if (!ifmsh->mshcfg.dot11MeshForwarding)
751 goto endperr; 745 goto endperr;
752 mesh_path_error_tx(sdata, ttl, target_addr, 746 mesh_path_error_tx(sdata, ttl, target_addr,
753 cpu_to_le32(target_sn), 747 target_sn, target_rcode,
754 cpu_to_le16(target_rcode),
755 broadcast_addr); 748 broadcast_addr);
756 } else 749 } else
757 spin_unlock_bh(&mpath->state_lock); 750 spin_unlock_bh(&mpath->state_lock);
@@ -847,11 +840,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
847 840
848 if (ifmsh->mshcfg.dot11MeshForwarding) { 841 if (ifmsh->mshcfg.dot11MeshForwarding) {
849 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, 842 mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
850 cpu_to_le32(orig_sn), 843 orig_sn, 0, NULL, 0, broadcast_addr,
851 0, NULL, 0, broadcast_addr, 844 hopcount, ttl, interval,
852 hopcount, ttl, cpu_to_le32(interval), 845 metric + metric_txsta, 0, sdata);
853 cpu_to_le32(metric + metric_txsta),
854 0, sdata);
855 } 846 }
856 847
857 rcu_read_unlock(); 848 rcu_read_unlock();
@@ -1049,11 +1040,9 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
1049 1040
1050 spin_unlock_bh(&mpath->state_lock); 1041 spin_unlock_bh(&mpath->state_lock);
1051 da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; 1042 da = (mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr;
1052 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, 1043 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn,
1053 cpu_to_le32(ifmsh->sn), target_flags, mpath->dst, 1044 target_flags, mpath->dst, mpath->sn, da, 0,
1054 cpu_to_le32(mpath->sn), da, 0, 1045 ttl, lifetime, 0, ifmsh->preq_id++, sdata);
1055 ttl, cpu_to_le32(lifetime), 0,
1056 cpu_to_le32(ifmsh->preq_id++), sdata);
1057 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); 1046 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
1058 1047
1059enddiscovery: 1048enddiscovery:
@@ -1212,10 +1201,9 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1212 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { 1201 switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) {
1213 case IEEE80211_PROACTIVE_RANN: 1202 case IEEE80211_PROACTIVE_RANN:
1214 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, 1203 mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr,
1215 cpu_to_le32(++ifmsh->sn), 1204 ++ifmsh->sn, 0, NULL, 0, broadcast_addr,
1216 0, NULL, 0, broadcast_addr, 1205 0, ifmsh->mshcfg.element_ttl,
1217 0, ifmsh->mshcfg.element_ttl, 1206 interval, 0, 0, sdata);
1218 cpu_to_le32(interval), 0, 0, sdata);
1219 break; 1207 break;
1220 case IEEE80211_PROACTIVE_PREQ_WITH_PREP: 1208 case IEEE80211_PROACTIVE_PREQ_WITH_PREP:
1221 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; 1209 flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG;
@@ -1224,11 +1212,10 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata)
1224 target_flags |= IEEE80211_PREQ_TO_FLAG | 1212 target_flags |= IEEE80211_PREQ_TO_FLAG |
1225 IEEE80211_PREQ_USN_FLAG; 1213 IEEE80211_PREQ_USN_FLAG;
1226 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, 1214 mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr,
1227 cpu_to_le32(++ifmsh->sn), target_flags, 1215 ++ifmsh->sn, target_flags,
1228 (u8 *) broadcast_addr, 0, broadcast_addr, 1216 (u8 *) broadcast_addr, 0, broadcast_addr,
1229 0, ifmsh->mshcfg.element_ttl, 1217 0, ifmsh->mshcfg.element_ttl, interval,
1230 cpu_to_le32(interval), 1218 0, ifmsh->preq_id++, sdata);
1231 0, cpu_to_le32(ifmsh->preq_id++), sdata);
1232 break; 1219 break;
1233 default: 1220 default:
1234 mhwmp_dbg(sdata, "Proactive mechanism not supported\n"); 1221 mhwmp_dbg(sdata, "Proactive mechanism not supported\n");
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 89aacfd2756d..7d050ed6fe5a 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -722,7 +722,6 @@ void mesh_plink_broken(struct sta_info *sta)
722 struct mpath_node *node; 722 struct mpath_node *node;
723 struct ieee80211_sub_if_data *sdata = sta->sdata; 723 struct ieee80211_sub_if_data *sdata = sta->sdata;
724 int i; 724 int i;
725 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
726 725
727 rcu_read_lock(); 726 rcu_read_lock();
728 tbl = rcu_dereference(mesh_paths); 727 tbl = rcu_dereference(mesh_paths);
@@ -736,9 +735,9 @@ void mesh_plink_broken(struct sta_info *sta)
736 ++mpath->sn; 735 ++mpath->sn;
737 spin_unlock_bh(&mpath->state_lock); 736 spin_unlock_bh(&mpath->state_lock);
738 mesh_path_error_tx(sdata, 737 mesh_path_error_tx(sdata,
739 sdata->u.mesh.mshcfg.element_ttl, 738 sdata->u.mesh.mshcfg.element_ttl,
740 mpath->dst, cpu_to_le32(mpath->sn), 739 mpath->dst, mpath->sn,
741 reason, bcast); 740 WLAN_REASON_MESH_PATH_DEST_UNREACHABLE, bcast);
742 } 741 }
743 } 742 }
744 rcu_read_unlock(); 743 rcu_read_unlock();
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 4301aa5aa227..cf83217103f9 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -19,12 +19,6 @@
19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \ 19#define mod_plink_timer(s, t) (mod_timer(&s->plink_timer, \
20 jiffies + HZ * t / 1000)) 20 jiffies + HZ * t / 1000))
21 21
22/* We only need a valid sta if user configured a minimum rssi_threshold. */
23#define rssi_threshold_check(sta, sdata) \
24 (sdata->u.mesh.mshcfg.rssi_threshold == 0 ||\
25 (sta && (s8) -ewma_read(&sta->avg_signal) > \
26 sdata->u.mesh.mshcfg.rssi_threshold))
27
28enum plink_event { 22enum plink_event {
29 PLINK_UNDEFINED, 23 PLINK_UNDEFINED,
30 OPN_ACPT, 24 OPN_ACPT,
@@ -61,7 +55,17 @@ static const char * const mplevents[] = {
61 55
62static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 56static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
63 enum ieee80211_self_protected_actioncode action, 57 enum ieee80211_self_protected_actioncode action,
64 u8 *da, __le16 llid, __le16 plid, __le16 reason); 58 u8 *da, u16 llid, u16 plid, u16 reason);
59
60
61/* We only need a valid sta if user configured a minimum rssi_threshold. */
62static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
63 struct sta_info *sta)
64{
65 s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
66 return rssi_threshold == 0 ||
67 (sta && (s8) -ewma_read(&sta->avg_signal) > rssi_threshold);
68}
65 69
66/** 70/**
67 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine 71 * mesh_plink_fsm_restart - restart a mesh peer link finite state machine
@@ -242,7 +246,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
242 246
243 spin_lock_bh(&sta->lock); 247 spin_lock_bh(&sta->lock);
244 changed = __mesh_plink_deactivate(sta); 248 changed = __mesh_plink_deactivate(sta);
245 sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED); 249 sta->reason = WLAN_REASON_MESH_PEER_CANCELED;
246 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 250 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
247 sta->sta.addr, sta->llid, sta->plid, 251 sta->sta.addr, sta->llid, sta->plid,
248 sta->reason); 252 sta->reason);
@@ -253,7 +257,7 @@ u32 mesh_plink_deactivate(struct sta_info *sta)
253 257
254static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, 258static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
255 enum ieee80211_self_protected_actioncode action, 259 enum ieee80211_self_protected_actioncode action,
256 u8 *da, __le16 llid, __le16 plid, __le16 reason) 260 u8 *da, u16 llid, u16 plid, u16 reason)
257{ 261{
258 struct ieee80211_local *local = sdata->local; 262 struct ieee80211_local *local = sdata->local;
259 struct sk_buff *skb; 263 struct sk_buff *skb;
@@ -279,7 +283,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
279 2 + 8 + /* peering IE */ 283 2 + 8 + /* peering IE */
280 sdata->u.mesh.ie_len); 284 sdata->u.mesh.ie_len);
281 if (!skb) 285 if (!skb)
282 return -1; 286 return err;
283 info = IEEE80211_SKB_CB(skb); 287 info = IEEE80211_SKB_CB(skb);
284 skb_reserve(skb, local->tx_headroom); 288 skb_reserve(skb, local->tx_headroom);
285 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len); 289 mgmt = (struct ieee80211_mgmt *) skb_put(skb, hdr_len);
@@ -301,7 +305,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
301 if (action == WLAN_SP_MESH_PEERING_CONFIRM) { 305 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
302 /* AID */ 306 /* AID */
303 pos = skb_put(skb, 2); 307 pos = skb_put(skb, 2);
304 memcpy(pos + 2, &plid, 2); 308 put_unaligned_le16(plid, pos + 2);
305 } 309 }
306 if (ieee80211_add_srates_ie(sdata, skb, true, band) || 310 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
307 ieee80211_add_ext_srates_ie(sdata, skb, true, band) || 311 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
@@ -343,14 +347,14 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
343 *pos++ = ie_len; 347 *pos++ = ie_len;
344 memcpy(pos, &peering_proto, 2); 348 memcpy(pos, &peering_proto, 2);
345 pos += 2; 349 pos += 2;
346 memcpy(pos, &llid, 2); 350 put_unaligned_le16(llid, pos);
347 pos += 2; 351 pos += 2;
348 if (include_plid) { 352 if (include_plid) {
349 memcpy(pos, &plid, 2); 353 put_unaligned_le16(plid, pos);
350 pos += 2; 354 pos += 2;
351 } 355 }
352 if (action == WLAN_SP_MESH_PEERING_CLOSE) { 356 if (action == WLAN_SP_MESH_PEERING_CLOSE) {
353 memcpy(pos, &reason, 2); 357 put_unaligned_le16(reason, pos);
354 pos += 2; 358 pos += 2;
355 } 359 }
356 360
@@ -518,7 +522,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
518 sta->plink_state == NL80211_PLINK_LISTEN && 522 sta->plink_state == NL80211_PLINK_LISTEN &&
519 sdata->u.mesh.accepting_plinks && 523 sdata->u.mesh.accepting_plinks &&
520 sdata->u.mesh.mshcfg.auto_open_plinks && 524 sdata->u.mesh.mshcfg.auto_open_plinks &&
521 rssi_threshold_check(sta, sdata)) 525 rssi_threshold_check(sdata, sta))
522 changed = mesh_plink_open(sta); 526 changed = mesh_plink_open(sta);
523 527
524 ieee80211_mps_frame_release(sta, elems); 528 ieee80211_mps_frame_release(sta, elems);
@@ -530,9 +534,10 @@ out:
530static void mesh_plink_timer(unsigned long data) 534static void mesh_plink_timer(unsigned long data)
531{ 535{
532 struct sta_info *sta; 536 struct sta_info *sta;
533 __le16 llid, plid, reason; 537 u16 reason = 0;
534 struct ieee80211_sub_if_data *sdata; 538 struct ieee80211_sub_if_data *sdata;
535 struct mesh_config *mshcfg; 539 struct mesh_config *mshcfg;
540 enum ieee80211_self_protected_actioncode action = 0;
536 541
537 /* 542 /*
538 * This STA is valid because sta_info_destroy() will 543 * This STA is valid because sta_info_destroy() will
@@ -553,9 +558,6 @@ static void mesh_plink_timer(unsigned long data)
553 mpl_dbg(sta->sdata, 558 mpl_dbg(sta->sdata,
554 "Mesh plink timer for %pM fired on state %s\n", 559 "Mesh plink timer for %pM fired on state %s\n",
555 sta->sta.addr, mplstates[sta->plink_state]); 560 sta->sta.addr, mplstates[sta->plink_state]);
556 reason = 0;
557 llid = sta->llid;
558 plid = sta->plid;
559 sdata = sta->sdata; 561 sdata = sta->sdata;
560 mshcfg = &sdata->u.mesh.mshcfg; 562 mshcfg = &sdata->u.mesh.mshcfg;
561 563
@@ -574,33 +576,31 @@ static void mesh_plink_timer(unsigned long data)
574 rand % sta->plink_timeout; 576 rand % sta->plink_timeout;
575 ++sta->plink_retries; 577 ++sta->plink_retries;
576 mod_plink_timer(sta, sta->plink_timeout); 578 mod_plink_timer(sta, sta->plink_timeout);
577 spin_unlock_bh(&sta->lock); 579 action = WLAN_SP_MESH_PEERING_OPEN;
578 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
579 sta->sta.addr, llid, 0, 0);
580 break; 580 break;
581 } 581 }
582 reason = cpu_to_le16(WLAN_REASON_MESH_MAX_RETRIES); 582 reason = WLAN_REASON_MESH_MAX_RETRIES;
583 /* fall through on else */ 583 /* fall through on else */
584 case NL80211_PLINK_CNF_RCVD: 584 case NL80211_PLINK_CNF_RCVD:
585 /* confirm timer */ 585 /* confirm timer */
586 if (!reason) 586 if (!reason)
587 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIRM_TIMEOUT); 587 reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
588 sta->plink_state = NL80211_PLINK_HOLDING; 588 sta->plink_state = NL80211_PLINK_HOLDING;
589 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout); 589 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
590 spin_unlock_bh(&sta->lock); 590 action = WLAN_SP_MESH_PEERING_CLOSE;
591 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
592 sta->sta.addr, llid, plid, reason);
593 break; 591 break;
594 case NL80211_PLINK_HOLDING: 592 case NL80211_PLINK_HOLDING:
595 /* holding timer */ 593 /* holding timer */
596 del_timer(&sta->plink_timer); 594 del_timer(&sta->plink_timer);
597 mesh_plink_fsm_restart(sta); 595 mesh_plink_fsm_restart(sta);
598 spin_unlock_bh(&sta->lock);
599 break; 596 break;
600 default: 597 default:
601 spin_unlock_bh(&sta->lock);
602 break; 598 break;
603 } 599 }
600 spin_unlock_bh(&sta->lock);
601 if (action)
602 mesh_plink_frame_tx(sdata, action, sta->sta.addr,
603 sta->llid, sta->plid, reason);
604} 604}
605 605
606static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout) 606static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
@@ -612,9 +612,40 @@ static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
612 add_timer(&sta->plink_timer); 612 add_timer(&sta->plink_timer);
613} 613}
614 614
615static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
616 u16 llid)
617{
618 struct ieee80211_local *local = sdata->local;
619 bool in_use = false;
620 struct sta_info *sta;
621
622 rcu_read_lock();
623 list_for_each_entry_rcu(sta, &local->sta_list, list) {
624 if (!memcmp(&sta->llid, &llid, sizeof(llid))) {
625 in_use = true;
626 break;
627 }
628 }
629 rcu_read_unlock();
630
631 return in_use;
632}
633
634static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
635{
636 u16 llid;
637
638 do {
639 get_random_bytes(&llid, sizeof(llid));
640 /* for mesh PS we still only have the AID range for TIM bits */
641 llid = (llid % IEEE80211_MAX_AID) + 1;
642 } while (llid_in_use(sdata, llid));
643
644 return llid;
645}
646
615u32 mesh_plink_open(struct sta_info *sta) 647u32 mesh_plink_open(struct sta_info *sta)
616{ 648{
617 __le16 llid;
618 struct ieee80211_sub_if_data *sdata = sta->sdata; 649 struct ieee80211_sub_if_data *sdata = sta->sdata;
619 u32 changed; 650 u32 changed;
620 651
@@ -622,8 +653,7 @@ u32 mesh_plink_open(struct sta_info *sta)
622 return 0; 653 return 0;
623 654
624 spin_lock_bh(&sta->lock); 655 spin_lock_bh(&sta->lock);
625 get_random_bytes(&llid, 2); 656 sta->llid = mesh_get_new_llid(sdata);
626 sta->llid = llid;
627 if (sta->plink_state != NL80211_PLINK_LISTEN && 657 if (sta->plink_state != NL80211_PLINK_LISTEN &&
628 sta->plink_state != NL80211_PLINK_BLOCKED) { 658 sta->plink_state != NL80211_PLINK_BLOCKED) {
629 spin_unlock_bh(&sta->lock); 659 spin_unlock_bh(&sta->lock);
@@ -640,7 +670,7 @@ u32 mesh_plink_open(struct sta_info *sta)
640 changed = ieee80211_mps_local_status_update(sdata); 670 changed = ieee80211_mps_local_status_update(sdata);
641 671
642 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, 672 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN,
643 sta->sta.addr, llid, 0, 0); 673 sta->sta.addr, sta->llid, 0, 0);
644 return changed; 674 return changed;
645} 675}
646 676
@@ -656,390 +686,147 @@ u32 mesh_plink_block(struct sta_info *sta)
656 return changed; 686 return changed;
657} 687}
658 688
659 689static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
660void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 690 struct sta_info *sta,
661 struct ieee80211_mgmt *mgmt, size_t len, 691 enum plink_event event)
662 struct ieee80211_rx_status *rx_status)
663{ 692{
664 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; 693 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
665 struct ieee802_11_elems elems;
666 struct sta_info *sta;
667 enum plink_event event;
668 enum ieee80211_self_protected_actioncode ftype;
669 size_t baselen;
670 bool matches_local = true;
671 u8 ie_len;
672 u8 *baseaddr;
673 u32 changed = 0;
674 __le16 plid, llid, reason;
675
676 /* need action_code, aux */
677 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
678 return;
679
680 if (sdata->u.mesh.user_mpm)
681 /* userspace must register for these */
682 return;
683
684 if (is_multicast_ether_addr(mgmt->da)) {
685 mpl_dbg(sdata,
686 "Mesh plink: ignore frame from multicast address\n");
687 return;
688 }
689
690 baseaddr = mgmt->u.action.u.self_prot.variable;
691 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
692 if (mgmt->u.action.u.self_prot.action_code ==
693 WLAN_SP_MESH_PEERING_CONFIRM) {
694 baseaddr += 4;
695 baselen += 4;
696 }
697 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
698
699 if (!elems.peering) {
700 mpl_dbg(sdata,
701 "Mesh plink: missing necessary peer link ie\n");
702 return;
703 }
704 694
705 if (elems.rsn_len && 695 u16 reason = (event == CLS_ACPT) ?
706 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { 696 WLAN_REASON_MESH_CLOSE : WLAN_REASON_MESH_CONFIG;
707 mpl_dbg(sdata,
708 "Mesh plink: can't establish link with secure peer\n");
709 return;
710 }
711 697
712 ftype = mgmt->u.action.u.self_prot.action_code; 698 sta->reason = reason;
713 ie_len = elems.peering_len; 699 sta->plink_state = NL80211_PLINK_HOLDING;
714 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) || 700 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
715 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || 701}
716 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
717 && ie_len != 8)) {
718 mpl_dbg(sdata,
719 "Mesh plink: incorrect plink ie length %d %d\n",
720 ftype, ie_len);
721 return;
722 }
723
724 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
725 (!elems.mesh_id || !elems.mesh_config)) {
726 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
727 return;
728 }
729 /* Note the lines below are correct, the llid in the frame is the plid
730 * from the point of view of this host.
731 */
732 memcpy(&plid, PLINK_GET_LLID(elems.peering), 2);
733 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
734 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
735 memcpy(&llid, PLINK_GET_PLID(elems.peering), 2);
736
737 /* WARNING: Only for sta pointer, is dropped & re-acquired */
738 rcu_read_lock();
739
740 sta = sta_info_get(sdata, mgmt->sa);
741 if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) {
742 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
743 rcu_read_unlock();
744 return;
745 }
746
747 if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
748 !rssi_threshold_check(sta, sdata)) {
749 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
750 mgmt->sa);
751 rcu_read_unlock();
752 return;
753 }
754
755 if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) {
756 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
757 rcu_read_unlock();
758 return;
759 }
760 702
761 if (sta && sta->plink_state == NL80211_PLINK_BLOCKED) { 703static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
762 rcu_read_unlock(); 704 struct sta_info *sta)
763 return; 705{
764 } 706 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
707 u32 changed = 0;
765 708
766 /* Now we will figure out the appropriate event... */ 709 del_timer(&sta->plink_timer);
767 event = PLINK_UNDEFINED; 710 sta->plink_state = NL80211_PLINK_ESTAB;
768 if (ftype != WLAN_SP_MESH_PEERING_CLOSE && 711 changed |= mesh_plink_inc_estab_count(sdata);
769 !mesh_matches_local(sdata, &elems)) { 712 changed |= mesh_set_ht_prot_mode(sdata);
770 matches_local = false; 713 changed |= mesh_set_short_slot_time(sdata);
771 switch (ftype) { 714 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
772 case WLAN_SP_MESH_PEERING_OPEN: 715 ieee80211_mps_sta_status_update(sta);
773 event = OPN_RJCT; 716 changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
774 break; 717 return changed;
775 case WLAN_SP_MESH_PEERING_CONFIRM: 718}
776 event = CNF_RJCT;
777 break;
778 default:
779 break;
780 }
781 }
782 719
783 if (!sta && !matches_local) { 720/**
784 rcu_read_unlock(); 721 * mesh_plink_fsm - step @sta MPM based on @event
785 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG); 722 *
786 llid = 0; 723 * @sdata: interface
787 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 724 * @sta: mesh neighbor
788 mgmt->sa, llid, plid, reason); 725 * @event: peering event
789 return; 726 *
790 } else if (!sta) { 727 * Return: changed MBSS flags
791 /* ftype == WLAN_SP_MESH_PEERING_OPEN */ 728 */
792 if (!mesh_plink_free_count(sdata)) { 729static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
793 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); 730 struct sta_info *sta, enum plink_event event)
794 rcu_read_unlock(); 731{
795 return; 732 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
796 } 733 enum ieee80211_self_protected_actioncode action = 0;
797 event = OPN_ACPT; 734 u32 changed = 0;
798 } else if (matches_local) {
799 switch (ftype) {
800 case WLAN_SP_MESH_PEERING_OPEN:
801 if (!mesh_plink_free_count(sdata) ||
802 (sta->plid && sta->plid != plid))
803 event = OPN_IGNR;
804 else
805 event = OPN_ACPT;
806 break;
807 case WLAN_SP_MESH_PEERING_CONFIRM:
808 if (!mesh_plink_free_count(sdata) ||
809 (sta->llid != llid || sta->plid != plid))
810 event = CNF_IGNR;
811 else
812 event = CNF_ACPT;
813 break;
814 case WLAN_SP_MESH_PEERING_CLOSE:
815 if (sta->plink_state == NL80211_PLINK_ESTAB)
816 /* Do not check for llid or plid. This does not
817 * follow the standard but since multiple plinks
818 * per sta are not supported, it is necessary in
819 * order to avoid a livelock when MP A sees an
820 * establish peer link to MP B but MP B does not
821 * see it. This can be caused by a timeout in
822 * B's peer link establishment or B beign
823 * restarted.
824 */
825 event = CLS_ACPT;
826 else if (sta->plid != plid)
827 event = CLS_IGNR;
828 else if (ie_len == 7 && sta->llid != llid)
829 event = CLS_IGNR;
830 else
831 event = CLS_ACPT;
832 break;
833 default:
834 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
835 rcu_read_unlock();
836 return;
837 }
838 }
839 735
840 if (event == OPN_ACPT) { 736 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
841 rcu_read_unlock(); 737 mplstates[sta->plink_state], mplevents[event]);
842 /* allocate sta entry if necessary and update info */
843 sta = mesh_sta_info_get(sdata, mgmt->sa, &elems);
844 if (!sta) {
845 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
846 rcu_read_unlock();
847 return;
848 }
849 }
850 738
851 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
852 mplstates[sta->plink_state], mplevents[event]);
853 reason = 0;
854 spin_lock_bh(&sta->lock); 739 spin_lock_bh(&sta->lock);
855 switch (sta->plink_state) { 740 switch (sta->plink_state) {
856 /* spin_unlock as soon as state is updated at each case */
857 case NL80211_PLINK_LISTEN: 741 case NL80211_PLINK_LISTEN:
858 switch (event) { 742 switch (event) {
859 case CLS_ACPT: 743 case CLS_ACPT:
860 mesh_plink_fsm_restart(sta); 744 mesh_plink_fsm_restart(sta);
861 spin_unlock_bh(&sta->lock);
862 break; 745 break;
863 case OPN_ACPT: 746 case OPN_ACPT:
864 sta->plink_state = NL80211_PLINK_OPN_RCVD; 747 sta->plink_state = NL80211_PLINK_OPN_RCVD;
865 sta->plid = plid; 748 sta->llid = mesh_get_new_llid(sdata);
866 get_random_bytes(&llid, 2);
867 sta->llid = llid;
868 mesh_plink_timer_set(sta, 749 mesh_plink_timer_set(sta,
869 mshcfg->dot11MeshRetryTimeout); 750 mshcfg->dot11MeshRetryTimeout);
870 751
871 /* set the non-peer mode to active during peering */ 752 /* set the non-peer mode to active during peering */
872 changed |= ieee80211_mps_local_status_update(sdata); 753 changed |= ieee80211_mps_local_status_update(sdata);
873 754 action = WLAN_SP_MESH_PEERING_OPEN;
874 spin_unlock_bh(&sta->lock);
875 mesh_plink_frame_tx(sdata,
876 WLAN_SP_MESH_PEERING_OPEN,
877 sta->sta.addr, llid, 0, 0);
878 mesh_plink_frame_tx(sdata,
879 WLAN_SP_MESH_PEERING_CONFIRM,
880 sta->sta.addr, llid, plid, 0);
881 break; 755 break;
882 default: 756 default:
883 spin_unlock_bh(&sta->lock);
884 break; 757 break;
885 } 758 }
886 break; 759 break;
887
888 case NL80211_PLINK_OPN_SNT: 760 case NL80211_PLINK_OPN_SNT:
889 switch (event) { 761 switch (event) {
890 case OPN_RJCT: 762 case OPN_RJCT:
891 case CNF_RJCT: 763 case CNF_RJCT:
892 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
893 case CLS_ACPT: 764 case CLS_ACPT:
894 if (!reason) 765 mesh_plink_close(sdata, sta, event);
895 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 766 action = WLAN_SP_MESH_PEERING_CLOSE;
896 sta->reason = reason;
897 sta->plink_state = NL80211_PLINK_HOLDING;
898 if (!mod_plink_timer(sta,
899 mshcfg->dot11MeshHoldingTimeout))
900 sta->ignore_plink_timer = true;
901
902 llid = sta->llid;
903 spin_unlock_bh(&sta->lock);
904 mesh_plink_frame_tx(sdata,
905 WLAN_SP_MESH_PEERING_CLOSE,
906 sta->sta.addr, llid, plid, reason);
907 break; 767 break;
908 case OPN_ACPT: 768 case OPN_ACPT:
909 /* retry timer is left untouched */ 769 /* retry timer is left untouched */
910 sta->plink_state = NL80211_PLINK_OPN_RCVD; 770 sta->plink_state = NL80211_PLINK_OPN_RCVD;
911 sta->plid = plid; 771 action = WLAN_SP_MESH_PEERING_CONFIRM;
912 llid = sta->llid;
913 spin_unlock_bh(&sta->lock);
914 mesh_plink_frame_tx(sdata,
915 WLAN_SP_MESH_PEERING_CONFIRM,
916 sta->sta.addr, llid, plid, 0);
917 break; 772 break;
918 case CNF_ACPT: 773 case CNF_ACPT:
919 sta->plink_state = NL80211_PLINK_CNF_RCVD; 774 sta->plink_state = NL80211_PLINK_CNF_RCVD;
920 if (!mod_plink_timer(sta, 775 if (!mod_plink_timer(sta,
921 mshcfg->dot11MeshConfirmTimeout)) 776 mshcfg->dot11MeshConfirmTimeout))
922 sta->ignore_plink_timer = true; 777 sta->ignore_plink_timer = true;
923
924 spin_unlock_bh(&sta->lock);
925 break; 778 break;
926 default: 779 default:
927 spin_unlock_bh(&sta->lock);
928 break; 780 break;
929 } 781 }
930 break; 782 break;
931
932 case NL80211_PLINK_OPN_RCVD: 783 case NL80211_PLINK_OPN_RCVD:
933 switch (event) { 784 switch (event) {
934 case OPN_RJCT: 785 case OPN_RJCT:
935 case CNF_RJCT: 786 case CNF_RJCT:
936 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
937 case CLS_ACPT: 787 case CLS_ACPT:
938 if (!reason) 788 mesh_plink_close(sdata, sta, event);
939 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 789 action = WLAN_SP_MESH_PEERING_CLOSE;
940 sta->reason = reason;
941 sta->plink_state = NL80211_PLINK_HOLDING;
942 if (!mod_plink_timer(sta,
943 mshcfg->dot11MeshHoldingTimeout))
944 sta->ignore_plink_timer = true;
945
946 llid = sta->llid;
947 spin_unlock_bh(&sta->lock);
948 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
949 sta->sta.addr, llid, plid, reason);
950 break; 790 break;
951 case OPN_ACPT: 791 case OPN_ACPT:
952 llid = sta->llid; 792 action = WLAN_SP_MESH_PEERING_CONFIRM;
953 spin_unlock_bh(&sta->lock);
954 mesh_plink_frame_tx(sdata,
955 WLAN_SP_MESH_PEERING_CONFIRM,
956 sta->sta.addr, llid, plid, 0);
957 break; 793 break;
958 case CNF_ACPT: 794 case CNF_ACPT:
959 del_timer(&sta->plink_timer); 795 changed |= mesh_plink_establish(sdata, sta);
960 sta->plink_state = NL80211_PLINK_ESTAB;
961 spin_unlock_bh(&sta->lock);
962 changed |= mesh_plink_inc_estab_count(sdata);
963 changed |= mesh_set_ht_prot_mode(sdata);
964 changed |= mesh_set_short_slot_time(sdata);
965 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
966 sta->sta.addr);
967 ieee80211_mps_sta_status_update(sta);
968 changed |= ieee80211_mps_set_sta_local_pm(sta,
969 mshcfg->power_mode);
970 break; 796 break;
971 default: 797 default:
972 spin_unlock_bh(&sta->lock);
973 break; 798 break;
974 } 799 }
975 break; 800 break;
976
977 case NL80211_PLINK_CNF_RCVD: 801 case NL80211_PLINK_CNF_RCVD:
978 switch (event) { 802 switch (event) {
979 case OPN_RJCT: 803 case OPN_RJCT:
980 case CNF_RJCT: 804 case CNF_RJCT:
981 reason = cpu_to_le16(WLAN_REASON_MESH_CONFIG);
982 case CLS_ACPT: 805 case CLS_ACPT:
983 if (!reason) 806 mesh_plink_close(sdata, sta, event);
984 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE); 807 action = WLAN_SP_MESH_PEERING_CLOSE;
985 sta->reason = reason;
986 sta->plink_state = NL80211_PLINK_HOLDING;
987 if (!mod_plink_timer(sta,
988 mshcfg->dot11MeshHoldingTimeout))
989 sta->ignore_plink_timer = true;
990
991 llid = sta->llid;
992 spin_unlock_bh(&sta->lock);
993 mesh_plink_frame_tx(sdata,
994 WLAN_SP_MESH_PEERING_CLOSE,
995 sta->sta.addr, llid, plid, reason);
996 break; 808 break;
997 case OPN_ACPT: 809 case OPN_ACPT:
998 del_timer(&sta->plink_timer); 810 changed |= mesh_plink_establish(sdata, sta);
999 sta->plink_state = NL80211_PLINK_ESTAB; 811 action = WLAN_SP_MESH_PEERING_CONFIRM;
1000 spin_unlock_bh(&sta->lock);
1001 changed |= mesh_plink_inc_estab_count(sdata);
1002 changed |= mesh_set_ht_prot_mode(sdata);
1003 changed |= mesh_set_short_slot_time(sdata);
1004 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n",
1005 sta->sta.addr);
1006 mesh_plink_frame_tx(sdata,
1007 WLAN_SP_MESH_PEERING_CONFIRM,
1008 sta->sta.addr, llid, plid, 0);
1009 ieee80211_mps_sta_status_update(sta);
1010 changed |= ieee80211_mps_set_sta_local_pm(sta,
1011 mshcfg->power_mode);
1012 break; 812 break;
1013 default: 813 default:
1014 spin_unlock_bh(&sta->lock);
1015 break; 814 break;
1016 } 815 }
1017 break; 816 break;
1018
1019 case NL80211_PLINK_ESTAB: 817 case NL80211_PLINK_ESTAB:
1020 switch (event) { 818 switch (event) {
1021 case CLS_ACPT: 819 case CLS_ACPT:
1022 reason = cpu_to_le16(WLAN_REASON_MESH_CLOSE);
1023 sta->reason = reason;
1024 changed |= __mesh_plink_deactivate(sta); 820 changed |= __mesh_plink_deactivate(sta);
1025 sta->plink_state = NL80211_PLINK_HOLDING;
1026 llid = sta->llid;
1027 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
1028 spin_unlock_bh(&sta->lock);
1029 changed |= mesh_set_ht_prot_mode(sdata); 821 changed |= mesh_set_ht_prot_mode(sdata);
1030 changed |= mesh_set_short_slot_time(sdata); 822 changed |= mesh_set_short_slot_time(sdata);
1031 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE, 823 mesh_plink_close(sdata, sta, event);
1032 sta->sta.addr, llid, plid, reason); 824 action = WLAN_SP_MESH_PEERING_CLOSE;
1033 break; 825 break;
1034 case OPN_ACPT: 826 case OPN_ACPT:
1035 llid = sta->llid; 827 action = WLAN_SP_MESH_PEERING_CONFIRM;
1036 spin_unlock_bh(&sta->lock);
1037 mesh_plink_frame_tx(sdata,
1038 WLAN_SP_MESH_PEERING_CONFIRM,
1039 sta->sta.addr, llid, plid, 0);
1040 break; 828 break;
1041 default: 829 default:
1042 spin_unlock_bh(&sta->lock);
1043 break; 830 break;
1044 } 831 }
1045 break; 832 break;
@@ -1049,32 +836,271 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1049 if (del_timer(&sta->plink_timer)) 836 if (del_timer(&sta->plink_timer))
1050 sta->ignore_plink_timer = 1; 837 sta->ignore_plink_timer = 1;
1051 mesh_plink_fsm_restart(sta); 838 mesh_plink_fsm_restart(sta);
1052 spin_unlock_bh(&sta->lock);
1053 break; 839 break;
1054 case OPN_ACPT: 840 case OPN_ACPT:
1055 case CNF_ACPT: 841 case CNF_ACPT:
1056 case OPN_RJCT: 842 case OPN_RJCT:
1057 case CNF_RJCT: 843 case CNF_RJCT:
1058 llid = sta->llid; 844 action = WLAN_SP_MESH_PEERING_CLOSE;
1059 reason = sta->reason;
1060 spin_unlock_bh(&sta->lock);
1061 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
1062 sta->sta.addr, llid, plid, reason);
1063 break; 845 break;
1064 default: 846 default:
1065 spin_unlock_bh(&sta->lock); 847 break;
1066 } 848 }
1067 break; 849 break;
1068 default: 850 default:
1069 /* should not get here, PLINK_BLOCKED is dealt with at the 851 /* should not get here, PLINK_BLOCKED is dealt with at the
1070 * beginning of the function 852 * beginning of the function
1071 */ 853 */
1072 spin_unlock_bh(&sta->lock);
1073 break; 854 break;
1074 } 855 }
856 spin_unlock_bh(&sta->lock);
857 if (action) {
858 mesh_plink_frame_tx(sdata, action, sta->sta.addr,
859 sta->llid, sta->plid, sta->reason);
860
861 /* also send confirm in open case */
862 if (action == WLAN_SP_MESH_PEERING_OPEN) {
863 mesh_plink_frame_tx(sdata,
864 WLAN_SP_MESH_PEERING_CONFIRM,
865 sta->sta.addr, sta->llid,
866 sta->plid, 0);
867 }
868 }
869
870 return changed;
871}
872
873/*
874 * mesh_plink_get_event - get correct MPM event
875 *
876 * @sdata: interface
877 * @sta: peer, leave NULL if processing a frame from a new suitable peer
878 * @elems: peering management IEs
879 * @ftype: frame type
880 * @llid: peer's peer link ID
881 * @plid: peer's local link ID
882 *
883 * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as
884 * an error.
885 */
886static enum plink_event
887mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
888 struct sta_info *sta,
889 struct ieee802_11_elems *elems,
890 enum ieee80211_self_protected_actioncode ftype,
891 u16 llid, u16 plid)
892{
893 enum plink_event event = PLINK_UNDEFINED;
894 u8 ie_len = elems->peering_len;
895 bool matches_local;
896
897 matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
898 mesh_matches_local(sdata, elems));
899
900 /* deny open request from non-matching peer */
901 if (!matches_local && !sta) {
902 event = OPN_RJCT;
903 goto out;
904 }
905
906 if (!sta) {
907 if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
908 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
909 goto out;
910 }
911 /* ftype == WLAN_SP_MESH_PEERING_OPEN */
912 if (!mesh_plink_free_count(sdata)) {
913 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
914 goto out;
915 }
916 } else {
917 if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
918 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
919 goto out;
920 }
921 if (sta->plink_state == NL80211_PLINK_BLOCKED)
922 goto out;
923 }
924
925 /* new matching peer */
926 if (!sta) {
927 event = OPN_ACPT;
928 goto out;
929 }
930
931 switch (ftype) {
932 case WLAN_SP_MESH_PEERING_OPEN:
933 if (!matches_local)
934 event = OPN_RJCT;
935 if (!mesh_plink_free_count(sdata) ||
936 (sta->plid && sta->plid != plid))
937 event = OPN_IGNR;
938 else
939 event = OPN_ACPT;
940 break;
941 case WLAN_SP_MESH_PEERING_CONFIRM:
942 if (!matches_local)
943 event = CNF_RJCT;
944 if (!mesh_plink_free_count(sdata) ||
945 (sta->llid != llid || sta->plid != plid))
946 event = CNF_IGNR;
947 else
948 event = CNF_ACPT;
949 break;
950 case WLAN_SP_MESH_PEERING_CLOSE:
951 if (sta->plink_state == NL80211_PLINK_ESTAB)
952 /* Do not check for llid or plid. This does not
953 * follow the standard but since multiple plinks
954 * per sta are not supported, it is necessary in
955 * order to avoid a livelock when MP A sees an
956 * establish peer link to MP B but MP B does not
957 * see it. This can be caused by a timeout in
958 * B's peer link establishment or B beign
959 * restarted.
960 */
961 event = CLS_ACPT;
962 else if (sta->plid != plid)
963 event = CLS_IGNR;
964 else if (ie_len == 8 && sta->llid != llid)
965 event = CLS_IGNR;
966 else
967 event = CLS_ACPT;
968 break;
969 default:
970 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
971 break;
972 }
973
974out:
975 return event;
976}
1075 977
978static void
979mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
980 struct ieee80211_mgmt *mgmt,
981 struct ieee802_11_elems *elems)
982{
983
984 struct sta_info *sta;
985 enum plink_event event;
986 enum ieee80211_self_protected_actioncode ftype;
987 u32 changed = 0;
988 u8 ie_len = elems->peering_len;
989 __le16 _plid, _llid;
990 u16 plid, llid = 0;
991
992 if (!elems->peering) {
993 mpl_dbg(sdata,
994 "Mesh plink: missing necessary peer link ie\n");
995 return;
996 }
997
998 if (elems->rsn_len &&
999 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
1000 mpl_dbg(sdata,
1001 "Mesh plink: can't establish link with secure peer\n");
1002 return;
1003 }
1004
1005 ftype = mgmt->u.action.u.self_prot.action_code;
1006 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
1007 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
1008 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
1009 && ie_len != 8)) {
1010 mpl_dbg(sdata,
1011 "Mesh plink: incorrect plink ie length %d %d\n",
1012 ftype, ie_len);
1013 return;
1014 }
1015
1016 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
1017 (!elems->mesh_id || !elems->mesh_config)) {
1018 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
1019 return;
1020 }
1021 /* Note the lines below are correct, the llid in the frame is the plid
1022 * from the point of view of this host.
1023 */
1024 memcpy(&_plid, PLINK_GET_LLID(elems->peering), sizeof(__le16));
1025 plid = le16_to_cpu(_plid);
1026 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
1027 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) {
1028 memcpy(&_llid, PLINK_GET_PLID(elems->peering), sizeof(__le16));
1029 llid = le16_to_cpu(_llid);
1030 }
1031
1032 /* WARNING: Only for sta pointer, is dropped & re-acquired */
1033 rcu_read_lock();
1034
1035 sta = sta_info_get(sdata, mgmt->sa);
1036
1037 if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
1038 !rssi_threshold_check(sdata, sta)) {
1039 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
1040 mgmt->sa);
1041 goto unlock_rcu;
1042 }
1043
1044 /* Now we will figure out the appropriate event... */
1045 event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid);
1046
1047 if (event == OPN_ACPT) {
1048 rcu_read_unlock();
1049 /* allocate sta entry if necessary and update info */
1050 sta = mesh_sta_info_get(sdata, mgmt->sa, elems);
1051 if (!sta) {
1052 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
1053 goto unlock_rcu;
1054 }
1055 sta->plid = plid;
1056 } else if (!sta && event == OPN_RJCT) {
1057 mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
1058 mgmt->sa, 0, plid,
1059 WLAN_REASON_MESH_CONFIG);
1060 goto unlock_rcu;
1061 } else if (!sta || event == PLINK_UNDEFINED) {
1062 /* something went wrong */
1063 goto unlock_rcu;
1064 }
1065
1066 changed |= mesh_plink_fsm(sdata, sta, event);
1067
1068unlock_rcu:
1076 rcu_read_unlock(); 1069 rcu_read_unlock();
1077 1070
1078 if (changed) 1071 if (changed)
1079 ieee80211_mbss_info_change_notify(sdata, changed); 1072 ieee80211_mbss_info_change_notify(sdata, changed);
1080} 1073}
1074
1075void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1076 struct ieee80211_mgmt *mgmt, size_t len,
1077 struct ieee80211_rx_status *rx_status)
1078{
1079 struct ieee802_11_elems elems;
1080 size_t baselen;
1081 u8 *baseaddr;
1082
1083 /* need action_code, aux */
1084 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
1085 return;
1086
1087 if (sdata->u.mesh.user_mpm)
1088 /* userspace must register for these */
1089 return;
1090
1091 if (is_multicast_ether_addr(mgmt->da)) {
1092 mpl_dbg(sdata,
1093 "Mesh plink: ignore frame from multicast address\n");
1094 return;
1095 }
1096
1097 baseaddr = mgmt->u.action.u.self_prot.variable;
1098 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
1099 if (mgmt->u.action.u.self_prot.action_code ==
1100 WLAN_SP_MESH_PEERING_CONFIRM) {
1101 baseaddr += 4;
1102 baselen += 4;
1103 }
1104 ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems);
1105 mesh_process_plink_frame(sdata, mgmt, &elems);
1106}
diff --git a/net/mac80211/mesh_ps.c b/net/mac80211/mesh_ps.c
index 0f79b78b5e86..2802f9d9279d 100644
--- a/net/mac80211/mesh_ps.c
+++ b/net/mac80211/mesh_ps.c
@@ -576,10 +576,9 @@ void ieee80211_mps_frame_release(struct sta_info *sta,
576 int ac, buffer_local = 0; 576 int ac, buffer_local = 0;
577 bool has_buffered = false; 577 bool has_buffered = false;
578 578
579 /* TIM map only for LLID <= IEEE80211_MAX_AID */
580 if (sta->plink_state == NL80211_PLINK_ESTAB) 579 if (sta->plink_state == NL80211_PLINK_ESTAB)
581 has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len, 580 has_buffered = ieee80211_check_tim(elems->tim, elems->tim_len,
582 le16_to_cpu(sta->llid) % IEEE80211_MAX_AID); 581 sta->llid);
583 582
584 if (has_buffered) 583 if (has_buffered)
585 mps_dbg(sta->sdata, "%pM indicates buffered frames\n", 584 mps_dbg(sta->sdata, "%pM indicates buffered frames\n",
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 05a256b38e24..d1cf2d553499 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -92,12 +92,20 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
92 if (stype != IEEE80211_STYPE_BEACON) 92 if (stype != IEEE80211_STYPE_BEACON)
93 return; 93 return;
94 94
95 /* The current tsf is a first approximation for the timestamp 95 /*
96 * for the received beacon. Further down we try to get a 96 * Get time when timestamp field was received. If we don't
97 * better value from the rx_status->mactime field if 97 * have rx timestamps, then use current tsf as an approximation.
98 * available. Also we have to call drv_get_tsf() before 98 * drv_get_tsf() must be called before entering the rcu-read
99 * entering the rcu-read section.*/ 99 * section.
100 t_r = drv_get_tsf(local, sdata); 100 */
101 if (ieee80211_have_rx_timestamp(rx_status))
102 t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
103 24 + 12 +
104 elems->total_len +
105 FCS_LEN,
106 24);
107 else
108 t_r = drv_get_tsf(local, sdata);
101 109
102 rcu_read_lock(); 110 rcu_read_lock();
103 sta = sta_info_get(sdata, mgmt->sa); 111 sta = sta_info_get(sdata, mgmt->sa);
@@ -117,14 +125,6 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
117 goto no_sync; 125 goto no_sync;
118 } 126 }
119 127
120 if (ieee80211_have_rx_timestamp(rx_status))
121 /* time when timestamp field was received */
122 t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
123 24 + 12 +
124 elems->total_len +
125 FCS_LEN,
126 24);
127
128 /* Timing offset calculation (see 13.13.2.2.2) */ 128 /* Timing offset calculation (see 13.13.2.2.2) */
129 t_t = le64_to_cpu(mgmt->u.beacon.timestamp); 129 t_t = le64_to_cpu(mgmt->u.beacon.timestamp);
130 sta->t_offset = t_t - t_r; 130 sta->t_offset = t_t - t_r;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b3a3ce316656..900ead344f5b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -330,6 +330,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
330 if (WARN_ON_ONCE(!sta)) 330 if (WARN_ON_ONCE(!sta))
331 return -EINVAL; 331 return -EINVAL;
332 332
333 /*
334 * if bss configuration changed store the new one -
335 * this may be applicable even if channel is identical
336 */
337 ht_opmode = le16_to_cpu(ht_oper->operation_mode);
338 if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
339 *changed |= BSS_CHANGED_HT;
340 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
341 }
342
333 chan = sdata->vif.bss_conf.chandef.chan; 343 chan = sdata->vif.bss_conf.chandef.chan;
334 sband = local->hw.wiphy->bands[chan->band]; 344 sband = local->hw.wiphy->bands[chan->band];
335 345
@@ -416,14 +426,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
416 IEEE80211_RC_BW_CHANGED); 426 IEEE80211_RC_BW_CHANGED);
417 } 427 }
418 428
419 ht_opmode = le16_to_cpu(ht_oper->operation_mode);
420
421 /* if bss configuration changed store the new one */
422 if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
423 *changed |= BSS_CHANGED_HT;
424 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
425 }
426
427 return 0; 429 return 0;
428} 430}
429 431
@@ -714,7 +716,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
714 } 716 }
715 717
716 /* if present, add any custom IEs that go before HT */ 718 /* if present, add any custom IEs that go before HT */
717 if (assoc_data->ie_len && assoc_data->ie) { 719 if (assoc_data->ie_len) {
718 static const u8 before_ht[] = { 720 static const u8 before_ht[] = {
719 WLAN_EID_SSID, 721 WLAN_EID_SSID,
720 WLAN_EID_SUPP_RATES, 722 WLAN_EID_SUPP_RATES,
@@ -748,7 +750,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
748 &assoc_data->ap_vht_cap); 750 &assoc_data->ap_vht_cap);
749 751
750 /* if present, add any custom non-vendor IEs that go after HT */ 752 /* if present, add any custom non-vendor IEs that go after HT */
751 if (assoc_data->ie_len && assoc_data->ie) { 753 if (assoc_data->ie_len) {
752 noffset = ieee80211_ie_split_vendor(assoc_data->ie, 754 noffset = ieee80211_ie_split_vendor(assoc_data->ie,
753 assoc_data->ie_len, 755 assoc_data->ie_len,
754 offset); 756 offset);
@@ -779,7 +781,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
779 } 781 }
780 782
781 /* add any remaining custom (i.e. vendor specific here) IEs */ 783 /* add any remaining custom (i.e. vendor specific here) IEs */
782 if (assoc_data->ie_len && assoc_data->ie) { 784 if (assoc_data->ie_len) {
783 noffset = assoc_data->ie_len; 785 noffset = assoc_data->ie_len;
784 pos = skb_put(skb, noffset - offset); 786 pos = skb_put(skb, noffset - offset);
785 memcpy(pos, assoc_data->ie + offset, noffset - offset); 787 memcpy(pos, assoc_data->ie + offset, noffset - offset);
@@ -886,8 +888,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
886 if (!ifmgd->associated) 888 if (!ifmgd->associated)
887 goto out; 889 goto out;
888 890
889 ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef, 891 ret = ieee80211_vif_change_channel(sdata, &changed);
890 &changed);
891 if (ret) { 892 if (ret) {
892 sdata_info(sdata, 893 sdata_info(sdata,
893 "vif channel switch failed, disconnecting\n"); 894 "vif channel switch failed, disconnecting\n");
@@ -897,7 +898,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
897 } 898 }
898 899
899 if (!local->use_chanctx) { 900 if (!local->use_chanctx) {
900 local->_oper_chandef = local->csa_chandef; 901 local->_oper_chandef = sdata->csa_chandef;
901 /* Call "hw_config" only if doing sw channel switch. 902 /* Call "hw_config" only if doing sw channel switch.
902 * Otherwise update the channel directly 903 * Otherwise update the channel directly
903 */ 904 */
@@ -908,7 +909,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
908 } 909 }
909 910
910 /* XXX: shouldn't really modify cfg80211-owned data! */ 911 /* XXX: shouldn't really modify cfg80211-owned data! */
911 ifmgd->associated->channel = local->csa_chandef.chan; 912 ifmgd->associated->channel = sdata->csa_chandef.chan;
912 913
913 /* XXX: wait for a beacon first? */ 914 /* XXX: wait for a beacon first? */
914 ieee80211_wake_queues_by_reason(&local->hw, 915 ieee80211_wake_queues_by_reason(&local->hw,
@@ -1035,7 +1036,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
1035 } 1036 }
1036 mutex_unlock(&local->chanctx_mtx); 1037 mutex_unlock(&local->chanctx_mtx);
1037 1038
1038 local->csa_chandef = csa_ie.chandef; 1039 sdata->csa_chandef = csa_ie.chandef;
1039 1040
1040 if (csa_ie.mode) 1041 if (csa_ie.mode)
1041 ieee80211_stop_queues_by_reason(&local->hw, 1042 ieee80211_stop_queues_by_reason(&local->hw,
@@ -1398,10 +1399,12 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
1398 struct ieee80211_sub_if_data *sdata = 1399 struct ieee80211_sub_if_data *sdata =
1399 container_of(delayed_work, struct ieee80211_sub_if_data, 1400 container_of(delayed_work, struct ieee80211_sub_if_data,
1400 dfs_cac_timer_work); 1401 dfs_cac_timer_work);
1402 struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef;
1401 1403
1402 ieee80211_vif_release_channel(sdata); 1404 ieee80211_vif_release_channel(sdata);
1403 1405 cfg80211_cac_event(sdata->dev, &chandef,
1404 cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); 1406 NL80211_RADAR_CAC_FINISHED,
1407 GFP_KERNEL);
1405} 1408}
1406 1409
1407/* MLME */ 1410/* MLME */
@@ -1745,6 +1748,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1745 1748
1746 ifmgd->flags = 0; 1749 ifmgd->flags = 0;
1747 ieee80211_vif_release_channel(sdata); 1750 ieee80211_vif_release_channel(sdata);
1751
1752 sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
1748} 1753}
1749 1754
1750void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 1755void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -4191,6 +4196,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4191 4196
4192 sdata->control_port_protocol = req->crypto.control_port_ethertype; 4197 sdata->control_port_protocol = req->crypto.control_port_ethertype;
4193 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; 4198 sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
4199 sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
4200 sdata->vif.type);
4194 4201
4195 /* kick off associate process */ 4202 /* kick off associate process */
4196 4203
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 505bc0dea074..b95e16c07081 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -54,6 +54,8 @@ static inline void rate_control_rate_init(struct sta_info *sta)
54 struct ieee80211_supported_band *sband; 54 struct ieee80211_supported_band *sband;
55 struct ieee80211_chanctx_conf *chanctx_conf; 55 struct ieee80211_chanctx_conf *chanctx_conf;
56 56
57 ieee80211_sta_set_rx_nss(sta);
58
57 if (!ref) 59 if (!ref)
58 return; 60 return;
59 61
@@ -67,8 +69,6 @@ static inline void rate_control_rate_init(struct sta_info *sta)
67 69
68 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band]; 70 sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
69 71
70 ieee80211_sta_set_rx_nss(sta);
71
72 ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista, 72 ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
73 priv_sta); 73 priv_sta);
74 rcu_read_unlock(); 74 rcu_read_unlock();
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 7fa1b36e6202..d2f19f7e7091 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -422,10 +422,9 @@ init_sample_table(struct minstrel_sta_info *mi)
422 memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates); 422 memset(mi->sample_table, 0xff, SAMPLE_COLUMNS * mi->n_rates);
423 423
424 for (col = 0; col < SAMPLE_COLUMNS; col++) { 424 for (col = 0; col < SAMPLE_COLUMNS; col++) {
425 prandom_bytes(rnd, sizeof(rnd));
425 for (i = 0; i < mi->n_rates; i++) { 426 for (i = 0; i < mi->n_rates; i++) {
426 get_random_bytes(rnd, sizeof(rnd));
427 new_idx = (i + rnd[i & 7]) % mi->n_rates; 427 new_idx = (i + rnd[i & 7]) % mi->n_rates;
428
429 while (SAMPLE_TBL(mi, new_idx, col) != 0xff) 428 while (SAMPLE_TBL(mi, new_idx, col) != 0xff)
430 new_idx = (new_idx + 1) % mi->n_rates; 429 new_idx = (new_idx + 1) % mi->n_rates;
431 430
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 4096ff6cc24f..d2ed18d82fe1 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -135,7 +135,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi);
135static int 135static int
136minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) 136minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate)
137{ 137{
138 return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, 138 return GROUP_IDX((rate->idx / 8) + 1,
139 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), 139 !!(rate->flags & IEEE80211_TX_RC_SHORT_GI),
140 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); 140 !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH));
141} 141}
@@ -148,7 +148,7 @@ minstrel_ht_get_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
148 148
149 if (rate->flags & IEEE80211_TX_RC_MCS) { 149 if (rate->flags & IEEE80211_TX_RC_MCS) {
150 group = minstrel_ht_get_group_idx(rate); 150 group = minstrel_ht_get_group_idx(rate);
151 idx = rate->idx % MCS_GROUP_RATES; 151 idx = rate->idx % 8;
152 } else { 152 } else {
153 group = MINSTREL_CCK_GROUP; 153 group = MINSTREL_CCK_GROUP;
154 154
@@ -637,8 +637,7 @@ minstrel_ht_set_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi,
637 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)]; 637 idx = mp->cck_rates[index % ARRAY_SIZE(mp->cck_rates)];
638 flags = 0; 638 flags = 0;
639 } else { 639 } else {
640 idx = index % MCS_GROUP_RATES + 640 idx = index % MCS_GROUP_RATES + (group->streams - 1) * 8;
641 (group->streams - 1) * MCS_GROUP_RATES;
642 flags = IEEE80211_TX_RC_MCS | group->flags; 641 flags = IEEE80211_TX_RC_MCS | group->flags;
643 } 642 }
644 643
@@ -702,12 +701,16 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
702 if (!mi->sample_tries) 701 if (!mi->sample_tries)
703 return -1; 702 return -1;
704 703
705 mg = &mi->groups[mi->sample_group]; 704 sample_group = mi->sample_group;
705 mg = &mi->groups[sample_group];
706 sample_idx = sample_table[mg->column][mg->index]; 706 sample_idx = sample_table[mg->column][mg->index];
707 minstrel_next_sample_idx(mi);
708
709 if (!(mg->supported & BIT(sample_idx)))
710 return -1;
711
707 mr = &mg->rates[sample_idx]; 712 mr = &mg->rates[sample_idx];
708 sample_group = mi->sample_group;
709 sample_idx += sample_group * MCS_GROUP_RATES; 713 sample_idx += sample_group * MCS_GROUP_RATES;
710 minstrel_next_sample_idx(mi);
711 714
712 /* 715 /*
713 * Sampling might add some overhead (RTS, no aggregation) 716 * Sampling might add some overhead (RTS, no aggregation)
@@ -818,7 +821,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
818 } 821 }
819 822
820 rate->idx = sample_idx % MCS_GROUP_RATES + 823 rate->idx = sample_idx % MCS_GROUP_RATES +
821 (sample_group->streams - 1) * MCS_GROUP_RATES; 824 (sample_group->streams - 1) * 8;
822 rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags; 825 rate->flags = IEEE80211_TX_RC_MCS | sample_group->flags;
823} 826}
824 827
@@ -1053,10 +1056,9 @@ init_sample_table(void)
1053 1056
1054 memset(sample_table, 0xff, sizeof(sample_table)); 1057 memset(sample_table, 0xff, sizeof(sample_table));
1055 for (col = 0; col < SAMPLE_COLUMNS; col++) { 1058 for (col = 0; col < SAMPLE_COLUMNS; col++) {
1059 prandom_bytes(rnd, sizeof(rnd));
1056 for (i = 0; i < MCS_GROUP_RATES; i++) { 1060 for (i = 0; i < MCS_GROUP_RATES; i++) {
1057 get_random_bytes(rnd, sizeof(rnd));
1058 new_idx = (i + rnd[i]) % MCS_GROUP_RATES; 1061 new_idx = (i + rnd[i]) % MCS_GROUP_RATES;
1059
1060 while (sample_table[col][new_idx] != 0xff) 1062 while (sample_table[col][new_idx] != 0xff)
1061 new_idx = (new_idx + 1) % MCS_GROUP_RATES; 1063 new_idx = (new_idx + 1) % MCS_GROUP_RATES;
1062 1064
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c
index df44a5ad8270..3e7d793de0c3 100644
--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c
+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c
@@ -54,8 +54,7 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p)
54 int r = bitrates[j % 4]; 54 int r = bitrates[j % 4];
55 p += sprintf(p, " %2u.%1uM", r / 10, r % 10); 55 p += sprintf(p, " %2u.%1uM", r / 10, r % 10);
56 } else { 56 } else {
57 p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 57 p += sprintf(p, " MCS%-2u", (mg->streams - 1) * 8 + j);
58 MCS_GROUP_RATES + j);
59 } 58 }
60 59
61 tp = mr->cur_tp / 10; 60 tp = mr->cur_tp / 10;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2b0debb0422b..2dfa75522733 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -638,6 +638,27 @@ static int ieee80211_get_mmie_keyidx(struct sk_buff *skb)
638 return le16_to_cpu(mmie->key_id); 638 return le16_to_cpu(mmie->key_id);
639} 639}
640 640
641static int iwl80211_get_cs_keyid(const struct ieee80211_cipher_scheme *cs,
642 struct sk_buff *skb)
643{
644 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
645 __le16 fc;
646 int hdrlen;
647 u8 keyid;
648
649 fc = hdr->frame_control;
650 hdrlen = ieee80211_hdrlen(fc);
651
652 if (skb->len < hdrlen + cs->hdr_len)
653 return -EINVAL;
654
655 skb_copy_bits(skb, hdrlen + cs->key_idx_off, &keyid, 1);
656 keyid &= cs->key_idx_mask;
657 keyid >>= cs->key_idx_shift;
658
659 return keyid;
660}
661
641static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) 662static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
642{ 663{
643 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 664 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
@@ -729,9 +750,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata
729 lockdep_assert_held(&tid_agg_rx->reorder_lock); 750 lockdep_assert_held(&tid_agg_rx->reorder_lock);
730 751
731 while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) { 752 while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) {
732 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 753 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
733 tid_agg_rx->ssn) %
734 tid_agg_rx->buf_size;
735 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 754 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
736 frames); 755 frames);
737 } 756 }
@@ -757,8 +776,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
757 lockdep_assert_held(&tid_agg_rx->reorder_lock); 776 lockdep_assert_held(&tid_agg_rx->reorder_lock);
758 777
759 /* release the buffer until next missing frame */ 778 /* release the buffer until next missing frame */
760 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 779 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
761 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
762 if (!tid_agg_rx->reorder_buf[index] && 780 if (!tid_agg_rx->reorder_buf[index] &&
763 tid_agg_rx->stored_mpdu_num) { 781 tid_agg_rx->stored_mpdu_num) {
764 /* 782 /*
@@ -793,15 +811,11 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata,
793 } else while (tid_agg_rx->reorder_buf[index]) { 811 } else while (tid_agg_rx->reorder_buf[index]) {
794 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, 812 ieee80211_release_reorder_frame(sdata, tid_agg_rx, index,
795 frames); 813 frames);
796 index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 814 index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
797 tid_agg_rx->ssn) %
798 tid_agg_rx->buf_size;
799 } 815 }
800 816
801 if (tid_agg_rx->stored_mpdu_num) { 817 if (tid_agg_rx->stored_mpdu_num) {
802 j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, 818 j = index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size;
803 tid_agg_rx->ssn) %
804 tid_agg_rx->buf_size;
805 819
806 for (; j != (index - 1) % tid_agg_rx->buf_size; 820 for (; j != (index - 1) % tid_agg_rx->buf_size;
807 j = (j + 1) % tid_agg_rx->buf_size) { 821 j = (j + 1) % tid_agg_rx->buf_size) {
@@ -861,8 +875,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
861 875
862 /* Now the new frame is always in the range of the reordering buffer */ 876 /* Now the new frame is always in the range of the reordering buffer */
863 877
864 index = ieee80211_sn_sub(mpdu_seq_num, 878 index = mpdu_seq_num % tid_agg_rx->buf_size;
865 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
866 879
867 /* check if we already stored this frame */ 880 /* check if we already stored this frame */
868 if (tid_agg_rx->reorder_buf[index]) { 881 if (tid_agg_rx->reorder_buf[index]) {
@@ -1369,6 +1382,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1369 struct ieee80211_key *sta_ptk = NULL; 1382 struct ieee80211_key *sta_ptk = NULL;
1370 int mmie_keyidx = -1; 1383 int mmie_keyidx = -1;
1371 __le16 fc; 1384 __le16 fc;
1385 const struct ieee80211_cipher_scheme *cs = NULL;
1372 1386
1373 /* 1387 /*
1374 * Key selection 101 1388 * Key selection 101
@@ -1406,11 +1420,19 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1406 1420
1407 /* start without a key */ 1421 /* start without a key */
1408 rx->key = NULL; 1422 rx->key = NULL;
1423 fc = hdr->frame_control;
1409 1424
1410 if (rx->sta) 1425 if (rx->sta) {
1411 sta_ptk = rcu_dereference(rx->sta->ptk); 1426 int keyid = rx->sta->ptk_idx;
1412 1427
1413 fc = hdr->frame_control; 1428 if (ieee80211_has_protected(fc) && rx->sta->cipher_scheme) {
1429 cs = rx->sta->cipher_scheme;
1430 keyid = iwl80211_get_cs_keyid(cs, rx->skb);
1431 if (unlikely(keyid < 0))
1432 return RX_DROP_UNUSABLE;
1433 }
1434 sta_ptk = rcu_dereference(rx->sta->ptk[keyid]);
1435 }
1414 1436
1415 if (!ieee80211_has_protected(fc)) 1437 if (!ieee80211_has_protected(fc))
1416 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 1438 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
@@ -1472,6 +1494,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1472 return RX_CONTINUE; 1494 return RX_CONTINUE;
1473 } else { 1495 } else {
1474 u8 keyid; 1496 u8 keyid;
1497
1475 /* 1498 /*
1476 * The device doesn't give us the IV so we won't be 1499 * The device doesn't give us the IV so we won't be
1477 * able to look up the key. That's ok though, we 1500 * able to look up the key. That's ok though, we
@@ -1487,15 +1510,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1487 1510
1488 hdrlen = ieee80211_hdrlen(fc); 1511 hdrlen = ieee80211_hdrlen(fc);
1489 1512
1490 if (rx->skb->len < 8 + hdrlen) 1513 if (cs) {
1491 return RX_DROP_UNUSABLE; /* TODO: count this? */ 1514 keyidx = iwl80211_get_cs_keyid(cs, rx->skb);
1492 1515
1493 /* 1516 if (unlikely(keyidx < 0))
1494 * no need to call ieee80211_wep_get_keyidx, 1517 return RX_DROP_UNUSABLE;
1495 * it verifies a bunch of things we've done already 1518 } else {
1496 */ 1519 if (rx->skb->len < 8 + hdrlen)
1497 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); 1520 return RX_DROP_UNUSABLE; /* TODO: count this? */
1498 keyidx = keyid >> 6; 1521 /*
1522 * no need to call ieee80211_wep_get_keyidx,
1523 * it verifies a bunch of things we've done already
1524 */
1525 skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
1526 keyidx = keyid >> 6;
1527 }
1499 1528
1500 /* check per-station GTK first, if multicast packet */ 1529 /* check per-station GTK first, if multicast packet */
1501 if (is_multicast_ether_addr(hdr->addr1) && rx->sta) 1530 if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
@@ -1543,11 +1572,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
1543 result = ieee80211_crypto_aes_cmac_decrypt(rx); 1572 result = ieee80211_crypto_aes_cmac_decrypt(rx);
1544 break; 1573 break;
1545 default: 1574 default:
1546 /* 1575 result = ieee80211_crypto_hw_decrypt(rx);
1547 * We can reach here only with HW-only algorithms
1548 * but why didn't it decrypt the frame?!
1549 */
1550 return RX_DROP_UNUSABLE;
1551 } 1576 }
1552 1577
1553 /* the hdr variable is invalid after the decrypt handlers */ 1578 /* the hdr variable is invalid after the decrypt handlers */
@@ -2057,7 +2082,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2057 struct ieee80211_sub_if_data *sdata = rx->sdata; 2082 struct ieee80211_sub_if_data *sdata = rx->sdata;
2058 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2083 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2059 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 2084 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
2060 __le16 reason = cpu_to_le16(WLAN_REASON_MESH_PATH_NOFORWARD);
2061 u16 q, hdrlen; 2085 u16 q, hdrlen;
2062 2086
2063 hdr = (struct ieee80211_hdr *) skb->data; 2087 hdr = (struct ieee80211_hdr *) skb->data;
@@ -2165,7 +2189,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2165 } else { 2189 } else {
2166 /* unable to resolve next hop */ 2190 /* unable to resolve next hop */
2167 mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, 2191 mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl,
2168 fwd_hdr->addr3, 0, reason, fwd_hdr->addr2); 2192 fwd_hdr->addr3, 0,
2193 WLAN_REASON_MESH_PATH_NOFORWARD,
2194 fwd_hdr->addr2);
2169 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); 2195 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route);
2170 kfree_skb(fwd_skb); 2196 kfree_skb(fwd_skb);
2171 return RX_DROP_MONITOR; 2197 return RX_DROP_MONITOR;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index bcc4833d7542..4d73c46df862 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -526,7 +526,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
526 ieee80211_hw_config(local, 0); 526 ieee80211_hw_config(local, 0);
527 527
528 if ((req->channels[0]->flags & 528 if ((req->channels[0]->flags &
529 IEEE80211_CHAN_PASSIVE_SCAN) || 529 IEEE80211_CHAN_NO_IR) ||
530 !local->scan_req->n_ssids) { 530 !local->scan_req->n_ssids) {
531 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 531 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
532 } else { 532 } else {
@@ -572,7 +572,7 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan)
572 * TODO: channel switching also consumes quite some time, 572 * TODO: channel switching also consumes quite some time,
573 * add that delay as well to get a better estimation 573 * add that delay as well to get a better estimation
574 */ 574 */
575 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 575 if (chan->flags & IEEE80211_CHAN_NO_IR)
576 return IEEE80211_PASSIVE_CHANNEL_TIME; 576 return IEEE80211_PASSIVE_CHANNEL_TIME;
577 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; 577 return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME;
578} 578}
@@ -696,7 +696,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
696 * 696 *
697 * In any case, it is not necessary for a passive scan. 697 * In any case, it is not necessary for a passive scan.
698 */ 698 */
699 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || 699 if (chan->flags & IEEE80211_CHAN_NO_IR ||
700 !local->scan_req->n_ssids) { 700 !local->scan_req->n_ssids) {
701 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; 701 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
702 local->next_scan_state = SCAN_DECISION; 702 local->next_scan_state = SCAN_DECISION;
@@ -881,7 +881,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
881 struct ieee80211_channel *tmp_ch = 881 struct ieee80211_channel *tmp_ch =
882 &local->hw.wiphy->bands[band]->channels[i]; 882 &local->hw.wiphy->bands[band]->channels[i];
883 883
884 if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS | 884 if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
885 IEEE80211_CHAN_DISABLED)) 885 IEEE80211_CHAN_DISABLED))
886 continue; 886 continue;
887 887
@@ -895,7 +895,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
895 895
896 local->int_scan_req->n_channels = n_ch; 896 local->int_scan_req->n_channels = n_ch;
897 } else { 897 } else {
898 if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS | 898 if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR |
899 IEEE80211_CHAN_DISABLED))) 899 IEEE80211_CHAN_DISABLED)))
900 goto unlock; 900 goto unlock;
901 901
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 1eb66e26e49d..8ed97f76c3cf 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -266,9 +266,17 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
266 */ 266 */
267void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) 267void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
268{ 268{
269 int i;
270
269 if (sta->rate_ctrl) 271 if (sta->rate_ctrl)
270 rate_control_free_sta(sta); 272 rate_control_free_sta(sta);
271 273
274 if (sta->tx_lat) {
275 for (i = 0; i < IEEE80211_NUM_TIDS; i++)
276 kfree(sta->tx_lat[i].bins);
277 kfree(sta->tx_lat);
278 }
279
272 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); 280 sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
273 281
274 kfree(sta); 282 kfree(sta);
@@ -333,6 +341,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
333 struct ieee80211_local *local = sdata->local; 341 struct ieee80211_local *local = sdata->local;
334 struct sta_info *sta; 342 struct sta_info *sta;
335 struct timespec uptime; 343 struct timespec uptime;
344 struct ieee80211_tx_latency_bin_ranges *tx_latency;
336 int i; 345 int i;
337 346
338 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp); 347 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@@ -410,6 +419,31 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
410 } 419 }
411 } 420 }
412 421
422 rcu_read_lock();
423
424 tx_latency = rcu_dereference(local->tx_latency);
425 /* init stations Tx latency statistics && TID bins */
426 if (tx_latency)
427 sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *
428 sizeof(struct ieee80211_tx_latency_stat),
429 GFP_ATOMIC);
430
431 /*
432 * if Tx latency and bins are enabled and the previous allocation
433 * succeeded
434 */
435 if (tx_latency && tx_latency->n_ranges && sta->tx_lat)
436 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
437 /* size of bins is size of the ranges +1 */
438 sta->tx_lat[i].bin_count =
439 tx_latency->n_ranges + 1;
440 sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count,
441 sizeof(u32),
442 GFP_ATOMIC);
443 }
444
445 rcu_read_unlock();
446
413 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); 447 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
414 448
415 return sta; 449 return sta;
@@ -507,6 +541,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
507 541
508 set_sta_flag(sta, WLAN_STA_INSERTED); 542 set_sta_flag(sta, WLAN_STA_INSERTED);
509 543
544 ieee80211_recalc_min_chandef(sdata);
510 ieee80211_sta_debugfs_add(sta); 545 ieee80211_sta_debugfs_add(sta);
511 rate_control_add_sta_debugfs(sta); 546 rate_control_add_sta_debugfs(sta);
512 547
@@ -630,8 +665,8 @@ void sta_info_recalc_tim(struct sta_info *sta)
630#ifdef CONFIG_MAC80211_MESH 665#ifdef CONFIG_MAC80211_MESH
631 } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) { 666 } else if (ieee80211_vif_is_mesh(&sta->sdata->vif)) {
632 ps = &sta->sdata->u.mesh.ps; 667 ps = &sta->sdata->u.mesh.ps;
633 /* TIM map only for PLID <= IEEE80211_MAX_AID */ 668 /* TIM map only for 1 <= PLID <= IEEE80211_MAX_AID */
634 id = le16_to_cpu(sta->plid) % IEEE80211_MAX_AID; 669 id = sta->plid % (IEEE80211_MAX_AID + 1);
635#endif 670#endif
636 } else { 671 } else {
637 return; 672 return;
@@ -869,6 +904,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
869 904
870 rate_control_remove_sta_debugfs(sta); 905 rate_control_remove_sta_debugfs(sta);
871 ieee80211_sta_debugfs_remove(sta); 906 ieee80211_sta_debugfs_remove(sta);
907 ieee80211_recalc_min_chandef(sdata);
872 908
873 call_rcu(&sta->rcu_head, free_sta_rcu); 909 call_rcu(&sta->rcu_head, free_sta_rcu);
874 910
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 3ef06a26b9cb..0218caf5c14a 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -220,6 +220,25 @@ struct sta_ampdu_mlme {
220 u8 dialog_token_allocator; 220 u8 dialog_token_allocator;
221}; 221};
222 222
223/*
224 * struct ieee80211_tx_latency_stat - Tx latency statistics
225 *
226 * Measures TX latency and jitter for a station per TID.
227 *
228 * @max: worst case latency
229 * @sum: sum of all latencies
230 * @counter: amount of Tx frames sent from interface
231 * @bins: each bin counts how many frames transmitted within a certain
232 * latency range. when disabled it is NULL.
233 * @bin_count: amount of bins.
234 */
235struct ieee80211_tx_latency_stat {
236 u32 max;
237 u32 sum;
238 u32 counter;
239 u32 *bins;
240 u32 bin_count;
241};
223 242
224/** 243/**
225 * struct sta_info - STA information 244 * struct sta_info - STA information
@@ -231,8 +250,10 @@ struct sta_ampdu_mlme {
231 * @hnext: hash table linked list pointer 250 * @hnext: hash table linked list pointer
232 * @local: pointer to the global information 251 * @local: pointer to the global information
233 * @sdata: virtual interface this station belongs to 252 * @sdata: virtual interface this station belongs to
234 * @ptk: peer key negotiated with this station, if any 253 * @ptk: peer keys negotiated with this station, if any
254 * @ptk_idx: last installed peer key index
235 * @gtk: group keys negotiated with this station, if any 255 * @gtk: group keys negotiated with this station, if any
256 * @gtk_idx: last installed group key index
236 * @rate_ctrl: rate control algorithm reference 257 * @rate_ctrl: rate control algorithm reference
237 * @rate_ctrl_priv: rate control private per-STA pointer 258 * @rate_ctrl_priv: rate control private per-STA pointer
238 * @last_tx_rate: rate used for last transmit, to report to userspace as 259 * @last_tx_rate: rate used for last transmit, to report to userspace as
@@ -274,6 +295,7 @@ struct sta_ampdu_mlme {
274 * @tid_seq: per-TID sequence numbers for sending to this STA 295 * @tid_seq: per-TID sequence numbers for sending to this STA
275 * @ampdu_mlme: A-MPDU state machine state 296 * @ampdu_mlme: A-MPDU state machine state
276 * @timer_to_tid: identity mapping to ID timers 297 * @timer_to_tid: identity mapping to ID timers
298 * @tx_lat: Tx latency statistics
277 * @llid: Local link ID 299 * @llid: Local link ID
278 * @plid: Peer link ID 300 * @plid: Peer link ID
279 * @reason: Cancel reason on PLINK_HOLDING state 301 * @reason: Cancel reason on PLINK_HOLDING state
@@ -303,6 +325,7 @@ struct sta_ampdu_mlme {
303 * @chain_signal_avg: signal average (per chain) 325 * @chain_signal_avg: signal average (per chain)
304 * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for 326 * @known_smps_mode: the smps_mode the client thinks we are in. Relevant for
305 * AP only. 327 * AP only.
328 * @cipher_scheme: optional cipher scheme for this station
306 */ 329 */
307struct sta_info { 330struct sta_info {
308 /* General information, mostly static */ 331 /* General information, mostly static */
@@ -312,7 +335,9 @@ struct sta_info {
312 struct ieee80211_local *local; 335 struct ieee80211_local *local;
313 struct ieee80211_sub_if_data *sdata; 336 struct ieee80211_sub_if_data *sdata;
314 struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; 337 struct ieee80211_key __rcu *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS];
315 struct ieee80211_key __rcu *ptk; 338 struct ieee80211_key __rcu *ptk[NUM_DEFAULT_KEYS];
339 u8 gtk_idx;
340 u8 ptk_idx;
316 struct rate_control_ref *rate_ctrl; 341 struct rate_control_ref *rate_ctrl;
317 void *rate_ctrl_priv; 342 void *rate_ctrl_priv;
318 spinlock_t lock; 343 spinlock_t lock;
@@ -380,14 +405,16 @@ struct sta_info {
380 struct sta_ampdu_mlme ampdu_mlme; 405 struct sta_ampdu_mlme ampdu_mlme;
381 u8 timer_to_tid[IEEE80211_NUM_TIDS]; 406 u8 timer_to_tid[IEEE80211_NUM_TIDS];
382 407
408 struct ieee80211_tx_latency_stat *tx_lat;
409
383#ifdef CONFIG_MAC80211_MESH 410#ifdef CONFIG_MAC80211_MESH
384 /* 411 /*
385 * Mesh peer link attributes 412 * Mesh peer link attributes
386 * TODO: move to a sub-structure that is referenced with pointer? 413 * TODO: move to a sub-structure that is referenced with pointer?
387 */ 414 */
388 __le16 llid; 415 u16 llid;
389 __le16 plid; 416 u16 plid;
390 __le16 reason; 417 u16 reason;
391 u8 plink_retries; 418 u8 plink_retries;
392 bool ignore_plink_timer; 419 bool ignore_plink_timer;
393 enum nl80211_plink_state plink_state; 420 enum nl80211_plink_state plink_state;
@@ -414,6 +441,7 @@ struct sta_info {
414 unsigned int beacon_loss_count; 441 unsigned int beacon_loss_count;
415 442
416 enum ieee80211_smps_mode known_smps_mode; 443 enum ieee80211_smps_mode known_smps_mode;
444 const struct ieee80211_cipher_scheme *cipher_scheme;
417 445
418 /* keep last! */ 446 /* keep last! */
419 struct ieee80211_sta sta; 447 struct ieee80211_sta sta;
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 52a152b01b06..1ee85c402439 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/export.h> 12#include <linux/export.h>
13#include <linux/etherdevice.h> 13#include <linux/etherdevice.h>
14#include <linux/time.h>
14#include <net/mac80211.h> 15#include <net/mac80211.h>
15#include <asm/unaligned.h> 16#include <asm/unaligned.h>
16#include "ieee80211_i.h" 17#include "ieee80211_i.h"
@@ -463,6 +464,77 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
463} 464}
464 465
465/* 466/*
467 * Measure Tx frame completion and removal time for Tx latency statistics
468 * calculation. A single Tx frame latency should be measured from when it
469 * is entering the Kernel until we receive Tx complete confirmation indication
470 * and remove the skb.
471 */
472static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local,
473 struct sk_buff *skb,
474 struct sta_info *sta,
475 struct ieee80211_hdr *hdr)
476{
477 ktime_t skb_dprt;
478 struct timespec dprt_time;
479 u32 msrmnt;
480 u16 tid;
481 u8 *qc;
482 int i, bin_range_count, bin_count;
483 u32 *bin_ranges;
484 __le16 fc;
485 struct ieee80211_tx_latency_stat *tx_lat;
486 struct ieee80211_tx_latency_bin_ranges *tx_latency;
487 ktime_t skb_arv = skb->tstamp;
488
489 tx_latency = rcu_dereference(local->tx_latency);
490
491 /* assert Tx latency stats are enabled & frame arrived when enabled */
492 if (!tx_latency || !ktime_to_ns(skb_arv))
493 return;
494
495 fc = hdr->frame_control;
496
497 if (!ieee80211_is_data(fc)) /* make sure it is a data frame */
498 return;
499
500 /* get frame tid */
501 if (ieee80211_is_data_qos(hdr->frame_control)) {
502 qc = ieee80211_get_qos_ctl(hdr);
503 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
504 } else {
505 tid = 0;
506 }
507
508 tx_lat = &sta->tx_lat[tid];
509
510 ktime_get_ts(&dprt_time); /* time stamp completion time */
511 skb_dprt = ktime_set(dprt_time.tv_sec, dprt_time.tv_nsec);
512 msrmnt = ktime_to_ms(ktime_sub(skb_dprt, skb_arv));
513
514 if (tx_lat->max < msrmnt) /* update stats */
515 tx_lat->max = msrmnt;
516 tx_lat->counter++;
517 tx_lat->sum += msrmnt;
518
519 if (!tx_lat->bins) /* bins not activated */
520 return;
521
522 /* count how many Tx frames transmitted with the appropriate latency */
523 bin_range_count = tx_latency->n_ranges;
524 bin_ranges = tx_latency->ranges;
525 bin_count = tx_lat->bin_count;
526
527 for (i = 0; i < bin_range_count; i++) {
528 if (msrmnt <= bin_ranges[i]) {
529 tx_lat->bins[i]++;
530 break;
531 }
532 }
533 if (i == bin_range_count) /* msrmnt is bigger than the biggest range */
534 tx_lat->bins[i]++;
535}
536
537/*
466 * Use a static threshold for now, best value to be determined 538 * Use a static threshold for now, best value to be determined
467 * by testing ... 539 * by testing ...
468 * Should it depend on: 540 * Should it depend on:
@@ -620,6 +692,12 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
620 692
621 if (acked) 693 if (acked)
622 sta->last_ack_signal = info->status.ack_signal; 694 sta->last_ack_signal = info->status.ack_signal;
695
696 /*
697 * Measure frame removal for tx latency
698 * statistics calculation
699 */
700 ieee80211_tx_latency_end_msrmnt(local, skb, sta, hdr);
623 } 701 }
624 702
625 rcu_read_unlock(); 703 rcu_read_unlock();
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index d4cee98533fd..e9ccf22f6dd9 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -41,14 +41,31 @@
41#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \ 41#define CHANDEF_PR_ARG __entry->control_freq, __entry->chan_width, \
42 __entry->center_freq1, __entry->center_freq2 42 __entry->center_freq1, __entry->center_freq2
43 43
44#define MIN_CHANDEF_ENTRY \
45 __field(u32, min_control_freq) \
46 __field(u32, min_chan_width) \
47 __field(u32, min_center_freq1) \
48 __field(u32, min_center_freq2)
49
50#define MIN_CHANDEF_ASSIGN(c) \
51 __entry->min_control_freq = (c)->chan ? (c)->chan->center_freq : 0; \
52 __entry->min_chan_width = (c)->width; \
53 __entry->min_center_freq1 = (c)->center_freq1; \
54 __entry->min_center_freq2 = (c)->center_freq2;
55#define MIN_CHANDEF_PR_FMT " min_control:%d MHz min_width:%d min_center: %d/%d MHz"
56#define MIN_CHANDEF_PR_ARG __entry->min_control_freq, __entry->min_chan_width, \
57 __entry->min_center_freq1, __entry->min_center_freq2
58
44#define CHANCTX_ENTRY CHANDEF_ENTRY \ 59#define CHANCTX_ENTRY CHANDEF_ENTRY \
60 MIN_CHANDEF_ENTRY \
45 __field(u8, rx_chains_static) \ 61 __field(u8, rx_chains_static) \
46 __field(u8, rx_chains_dynamic) 62 __field(u8, rx_chains_dynamic)
47#define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \ 63#define CHANCTX_ASSIGN CHANDEF_ASSIGN(&ctx->conf.def) \
64 MIN_CHANDEF_ASSIGN(&ctx->conf.min_def) \
48 __entry->rx_chains_static = ctx->conf.rx_chains_static; \ 65 __entry->rx_chains_static = ctx->conf.rx_chains_static; \
49 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic 66 __entry->rx_chains_dynamic = ctx->conf.rx_chains_dynamic
50#define CHANCTX_PR_FMT CHANDEF_PR_FMT " chains:%d/%d" 67#define CHANCTX_PR_FMT CHANDEF_PR_FMT MIN_CHANDEF_PR_FMT " chains:%d/%d"
51#define CHANCTX_PR_ARG CHANDEF_PR_ARG, \ 68#define CHANCTX_PR_ARG CHANDEF_PR_ARG, MIN_CHANDEF_PR_ARG, \
52 __entry->rx_chains_static, __entry->rx_chains_dynamic 69 __entry->rx_chains_static, __entry->rx_chains_dynamic
53 70
54 71
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c558b246ef00..6d59e21cdb9f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -19,6 +19,7 @@
19#include <linux/bitmap.h> 19#include <linux/bitmap.h>
20#include <linux/rcupdate.h> 20#include <linux/rcupdate.h>
21#include <linux/export.h> 21#include <linux/export.h>
22#include <linux/time.h>
22#include <net/net_namespace.h> 23#include <net/net_namespace.h>
23#include <net/ieee80211_radiotap.h> 24#include <net/ieee80211_radiotap.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
@@ -557,7 +558,8 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
557 558
558 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) 559 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
559 tx->key = NULL; 560 tx->key = NULL;
560 else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) 561 else if (tx->sta &&
562 (key = rcu_dereference(tx->sta->ptk[tx->sta->ptk_idx])))
561 tx->key = key; 563 tx->key = key;
562 else if (ieee80211_is_mgmt(hdr->frame_control) && 564 else if (ieee80211_is_mgmt(hdr->frame_control) &&
563 is_multicast_ether_addr(hdr->addr1) && 565 is_multicast_ether_addr(hdr->addr1) &&
@@ -840,15 +842,16 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
840 rem -= fraglen; 842 rem -= fraglen;
841 tmp = dev_alloc_skb(local->tx_headroom + 843 tmp = dev_alloc_skb(local->tx_headroom +
842 frag_threshold + 844 frag_threshold +
843 IEEE80211_ENCRYPT_HEADROOM + 845 tx->sdata->encrypt_headroom +
844 IEEE80211_ENCRYPT_TAILROOM); 846 IEEE80211_ENCRYPT_TAILROOM);
845 if (!tmp) 847 if (!tmp)
846 return -ENOMEM; 848 return -ENOMEM;
847 849
848 __skb_queue_tail(&tx->skbs, tmp); 850 __skb_queue_tail(&tx->skbs, tmp);
849 851
850 skb_reserve(tmp, local->tx_headroom + 852 skb_reserve(tmp,
851 IEEE80211_ENCRYPT_HEADROOM); 853 local->tx_headroom + tx->sdata->encrypt_headroom);
854
852 /* copy control information */ 855 /* copy control information */
853 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb)); 856 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
854 857
@@ -1485,7 +1488,7 @@ void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1485 1488
1486 headroom = local->tx_headroom; 1489 headroom = local->tx_headroom;
1487 if (may_encrypt) 1490 if (may_encrypt)
1488 headroom += IEEE80211_ENCRYPT_HEADROOM; 1491 headroom += sdata->encrypt_headroom;
1489 headroom -= skb_headroom(skb); 1492 headroom -= skb_headroom(skb);
1490 headroom = max_t(int, 0, headroom); 1493 headroom = max_t(int, 0, headroom);
1491 1494
@@ -1724,8 +1727,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1724 * radar detection by itself. We can do that later by adding a 1727 * radar detection by itself. We can do that later by adding a
1725 * monitor flag interfaces used for AP support. 1728 * monitor flag interfaces used for AP support.
1726 */ 1729 */
1727 if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | 1730 if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR)))
1728 IEEE80211_CHAN_PASSIVE_SCAN)))
1729 goto fail_rcu; 1731 goto fail_rcu;
1730 1732
1731 ieee80211_xmit(sdata, skb, chan->band); 1733 ieee80211_xmit(sdata, skb, chan->band);
@@ -1740,6 +1742,26 @@ fail:
1740 return NETDEV_TX_OK; /* meaning, we dealt with the skb */ 1742 return NETDEV_TX_OK; /* meaning, we dealt with the skb */
1741} 1743}
1742 1744
1745/*
1746 * Measure Tx frame arrival time for Tx latency statistics calculation
1747 * A single Tx frame latency should be measured from when it is entering the
1748 * Kernel until we receive Tx complete confirmation indication and the skb is
1749 * freed.
1750 */
1751static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local,
1752 struct sk_buff *skb)
1753{
1754 struct timespec skb_arv;
1755 struct ieee80211_tx_latency_bin_ranges *tx_latency;
1756
1757 tx_latency = rcu_dereference(local->tx_latency);
1758 if (!tx_latency)
1759 return;
1760
1761 ktime_get_ts(&skb_arv);
1762 skb->tstamp = ktime_set(skb_arv.tv_sec, skb_arv.tv_nsec);
1763}
1764
1743/** 1765/**
1744 * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type 1766 * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type
1745 * subinterfaces (wlan#, WDS, and VLAN interfaces) 1767 * subinterfaces (wlan#, WDS, and VLAN interfaces)
@@ -1790,6 +1812,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1790 1812
1791 rcu_read_lock(); 1813 rcu_read_lock();
1792 1814
1815 /* Measure frame arrival for Tx latency statistics calculation */
1816 ieee80211_tx_latency_start_msrmnt(local, skb);
1817
1793 switch (sdata->vif.type) { 1818 switch (sdata->vif.type) {
1794 case NL80211_IFTYPE_AP_VLAN: 1819 case NL80211_IFTYPE_AP_VLAN:
1795 sta = rcu_dereference(sdata->u.vlan.sta); 1820 sta = rcu_dereference(sdata->u.vlan.sta);
@@ -2109,7 +2134,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2109 */ 2134 */
2110 2135
2111 if (head_need > 0 || skb_cloned(skb)) { 2136 if (head_need > 0 || skb_cloned(skb)) {
2112 head_need += IEEE80211_ENCRYPT_HEADROOM; 2137 head_need += sdata->encrypt_headroom;
2113 head_need += local->tx_headroom; 2138 head_need += local->tx_headroom;
2114 head_need = max_t(int, 0, head_need); 2139 head_need = max_t(int, 0, head_need);
2115 if (ieee80211_skb_resize(sdata, skb, head_need, true)) { 2140 if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9f9b9bd3fd44..875e172c001c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1804,6 +1804,26 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
1804 mutex_unlock(&local->chanctx_mtx); 1804 mutex_unlock(&local->chanctx_mtx);
1805} 1805}
1806 1806
1807void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata)
1808{
1809 struct ieee80211_local *local = sdata->local;
1810 struct ieee80211_chanctx_conf *chanctx_conf;
1811 struct ieee80211_chanctx *chanctx;
1812
1813 mutex_lock(&local->chanctx_mtx);
1814
1815 chanctx_conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1816 lockdep_is_held(&local->chanctx_mtx));
1817
1818 if (WARN_ON_ONCE(!chanctx_conf))
1819 goto unlock;
1820
1821 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
1822 ieee80211_recalc_chanctx_min_def(local, chanctx);
1823 unlock:
1824 mutex_unlock(&local->chanctx_mtx);
1825}
1826
1807static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id) 1827static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
1808{ 1828{
1809 int i; 1829 int i;
@@ -2259,14 +2279,17 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
2259void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) 2279void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
2260{ 2280{
2261 struct ieee80211_sub_if_data *sdata; 2281 struct ieee80211_sub_if_data *sdata;
2282 struct cfg80211_chan_def chandef;
2262 2283
2263 mutex_lock(&local->iflist_mtx); 2284 mutex_lock(&local->iflist_mtx);
2264 list_for_each_entry(sdata, &local->interfaces, list) { 2285 list_for_each_entry(sdata, &local->interfaces, list) {
2265 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); 2286 cancel_delayed_work_sync(&sdata->dfs_cac_timer_work);
2266 2287
2267 if (sdata->wdev.cac_started) { 2288 if (sdata->wdev.cac_started) {
2289 chandef = sdata->vif.bss_conf.chandef;
2268 ieee80211_vif_release_channel(sdata); 2290 ieee80211_vif_release_channel(sdata);
2269 cfg80211_cac_event(sdata->dev, 2291 cfg80211_cac_event(sdata->dev,
2292 &chandef,
2270 NL80211_RADAR_CAC_ABORTED, 2293 NL80211_RADAR_CAC_ABORTED,
2271 GFP_KERNEL); 2294 GFP_KERNEL);
2272 } 2295 }
@@ -2445,7 +2468,6 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
2445 2468
2446 if (ieee80211_vif_is_mesh(&sdata->vif)) { 2469 if (ieee80211_vif_is_mesh(&sdata->vif)) {
2447 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 2470 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
2448 __le16 pre_value;
2449 2471
2450 skb_put(skb, 8); 2472 skb_put(skb, 8);
2451 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */ 2473 *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */
@@ -2457,11 +2479,78 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
2457 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; 2479 WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
2458 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ 2480 put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
2459 pos += 2; 2481 pos += 2;
2460 pre_value = cpu_to_le16(ifmsh->pre_value); 2482 put_unaligned_le16(ifmsh->pre_value, pos);/* Precedence Value */
2461 memcpy(pos, &pre_value, 2); /* Precedence Value */
2462 pos += 2; 2483 pos += 2;
2463 } 2484 }
2464 2485
2465 ieee80211_tx_skb(sdata, skb); 2486 ieee80211_tx_skb(sdata, skb);
2466 return 0; 2487 return 0;
2467} 2488}
2489
2490bool ieee80211_cs_valid(const struct ieee80211_cipher_scheme *cs)
2491{
2492 return !(cs == NULL || cs->cipher == 0 ||
2493 cs->hdr_len < cs->pn_len + cs->pn_off ||
2494 cs->hdr_len <= cs->key_idx_off ||
2495 cs->key_idx_shift > 7 ||
2496 cs->key_idx_mask == 0);
2497}
2498
2499bool ieee80211_cs_list_valid(const struct ieee80211_cipher_scheme *cs, int n)
2500{
2501 int i;
2502
2503 /* Ensure we have enough iftype bitmap space for all iftype values */
2504 WARN_ON((NUM_NL80211_IFTYPES / 8 + 1) > sizeof(cs[0].iftype));
2505
2506 for (i = 0; i < n; i++)
2507 if (!ieee80211_cs_valid(&cs[i]))
2508 return false;
2509
2510 return true;
2511}
2512
2513const struct ieee80211_cipher_scheme *
2514ieee80211_cs_get(struct ieee80211_local *local, u32 cipher,
2515 enum nl80211_iftype iftype)
2516{
2517 const struct ieee80211_cipher_scheme *l = local->hw.cipher_schemes;
2518 int n = local->hw.n_cipher_schemes;
2519 int i;
2520 const struct ieee80211_cipher_scheme *cs = NULL;
2521
2522 for (i = 0; i < n; i++) {
2523 if (l[i].cipher == cipher) {
2524 cs = &l[i];
2525 break;
2526 }
2527 }
2528
2529 if (!cs || !(cs->iftype & BIT(iftype)))
2530 return NULL;
2531
2532 return cs;
2533}
2534
2535int ieee80211_cs_headroom(struct ieee80211_local *local,
2536 struct cfg80211_crypto_settings *crypto,
2537 enum nl80211_iftype iftype)
2538{
2539 const struct ieee80211_cipher_scheme *cs;
2540 int headroom = IEEE80211_ENCRYPT_HEADROOM;
2541 int i;
2542
2543 for (i = 0; i < crypto->n_ciphers_pairwise; i++) {
2544 cs = ieee80211_cs_get(local, crypto->ciphers_pairwise[i],
2545 iftype);
2546
2547 if (cs && headroom < cs->hdr_len)
2548 headroom = cs->hdr_len;
2549 }
2550
2551 cs = ieee80211_cs_get(local, crypto->cipher_group, iftype);
2552 if (cs && headroom < cs->hdr_len)
2553 headroom = cs->hdr_len;
2554
2555 return headroom;
2556}
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index de0112785aae..d75f35c6e1a0 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -182,16 +182,15 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
182 IEEE80211_VHT_CAP_SHORT_GI_160); 182 IEEE80211_VHT_CAP_SHORT_GI_160);
183 183
184 /* remaining ones */ 184 /* remaining ones */
185 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) { 185 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)
186 vht_cap->cap |= cap_info & 186 vht_cap->cap |= cap_info &
187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | 187 (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
188 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MAX); 188 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK);
189 }
190 189
191 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) 190 if (own_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)
192 vht_cap->cap |= cap_info & 191 vht_cap->cap |= cap_info &
193 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | 192 (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
194 IEEE80211_VHT_CAP_BEAMFORMEE_STS_MAX); 193 IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK);
195 194
196 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) 195 if (own_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)
197 vht_cap->cap |= cap_info & 196 vht_cap->cap |= cap_info &
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index d65728220763..7313d379c0d3 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -545,6 +545,106 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
545 return RX_CONTINUE; 545 return RX_CONTINUE;
546} 546}
547 547
548static ieee80211_tx_result
549ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx,
550 struct sk_buff *skb)
551{
552 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
553 struct ieee80211_key *key = tx->key;
554 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
555 const struct ieee80211_cipher_scheme *cs = key->sta->cipher_scheme;
556 int hdrlen;
557 u8 *pos;
558
559 if (info->control.hw_key &&
560 !(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) {
561 /* hwaccel has no need for preallocated head room */
562 return TX_CONTINUE;
563 }
564
565 if (unlikely(skb_headroom(skb) < cs->hdr_len &&
566 pskb_expand_head(skb, cs->hdr_len, 0, GFP_ATOMIC)))
567 return TX_DROP;
568
569 hdrlen = ieee80211_hdrlen(hdr->frame_control);
570
571 pos = skb_push(skb, cs->hdr_len);
572 memmove(pos, pos + cs->hdr_len, hdrlen);
573 skb_set_network_header(skb, skb_network_offset(skb) + cs->hdr_len);
574
575 return TX_CONTINUE;
576}
577
578static inline int ieee80211_crypto_cs_pn_compare(u8 *pn1, u8 *pn2, int len)
579{
580 int i;
581
582 /* pn is little endian */
583 for (i = len - 1; i >= 0; i--) {
584 if (pn1[i] < pn2[i])
585 return -1;
586 else if (pn1[i] > pn2[i])
587 return 1;
588 }
589
590 return 0;
591}
592
593static ieee80211_rx_result
594ieee80211_crypto_cs_decrypt(struct ieee80211_rx_data *rx)
595{
596 struct ieee80211_key *key = rx->key;
597 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
598 const struct ieee80211_cipher_scheme *cs = NULL;
599 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
600 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
601 int data_len;
602 u8 *rx_pn;
603 u8 *skb_pn;
604 u8 qos_tid;
605
606 if (!rx->sta || !rx->sta->cipher_scheme ||
607 !(status->flag & RX_FLAG_DECRYPTED))
608 return RX_DROP_UNUSABLE;
609
610 if (!ieee80211_is_data(hdr->frame_control))
611 return RX_CONTINUE;
612
613 cs = rx->sta->cipher_scheme;
614
615 data_len = rx->skb->len - hdrlen - cs->hdr_len;
616
617 if (data_len < 0)
618 return RX_DROP_UNUSABLE;
619
620 if (ieee80211_is_data_qos(hdr->frame_control))
621 qos_tid = *ieee80211_get_qos_ctl(hdr) &
622 IEEE80211_QOS_CTL_TID_MASK;
623 else
624 qos_tid = 0;
625
626 if (skb_linearize(rx->skb))
627 return RX_DROP_UNUSABLE;
628
629 hdr = (struct ieee80211_hdr *)rx->skb->data;
630
631 rx_pn = key->u.gen.rx_pn[qos_tid];
632 skb_pn = rx->skb->data + hdrlen + cs->pn_off;
633
634 if (ieee80211_crypto_cs_pn_compare(skb_pn, rx_pn, cs->pn_len) <= 0)
635 return RX_DROP_UNUSABLE;
636
637 memcpy(rx_pn, skb_pn, cs->pn_len);
638
639 /* remove security header and MIC */
640 if (pskb_trim(rx->skb, rx->skb->len - cs->mic_len))
641 return RX_DROP_UNUSABLE;
642
643 memmove(rx->skb->data + cs->hdr_len, rx->skb->data, hdrlen);
644 skb_pull(rx->skb, cs->hdr_len);
645
646 return RX_CONTINUE;
647}
548 648
549static void bip_aad(struct sk_buff *skb, u8 *aad) 649static void bip_aad(struct sk_buff *skb, u8 *aad)
550{ 650{
@@ -685,6 +785,7 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
685{ 785{
686 struct sk_buff *skb; 786 struct sk_buff *skb;
687 struct ieee80211_tx_info *info = NULL; 787 struct ieee80211_tx_info *info = NULL;
788 ieee80211_tx_result res;
688 789
689 skb_queue_walk(&tx->skbs, skb) { 790 skb_queue_walk(&tx->skbs, skb) {
690 info = IEEE80211_SKB_CB(skb); 791 info = IEEE80211_SKB_CB(skb);
@@ -692,9 +793,24 @@ ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx)
692 /* handle hw-only algorithm */ 793 /* handle hw-only algorithm */
693 if (!info->control.hw_key) 794 if (!info->control.hw_key)
694 return TX_DROP; 795 return TX_DROP;
796
797 if (tx->key->sta->cipher_scheme) {
798 res = ieee80211_crypto_cs_encrypt(tx, skb);
799 if (res != TX_CONTINUE)
800 return res;
801 }
695 } 802 }
696 803
697 ieee80211_tx_set_protected(tx); 804 ieee80211_tx_set_protected(tx);
698 805
699 return TX_CONTINUE; 806 return TX_CONTINUE;
700} 807}
808
809ieee80211_rx_result
810ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx)
811{
812 if (rx->sta->cipher_scheme)
813 return ieee80211_crypto_cs_decrypt(rx);
814
815 return RX_DROP_UNUSABLE;
816}
diff --git a/net/mac80211/wpa.h b/net/mac80211/wpa.h
index 07e33f899c71..62e5a12dfe0a 100644
--- a/net/mac80211/wpa.h
+++ b/net/mac80211/wpa.h
@@ -34,5 +34,7 @@ ieee80211_rx_result
34ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx); 34ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
35ieee80211_tx_result 35ieee80211_tx_result
36ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx); 36ieee80211_crypto_hw_encrypt(struct ieee80211_tx_data *tx);
37ieee80211_rx_result
38ieee80211_crypto_hw_decrypt(struct ieee80211_rx_data *rx);
37 39
38#endif /* WPA_H */ 40#endif /* WPA_H */
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 9b8cc877eb19..78559b5bbd1f 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -277,6 +277,32 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
277 width, dfs_state); 277 width, dfs_state);
278} 278}
279 279
280static u32 cfg80211_get_start_freq(u32 center_freq,
281 u32 bandwidth)
282{
283 u32 start_freq;
284
285 if (bandwidth <= 20)
286 start_freq = center_freq;
287 else
288 start_freq = center_freq - bandwidth/2 + 10;
289
290 return start_freq;
291}
292
293static u32 cfg80211_get_end_freq(u32 center_freq,
294 u32 bandwidth)
295{
296 u32 end_freq;
297
298 if (bandwidth <= 20)
299 end_freq = center_freq;
300 else
301 end_freq = center_freq + bandwidth/2 - 10;
302
303 return end_freq;
304}
305
280static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, 306static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
281 u32 center_freq, 307 u32 center_freq,
282 u32 bandwidth) 308 u32 bandwidth)
@@ -284,13 +310,8 @@ static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
284 struct ieee80211_channel *c; 310 struct ieee80211_channel *c;
285 u32 freq, start_freq, end_freq; 311 u32 freq, start_freq, end_freq;
286 312
287 if (bandwidth <= 20) { 313 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
288 start_freq = center_freq; 314 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
289 end_freq = center_freq;
290 } else {
291 start_freq = center_freq - bandwidth/2 + 10;
292 end_freq = center_freq + bandwidth/2 - 10;
293 }
294 315
295 for (freq = start_freq; freq <= end_freq; freq += 20) { 316 for (freq = start_freq; freq <= end_freq; freq += 20) {
296 c = ieee80211_get_channel(wiphy, freq); 317 c = ieee80211_get_channel(wiphy, freq);
@@ -330,33 +351,159 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
330} 351}
331EXPORT_SYMBOL(cfg80211_chandef_dfs_required); 352EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
332 353
333static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 354static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
334 u32 center_freq, u32 bandwidth, 355 u32 center_freq,
335 u32 prohibited_flags) 356 u32 bandwidth)
336{ 357{
337 struct ieee80211_channel *c; 358 struct ieee80211_channel *c;
338 u32 freq, start_freq, end_freq; 359 u32 freq, start_freq, end_freq;
360 int count = 0;
339 361
340 if (bandwidth <= 20) { 362 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
341 start_freq = center_freq; 363 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
342 end_freq = center_freq; 364
343 } else { 365 /*
344 start_freq = center_freq - bandwidth/2 + 10; 366 * Check entire range of channels for the bandwidth.
345 end_freq = center_freq + bandwidth/2 - 10; 367 * Check all channels are DFS channels (DFS_USABLE or
368 * DFS_AVAILABLE). Return number of usable channels
369 * (require CAC). Allow DFS and non-DFS channel mix.
370 */
371 for (freq = start_freq; freq <= end_freq; freq += 20) {
372 c = ieee80211_get_channel(wiphy, freq);
373 if (!c)
374 return -EINVAL;
375
376 if (c->flags & IEEE80211_CHAN_DISABLED)
377 return -EINVAL;
378
379 if (c->flags & IEEE80211_CHAN_RADAR) {
380 if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
381 return -EINVAL;
382
383 if (c->dfs_state == NL80211_DFS_USABLE)
384 count++;
385 }
346 } 386 }
347 387
388 return count;
389}
390
391bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
392 const struct cfg80211_chan_def *chandef)
393{
394 int width;
395 int r1, r2 = 0;
396
397 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
398 return false;
399
400 width = cfg80211_chandef_get_width(chandef);
401 if (width < 0)
402 return false;
403
404 r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1,
405 width);
406
407 if (r1 < 0)
408 return false;
409
410 switch (chandef->width) {
411 case NL80211_CHAN_WIDTH_80P80:
412 WARN_ON(!chandef->center_freq2);
413 r2 = cfg80211_get_chans_dfs_usable(wiphy,
414 chandef->center_freq2,
415 width);
416 if (r2 < 0)
417 return false;
418 break;
419 default:
420 WARN_ON(chandef->center_freq2);
421 break;
422 }
423
424 return (r1 + r2 > 0);
425}
426
427
428static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
429 u32 center_freq,
430 u32 bandwidth)
431{
432 struct ieee80211_channel *c;
433 u32 freq, start_freq, end_freq;
434
435 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
436 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
437
438 /*
439 * Check entire range of channels for the bandwidth.
440 * If any channel in between is disabled or has not
441 * had gone through CAC return false
442 */
348 for (freq = start_freq; freq <= end_freq; freq += 20) { 443 for (freq = start_freq; freq <= end_freq; freq += 20) {
349 c = ieee80211_get_channel(wiphy, freq); 444 c = ieee80211_get_channel(wiphy, freq);
350 if (!c) 445 if (!c)
351 return false; 446 return false;
352 447
353 /* check for radar flags */ 448 if (c->flags & IEEE80211_CHAN_DISABLED)
354 if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) && 449 return false;
450
451 if ((c->flags & IEEE80211_CHAN_RADAR) &&
355 (c->dfs_state != NL80211_DFS_AVAILABLE)) 452 (c->dfs_state != NL80211_DFS_AVAILABLE))
356 return false; 453 return false;
454 }
455
456 return true;
457}
458
459static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
460 const struct cfg80211_chan_def *chandef)
461{
462 int width;
463 int r;
464
465 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
466 return false;
467
468 width = cfg80211_chandef_get_width(chandef);
469 if (width < 0)
470 return false;
471
472 r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1,
473 width);
474
475 /* If any of channels unavailable for cf1 just return */
476 if (!r)
477 return r;
478
479 switch (chandef->width) {
480 case NL80211_CHAN_WIDTH_80P80:
481 WARN_ON(!chandef->center_freq2);
482 r = cfg80211_get_chans_dfs_available(wiphy,
483 chandef->center_freq2,
484 width);
485 default:
486 WARN_ON(chandef->center_freq2);
487 break;
488 }
489
490 return r;
491}
357 492
358 /* check for the other flags */ 493
359 if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR) 494static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
495 u32 center_freq, u32 bandwidth,
496 u32 prohibited_flags)
497{
498 struct ieee80211_channel *c;
499 u32 freq, start_freq, end_freq;
500
501 start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
502 end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
503
504 for (freq = start_freq; freq <= end_freq; freq += 20) {
505 c = ieee80211_get_channel(wiphy, freq);
506 if (!c || c->flags & prohibited_flags)
360 return false; 507 return false;
361 } 508 }
362 509
@@ -462,14 +609,19 @@ bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
462 struct cfg80211_chan_def *chandef) 609 struct cfg80211_chan_def *chandef)
463{ 610{
464 bool res; 611 bool res;
612 u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
613 IEEE80211_CHAN_NO_IR |
614 IEEE80211_CHAN_RADAR;
465 615
466 trace_cfg80211_reg_can_beacon(wiphy, chandef); 616 trace_cfg80211_reg_can_beacon(wiphy, chandef);
467 617
468 res = cfg80211_chandef_usable(wiphy, chandef, 618 if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 &&
469 IEEE80211_CHAN_DISABLED | 619 cfg80211_chandef_dfs_available(wiphy, chandef)) {
470 IEEE80211_CHAN_PASSIVE_SCAN | 620 /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
471 IEEE80211_CHAN_NO_IBSS | 621 prohibited_flags = IEEE80211_CHAN_DISABLED;
472 IEEE80211_CHAN_RADAR); 622 }
623
624 res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
473 625
474 trace_cfg80211_return_bool(res); 626 trace_cfg80211_return_bool(res);
475 return res; 627 return res;
@@ -510,6 +662,7 @@ cfg80211_get_chan_state(struct wireless_dev *wdev,
510 : CHAN_MODE_EXCLUSIVE; 662 : CHAN_MODE_EXCLUSIVE;
511 return; 663 return;
512 } 664 }
665 break;
513 case NL80211_IFTYPE_STATION: 666 case NL80211_IFTYPE_STATION:
514 case NL80211_IFTYPE_P2P_CLIENT: 667 case NL80211_IFTYPE_P2P_CLIENT:
515 if (wdev->current_bss) { 668 if (wdev->current_bss) {
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 52b865fb7351..06db6eb5258a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -357,8 +357,6 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
357 rdev->wiphy.rts_threshold = (u32) -1; 357 rdev->wiphy.rts_threshold = (u32) -1;
358 rdev->wiphy.coverage_class = 0; 358 rdev->wiphy.coverage_class = 0;
359 359
360 rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH;
361
362 return &rdev->wiphy; 360 return &rdev->wiphy;
363} 361}
364EXPORT_SYMBOL(wiphy_new); 362EXPORT_SYMBOL(wiphy_new);
@@ -575,6 +573,8 @@ int wiphy_register(struct wiphy *wiphy)
575 /* check and set up bitrates */ 573 /* check and set up bitrates */
576 ieee80211_set_bitrate_flags(wiphy); 574 ieee80211_set_bitrate_flags(wiphy);
577 575
576 rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;
577
578 rtnl_lock(); 578 rtnl_lock();
579 res = device_add(&rdev->wiphy.dev); 579 res = device_add(&rdev->wiphy.dev);
580 if (res) { 580 if (res) {
@@ -595,7 +595,7 @@ int wiphy_register(struct wiphy *wiphy)
595 if (IS_ERR(rdev->wiphy.debugfsdir)) 595 if (IS_ERR(rdev->wiphy.debugfsdir))
596 rdev->wiphy.debugfsdir = NULL; 596 rdev->wiphy.debugfsdir = NULL;
597 597
598 if (wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 598 if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
599 struct regulatory_request request; 599 struct regulatory_request request;
600 600
601 request.wiphy_idx = get_wiphy_idx(wiphy); 601 request.wiphy_idx = get_wiphy_idx(wiphy);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index af10e59af2d8..0a277c33bb02 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -317,9 +317,8 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid);
317void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); 317void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev);
318int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 318int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
319 struct wireless_dev *wdev, 319 struct wireless_dev *wdev,
320 struct ieee80211_channel *chan, bool offchan, 320 struct cfg80211_mgmt_tx_params *params,
321 unsigned int wait, const u8 *buf, size_t len, 321 u64 *cookie);
322 bool no_cck, bool dont_wait_for_ack, u64 *cookie);
323void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 322void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
324 const struct ieee80211_ht_cap *ht_capa_mask); 323 const struct ieee80211_ht_cap *ht_capa_mask);
325void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, 324void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
@@ -382,6 +381,19 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
382 enum cfg80211_chan_mode chanmode, 381 enum cfg80211_chan_mode chanmode,
383 u8 radar_detect); 382 u8 radar_detect);
384 383
384/**
385 * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
386 * @wiphy: the wiphy to validate against
387 * @chandef: the channel definition to check
388 *
389 * Checks if chandef is usable and we can/need start CAC on such channel.
390 *
391 * Return: Return true if all channels available and at least
392 * one channel require CAC (NL80211_DFS_USABLE)
393 */
394bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
395 const struct cfg80211_chan_def *chandef);
396
385void cfg80211_set_dfs_state(struct wiphy *wiphy, 397void cfg80211_set_dfs_state(struct wiphy *wiphy,
386 const struct cfg80211_chan_def *chandef, 398 const struct cfg80211_chan_def *chandef,
387 enum nl80211_dfs_state dfs_state); 399 enum nl80211_dfs_state dfs_state);
diff --git a/net/wireless/genregdb.awk b/net/wireless/genregdb.awk
index 42ed274e81f4..9a8217d2a908 100644
--- a/net/wireless/genregdb.awk
+++ b/net/wireless/genregdb.awk
@@ -33,15 +33,7 @@ BEGIN {
33 regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n" 33 regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n"
34} 34}
35 35
36/^[ \t]*#/ { 36function parse_country_head() {
37 # Ignore
38}
39
40!active && /^[ \t]*$/ {
41 # Ignore
42}
43
44!active && /country/ {
45 country=$2 37 country=$2
46 sub(/:/, "", country) 38 sub(/:/, "", country)
47 printf "static const struct ieee80211_regdomain regdom_%s = {\n", country 39 printf "static const struct ieee80211_regdomain regdom_%s = {\n", country
@@ -57,7 +49,8 @@ BEGIN {
57 regdb = regdb "\t&regdom_" country ",\n" 49 regdb = regdb "\t&regdom_" country ",\n"
58} 50}
59 51
60active && /^[ \t]*\(/ { 52function parse_reg_rule()
53{
61 start = $1 54 start = $1
62 sub(/\(/, "", start) 55 sub(/\(/, "", start)
63 end = $3 56 end = $3
@@ -107,17 +100,21 @@ active && /^[ \t]*\(/ {
107 } else if (flagarray[arg] == "PTMP-ONLY") { 100 } else if (flagarray[arg] == "PTMP-ONLY") {
108 flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | " 101 flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | "
109 } else if (flagarray[arg] == "PASSIVE-SCAN") { 102 } else if (flagarray[arg] == "PASSIVE-SCAN") {
110 flags = flags "\n\t\t\tNL80211_RRF_PASSIVE_SCAN | " 103 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
111 } else if (flagarray[arg] == "NO-IBSS") { 104 } else if (flagarray[arg] == "NO-IBSS") {
112 flags = flags "\n\t\t\tNL80211_RRF_NO_IBSS | " 105 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
106 } else if (flagarray[arg] == "NO-IR") {
107 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
113 } 108 }
109
114 } 110 }
115 flags = flags "0" 111 flags = flags "0"
116 printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags 112 printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags
117 rules++ 113 rules++
118} 114}
119 115
120active && /^[ \t]*$/ { 116function print_tail_country()
117{
121 active = 0 118 active = 0
122 printf "\t},\n" 119 printf "\t},\n"
123 printf "\t.n_reg_rules = %d\n", rules 120 printf "\t.n_reg_rules = %d\n", rules
@@ -125,7 +122,29 @@ active && /^[ \t]*$/ {
125 rules = 0; 122 rules = 0;
126} 123}
127 124
125/^[ \t]*#/ {
126 # Ignore
127}
128
129!active && /^[ \t]*$/ {
130 # Ignore
131}
132
133!active && /country/ {
134 parse_country_head()
135}
136
137active && /^[ \t]*\(/ {
138 parse_reg_rule()
139}
140
141active && /^[ \t]*$/ {
142 print_tail_country()
143}
144
128END { 145END {
146 if (active)
147 print_tail_country()
129 print regdb "};" 148 print regdb "};"
130 print "" 149 print ""
131 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);" 150 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 89737ee2669a..730147ed8e65 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -274,7 +274,7 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
274 274
275 for (i = 0; i < sband->n_channels; i++) { 275 for (i = 0; i < sband->n_channels; i++) {
276 chan = &sband->channels[i]; 276 chan = &sband->channels[i];
277 if (chan->flags & IEEE80211_CHAN_NO_IBSS) 277 if (chan->flags & IEEE80211_CHAN_NO_IR)
278 continue; 278 continue;
279 if (chan->flags & IEEE80211_CHAN_DISABLED) 279 if (chan->flags & IEEE80211_CHAN_DISABLED)
280 continue; 280 continue;
@@ -346,7 +346,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
346 chan = ieee80211_get_channel(wdev->wiphy, freq); 346 chan = ieee80211_get_channel(wdev->wiphy, freq);
347 if (!chan) 347 if (!chan)
348 return -EINVAL; 348 return -EINVAL;
349 if (chan->flags & IEEE80211_CHAN_NO_IBSS || 349 if (chan->flags & IEEE80211_CHAN_NO_IR ||
350 chan->flags & IEEE80211_CHAN_DISABLED) 350 chan->flags & IEEE80211_CHAN_DISABLED)
351 return -EINVAL; 351 return -EINVAL;
352 } 352 }
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 0553fd4d85ae..b0e1869de7de 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -141,8 +141,7 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
141 141
142 for (i = 0; i < sband->n_channels; i++) { 142 for (i = 0; i < sband->n_channels; i++) {
143 chan = &sband->channels[i]; 143 chan = &sband->channels[i];
144 if (chan->flags & (IEEE80211_CHAN_NO_IBSS | 144 if (chan->flags & (IEEE80211_CHAN_NO_IR |
145 IEEE80211_CHAN_PASSIVE_SCAN |
146 IEEE80211_CHAN_DISABLED | 145 IEEE80211_CHAN_DISABLED |
147 IEEE80211_CHAN_RADAR)) 146 IEEE80211_CHAN_RADAR))
148 continue; 147 continue;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 6a6b1c8e907d..52cca05044a8 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -520,9 +520,7 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
520 520
521int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 521int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
522 struct wireless_dev *wdev, 522 struct wireless_dev *wdev,
523 struct ieee80211_channel *chan, bool offchan, 523 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
524 unsigned int wait, const u8 *buf, size_t len,
525 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
526{ 524{
527 const struct ieee80211_mgmt *mgmt; 525 const struct ieee80211_mgmt *mgmt;
528 u16 stype; 526 u16 stype;
@@ -533,10 +531,10 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
533 if (!rdev->ops->mgmt_tx) 531 if (!rdev->ops->mgmt_tx)
534 return -EOPNOTSUPP; 532 return -EOPNOTSUPP;
535 533
536 if (len < 24 + 1) 534 if (params->len < 24 + 1)
537 return -EINVAL; 535 return -EINVAL;
538 536
539 mgmt = (const struct ieee80211_mgmt *) buf; 537 mgmt = (const struct ieee80211_mgmt *)params->buf;
540 538
541 if (!ieee80211_is_mgmt(mgmt->frame_control)) 539 if (!ieee80211_is_mgmt(mgmt->frame_control))
542 return -EINVAL; 540 return -EINVAL;
@@ -615,9 +613,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
615 return -EINVAL; 613 return -EINVAL;
616 614
617 /* Transmit the Action frame as requested by user space */ 615 /* Transmit the Action frame as requested by user space */
618 return rdev_mgmt_tx(rdev, wdev, chan, offchan, 616 return rdev_mgmt_tx(rdev, wdev, params, cookie);
619 wait, buf, len, no_cck, dont_wait_for_ack,
620 cookie);
621} 617}
622 618
623bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, 619bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
@@ -763,12 +759,12 @@ void cfg80211_radar_event(struct wiphy *wiphy,
763EXPORT_SYMBOL(cfg80211_radar_event); 759EXPORT_SYMBOL(cfg80211_radar_event);
764 760
765void cfg80211_cac_event(struct net_device *netdev, 761void cfg80211_cac_event(struct net_device *netdev,
762 const struct cfg80211_chan_def *chandef,
766 enum nl80211_radar_event event, gfp_t gfp) 763 enum nl80211_radar_event event, gfp_t gfp)
767{ 764{
768 struct wireless_dev *wdev = netdev->ieee80211_ptr; 765 struct wireless_dev *wdev = netdev->ieee80211_ptr;
769 struct wiphy *wiphy = wdev->wiphy; 766 struct wiphy *wiphy = wdev->wiphy;
770 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 767 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
771 struct cfg80211_chan_def chandef;
772 unsigned long timeout; 768 unsigned long timeout;
773 769
774 trace_cfg80211_cac_event(netdev, event); 770 trace_cfg80211_cac_event(netdev, event);
@@ -779,14 +775,12 @@ void cfg80211_cac_event(struct net_device *netdev,
779 if (WARN_ON(!wdev->channel)) 775 if (WARN_ON(!wdev->channel))
780 return; 776 return;
781 777
782 cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
783
784 switch (event) { 778 switch (event) {
785 case NL80211_RADAR_CAC_FINISHED: 779 case NL80211_RADAR_CAC_FINISHED:
786 timeout = wdev->cac_start_time + 780 timeout = wdev->cac_start_time +
787 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); 781 msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
788 WARN_ON(!time_after_eq(jiffies, timeout)); 782 WARN_ON(!time_after_eq(jiffies, timeout));
789 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE); 783 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
790 break; 784 break;
791 case NL80211_RADAR_CAC_ABORTED: 785 case NL80211_RADAR_CAC_ABORTED:
792 break; 786 break;
@@ -796,6 +790,6 @@ void cfg80211_cac_event(struct net_device *netdev,
796 } 790 }
797 wdev->cac_started = false; 791 wdev->cac_started = false;
798 792
799 nl80211_radar_notify(rdev, &chandef, event, netdev, gfp); 793 nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
800} 794}
801EXPORT_SYMBOL(cfg80211_cac_event); 795EXPORT_SYMBOL(cfg80211_cac_event);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 138dc3bb8b67..a693f86e5970 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -564,12 +564,12 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
564 if ((chan->flags & IEEE80211_CHAN_DISABLED) && 564 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
565 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) 565 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
566 goto nla_put_failure; 566 goto nla_put_failure;
567 if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && 567 if (chan->flags & IEEE80211_CHAN_NO_IR) {
568 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) 568 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
569 goto nla_put_failure; 569 goto nla_put_failure;
570 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 570 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
571 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 571 goto nla_put_failure;
572 goto nla_put_failure; 572 }
573 if (chan->flags & IEEE80211_CHAN_RADAR) { 573 if (chan->flags & IEEE80211_CHAN_RADAR) {
574 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 574 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
575 goto nla_put_failure; 575 goto nla_put_failure;
@@ -1247,10 +1247,6 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1247 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && 1247 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
1248 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) 1248 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
1249 goto nla_put_failure; 1249 goto nla_put_failure;
1250 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
1251 nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ))
1252 goto nla_put_failure;
1253
1254 state->split_start++; 1250 state->split_start++;
1255 if (state->split) 1251 if (state->split)
1256 break; 1252 break;
@@ -1579,6 +1575,11 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *dev,
1579 if (nl80211_send_coalesce(msg, dev)) 1575 if (nl80211_send_coalesce(msg, dev))
1580 goto nla_put_failure; 1576 goto nla_put_failure;
1581 1577
1578 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
1579 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
1580 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
1581 goto nla_put_failure;
1582
1582 /* done */ 1583 /* done */
1583 state->split_start = 0; 1584 state->split_start = 0;
1584 break; 1585 break;
@@ -2187,7 +2188,7 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
2187} 2188}
2188 2189
2189static int nl80211_send_chandef(struct sk_buff *msg, 2190static int nl80211_send_chandef(struct sk_buff *msg,
2190 struct cfg80211_chan_def *chandef) 2191 const struct cfg80211_chan_def *chandef)
2191{ 2192{
2192 WARN_ON(!cfg80211_chandef_valid(chandef)); 2193 WARN_ON(!cfg80211_chandef_valid(chandef));
2193 2194
@@ -3236,6 +3237,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3236 return PTR_ERR(params.acl); 3237 return PTR_ERR(params.acl);
3237 } 3238 }
3238 3239
3240 wdev_lock(wdev);
3239 err = rdev_start_ap(rdev, dev, &params); 3241 err = rdev_start_ap(rdev, dev, &params);
3240 if (!err) { 3242 if (!err) {
3241 wdev->preset_chandef = params.chandef; 3243 wdev->preset_chandef = params.chandef;
@@ -3244,6 +3246,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3244 wdev->ssid_len = params.ssid_len; 3246 wdev->ssid_len = params.ssid_len;
3245 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 3247 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
3246 } 3248 }
3249 wdev_unlock(wdev);
3247 3250
3248 kfree(params.acl); 3251 kfree(params.acl);
3249 3252
@@ -3272,7 +3275,11 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
3272 if (err) 3275 if (err)
3273 return err; 3276 return err;
3274 3277
3275 return rdev_change_beacon(rdev, dev, &params); 3278 wdev_lock(wdev);
3279 err = rdev_change_beacon(rdev, dev, &params);
3280 wdev_unlock(wdev);
3281
3282 return err;
3276} 3283}
3277 3284
3278static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) 3285static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
@@ -4478,7 +4485,9 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4478{ 4485{
4479 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 4486 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4480 struct net_device *dev = info->user_ptr[1]; 4487 struct net_device *dev = info->user_ptr[1];
4488 struct wireless_dev *wdev = dev->ieee80211_ptr;
4481 struct bss_parameters params; 4489 struct bss_parameters params;
4490 int err;
4482 4491
4483 memset(&params, 0, sizeof(params)); 4492 memset(&params, 0, sizeof(params));
4484 /* default to not changing parameters */ 4493 /* default to not changing parameters */
@@ -4544,7 +4553,11 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
4544 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) 4553 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4545 return -EOPNOTSUPP; 4554 return -EOPNOTSUPP;
4546 4555
4547 return rdev_change_bss(rdev, dev, &params); 4556 wdev_lock(wdev);
4557 err = rdev_change_bss(rdev, dev, &params);
4558 wdev_unlock(wdev);
4559
4560 return err;
4548} 4561}
4549 4562
4550static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { 4563static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
@@ -5098,7 +5111,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5098 char *alpha2 = NULL; 5111 char *alpha2 = NULL;
5099 int rem_reg_rules = 0, r = 0; 5112 int rem_reg_rules = 0, r = 0;
5100 u32 num_rules = 0, rule_idx = 0, size_of_regd; 5113 u32 num_rules = 0, rule_idx = 0, size_of_regd;
5101 u8 dfs_region = 0; 5114 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
5102 struct ieee80211_regdomain *rd = NULL; 5115 struct ieee80211_regdomain *rd = NULL;
5103 5116
5104 if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) 5117 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
@@ -5119,6 +5132,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5119 return -EINVAL; 5132 return -EINVAL;
5120 } 5133 }
5121 5134
5135 if (!reg_is_valid_request(alpha2))
5136 return -EINVAL;
5137
5122 size_of_regd = sizeof(struct ieee80211_regdomain) + 5138 size_of_regd = sizeof(struct ieee80211_regdomain) +
5123 num_rules * sizeof(struct ieee80211_reg_rule); 5139 num_rules * sizeof(struct ieee80211_reg_rule);
5124 5140
@@ -5365,10 +5381,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5365 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 5381 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
5366 request->flags = nla_get_u32( 5382 request->flags = nla_get_u32(
5367 info->attrs[NL80211_ATTR_SCAN_FLAGS]); 5383 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
5368 if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5384 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
5369 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || 5385 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
5370 ((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
5371 !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
5372 err = -EOPNOTSUPP; 5386 err = -EOPNOTSUPP;
5373 goto out_free; 5387 goto out_free;
5374 } 5388 }
@@ -5608,10 +5622,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5608 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { 5622 if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
5609 request->flags = nla_get_u32( 5623 request->flags = nla_get_u32(
5610 info->attrs[NL80211_ATTR_SCAN_FLAGS]); 5624 info->attrs[NL80211_ATTR_SCAN_FLAGS]);
5611 if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && 5625 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
5612 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || 5626 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
5613 ((request->flags & NL80211_SCAN_FLAG_FLUSH) &&
5614 !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) {
5615 err = -EOPNOTSUPP; 5627 err = -EOPNOTSUPP;
5616 goto out_free; 5628 goto out_free;
5617 } 5629 }
@@ -5674,7 +5686,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5674 if (err == 0) 5686 if (err == 0)
5675 return -EINVAL; 5687 return -EINVAL;
5676 5688
5677 if (chandef.chan->dfs_state != NL80211_DFS_USABLE) 5689 if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef))
5678 return -EINVAL; 5690 return -EINVAL;
5679 5691
5680 if (!rdev->ops->start_radar_detection) 5692 if (!rdev->ops->start_radar_detection)
@@ -5814,7 +5826,11 @@ skip_beacons:
5814 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) 5826 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
5815 params.block_tx = true; 5827 params.block_tx = true;
5816 5828
5817 return rdev_channel_switch(rdev, dev, &params); 5829 wdev_lock(wdev);
5830 err = rdev_channel_switch(rdev, dev, &params);
5831 wdev_unlock(wdev);
5832
5833 return err;
5818} 5834}
5819 5835
5820static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, 5836static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
@@ -7447,10 +7463,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7447 void *hdr = NULL; 7463 void *hdr = NULL;
7448 u64 cookie; 7464 u64 cookie;
7449 struct sk_buff *msg = NULL; 7465 struct sk_buff *msg = NULL;
7450 unsigned int wait = 0; 7466 struct cfg80211_mgmt_tx_params params = {
7451 bool offchan, no_cck, dont_wait_for_ack; 7467 .dont_wait_for_ack =
7452 7468 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
7453 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 7469 };
7454 7470
7455 if (!info->attrs[NL80211_ATTR_FRAME]) 7471 if (!info->attrs[NL80211_ATTR_FRAME])
7456 return -EINVAL; 7472 return -EINVAL;
@@ -7477,24 +7493,24 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7477 if (info->attrs[NL80211_ATTR_DURATION]) { 7493 if (info->attrs[NL80211_ATTR_DURATION]) {
7478 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 7494 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7479 return -EINVAL; 7495 return -EINVAL;
7480 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); 7496 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
7481 7497
7482 /* 7498 /*
7483 * We should wait on the channel for at least a minimum amount 7499 * We should wait on the channel for at least a minimum amount
7484 * of time (10ms) but no longer than the driver supports. 7500 * of time (10ms) but no longer than the driver supports.
7485 */ 7501 */
7486 if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || 7502 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
7487 wait > rdev->wiphy.max_remain_on_channel_duration) 7503 params.wait > rdev->wiphy.max_remain_on_channel_duration)
7488 return -EINVAL; 7504 return -EINVAL;
7489 7505
7490 } 7506 }
7491 7507
7492 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 7508 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
7493 7509
7494 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 7510 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7495 return -EINVAL; 7511 return -EINVAL;
7496 7512
7497 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 7513 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
7498 7514
7499 /* get the channel if any has been specified, otherwise pass NULL to 7515 /* get the channel if any has been specified, otherwise pass NULL to
7500 * the driver. The latter will use the current one 7516 * the driver. The latter will use the current one
@@ -7506,10 +7522,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7506 return err; 7522 return err;
7507 } 7523 }
7508 7524
7509 if (!chandef.chan && offchan) 7525 if (!chandef.chan && params.offchan)
7510 return -EINVAL; 7526 return -EINVAL;
7511 7527
7512 if (!dont_wait_for_ack) { 7528 if (!params.dont_wait_for_ack) {
7513 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7529 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7514 if (!msg) 7530 if (!msg)
7515 return -ENOMEM; 7531 return -ENOMEM;
@@ -7522,10 +7538,10 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7522 } 7538 }
7523 } 7539 }
7524 7540
7525 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait, 7541 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
7526 nla_data(info->attrs[NL80211_ATTR_FRAME]), 7542 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
7527 nla_len(info->attrs[NL80211_ATTR_FRAME]), 7543 params.chan = chandef.chan;
7528 no_cck, dont_wait_for_ack, &cookie); 7544 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
7529 if (err) 7545 if (err)
7530 goto free_msg; 7546 goto free_msg;
7531 7547
@@ -10810,21 +10826,18 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
10810 struct wiphy *wiphy = wdev->wiphy; 10826 struct wiphy *wiphy = wdev->wiphy;
10811 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 10827 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10812 10828
10813 trace_cfg80211_ch_switch_notify(dev, chandef); 10829 ASSERT_WDEV_LOCK(wdev);
10814 10830
10815 wdev_lock(wdev); 10831 trace_cfg80211_ch_switch_notify(dev, chandef);
10816 10832
10817 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && 10833 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
10818 wdev->iftype != NL80211_IFTYPE_P2P_GO && 10834 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
10819 wdev->iftype != NL80211_IFTYPE_ADHOC && 10835 wdev->iftype != NL80211_IFTYPE_ADHOC &&
10820 wdev->iftype != NL80211_IFTYPE_MESH_POINT)) 10836 wdev->iftype != NL80211_IFTYPE_MESH_POINT))
10821 goto out; 10837 return;
10822 10838
10823 wdev->channel = chandef->chan; 10839 wdev->channel = chandef->chan;
10824 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); 10840 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL);
10825out:
10826 wdev_unlock(wdev);
10827 return;
10828} 10841}
10829EXPORT_SYMBOL(cfg80211_ch_switch_notify); 10842EXPORT_SYMBOL(cfg80211_ch_switch_notify);
10830 10843
@@ -10883,7 +10896,7 @@ EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
10883 10896
10884void 10897void
10885nl80211_radar_notify(struct cfg80211_registered_device *rdev, 10898nl80211_radar_notify(struct cfg80211_registered_device *rdev,
10886 struct cfg80211_chan_def *chandef, 10899 const struct cfg80211_chan_def *chandef,
10887 enum nl80211_radar_event event, 10900 enum nl80211_radar_event event,
10888 struct net_device *netdev, gfp_t gfp) 10901 struct net_device *netdev, gfp_t gfp)
10889{ 10902{
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 2c0f2b3c07cb..b1b231324e10 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -70,7 +70,7 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
70 70
71void 71void
72nl80211_radar_notify(struct cfg80211_registered_device *rdev, 72nl80211_radar_notify(struct cfg80211_registered_device *rdev,
73 struct cfg80211_chan_def *chandef, 73 const struct cfg80211_chan_def *chandef,
74 enum nl80211_radar_event event, 74 enum nl80211_radar_event event,
75 struct net_device *netdev, gfp_t gfp); 75 struct net_device *netdev, gfp_t gfp);
76 76
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index 37ce9fdfe934..a6c03ab14a0d 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -624,16 +624,12 @@ rdev_cancel_remain_on_channel(struct cfg80211_registered_device *rdev,
624 624
625static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev, 625static inline int rdev_mgmt_tx(struct cfg80211_registered_device *rdev,
626 struct wireless_dev *wdev, 626 struct wireless_dev *wdev,
627 struct ieee80211_channel *chan, bool offchan, 627 struct cfg80211_mgmt_tx_params *params,
628 unsigned int wait, const u8 *buf, size_t len, 628 u64 *cookie)
629 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
630{ 629{
631 int ret; 630 int ret;
632 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, chan, offchan, 631 trace_rdev_mgmt_tx(&rdev->wiphy, wdev, params);
633 wait, no_cck, dont_wait_for_ack); 632 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, params, cookie);
634 ret = rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
635 wait, buf, len, no_cck,
636 dont_wait_for_ack, cookie);
637 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie); 633 trace_rdev_return_int_cookie(&rdev->wiphy, ret, *cookie);
638 return ret; 634 return ret;
639} 635}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 7da67fd0b418..ec54e1aac8e2 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -120,6 +120,21 @@ static const struct ieee80211_regdomain *get_wiphy_regdom(struct wiphy *wiphy)
120 return rtnl_dereference(wiphy->regd); 120 return rtnl_dereference(wiphy->regd);
121} 121}
122 122
123static const char *reg_dfs_region_str(enum nl80211_dfs_regions dfs_region)
124{
125 switch (dfs_region) {
126 case NL80211_DFS_UNSET:
127 return "unset";
128 case NL80211_DFS_FCC:
129 return "FCC";
130 case NL80211_DFS_ETSI:
131 return "ETSI";
132 case NL80211_DFS_JP:
133 return "JP";
134 }
135 return "Unknown";
136}
137
123static void rcu_free_regdom(const struct ieee80211_regdomain *r) 138static void rcu_free_regdom(const struct ieee80211_regdomain *r)
124{ 139{
125 if (!r) 140 if (!r)
@@ -163,35 +178,29 @@ static const struct ieee80211_regdomain world_regdom = {
163 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), 178 REG_RULE(2412-10, 2462+10, 40, 6, 20, 0),
164 /* IEEE 802.11b/g, channels 12..13. */ 179 /* IEEE 802.11b/g, channels 12..13. */
165 REG_RULE(2467-10, 2472+10, 40, 6, 20, 180 REG_RULE(2467-10, 2472+10, 40, 6, 20,
166 NL80211_RRF_PASSIVE_SCAN | 181 NL80211_RRF_NO_IR),
167 NL80211_RRF_NO_IBSS),
168 /* IEEE 802.11 channel 14 - Only JP enables 182 /* IEEE 802.11 channel 14 - Only JP enables
169 * this and for 802.11b only */ 183 * this and for 802.11b only */
170 REG_RULE(2484-10, 2484+10, 20, 6, 20, 184 REG_RULE(2484-10, 2484+10, 20, 6, 20,
171 NL80211_RRF_PASSIVE_SCAN | 185 NL80211_RRF_NO_IR |
172 NL80211_RRF_NO_IBSS |
173 NL80211_RRF_NO_OFDM), 186 NL80211_RRF_NO_OFDM),
174 /* IEEE 802.11a, channel 36..48 */ 187 /* IEEE 802.11a, channel 36..48 */
175 REG_RULE(5180-10, 5240+10, 160, 6, 20, 188 REG_RULE(5180-10, 5240+10, 160, 6, 20,
176 NL80211_RRF_PASSIVE_SCAN | 189 NL80211_RRF_NO_IR),
177 NL80211_RRF_NO_IBSS),
178 190
179 /* IEEE 802.11a, channel 52..64 - DFS required */ 191 /* IEEE 802.11a, channel 52..64 - DFS required */
180 REG_RULE(5260-10, 5320+10, 160, 6, 20, 192 REG_RULE(5260-10, 5320+10, 160, 6, 20,
181 NL80211_RRF_PASSIVE_SCAN | 193 NL80211_RRF_NO_IR |
182 NL80211_RRF_NO_IBSS |
183 NL80211_RRF_DFS), 194 NL80211_RRF_DFS),
184 195
185 /* IEEE 802.11a, channel 100..144 - DFS required */ 196 /* IEEE 802.11a, channel 100..144 - DFS required */
186 REG_RULE(5500-10, 5720+10, 160, 6, 20, 197 REG_RULE(5500-10, 5720+10, 160, 6, 20,
187 NL80211_RRF_PASSIVE_SCAN | 198 NL80211_RRF_NO_IR |
188 NL80211_RRF_NO_IBSS |
189 NL80211_RRF_DFS), 199 NL80211_RRF_DFS),
190 200
191 /* IEEE 802.11a, channel 149..165 */ 201 /* IEEE 802.11a, channel 149..165 */
192 REG_RULE(5745-10, 5825+10, 80, 6, 20, 202 REG_RULE(5745-10, 5825+10, 80, 6, 20,
193 NL80211_RRF_PASSIVE_SCAN | 203 NL80211_RRF_NO_IR),
194 NL80211_RRF_NO_IBSS),
195 204
196 /* IEEE 802.11ad (60gHz), channels 1..3 */ 205 /* IEEE 802.11ad (60gHz), channels 1..3 */
197 REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0), 206 REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0),
@@ -208,11 +217,26 @@ static char user_alpha2[2];
208module_param(ieee80211_regdom, charp, 0444); 217module_param(ieee80211_regdom, charp, 0444);
209MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 218MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
210 219
220static void reg_kfree_last_request(void)
221{
222 struct regulatory_request *lr;
223
224 lr = get_last_request();
225
226 if (lr != &core_request_world && lr)
227 kfree_rcu(lr, rcu_head);
228}
229
230static void reg_update_last_request(struct regulatory_request *request)
231{
232 reg_kfree_last_request();
233 rcu_assign_pointer(last_request, request);
234}
235
211static void reset_regdomains(bool full_reset, 236static void reset_regdomains(bool full_reset,
212 const struct ieee80211_regdomain *new_regdom) 237 const struct ieee80211_regdomain *new_regdom)
213{ 238{
214 const struct ieee80211_regdomain *r; 239 const struct ieee80211_regdomain *r;
215 struct regulatory_request *lr;
216 240
217 ASSERT_RTNL(); 241 ASSERT_RTNL();
218 242
@@ -235,10 +259,7 @@ static void reset_regdomains(bool full_reset,
235 if (!full_reset) 259 if (!full_reset)
236 return; 260 return;
237 261
238 lr = get_last_request(); 262 reg_update_last_request(&core_request_world);
239 if (lr != &core_request_world && lr)
240 kfree_rcu(lr, rcu_head);
241 rcu_assign_pointer(last_request, &core_request_world);
242} 263}
243 264
244/* 265/*
@@ -456,7 +477,15 @@ static int call_crda(const char *alpha2)
456 return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE); 477 return kobject_uevent(&reg_pdev->dev.kobj, KOBJ_CHANGE);
457} 478}
458 479
459static bool reg_is_valid_request(const char *alpha2) 480static enum reg_request_treatment
481reg_call_crda(struct regulatory_request *request)
482{
483 if (call_crda(request->alpha2))
484 return REG_REQ_IGNORE;
485 return REG_REQ_OK;
486}
487
488bool reg_is_valid_request(const char *alpha2)
460{ 489{
461 struct regulatory_request *lr = get_last_request(); 490 struct regulatory_request *lr = get_last_request();
462 491
@@ -557,6 +586,20 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
557} 586}
558 587
559/* 588/*
589 * Later on we can perhaps use the more restrictive DFS
590 * region but we don't have information for that yet so
591 * for now simply disallow conflicts.
592 */
593static enum nl80211_dfs_regions
594reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1,
595 const enum nl80211_dfs_regions dfs_region2)
596{
597 if (dfs_region1 != dfs_region2)
598 return NL80211_DFS_UNSET;
599 return dfs_region1;
600}
601
602/*
560 * Helper for regdom_intersect(), this does the real 603 * Helper for regdom_intersect(), this does the real
561 * mathematical intersection fun 604 * mathematical intersection fun
562 */ 605 */
@@ -687,6 +730,8 @@ regdom_intersect(const struct ieee80211_regdomain *rd1,
687 rd->n_reg_rules = num_rules; 730 rd->n_reg_rules = num_rules;
688 rd->alpha2[0] = '9'; 731 rd->alpha2[0] = '9';
689 rd->alpha2[1] = '8'; 732 rd->alpha2[1] = '8';
733 rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region,
734 rd2->dfs_region);
690 735
691 return rd; 736 return rd;
692} 737}
@@ -698,10 +743,8 @@ regdom_intersect(const struct ieee80211_regdomain *rd1,
698static u32 map_regdom_flags(u32 rd_flags) 743static u32 map_regdom_flags(u32 rd_flags)
699{ 744{
700 u32 channel_flags = 0; 745 u32 channel_flags = 0;
701 if (rd_flags & NL80211_RRF_PASSIVE_SCAN) 746 if (rd_flags & NL80211_RRF_NO_IR_ALL)
702 channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN; 747 channel_flags |= IEEE80211_CHAN_NO_IR;
703 if (rd_flags & NL80211_RRF_NO_IBSS)
704 channel_flags |= IEEE80211_CHAN_NO_IBSS;
705 if (rd_flags & NL80211_RRF_DFS) 748 if (rd_flags & NL80211_RRF_DFS)
706 channel_flags |= IEEE80211_CHAN_RADAR; 749 channel_flags |= IEEE80211_CHAN_RADAR;
707 if (rd_flags & NL80211_RRF_NO_OFDM) 750 if (rd_flags & NL80211_RRF_NO_OFDM)
@@ -854,8 +897,18 @@ static void handle_channel(struct wiphy *wiphy,
854 PTR_ERR(reg_rule) == -ERANGE) 897 PTR_ERR(reg_rule) == -ERANGE)
855 return; 898 return;
856 899
857 REG_DBG_PRINT("Disabling freq %d MHz\n", chan->center_freq); 900 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
858 chan->flags |= IEEE80211_CHAN_DISABLED; 901 request_wiphy && request_wiphy == wiphy &&
902 request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
903 REG_DBG_PRINT("Disabling freq %d MHz for good\n",
904 chan->center_freq);
905 chan->orig_flags |= IEEE80211_CHAN_DISABLED;
906 chan->flags = chan->orig_flags;
907 } else {
908 REG_DBG_PRINT("Disabling freq %d MHz\n",
909 chan->center_freq);
910 chan->flags |= IEEE80211_CHAN_DISABLED;
911 }
859 return; 912 return;
860 } 913 }
861 914
@@ -873,7 +926,7 @@ static void handle_channel(struct wiphy *wiphy,
873 926
874 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 927 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
875 request_wiphy && request_wiphy == wiphy && 928 request_wiphy && request_wiphy == wiphy &&
876 request_wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) { 929 request_wiphy->regulatory_flags & REGULATORY_STRICT_REG) {
877 /* 930 /*
878 * This guarantees the driver's requested regulatory domain 931 * This guarantees the driver's requested regulatory domain
879 * will always be used as a base for further regulatory 932 * will always be used as a base for further regulatory
@@ -899,13 +952,11 @@ static void handle_channel(struct wiphy *wiphy,
899 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp); 952 chan->max_reg_power = (int) MBM_TO_DBM(power_rule->max_eirp);
900 if (chan->orig_mpwr) { 953 if (chan->orig_mpwr) {
901 /* 954 /*
902 * Devices that have their own custom regulatory domain 955 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
903 * but also use WIPHY_FLAG_STRICT_REGULATORY will follow the 956 * will always follow the passed country IE power settings.
904 * passed country IE power settings.
905 */ 957 */
906 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && 958 if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
907 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY && 959 wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_FOLLOW_POWER)
908 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY)
909 chan->max_power = chan->max_reg_power; 960 chan->max_power = chan->max_reg_power;
910 else 961 else
911 chan->max_power = min(chan->orig_mpwr, 962 chan->max_power = min(chan->orig_mpwr,
@@ -975,8 +1026,8 @@ static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy)
975 1026
976static bool wiphy_strict_alpha2_regd(struct wiphy *wiphy) 1027static bool wiphy_strict_alpha2_regd(struct wiphy *wiphy)
977{ 1028{
978 if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && 1029 if (wiphy->regulatory_flags & REGULATORY_STRICT_REG &&
979 !(wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY)) 1030 !(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG))
980 return true; 1031 return true;
981 return false; 1032 return false;
982} 1033}
@@ -994,7 +1045,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
994 } 1045 }
995 1046
996 if (initiator == NL80211_REGDOM_SET_BY_CORE && 1047 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
997 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 1048 wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
998 REG_DBG_PRINT("Ignoring regulatory request set by %s " 1049 REG_DBG_PRINT("Ignoring regulatory request set by %s "
999 "since the driver uses its own custom " 1050 "since the driver uses its own custom "
1000 "regulatory domain\n", 1051 "regulatory domain\n",
@@ -1032,7 +1083,7 @@ static bool reg_is_world_roaming(struct wiphy *wiphy)
1032 return true; 1083 return true;
1033 1084
1034 if (lr && lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && 1085 if (lr && lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1035 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) 1086 wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
1036 return true; 1087 return true;
1037 1088
1038 return false; 1089 return false;
@@ -1060,19 +1111,14 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx,
1060 if (!reg_is_world_roaming(wiphy)) 1111 if (!reg_is_world_roaming(wiphy))
1061 return; 1112 return;
1062 1113
1063 if (wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS) 1114 if (wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS)
1064 return; 1115 return;
1065 1116
1066 chan_before.center_freq = chan->center_freq; 1117 chan_before.center_freq = chan->center_freq;
1067 chan_before.flags = chan->flags; 1118 chan_before.flags = chan->flags;
1068 1119
1069 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { 1120 if (chan->flags & IEEE80211_CHAN_NO_IR) {
1070 chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; 1121 chan->flags &= ~IEEE80211_CHAN_NO_IR;
1071 channel_changed = true;
1072 }
1073
1074 if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
1075 chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
1076 channel_changed = true; 1122 channel_changed = true;
1077 } 1123 }
1078 1124
@@ -1205,14 +1251,30 @@ static void reg_process_ht_flags(struct wiphy *wiphy)
1205 reg_process_ht_flags_band(wiphy, wiphy->bands[band]); 1251 reg_process_ht_flags_band(wiphy, wiphy->bands[band]);
1206} 1252}
1207 1253
1254static void reg_call_notifier(struct wiphy *wiphy,
1255 struct regulatory_request *request)
1256{
1257 if (wiphy->reg_notifier)
1258 wiphy->reg_notifier(wiphy, request);
1259}
1260
1208static void wiphy_update_regulatory(struct wiphy *wiphy, 1261static void wiphy_update_regulatory(struct wiphy *wiphy,
1209 enum nl80211_reg_initiator initiator) 1262 enum nl80211_reg_initiator initiator)
1210{ 1263{
1211 enum ieee80211_band band; 1264 enum ieee80211_band band;
1212 struct regulatory_request *lr = get_last_request(); 1265 struct regulatory_request *lr = get_last_request();
1213 1266
1214 if (ignore_reg_update(wiphy, initiator)) 1267 if (ignore_reg_update(wiphy, initiator)) {
1268 /*
1269 * Regulatory updates set by CORE are ignored for custom
1270 * regulatory cards. Let us notify the changes to the driver,
1271 * as some drivers used this to restore its orig_* reg domain.
1272 */
1273 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
1274 wiphy->regulatory_flags & REGULATORY_CUSTOM_REG)
1275 reg_call_notifier(wiphy, lr);
1215 return; 1276 return;
1277 }
1216 1278
1217 lr->dfs_region = get_cfg80211_regdom()->dfs_region; 1279 lr->dfs_region = get_cfg80211_regdom()->dfs_region;
1218 1280
@@ -1221,9 +1283,7 @@ static void wiphy_update_regulatory(struct wiphy *wiphy,
1221 1283
1222 reg_process_beacons(wiphy); 1284 reg_process_beacons(wiphy);
1223 reg_process_ht_flags(wiphy); 1285 reg_process_ht_flags(wiphy);
1224 1286 reg_call_notifier(wiphy, lr);
1225 if (wiphy->reg_notifier)
1226 wiphy->reg_notifier(wiphy, lr);
1227} 1287}
1228 1288
1229static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) 1289static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
@@ -1236,15 +1296,6 @@ static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator)
1236 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 1296 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1237 wiphy = &rdev->wiphy; 1297 wiphy = &rdev->wiphy;
1238 wiphy_update_regulatory(wiphy, initiator); 1298 wiphy_update_regulatory(wiphy, initiator);
1239 /*
1240 * Regulatory updates set by CORE are ignored for custom
1241 * regulatory cards. Let us notify the changes to the driver,
1242 * as some drivers used this to restore its orig_* reg domain.
1243 */
1244 if (initiator == NL80211_REGDOM_SET_BY_CORE &&
1245 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY &&
1246 wiphy->reg_notifier)
1247 wiphy->reg_notifier(wiphy, get_last_request());
1248 } 1299 }
1249} 1300}
1250 1301
@@ -1263,7 +1314,8 @@ static void handle_channel_custom(struct wiphy *wiphy,
1263 if (IS_ERR(reg_rule)) { 1314 if (IS_ERR(reg_rule)) {
1264 REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n", 1315 REG_DBG_PRINT("Disabling freq %d MHz as custom regd has no rule that fits it\n",
1265 chan->center_freq); 1316 chan->center_freq);
1266 chan->flags = IEEE80211_CHAN_DISABLED; 1317 chan->orig_flags |= IEEE80211_CHAN_DISABLED;
1318 chan->flags = chan->orig_flags;
1267 return; 1319 return;
1268 } 1320 }
1269 1321
@@ -1305,6 +1357,10 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1305 enum ieee80211_band band; 1357 enum ieee80211_band band;
1306 unsigned int bands_set = 0; 1358 unsigned int bands_set = 0;
1307 1359
1360 WARN(!(wiphy->regulatory_flags & REGULATORY_CUSTOM_REG),
1361 "wiphy should have REGULATORY_CUSTOM_REG\n");
1362 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
1363
1308 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1364 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1309 if (!wiphy->bands[band]) 1365 if (!wiphy->bands[band])
1310 continue; 1366 continue;
@@ -1320,225 +1376,285 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1320} 1376}
1321EXPORT_SYMBOL(wiphy_apply_custom_regulatory); 1377EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
1322 1378
1323/* This has the logic which determines when a new request 1379static void reg_set_request_processed(void)
1324 * should be ignored. */
1325static enum reg_request_treatment
1326get_reg_request_treatment(struct wiphy *wiphy,
1327 struct regulatory_request *pending_request)
1328{ 1380{
1329 struct wiphy *last_wiphy = NULL; 1381 bool need_more_processing = false;
1330 struct regulatory_request *lr = get_last_request(); 1382 struct regulatory_request *lr = get_last_request();
1331 1383
1332 /* All initial requests are respected */ 1384 lr->processed = true;
1333 if (!lr)
1334 return REG_REQ_OK;
1335 1385
1336 switch (pending_request->initiator) { 1386 spin_lock(&reg_requests_lock);
1337 case NL80211_REGDOM_SET_BY_CORE: 1387 if (!list_empty(&reg_requests_list))
1338 return REG_REQ_OK; 1388 need_more_processing = true;
1339 case NL80211_REGDOM_SET_BY_COUNTRY_IE: 1389 spin_unlock(&reg_requests_lock);
1340 if (reg_request_cell_base(lr)) {
1341 /* Trust a Cell base station over the AP's country IE */
1342 if (regdom_changes(pending_request->alpha2))
1343 return REG_REQ_IGNORE;
1344 return REG_REQ_ALREADY_SET;
1345 }
1346 1390
1347 last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 1391 if (lr->initiator == NL80211_REGDOM_SET_BY_USER)
1392 cancel_delayed_work(&reg_timeout);
1348 1393
1349 if (unlikely(!is_an_alpha2(pending_request->alpha2))) 1394 if (need_more_processing)
1350 return -EINVAL; 1395 schedule_work(&reg_work);
1351 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1396}
1352 if (last_wiphy != wiphy) {
1353 /*
1354 * Two cards with two APs claiming different
1355 * Country IE alpha2s. We could
1356 * intersect them, but that seems unlikely
1357 * to be correct. Reject second one for now.
1358 */
1359 if (regdom_changes(pending_request->alpha2))
1360 return REG_REQ_IGNORE;
1361 return REG_REQ_ALREADY_SET;
1362 }
1363 /*
1364 * Two consecutive Country IE hints on the same wiphy.
1365 * This should be picked up early by the driver/stack
1366 */
1367 if (WARN_ON(regdom_changes(pending_request->alpha2)))
1368 return REG_REQ_OK;
1369 return REG_REQ_ALREADY_SET;
1370 }
1371 return REG_REQ_OK;
1372 case NL80211_REGDOM_SET_BY_DRIVER:
1373 if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
1374 if (regdom_changes(pending_request->alpha2))
1375 return REG_REQ_OK;
1376 return REG_REQ_ALREADY_SET;
1377 }
1378 1397
1379 /* 1398/**
1380 * This would happen if you unplug and plug your card 1399 * reg_process_hint_core - process core regulatory requests
1381 * back in or if you add a new device for which the previously 1400 * @pending_request: a pending core regulatory request
1382 * loaded card also agrees on the regulatory domain. 1401 *
1383 */ 1402 * The wireless subsystem can use this function to process
1384 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER && 1403 * a regulatory request issued by the regulatory core.
1385 !regdom_changes(pending_request->alpha2)) 1404 *
1386 return REG_REQ_ALREADY_SET; 1405 * Returns one of the different reg request treatment values.
1406 */
1407static enum reg_request_treatment
1408reg_process_hint_core(struct regulatory_request *core_request)
1409{
1410
1411 core_request->intersect = false;
1412 core_request->processed = false;
1413
1414 reg_update_last_request(core_request);
1387 1415
1416 return reg_call_crda(core_request);
1417}
1418
1419static enum reg_request_treatment
1420__reg_process_hint_user(struct regulatory_request *user_request)
1421{
1422 struct regulatory_request *lr = get_last_request();
1423
1424 if (reg_request_cell_base(user_request))
1425 return reg_ignore_cell_hint(user_request);
1426
1427 if (reg_request_cell_base(lr))
1428 return REG_REQ_IGNORE;
1429
1430 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)
1388 return REG_REQ_INTERSECT; 1431 return REG_REQ_INTERSECT;
1389 case NL80211_REGDOM_SET_BY_USER: 1432 /*
1390 if (reg_request_cell_base(pending_request)) 1433 * If the user knows better the user should set the regdom
1391 return reg_ignore_cell_hint(pending_request); 1434 * to their country before the IE is picked up
1435 */
1436 if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
1437 lr->intersect)
1438 return REG_REQ_IGNORE;
1439 /*
1440 * Process user requests only after previous user/driver/core
1441 * requests have been processed
1442 */
1443 if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
1444 lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1445 lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
1446 regdom_changes(lr->alpha2))
1447 return REG_REQ_IGNORE;
1392 1448
1393 if (reg_request_cell_base(lr)) 1449 if (!regdom_changes(user_request->alpha2))
1394 return REG_REQ_IGNORE; 1450 return REG_REQ_ALREADY_SET;
1395 1451
1396 if (lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) 1452 return REG_REQ_OK;
1397 return REG_REQ_INTERSECT; 1453}
1398 /*
1399 * If the user knows better the user should set the regdom
1400 * to their country before the IE is picked up
1401 */
1402 if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
1403 lr->intersect)
1404 return REG_REQ_IGNORE;
1405 /*
1406 * Process user requests only after previous user/driver/core
1407 * requests have been processed
1408 */
1409 if ((lr->initiator == NL80211_REGDOM_SET_BY_CORE ||
1410 lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
1411 lr->initiator == NL80211_REGDOM_SET_BY_USER) &&
1412 regdom_changes(lr->alpha2))
1413 return REG_REQ_IGNORE;
1414 1454
1415 if (!regdom_changes(pending_request->alpha2)) 1455/**
1416 return REG_REQ_ALREADY_SET; 1456 * reg_process_hint_user - process user regulatory requests
1457 * @user_request: a pending user regulatory request
1458 *
1459 * The wireless subsystem can use this function to process
1460 * a regulatory request initiated by userspace.
1461 *
1462 * Returns one of the different reg request treatment values.
1463 */
1464static enum reg_request_treatment
1465reg_process_hint_user(struct regulatory_request *user_request)
1466{
1467 enum reg_request_treatment treatment;
1417 1468
1418 return REG_REQ_OK; 1469 treatment = __reg_process_hint_user(user_request);
1470 if (treatment == REG_REQ_IGNORE ||
1471 treatment == REG_REQ_ALREADY_SET) {
1472 kfree(user_request);
1473 return treatment;
1419 } 1474 }
1420 1475
1421 return REG_REQ_IGNORE; 1476 user_request->intersect = treatment == REG_REQ_INTERSECT;
1477 user_request->processed = false;
1478
1479 reg_update_last_request(user_request);
1480
1481 user_alpha2[0] = user_request->alpha2[0];
1482 user_alpha2[1] = user_request->alpha2[1];
1483
1484 return reg_call_crda(user_request);
1422} 1485}
1423 1486
1424static void reg_set_request_processed(void) 1487static enum reg_request_treatment
1488__reg_process_hint_driver(struct regulatory_request *driver_request)
1425{ 1489{
1426 bool need_more_processing = false;
1427 struct regulatory_request *lr = get_last_request(); 1490 struct regulatory_request *lr = get_last_request();
1428 1491
1429 lr->processed = true; 1492 if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
1430 1493 if (regdom_changes(driver_request->alpha2))
1431 spin_lock(&reg_requests_lock); 1494 return REG_REQ_OK;
1432 if (!list_empty(&reg_requests_list)) 1495 return REG_REQ_ALREADY_SET;
1433 need_more_processing = true; 1496 }
1434 spin_unlock(&reg_requests_lock);
1435 1497
1436 if (lr->initiator == NL80211_REGDOM_SET_BY_USER) 1498 /*
1437 cancel_delayed_work(&reg_timeout); 1499 * This would happen if you unplug and plug your card
1500 * back in or if you add a new device for which the previously
1501 * loaded card also agrees on the regulatory domain.
1502 */
1503 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
1504 !regdom_changes(driver_request->alpha2))
1505 return REG_REQ_ALREADY_SET;
1438 1506
1439 if (need_more_processing) 1507 return REG_REQ_INTERSECT;
1440 schedule_work(&reg_work);
1441} 1508}
1442 1509
1443/** 1510/**
1444 * __regulatory_hint - hint to the wireless core a regulatory domain 1511 * reg_process_hint_driver - process driver regulatory requests
1445 * @wiphy: if the hint comes from country information from an AP, this 1512 * @driver_request: a pending driver regulatory request
1446 * is required to be set to the wiphy that received the information
1447 * @pending_request: the regulatory request currently being processed
1448 * 1513 *
1449 * The Wireless subsystem can use this function to hint to the wireless core 1514 * The wireless subsystem can use this function to process
1450 * what it believes should be the current regulatory domain. 1515 * a regulatory request issued by an 802.11 driver.
1451 * 1516 *
1452 * Returns one of the different reg request treatment values. 1517 * Returns one of the different reg request treatment values.
1453 */ 1518 */
1454static enum reg_request_treatment 1519static enum reg_request_treatment
1455__regulatory_hint(struct wiphy *wiphy, 1520reg_process_hint_driver(struct wiphy *wiphy,
1456 struct regulatory_request *pending_request) 1521 struct regulatory_request *driver_request)
1457{ 1522{
1458 const struct ieee80211_regdomain *regd; 1523 const struct ieee80211_regdomain *regd;
1459 bool intersect = false;
1460 enum reg_request_treatment treatment; 1524 enum reg_request_treatment treatment;
1461 struct regulatory_request *lr;
1462 1525
1463 treatment = get_reg_request_treatment(wiphy, pending_request); 1526 treatment = __reg_process_hint_driver(driver_request);
1464 1527
1465 switch (treatment) { 1528 switch (treatment) {
1466 case REG_REQ_INTERSECT:
1467 if (pending_request->initiator ==
1468 NL80211_REGDOM_SET_BY_DRIVER) {
1469 regd = reg_copy_regd(get_cfg80211_regdom());
1470 if (IS_ERR(regd)) {
1471 kfree(pending_request);
1472 return PTR_ERR(regd);
1473 }
1474 rcu_assign_pointer(wiphy->regd, regd);
1475 }
1476 intersect = true;
1477 break;
1478 case REG_REQ_OK: 1529 case REG_REQ_OK:
1479 break; 1530 break;
1480 default: 1531 case REG_REQ_IGNORE:
1481 /* 1532 kfree(driver_request);
1482 * If the regulatory domain being requested by the
1483 * driver has already been set just copy it to the
1484 * wiphy
1485 */
1486 if (treatment == REG_REQ_ALREADY_SET &&
1487 pending_request->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
1488 regd = reg_copy_regd(get_cfg80211_regdom());
1489 if (IS_ERR(regd)) {
1490 kfree(pending_request);
1491 return REG_REQ_IGNORE;
1492 }
1493 treatment = REG_REQ_ALREADY_SET;
1494 rcu_assign_pointer(wiphy->regd, regd);
1495 goto new_request;
1496 }
1497 kfree(pending_request);
1498 return treatment; 1533 return treatment;
1534 case REG_REQ_INTERSECT:
1535 /* fall through */
1536 case REG_REQ_ALREADY_SET:
1537 regd = reg_copy_regd(get_cfg80211_regdom());
1538 if (IS_ERR(regd)) {
1539 kfree(driver_request);
1540 return REG_REQ_IGNORE;
1541 }
1542 rcu_assign_pointer(wiphy->regd, regd);
1499 } 1543 }
1500 1544
1501new_request:
1502 lr = get_last_request();
1503 if (lr != &core_request_world && lr)
1504 kfree_rcu(lr, rcu_head);
1505 1545
1506 pending_request->intersect = intersect; 1546 driver_request->intersect = treatment == REG_REQ_INTERSECT;
1507 pending_request->processed = false; 1547 driver_request->processed = false;
1508 rcu_assign_pointer(last_request, pending_request);
1509 lr = pending_request;
1510 1548
1511 pending_request = NULL; 1549 reg_update_last_request(driver_request);
1512 1550
1513 if (lr->initiator == NL80211_REGDOM_SET_BY_USER) { 1551 /*
1514 user_alpha2[0] = lr->alpha2[0]; 1552 * Since CRDA will not be called in this case as we already
1515 user_alpha2[1] = lr->alpha2[1]; 1553 * have applied the requested regulatory domain before we just
1554 * inform userspace we have processed the request
1555 */
1556 if (treatment == REG_REQ_ALREADY_SET) {
1557 nl80211_send_reg_change_event(driver_request);
1558 reg_set_request_processed();
1559 return treatment;
1516 } 1560 }
1517 1561
1518 /* When r == REG_REQ_INTERSECT we do need to call CRDA */ 1562 return reg_call_crda(driver_request);
1519 if (treatment != REG_REQ_OK && treatment != REG_REQ_INTERSECT) { 1563}
1564
1565static enum reg_request_treatment
1566__reg_process_hint_country_ie(struct wiphy *wiphy,
1567 struct regulatory_request *country_ie_request)
1568{
1569 struct wiphy *last_wiphy = NULL;
1570 struct regulatory_request *lr = get_last_request();
1571
1572 if (reg_request_cell_base(lr)) {
1573 /* Trust a Cell base station over the AP's country IE */
1574 if (regdom_changes(country_ie_request->alpha2))
1575 return REG_REQ_IGNORE;
1576 return REG_REQ_ALREADY_SET;
1577 } else {
1578 if (wiphy->regulatory_flags & REGULATORY_COUNTRY_IE_IGNORE)
1579 return REG_REQ_IGNORE;
1580 }
1581
1582 if (unlikely(!is_an_alpha2(country_ie_request->alpha2)))
1583 return -EINVAL;
1584
1585 if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE)
1586 return REG_REQ_OK;
1587
1588 last_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
1589
1590 if (last_wiphy != wiphy) {
1520 /* 1591 /*
1521 * Since CRDA will not be called in this case as we already 1592 * Two cards with two APs claiming different
1522 * have applied the requested regulatory domain before we just 1593 * Country IE alpha2s. We could
1523 * inform userspace we have processed the request 1594 * intersect them, but that seems unlikely
1595 * to be correct. Reject second one for now.
1524 */ 1596 */
1525 if (treatment == REG_REQ_ALREADY_SET) { 1597 if (regdom_changes(country_ie_request->alpha2))
1526 nl80211_send_reg_change_event(lr); 1598 return REG_REQ_IGNORE;
1527 reg_set_request_processed(); 1599 return REG_REQ_ALREADY_SET;
1528 }
1529 return treatment;
1530 } 1600 }
1601 /*
1602 * Two consecutive Country IE hints on the same wiphy.
1603 * This should be picked up early by the driver/stack
1604 */
1605 if (WARN_ON(regdom_changes(country_ie_request->alpha2)))
1606 return REG_REQ_OK;
1607 return REG_REQ_ALREADY_SET;
1608}
1609
1610/**
1611 * reg_process_hint_country_ie - process regulatory requests from country IEs
1612 * @country_ie_request: a regulatory request from a country IE
1613 *
1614 * The wireless subsystem can use this function to process
1615 * a regulatory request issued by a country Information Element.
1616 *
1617 * Returns one of the different reg request treatment values.
1618 */
1619static enum reg_request_treatment
1620reg_process_hint_country_ie(struct wiphy *wiphy,
1621 struct regulatory_request *country_ie_request)
1622{
1623 enum reg_request_treatment treatment;
1624
1625 treatment = __reg_process_hint_country_ie(wiphy, country_ie_request);
1531 1626
1532 if (call_crda(lr->alpha2)) 1627 switch (treatment) {
1628 case REG_REQ_OK:
1629 break;
1630 case REG_REQ_IGNORE:
1631 /* fall through */
1632 case REG_REQ_ALREADY_SET:
1633 kfree(country_ie_request);
1634 return treatment;
1635 case REG_REQ_INTERSECT:
1636 kfree(country_ie_request);
1637 /*
1638 * This doesn't happen yet, not sure we
1639 * ever want to support it for this case.
1640 */
1641 WARN_ONCE(1, "Unexpected intersection for country IEs");
1533 return REG_REQ_IGNORE; 1642 return REG_REQ_IGNORE;
1534 return REG_REQ_OK; 1643 }
1644
1645 country_ie_request->intersect = false;
1646 country_ie_request->processed = false;
1647
1648 reg_update_last_request(country_ie_request);
1649
1650 return reg_call_crda(country_ie_request);
1535} 1651}
1536 1652
1537/* This processes *all* regulatory hints */ 1653/* This processes *all* regulatory hints */
1538static void reg_process_hint(struct regulatory_request *reg_request, 1654static void reg_process_hint(struct regulatory_request *reg_request)
1539 enum nl80211_reg_initiator reg_initiator)
1540{ 1655{
1541 struct wiphy *wiphy = NULL; 1656 struct wiphy *wiphy = NULL;
1657 enum reg_request_treatment treatment;
1542 1658
1543 if (WARN_ON(!reg_request->alpha2)) 1659 if (WARN_ON(!reg_request->alpha2))
1544 return; 1660 return;
@@ -1546,23 +1662,37 @@ static void reg_process_hint(struct regulatory_request *reg_request,
1546 if (reg_request->wiphy_idx != WIPHY_IDX_INVALID) 1662 if (reg_request->wiphy_idx != WIPHY_IDX_INVALID)
1547 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); 1663 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
1548 1664
1549 if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) { 1665 if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER && !wiphy) {
1550 kfree(reg_request); 1666 kfree(reg_request);
1551 return; 1667 return;
1552 } 1668 }
1553 1669
1554 switch (__regulatory_hint(wiphy, reg_request)) { 1670 switch (reg_request->initiator) {
1555 case REG_REQ_ALREADY_SET: 1671 case NL80211_REGDOM_SET_BY_CORE:
1556 /* This is required so that the orig_* parameters are saved */ 1672 reg_process_hint_core(reg_request);
1557 if (wiphy && wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) 1673 return;
1558 wiphy_update_regulatory(wiphy, reg_initiator); 1674 case NL80211_REGDOM_SET_BY_USER:
1675 treatment = reg_process_hint_user(reg_request);
1676 if (treatment == REG_REQ_OK ||
1677 treatment == REG_REQ_ALREADY_SET)
1678 return;
1679 schedule_delayed_work(&reg_timeout, msecs_to_jiffies(3142));
1680 return;
1681 case NL80211_REGDOM_SET_BY_DRIVER:
1682 treatment = reg_process_hint_driver(wiphy, reg_request);
1559 break; 1683 break;
1560 default: 1684 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
1561 if (reg_initiator == NL80211_REGDOM_SET_BY_USER) 1685 treatment = reg_process_hint_country_ie(wiphy, reg_request);
1562 schedule_delayed_work(&reg_timeout,
1563 msecs_to_jiffies(3142));
1564 break; 1686 break;
1687 default:
1688 WARN(1, "invalid initiator %d\n", reg_request->initiator);
1689 return;
1565 } 1690 }
1691
1692 /* This is required so that the orig_* parameters are saved */
1693 if (treatment == REG_REQ_ALREADY_SET && wiphy &&
1694 wiphy->regulatory_flags & REGULATORY_STRICT_REG)
1695 wiphy_update_regulatory(wiphy, reg_request->initiator);
1566} 1696}
1567 1697
1568/* 1698/*
@@ -1596,7 +1726,7 @@ static void reg_process_pending_hints(void)
1596 1726
1597 spin_unlock(&reg_requests_lock); 1727 spin_unlock(&reg_requests_lock);
1598 1728
1599 reg_process_hint(reg_request, reg_request->initiator); 1729 reg_process_hint(reg_request);
1600} 1730}
1601 1731
1602/* Processes beacon hints -- this has nothing to do with country IEs */ 1732/* Processes beacon hints -- this has nothing to do with country IEs */
@@ -1888,7 +2018,7 @@ static void restore_regulatory_settings(bool reset_user)
1888 world_alpha2[1] = cfg80211_world_regdom->alpha2[1]; 2018 world_alpha2[1] = cfg80211_world_regdom->alpha2[1];
1889 2019
1890 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2020 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1891 if (rdev->wiphy.flags & WIPHY_FLAG_CUSTOM_REGULATORY) 2021 if (rdev->wiphy.regulatory_flags & REGULATORY_CUSTOM_REG)
1892 restore_custom_reg_settings(&rdev->wiphy); 2022 restore_custom_reg_settings(&rdev->wiphy);
1893 } 2023 }
1894 2024
@@ -2016,7 +2146,7 @@ static void print_rd_rules(const struct ieee80211_regdomain *rd)
2016 } 2146 }
2017} 2147}
2018 2148
2019bool reg_supported_dfs_region(u8 dfs_region) 2149bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region)
2020{ 2150{
2021 switch (dfs_region) { 2151 switch (dfs_region) {
2022 case NL80211_DFS_UNSET: 2152 case NL80211_DFS_UNSET:
@@ -2031,27 +2161,6 @@ bool reg_supported_dfs_region(u8 dfs_region)
2031 } 2161 }
2032} 2162}
2033 2163
2034static void print_dfs_region(u8 dfs_region)
2035{
2036 if (!dfs_region)
2037 return;
2038
2039 switch (dfs_region) {
2040 case NL80211_DFS_FCC:
2041 pr_info(" DFS Master region FCC");
2042 break;
2043 case NL80211_DFS_ETSI:
2044 pr_info(" DFS Master region ETSI");
2045 break;
2046 case NL80211_DFS_JP:
2047 pr_info(" DFS Master region JP");
2048 break;
2049 default:
2050 pr_info(" DFS Master region Unknown");
2051 break;
2052 }
2053}
2054
2055static void print_regdomain(const struct ieee80211_regdomain *rd) 2164static void print_regdomain(const struct ieee80211_regdomain *rd)
2056{ 2165{
2057 struct regulatory_request *lr = get_last_request(); 2166 struct regulatory_request *lr = get_last_request();
@@ -2083,7 +2192,7 @@ static void print_regdomain(const struct ieee80211_regdomain *rd)
2083 } 2192 }
2084 } 2193 }
2085 2194
2086 print_dfs_region(rd->dfs_region); 2195 pr_info(" DFS Master region: %s", reg_dfs_region_str(rd->dfs_region));
2087 print_rd_rules(rd); 2196 print_rd_rules(rd);
2088} 2197}
2089 2198
@@ -2093,48 +2202,60 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd)
2093 print_rd_rules(rd); 2202 print_rd_rules(rd);
2094} 2203}
2095 2204
2096/* Takes ownership of rd only if it doesn't fail */ 2205static int reg_set_rd_core(const struct ieee80211_regdomain *rd)
2097static int __set_regdom(const struct ieee80211_regdomain *rd) 2206{
2207 if (!is_world_regdom(rd->alpha2))
2208 return -EINVAL;
2209 update_world_regdomain(rd);
2210 return 0;
2211}
2212
2213static int reg_set_rd_user(const struct ieee80211_regdomain *rd,
2214 struct regulatory_request *user_request)
2098{ 2215{
2099 const struct ieee80211_regdomain *regd;
2100 const struct ieee80211_regdomain *intersected_rd = NULL; 2216 const struct ieee80211_regdomain *intersected_rd = NULL;
2101 struct wiphy *request_wiphy;
2102 struct regulatory_request *lr = get_last_request();
2103 2217
2104 /* Some basic sanity checks first */ 2218 if (is_world_regdom(rd->alpha2))
2219 return -EINVAL;
2220
2221 if (!regdom_changes(rd->alpha2))
2222 return -EALREADY;
2105 2223
2106 if (!reg_is_valid_request(rd->alpha2)) 2224 if (!is_valid_rd(rd)) {
2225 pr_err("Invalid regulatory domain detected:\n");
2226 print_regdomain_info(rd);
2107 return -EINVAL; 2227 return -EINVAL;
2228 }
2108 2229
2109 if (is_world_regdom(rd->alpha2)) { 2230 if (!user_request->intersect) {
2110 update_world_regdomain(rd); 2231 reset_regdomains(false, rd);
2111 return 0; 2232 return 0;
2112 } 2233 }
2113 2234
2114 if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) && 2235 intersected_rd = regdom_intersect(rd, get_cfg80211_regdom());
2115 !is_unknown_alpha2(rd->alpha2)) 2236 if (!intersected_rd)
2116 return -EINVAL; 2237 return -EINVAL;
2117 2238
2118 /* 2239 kfree(rd);
2119 * Lets only bother proceeding on the same alpha2 if the current 2240 rd = NULL;
2120 * rd is non static (it means CRDA was present and was used last) 2241 reset_regdomains(false, intersected_rd);
2121 * and the pending request came in from a country IE
2122 */
2123 if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
2124 /*
2125 * If someone else asked us to change the rd lets only bother
2126 * checking if the alpha2 changes if CRDA was already called
2127 */
2128 if (!regdom_changes(rd->alpha2))
2129 return -EALREADY;
2130 }
2131 2242
2132 /* 2243 return 0;
2133 * Now lets set the regulatory domain, update all driver channels 2244}
2134 * and finally inform them of what we have done, in case they want 2245
2135 * to review or adjust their own settings based on their own 2246static int reg_set_rd_driver(const struct ieee80211_regdomain *rd,
2136 * internal EEPROM data 2247 struct regulatory_request *driver_request)
2137 */ 2248{
2249 const struct ieee80211_regdomain *regd;
2250 const struct ieee80211_regdomain *intersected_rd = NULL;
2251 const struct ieee80211_regdomain *tmp;
2252 struct wiphy *request_wiphy;
2253
2254 if (is_world_regdom(rd->alpha2))
2255 return -EINVAL;
2256
2257 if (!regdom_changes(rd->alpha2))
2258 return -EALREADY;
2138 2259
2139 if (!is_valid_rd(rd)) { 2260 if (!is_valid_rd(rd)) {
2140 pr_err("Invalid regulatory domain detected:\n"); 2261 pr_err("Invalid regulatory domain detected:\n");
@@ -2142,29 +2263,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2142 return -EINVAL; 2263 return -EINVAL;
2143 } 2264 }
2144 2265
2145 request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx); 2266 request_wiphy = wiphy_idx_to_wiphy(driver_request->wiphy_idx);
2146 if (!request_wiphy && 2267 if (!request_wiphy) {
2147 (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER ||
2148 lr->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE)) {
2149 schedule_delayed_work(&reg_timeout, 0); 2268 schedule_delayed_work(&reg_timeout, 0);
2150 return -ENODEV; 2269 return -ENODEV;
2151 } 2270 }
2152 2271
2153 if (!lr->intersect) { 2272 if (!driver_request->intersect) {
2154 if (lr->initiator != NL80211_REGDOM_SET_BY_DRIVER) {
2155 reset_regdomains(false, rd);
2156 return 0;
2157 }
2158
2159 /*
2160 * For a driver hint, lets copy the regulatory domain the
2161 * driver wanted to the wiphy to deal with conflicts
2162 */
2163
2164 /*
2165 * Userspace could have sent two replies with only
2166 * one kernel request.
2167 */
2168 if (request_wiphy->regd) 2273 if (request_wiphy->regd)
2169 return -EALREADY; 2274 return -EALREADY;
2170 2275
@@ -2177,38 +2282,59 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
2177 return 0; 2282 return 0;
2178 } 2283 }
2179 2284
2180 /* Intersection requires a bit more work */ 2285 intersected_rd = regdom_intersect(rd, get_cfg80211_regdom());
2286 if (!intersected_rd)
2287 return -EINVAL;
2181 2288
2182 if (lr->initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { 2289 /*
2183 intersected_rd = regdom_intersect(rd, get_cfg80211_regdom()); 2290 * We can trash what CRDA provided now.
2184 if (!intersected_rd) 2291 * However if a driver requested this specific regulatory
2185 return -EINVAL; 2292 * domain we keep it for its private use
2293 */
2294 tmp = get_wiphy_regdom(request_wiphy);
2295 rcu_assign_pointer(request_wiphy->regd, rd);
2296 rcu_free_regdom(tmp);
2186 2297
2187 /* 2298 rd = NULL;
2188 * We can trash what CRDA provided now.
2189 * However if a driver requested this specific regulatory
2190 * domain we keep it for its private use
2191 */
2192 if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER) {
2193 const struct ieee80211_regdomain *tmp;
2194 2299
2195 tmp = get_wiphy_regdom(request_wiphy); 2300 reset_regdomains(false, intersected_rd);
2196 rcu_assign_pointer(request_wiphy->regd, rd);
2197 rcu_free_regdom(tmp);
2198 } else {
2199 kfree(rd);
2200 }
2201 2301
2202 rd = NULL; 2302 return 0;
2303}
2203 2304
2204 reset_regdomains(false, intersected_rd); 2305static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
2306 struct regulatory_request *country_ie_request)
2307{
2308 struct wiphy *request_wiphy;
2205 2309
2206 return 0; 2310 if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
2311 !is_unknown_alpha2(rd->alpha2))
2312 return -EINVAL;
2313
2314 /*
2315 * Lets only bother proceeding on the same alpha2 if the current
2316 * rd is non static (it means CRDA was present and was used last)
2317 * and the pending request came in from a country IE
2318 */
2319
2320 if (!is_valid_rd(rd)) {
2321 pr_err("Invalid regulatory domain detected:\n");
2322 print_regdomain_info(rd);
2323 return -EINVAL;
2207 } 2324 }
2208 2325
2209 return -EINVAL; 2326 request_wiphy = wiphy_idx_to_wiphy(country_ie_request->wiphy_idx);
2210} 2327 if (!request_wiphy) {
2328 schedule_delayed_work(&reg_timeout, 0);
2329 return -ENODEV;
2330 }
2331
2332 if (country_ie_request->intersect)
2333 return -EINVAL;
2211 2334
2335 reset_regdomains(false, rd);
2336 return 0;
2337}
2212 2338
2213/* 2339/*
2214 * Use this call to set the current regulatory domain. Conflicts with 2340 * Use this call to set the current regulatory domain. Conflicts with
@@ -2220,10 +2346,32 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2220 struct regulatory_request *lr; 2346 struct regulatory_request *lr;
2221 int r; 2347 int r;
2222 2348
2349 if (!reg_is_valid_request(rd->alpha2)) {
2350 kfree(rd);
2351 return -EINVAL;
2352 }
2353
2223 lr = get_last_request(); 2354 lr = get_last_request();
2224 2355
2225 /* Note that this doesn't update the wiphys, this is done below */ 2356 /* Note that this doesn't update the wiphys, this is done below */
2226 r = __set_regdom(rd); 2357 switch (lr->initiator) {
2358 case NL80211_REGDOM_SET_BY_CORE:
2359 r = reg_set_rd_core(rd);
2360 break;
2361 case NL80211_REGDOM_SET_BY_USER:
2362 r = reg_set_rd_user(rd, lr);
2363 break;
2364 case NL80211_REGDOM_SET_BY_DRIVER:
2365 r = reg_set_rd_driver(rd, lr);
2366 break;
2367 case NL80211_REGDOM_SET_BY_COUNTRY_IE:
2368 r = reg_set_rd_country_ie(rd, lr);
2369 break;
2370 default:
2371 WARN(1, "invalid initiator %d\n", lr->initiator);
2372 return -EINVAL;
2373 }
2374
2227 if (r) { 2375 if (r) {
2228 if (r == -EALREADY) 2376 if (r == -EALREADY)
2229 reg_set_request_processed(); 2377 reg_set_request_processed();
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 9677e3c13da9..cc4c2c0a6723 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -18,8 +18,9 @@
18 18
19extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain; 19extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
20 20
21bool reg_is_valid_request(const char *alpha2);
21bool is_world_regdom(const char *alpha2); 22bool is_world_regdom(const char *alpha2);
22bool reg_supported_dfs_region(u8 dfs_region); 23bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region);
23 24
24int regulatory_hint_user(const char *alpha2, 25int regulatory_hint_user(const char *alpha2,
25 enum nl80211_user_reg_hint_type user_reg_hint_type); 26 enum nl80211_user_reg_hint_type user_reg_hint_type);
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index ba5f0d6614d5..f7aa7a72d9bc 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1653,9 +1653,8 @@ TRACE_EVENT(rdev_cancel_remain_on_channel,
1653 1653
1654TRACE_EVENT(rdev_mgmt_tx, 1654TRACE_EVENT(rdev_mgmt_tx,
1655 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev, 1655 TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
1656 struct ieee80211_channel *chan, bool offchan, 1656 struct cfg80211_mgmt_tx_params *params),
1657 unsigned int wait, bool no_cck, bool dont_wait_for_ack), 1657 TP_ARGS(wiphy, wdev, params),
1658 TP_ARGS(wiphy, wdev, chan, offchan, wait, no_cck, dont_wait_for_ack),
1659 TP_STRUCT__entry( 1658 TP_STRUCT__entry(
1660 WIPHY_ENTRY 1659 WIPHY_ENTRY
1661 WDEV_ENTRY 1660 WDEV_ENTRY
@@ -1668,11 +1667,11 @@ TRACE_EVENT(rdev_mgmt_tx,
1668 TP_fast_assign( 1667 TP_fast_assign(
1669 WIPHY_ASSIGN; 1668 WIPHY_ASSIGN;
1670 WDEV_ASSIGN; 1669 WDEV_ASSIGN;
1671 CHAN_ASSIGN(chan); 1670 CHAN_ASSIGN(params->chan);
1672 __entry->offchan = offchan; 1671 __entry->offchan = params->offchan;
1673 __entry->wait = wait; 1672 __entry->wait = params->wait;
1674 __entry->no_cck = no_cck; 1673 __entry->no_cck = params->no_cck;
1675 __entry->dont_wait_for_ack = dont_wait_for_ack; 1674 __entry->dont_wait_for_ack = params->dont_wait_for_ack;
1676 ), 1675 ),
1677 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s," 1676 TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT ", " CHAN_PR_FMT ", offchan: %s,"
1678 " wait: %u, no cck: %s, dont wait for ack: %s", 1677 " wait: %u, no cck: %s, dont wait for ack: %s",