aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-03-29 16:50:10 -0400
committerDavid S. Miller <davem@davemloft.net>2010-03-29 16:50:10 -0400
commit7905e357ebe67a26d9dc8caa1a0b8346431b5f0d (patch)
tree134442df2f062caa6cebda1b352948b8209efcec /drivers
parent083ba279d52bcad20f1dfa3cefd4255cbe82d521 (diff)
parent76232ebf898c4d5e657f2b663fbf7108bca80ded (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ps3_gelic_wireless.c35
-rw-r--r--drivers/net/wireless/ath/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile10
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c421
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c993
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h105
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h441
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c260
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c713
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1626
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c604
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c463
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h246
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c134
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h141
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c319
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h126
-rw-r--r--drivers/net/wireless/ath/debug.h1
-rw-r--r--drivers/net/wireless/b43/main.c5
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c83
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c124
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c154
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c102
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c155
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c630
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c72
-rw-r--r--drivers/net/wireless/libertas/assoc.c22
-rw-r--r--drivers/net/wireless/libertas/dev.h1
-rw-r--r--drivers/net/wireless/libertas/main.c1
-rw-r--r--drivers/net/wireless/libertas/wext.c4
-rw-r--r--drivers/net/wireless/orinoco/wext.c94
-rw-r--r--drivers/net/wireless/ray_cs.c212
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c25
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h68
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_boot.c8
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c218
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.h12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_conf.h330
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_debugfs.c12
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_io.h13
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c496
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_sdio.c74
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c35
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.h3
-rw-r--r--drivers/net/wireless/wl3501_cs.c52
69 files changed, 8589 insertions, 1421 deletions
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index 505f9a194369..a9153a3481e1 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -2279,26 +2279,25 @@ void gelic_wl_interrupt(struct net_device *netdev, u64 status)
2279/* 2279/*
2280 * driver helpers 2280 * driver helpers
2281 */ 2281 */
2282#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT]
2283static const iw_handler gelic_wl_wext_handler[] = 2282static const iw_handler gelic_wl_wext_handler[] =
2284{ 2283{
2285 IW_IOCTL(SIOCGIWNAME) = gelic_wl_get_name, 2284 IW_HANDLER(SIOCGIWNAME, gelic_wl_get_name),
2286 IW_IOCTL(SIOCGIWRANGE) = gelic_wl_get_range, 2285 IW_HANDLER(SIOCGIWRANGE, gelic_wl_get_range),
2287 IW_IOCTL(SIOCSIWSCAN) = gelic_wl_set_scan, 2286 IW_HANDLER(SIOCSIWSCAN, gelic_wl_set_scan),
2288 IW_IOCTL(SIOCGIWSCAN) = gelic_wl_get_scan, 2287 IW_HANDLER(SIOCGIWSCAN, gelic_wl_get_scan),
2289 IW_IOCTL(SIOCSIWAUTH) = gelic_wl_set_auth, 2288 IW_HANDLER(SIOCSIWAUTH, gelic_wl_set_auth),
2290 IW_IOCTL(SIOCGIWAUTH) = gelic_wl_get_auth, 2289 IW_HANDLER(SIOCGIWAUTH, gelic_wl_get_auth),
2291 IW_IOCTL(SIOCSIWESSID) = gelic_wl_set_essid, 2290 IW_HANDLER(SIOCSIWESSID, gelic_wl_set_essid),
2292 IW_IOCTL(SIOCGIWESSID) = gelic_wl_get_essid, 2291 IW_HANDLER(SIOCGIWESSID, gelic_wl_get_essid),
2293 IW_IOCTL(SIOCSIWENCODE) = gelic_wl_set_encode, 2292 IW_HANDLER(SIOCSIWENCODE, gelic_wl_set_encode),
2294 IW_IOCTL(SIOCGIWENCODE) = gelic_wl_get_encode, 2293 IW_HANDLER(SIOCGIWENCODE, gelic_wl_get_encode),
2295 IW_IOCTL(SIOCSIWAP) = gelic_wl_set_ap, 2294 IW_HANDLER(SIOCSIWAP, gelic_wl_set_ap),
2296 IW_IOCTL(SIOCGIWAP) = gelic_wl_get_ap, 2295 IW_HANDLER(SIOCGIWAP, gelic_wl_get_ap),
2297 IW_IOCTL(SIOCSIWENCODEEXT) = gelic_wl_set_encodeext, 2296 IW_HANDLER(SIOCSIWENCODEEXT, gelic_wl_set_encodeext),
2298 IW_IOCTL(SIOCGIWENCODEEXT) = gelic_wl_get_encodeext, 2297 IW_HANDLER(SIOCGIWENCODEEXT, gelic_wl_get_encodeext),
2299 IW_IOCTL(SIOCSIWMODE) = gelic_wl_set_mode, 2298 IW_HANDLER(SIOCSIWMODE, gelic_wl_set_mode),
2300 IW_IOCTL(SIOCGIWMODE) = gelic_wl_get_mode, 2299 IW_HANDLER(SIOCGIWMODE, gelic_wl_get_mode),
2301 IW_IOCTL(SIOCGIWNICKN) = gelic_wl_get_nick, 2300 IW_HANDLER(SIOCGIWNICKN, gelic_wl_get_nick),
2302}; 2301};
2303 2302
2304static const struct iw_handler_def gelic_wl_wext_handler_def = { 2303static const struct iw_handler_def gelic_wl_wext_handler_def = {
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 4e7a7fd695c8..0a75be027afa 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This will enable the support for the Atheros wireless drivers. 5 This will enable the support for the Atheros wireless drivers.
6 ath5k, ath9k and ar9170 drivers share some common code, this option 6 ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
7 enables the common ath.ko module which shares common helpers. 7 enables the common ath.ko module which shares common helpers.
8 8
9 For more information and documentation on this module you can visit: 9 For more information and documentation on this module you can visit:
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5774cea23a3b..35f23bdc442f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS
32 32
33 Also required for changing debug message flags at run time. 33 Also required for changing debug message flags at run time.
34 34
35config ATH9K_HTC
36 tristate "Atheros HTC based wireless cards support"
37 depends on USB && MAC80211
38 select ATH9K_HW
39 select MAC80211_LEDS
40 select LEDS_CLASS
41 select NEW_LEDS
42 select ATH9K_COMMON
43 ---help---
44 Support for Atheros HTC based cards.
45 Chipsets supported: AR9271
46
47 For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
48
49 The built module will be ath9k_htc.
50
51config ATH9K_HTC_DEBUGFS
52 bool "Atheros ath9k_htc debugging"
53 depends on ATH9K_HTC && DEBUG_FS
54 ---help---
55 Say Y, if you need access to ath9k_htc's statistics.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b50d5eb9ec3..97133beda269 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -28,3 +28,13 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
28 28
29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
30ath9k_common-y:= common.o 30ath9k_common-y:= common.o
31
32ath9k_htc-y += htc_hst.o \
33 hif_usb.o \
34 wmi.o \
35 htc_drv_txrx.o \
36 htc_drv_main.o \
37 htc_drv_beacon.o \
38 htc_drv_init.o
39
40obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 238a5744d8e9..d5026e4f484b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -101,9 +101,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
101 nf = 0 - ((nf ^ 0x1ff) + 1); 101 nf = 0 - ((nf ^ 0x1ff) + 1);
102 ath_print(common, ATH_DBG_CALIBRATE, 102 ath_print(common, ATH_DBG_CALIBRATE,
103 "NF calibrated [ctl] [chain 0] is %d\n", nf); 103 "NF calibrated [ctl] [chain 0] is %d\n", nf);
104
105 if (AR_SREV_9271(ah) && (nf >= -114))
106 nf = -116;
107
104 nfarray[0] = nf; 108 nfarray[0] = nf;
105 109
106 if (!AR_SREV_9285(ah)) { 110 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
107 if (AR_SREV_9280_10_OR_LATER(ah)) 111 if (AR_SREV_9280_10_OR_LATER(ah))
108 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), 112 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
109 AR9280_PHY_CH1_MINCCA_PWR); 113 AR9280_PHY_CH1_MINCCA_PWR);
@@ -139,9 +143,13 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
139 nf = 0 - ((nf ^ 0x1ff) + 1); 143 nf = 0 - ((nf ^ 0x1ff) + 1);
140 ath_print(common, ATH_DBG_CALIBRATE, 144 ath_print(common, ATH_DBG_CALIBRATE,
141 "NF calibrated [ext] [chain 0] is %d\n", nf); 145 "NF calibrated [ext] [chain 0] is %d\n", nf);
146
147 if (AR_SREV_9271(ah) && (nf >= -114))
148 nf = -116;
149
142 nfarray[3] = nf; 150 nfarray[3] = nf;
143 151
144 if (!AR_SREV_9285(ah)) { 152 if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) {
145 if (AR_SREV_9280_10_OR_LATER(ah)) 153 if (AR_SREV_9280_10_OR_LATER(ah))
146 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), 154 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
147 AR9280_PHY_CH1_EXT_MINCCA_PWR); 155 AR9280_PHY_CH1_EXT_MINCCA_PWR);
@@ -621,7 +629,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
621 u8 chainmask, rx_chain_status; 629 u8 chainmask, rx_chain_status;
622 630
623 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); 631 rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
624 if (AR_SREV_9285(ah)) 632 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
625 chainmask = 0x9; 633 chainmask = 0x9;
626 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { 634 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
627 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) 635 if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
@@ -715,7 +723,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
715 723
716 if (AR_SREV_9280(ah)) 724 if (AR_SREV_9280(ah))
717 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; 725 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
718 else if (AR_SREV_9285(ah)) 726 else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
719 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; 727 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
720 else if (AR_SREV_9287(ah)) 728 else if (AR_SREV_9287(ah))
721 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; 729 noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
@@ -1051,9 +1059,12 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
1051 /* Do NF cal only at longer intervals */ 1059 /* Do NF cal only at longer intervals */
1052 if (longcal) { 1060 if (longcal) {
1053 /* Do periodic PAOffset Cal */ 1061 /* Do periodic PAOffset Cal */
1054 if (AR_SREV_9271(ah)) 1062 if (AR_SREV_9271(ah)) {
1055 ath9k_hw_9271_pa_cal(ah, false); 1063 if (!ah->pacal_info.skipcount)
1056 else if (AR_SREV_9285_11_OR_LATER(ah)) { 1064 ath9k_hw_9271_pa_cal(ah, false);
1065 else
1066 ah->pacal_info.skipcount--;
1067 } else if (AR_SREV_9285_11_OR_LATER(ah)) {
1057 if (!ah->pacal_info.skipcount) 1068 if (!ah->pacal_info.skipcount)
1058 ath9k_hw_9285_pa_cal(ah, false); 1069 ath9k_hw_9285_pa_cal(ah, false);
1059 else 1070 else
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4d775ae141db..7902d287f671 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -286,6 +286,427 @@ int ath9k_cmn_padpos(__le16 frame_control)
286} 286}
287EXPORT_SYMBOL(ath9k_cmn_padpos); 287EXPORT_SYMBOL(ath9k_cmn_padpos);
288 288
289int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
290{
291 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
292
293 if (tx_info->control.hw_key) {
294 if (tx_info->control.hw_key->alg == ALG_WEP)
295 return ATH9K_KEY_TYPE_WEP;
296 else if (tx_info->control.hw_key->alg == ALG_TKIP)
297 return ATH9K_KEY_TYPE_TKIP;
298 else if (tx_info->control.hw_key->alg == ALG_CCMP)
299 return ATH9K_KEY_TYPE_AES;
300 }
301
302 return ATH9K_KEY_TYPE_CLEAR;
303}
304EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
305
306/*
307 * Calculate the RX filter to be set in the HW.
308 */
309u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
310 unsigned int rxfilter)
311{
312#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
313
314 u32 rfilt;
315
316 rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
317 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
318 | ATH9K_RX_FILTER_MCAST;
319
320 /* If not a STA, enable processing of Probe Requests */
321 if (ah->opmode != NL80211_IFTYPE_STATION)
322 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
323
324 /*
325 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
326 * mode interface or when in monitor mode. AP mode does not need this
327 * since it receives all in-BSS frames anyway.
328 */
329 if (((ah->opmode != NL80211_IFTYPE_AP) &&
330 (rxfilter & FIF_PROMISC_IN_BSS)) ||
331 (ah->opmode == NL80211_IFTYPE_MONITOR))
332 rfilt |= ATH9K_RX_FILTER_PROM;
333
334 if (rxfilter & FIF_CONTROL)
335 rfilt |= ATH9K_RX_FILTER_CONTROL;
336
337 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
338 !(rxfilter & FIF_BCN_PRBRESP_PROMISC))
339 rfilt |= ATH9K_RX_FILTER_MYBEACON;
340 else
341 rfilt |= ATH9K_RX_FILTER_BEACON;
342
343 if ((AR_SREV_9280_10_OR_LATER(ah) ||
344 AR_SREV_9285_10_OR_LATER(ah)) &&
345 (ah->opmode == NL80211_IFTYPE_AP) &&
346 (rxfilter & FIF_PSPOLL))
347 rfilt |= ATH9K_RX_FILTER_PSPOLL;
348
349 if (conf_is_ht(&hw->conf))
350 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
351
352 return rfilt;
353
354#undef RX_FILTER_PRESERVE
355}
356EXPORT_SYMBOL(ath9k_cmn_calcrxfilter);
357
358/*
359 * Recv initialization for opmode change.
360 */
361void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
362 unsigned int rxfilter)
363{
364 struct ath_common *common = ath9k_hw_common(ah);
365
366 u32 rfilt, mfilt[2];
367
368 /* configure rx filter */
369 rfilt = ath9k_cmn_calcrxfilter(hw, ah, rxfilter);
370 ath9k_hw_setrxfilter(ah, rfilt);
371
372 /* configure bssid mask */
373 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
374 ath_hw_setbssidmask(common);
375
376 /* configure operational mode */
377 ath9k_hw_setopmode(ah);
378
379 /* Handle any link-level address change. */
380 ath9k_hw_setmac(ah, common->macaddr);
381
382 /* calculate and install multicast filter */
383 mfilt[0] = mfilt[1] = ~0;
384 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
385}
386EXPORT_SYMBOL(ath9k_cmn_opmode_init);
387
388static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
389 enum nl80211_channel_type channel_type)
390{
391 u32 chanmode = 0;
392
393 switch (chan->band) {
394 case IEEE80211_BAND_2GHZ:
395 switch (channel_type) {
396 case NL80211_CHAN_NO_HT:
397 case NL80211_CHAN_HT20:
398 chanmode = CHANNEL_G_HT20;
399 break;
400 case NL80211_CHAN_HT40PLUS:
401 chanmode = CHANNEL_G_HT40PLUS;
402 break;
403 case NL80211_CHAN_HT40MINUS:
404 chanmode = CHANNEL_G_HT40MINUS;
405 break;
406 }
407 break;
408 case IEEE80211_BAND_5GHZ:
409 switch (channel_type) {
410 case NL80211_CHAN_NO_HT:
411 case NL80211_CHAN_HT20:
412 chanmode = CHANNEL_A_HT20;
413 break;
414 case NL80211_CHAN_HT40PLUS:
415 chanmode = CHANNEL_A_HT40PLUS;
416 break;
417 case NL80211_CHAN_HT40MINUS:
418 chanmode = CHANNEL_A_HT40MINUS;
419 break;
420 }
421 break;
422 default:
423 break;
424 }
425
426 return chanmode;
427}
428
429/*
430 * Update internal channel flags.
431 */
432void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
433 struct ath9k_channel *ichan)
434{
435 struct ieee80211_channel *chan = hw->conf.channel;
436 struct ieee80211_conf *conf = &hw->conf;
437
438 ichan->channel = chan->center_freq;
439 ichan->chan = chan;
440
441 if (chan->band == IEEE80211_BAND_2GHZ) {
442 ichan->chanmode = CHANNEL_G;
443 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
444 } else {
445 ichan->chanmode = CHANNEL_A;
446 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
447 }
448
449 if (conf_is_ht(conf))
450 ichan->chanmode = ath9k_get_extchanmode(chan,
451 conf->channel_type);
452}
453EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
454
455/*
456 * Get the internal channel reference.
457 */
458struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
459 struct ath_hw *ah)
460{
461 struct ieee80211_channel *curchan = hw->conf.channel;
462 struct ath9k_channel *channel;
463 u8 chan_idx;
464
465 chan_idx = curchan->hw_value;
466 channel = &ah->channels[chan_idx];
467 ath9k_cmn_update_ichannel(hw, channel);
468
469 return channel;
470}
471EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
472
473static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
474 struct ath9k_keyval *hk, const u8 *addr,
475 bool authenticator)
476{
477 struct ath_hw *ah = common->ah;
478 const u8 *key_rxmic;
479 const u8 *key_txmic;
480
481 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
482 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
483
484 if (addr == NULL) {
485 /*
486 * Group key installation - only two key cache entries are used
487 * regardless of splitmic capability since group key is only
488 * used either for TX or RX.
489 */
490 if (authenticator) {
491 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
492 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
493 } else {
494 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
495 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
496 }
497 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
498 }
499 if (!common->splitmic) {
500 /* TX and RX keys share the same key cache entry. */
501 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
502 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
503 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
504 }
505
506 /* Separate key cache entries for TX and RX */
507
508 /* TX key goes at first index, RX key at +32. */
509 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
510 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
511 /* TX MIC entry failed. No need to proceed further */
512 ath_print(common, ATH_DBG_FATAL,
513 "Setting TX MIC Key Failed\n");
514 return 0;
515 }
516
517 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
518 /* XXX delete tx key on failure? */
519 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
520}
521
522static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
523{
524 int i;
525
526 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
527 if (test_bit(i, common->keymap) ||
528 test_bit(i + 64, common->keymap))
529 continue; /* At least one part of TKIP key allocated */
530 if (common->splitmic &&
531 (test_bit(i + 32, common->keymap) ||
532 test_bit(i + 64 + 32, common->keymap)))
533 continue; /* At least one part of TKIP key allocated */
534
535 /* Found a free slot for a TKIP key */
536 return i;
537 }
538 return -1;
539}
540
541static int ath_reserve_key_cache_slot(struct ath_common *common)
542{
543 int i;
544
545 /* First, try to find slots that would not be available for TKIP. */
546 if (common->splitmic) {
547 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
548 if (!test_bit(i, common->keymap) &&
549 (test_bit(i + 32, common->keymap) ||
550 test_bit(i + 64, common->keymap) ||
551 test_bit(i + 64 + 32, common->keymap)))
552 return i;
553 if (!test_bit(i + 32, common->keymap) &&
554 (test_bit(i, common->keymap) ||
555 test_bit(i + 64, common->keymap) ||
556 test_bit(i + 64 + 32, common->keymap)))
557 return i + 32;
558 if (!test_bit(i + 64, common->keymap) &&
559 (test_bit(i , common->keymap) ||
560 test_bit(i + 32, common->keymap) ||
561 test_bit(i + 64 + 32, common->keymap)))
562 return i + 64;
563 if (!test_bit(i + 64 + 32, common->keymap) &&
564 (test_bit(i, common->keymap) ||
565 test_bit(i + 32, common->keymap) ||
566 test_bit(i + 64, common->keymap)))
567 return i + 64 + 32;
568 }
569 } else {
570 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
571 if (!test_bit(i, common->keymap) &&
572 test_bit(i + 64, common->keymap))
573 return i;
574 if (test_bit(i, common->keymap) &&
575 !test_bit(i + 64, common->keymap))
576 return i + 64;
577 }
578 }
579
580 /* No partially used TKIP slots, pick any available slot */
581 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
582 /* Do not allow slots that could be needed for TKIP group keys
583 * to be used. This limitation could be removed if we know that
584 * TKIP will not be used. */
585 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
586 continue;
587 if (common->splitmic) {
588 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
589 continue;
590 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
591 continue;
592 }
593
594 if (!test_bit(i, common->keymap))
595 return i; /* Found a free slot for a key */
596 }
597
598 /* No free slot found */
599 return -1;
600}
601
602/*
603 * Configure encryption in the HW.
604 */
605int ath9k_cmn_key_config(struct ath_common *common,
606 struct ieee80211_vif *vif,
607 struct ieee80211_sta *sta,
608 struct ieee80211_key_conf *key)
609{
610 struct ath_hw *ah = common->ah;
611 struct ath9k_keyval hk;
612 const u8 *mac = NULL;
613 int ret = 0;
614 int idx;
615
616 memset(&hk, 0, sizeof(hk));
617
618 switch (key->alg) {
619 case ALG_WEP:
620 hk.kv_type = ATH9K_CIPHER_WEP;
621 break;
622 case ALG_TKIP:
623 hk.kv_type = ATH9K_CIPHER_TKIP;
624 break;
625 case ALG_CCMP:
626 hk.kv_type = ATH9K_CIPHER_AES_CCM;
627 break;
628 default:
629 return -EOPNOTSUPP;
630 }
631
632 hk.kv_len = key->keylen;
633 memcpy(hk.kv_val, key->key, key->keylen);
634
635 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
636 /* For now, use the default keys for broadcast keys. This may
637 * need to change with virtual interfaces. */
638 idx = key->keyidx;
639 } else if (key->keyidx) {
640 if (WARN_ON(!sta))
641 return -EOPNOTSUPP;
642 mac = sta->addr;
643
644 if (vif->type != NL80211_IFTYPE_AP) {
645 /* Only keyidx 0 should be used with unicast key, but
646 * allow this for client mode for now. */
647 idx = key->keyidx;
648 } else
649 return -EIO;
650 } else {
651 if (WARN_ON(!sta))
652 return -EOPNOTSUPP;
653 mac = sta->addr;
654
655 if (key->alg == ALG_TKIP)
656 idx = ath_reserve_key_cache_slot_tkip(common);
657 else
658 idx = ath_reserve_key_cache_slot(common);
659 if (idx < 0)
660 return -ENOSPC; /* no free key cache entries */
661 }
662
663 if (key->alg == ALG_TKIP)
664 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
665 vif->type == NL80211_IFTYPE_AP);
666 else
667 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
668
669 if (!ret)
670 return -EIO;
671
672 set_bit(idx, common->keymap);
673 if (key->alg == ALG_TKIP) {
674 set_bit(idx + 64, common->keymap);
675 if (common->splitmic) {
676 set_bit(idx + 32, common->keymap);
677 set_bit(idx + 64 + 32, common->keymap);
678 }
679 }
680
681 return idx;
682}
683EXPORT_SYMBOL(ath9k_cmn_key_config);
684
685/*
686 * Delete Key.
687 */
688void ath9k_cmn_key_delete(struct ath_common *common,
689 struct ieee80211_key_conf *key)
690{
691 struct ath_hw *ah = common->ah;
692
693 ath9k_hw_keyreset(ah, key->hw_key_idx);
694 if (key->hw_key_idx < IEEE80211_WEP_NKID)
695 return;
696
697 clear_bit(key->hw_key_idx, common->keymap);
698 if (key->alg != ALG_TKIP)
699 return;
700
701 clear_bit(key->hw_key_idx + 64, common->keymap);
702 if (common->splitmic) {
703 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
704 clear_bit(key->hw_key_idx + 32, common->keymap);
705 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
706 }
707}
708EXPORT_SYMBOL(ath9k_cmn_key_delete);
709
289static int __init ath9k_cmn_init(void) 710static int __init ath9k_cmn_init(void)
290{ 711{
291 return 0; 712 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 042999c2fe9c..bbcc57f6eba3 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,6 +23,8 @@
23 23
24/* Common header for Atheros 802.11n base driver cores */ 24/* Common header for Atheros 802.11n base driver cores */
25 25
26#define IEEE80211_WEP_NKID 4
27
26#define WME_NUM_TID 16 28#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 29#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 30#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -125,3 +127,18 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
125 bool decrypt_error); 127 bool decrypt_error);
126 128
127int ath9k_cmn_padpos(__le16 frame_control); 129int ath9k_cmn_padpos(__le16 frame_control);
130int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
131u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
132 unsigned int rxfilter);
133void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
134 unsigned int rxfilter);
135void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
136 struct ath9k_channel *ichan);
137struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
138 struct ath_hw *ah);
139int ath9k_cmn_key_config(struct ath_common *common,
140 struct ieee80211_vif *vif,
141 struct ieee80211_sta *sta,
142 struct ieee80211_key_conf *key);
143void ath9k_cmn_key_delete(struct ath_common *common,
144 struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
new file mode 100644
index 000000000000..fc4f6e8c9ef3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -0,0 +1,993 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19#define ATH9K_FW_USB_DEV(devid, fw) \
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
21
22static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"),
24 { },
25};
26
27MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
28
29static int __hif_usb_tx(struct hif_device_usb *hif_dev);
30
31static void hif_usb_regout_cb(struct urb *urb)
32{
33 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
34 struct hif_device_usb *hif_dev = cmd->hif_dev;
35
36 if (!hif_dev) {
37 usb_free_urb(urb);
38 if (cmd) {
39 if (cmd->skb)
40 dev_kfree_skb_any(cmd->skb);
41 kfree(cmd);
42 }
43 return;
44 }
45
46 switch (urb->status) {
47 case 0:
48 break;
49 case -ENOENT:
50 case -ECONNRESET:
51 break;
52 case -ENODEV:
53 case -ESHUTDOWN:
54 return;
55 default:
56 break;
57 }
58
59 if (cmd) {
60 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
61 cmd->skb, 1);
62 kfree(cmd);
63 usb_free_urb(urb);
64 }
65}
66
67static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
68 struct sk_buff *skb)
69{
70 struct urb *urb;
71 struct cmd_buf *cmd;
72 int ret = 0;
73
74 urb = usb_alloc_urb(0, GFP_KERNEL);
75 if (urb == NULL)
76 return -ENOMEM;
77
78 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
79 if (cmd == NULL) {
80 usb_free_urb(urb);
81 return -ENOMEM;
82 }
83
84 cmd->skb = skb;
85 cmd->hif_dev = hif_dev;
86
87 usb_fill_int_urb(urb, hif_dev->udev,
88 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
89 skb->data, skb->len,
90 hif_usb_regout_cb, cmd, 1);
91
92 ret = usb_submit_urb(urb, GFP_KERNEL);
93 if (ret) {
94 usb_free_urb(urb);
95 kfree(cmd);
96 }
97
98 return ret;
99}
100
101static void hif_usb_tx_cb(struct urb *urb)
102{
103 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
104 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
105 struct sk_buff *skb;
106 bool drop, flush;
107
108 if (!hif_dev)
109 return;
110
111 switch (urb->status) {
112 case 0:
113 break;
114 case -ENOENT:
115 case -ECONNRESET:
116 break;
117 case -ENODEV:
118 case -ESHUTDOWN:
119 return;
120 default:
121 break;
122 }
123
124 if (tx_buf) {
125 spin_lock(&hif_dev->tx.tx_lock);
126 drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
127 flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
128 spin_unlock(&hif_dev->tx.tx_lock);
129
130 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
131 if (!drop && !flush) {
132 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
133 skb, 1);
134 TX_STAT_INC(skb_completed);
135 } else {
136 dev_kfree_skb_any(skb);
137 }
138 }
139
140 if (flush)
141 return;
142
143 tx_buf->len = tx_buf->offset = 0;
144 __skb_queue_head_init(&tx_buf->skb_queue);
145
146 spin_lock(&hif_dev->tx.tx_lock);
147 list_del(&tx_buf->list);
148 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
149 hif_dev->tx.tx_buf_cnt++;
150 if (!drop)
151 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
152 TX_STAT_INC(buf_completed);
153 spin_unlock(&hif_dev->tx.tx_lock);
154 }
155}
156
157/* TX lock has to be taken */
158static int __hif_usb_tx(struct hif_device_usb *hif_dev)
159{
160 struct tx_buf *tx_buf = NULL;
161 struct sk_buff *nskb = NULL;
162 int ret = 0, i;
163 u16 *hdr, tx_skb_cnt = 0;
164 u8 *buf;
165
166 if (hif_dev->tx.tx_skb_cnt == 0)
167 return 0;
168
169 /* Check if a free TX buffer is available */
170 if (list_empty(&hif_dev->tx.tx_buf))
171 return 0;
172
173 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
174 list_del(&tx_buf->list);
175 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
176 hif_dev->tx.tx_buf_cnt--;
177
178 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
179
180 for (i = 0; i < tx_skb_cnt; i++) {
181 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
182
183 /* Should never be NULL */
184 BUG_ON(!nskb);
185
186 hif_dev->tx.tx_skb_cnt--;
187
188 buf = tx_buf->buf;
189 buf += tx_buf->offset;
190 hdr = (u16 *)buf;
191 *hdr++ = nskb->len;
192 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
193 buf += 4;
194 memcpy(buf, nskb->data, nskb->len);
195 tx_buf->len = nskb->len + 4;
196
197 if (i < (tx_skb_cnt - 1))
198 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
199
200 if (i == (tx_skb_cnt - 1))
201 tx_buf->len += tx_buf->offset;
202
203 __skb_queue_tail(&tx_buf->skb_queue, nskb);
204 TX_STAT_INC(skb_queued);
205 }
206
207 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
208 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
209 tx_buf->buf, tx_buf->len,
210 hif_usb_tx_cb, tx_buf);
211
212 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
213 if (ret) {
214 tx_buf->len = tx_buf->offset = 0;
215 __skb_queue_purge(&tx_buf->skb_queue);
216 __skb_queue_head_init(&tx_buf->skb_queue);
217 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
218 hif_dev->tx.tx_buf_cnt++;
219 }
220
221 if (!ret)
222 TX_STAT_INC(buf_queued);
223
224 return ret;
225}
226
227static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
228 struct ath9k_htc_tx_ctl *tx_ctl)
229{
230 unsigned long flags;
231
232 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
233
234 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
235 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
236 return -ENODEV;
237 }
238
239 /* Check if the max queue count has been reached */
240 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
241 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
242 return -ENOMEM;
243 }
244
245 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
246 hif_dev->tx.tx_skb_cnt++;
247
248 /* Send normal frames immediately */
249 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
250 __hif_usb_tx(hif_dev);
251
252 /* Check if AMPDUs have to be sent immediately */
253 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
254 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
255 (hif_dev->tx.tx_skb_cnt < 2)) {
256 __hif_usb_tx(hif_dev);
257 }
258
259 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
260
261 return 0;
262}
263
264static void hif_usb_start(void *hif_handle, u8 pipe_id)
265{
266 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
267 unsigned long flags;
268
269 hif_dev->flags |= HIF_USB_START;
270
271 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
272 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
273 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
274}
275
276static void hif_usb_stop(void *hif_handle, u8 pipe_id)
277{
278 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
279 unsigned long flags;
280
281 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
282 __skb_queue_purge(&hif_dev->tx.tx_skb_queue);
283 hif_dev->tx.tx_skb_cnt = 0;
284 hif_dev->tx.flags |= HIF_USB_TX_STOP;
285 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
286}
287
288static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
289 struct ath9k_htc_tx_ctl *tx_ctl)
290{
291 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
292 int ret = 0;
293
294 switch (pipe_id) {
295 case USB_WLAN_TX_PIPE:
296 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
297 break;
298 case USB_REG_OUT_PIPE:
299 ret = hif_usb_send_regout(hif_dev, skb);
300 break;
301 default:
302 ret = -EINVAL;
303 break;
304 }
305
306 return ret;
307}
308
309static struct ath9k_htc_hif hif_usb = {
310 .transport = ATH9K_HIF_USB,
311 .name = "ath9k_hif_usb",
312
313 .control_ul_pipe = USB_REG_OUT_PIPE,
314 .control_dl_pipe = USB_REG_IN_PIPE,
315
316 .start = hif_usb_start,
317 .stop = hif_usb_stop,
318 .send = hif_usb_send,
319};
320
321static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
322 struct sk_buff *skb)
323{
324 struct sk_buff *nskb, *skb_pool[8];
325 int index = 0, i = 0, chk_idx, len = skb->len;
326 int rx_remain_len = 0, rx_pkt_len = 0;
327 u16 pkt_len, pkt_tag, pool_index = 0;
328 u8 *ptr;
329
330 rx_remain_len = hif_dev->rx_remain_len;
331 rx_pkt_len = hif_dev->rx_transfer_len;
332
333 if (rx_remain_len != 0) {
334 struct sk_buff *remain_skb = hif_dev->remain_skb;
335
336 if (remain_skb) {
337 ptr = (u8 *) remain_skb->data;
338
339 index = rx_remain_len;
340 rx_remain_len -= hif_dev->rx_pad_len;
341 ptr += rx_pkt_len;
342
343 memcpy(ptr, skb->data, rx_remain_len);
344
345 rx_pkt_len += rx_remain_len;
346 hif_dev->rx_remain_len = 0;
347 skb_put(remain_skb, rx_pkt_len);
348
349 skb_pool[pool_index++] = remain_skb;
350
351 } else {
352 index = rx_remain_len;
353 }
354 }
355
356 while (index < len) {
357 ptr = (u8 *) skb->data;
358
359 pkt_len = ptr[index] + (ptr[index+1] << 8);
360 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
361
362 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
363 u16 pad_len;
364
365 pad_len = 4 - (pkt_len & 0x3);
366 if (pad_len == 4)
367 pad_len = 0;
368
369 chk_idx = index;
370 index = index + 4 + pkt_len + pad_len;
371
372 if (index > MAX_RX_BUF_SIZE) {
373 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
374 hif_dev->rx_transfer_len =
375 MAX_RX_BUF_SIZE - chk_idx - 4;
376 hif_dev->rx_pad_len = pad_len;
377
378 nskb = __dev_alloc_skb(pkt_len + 32,
379 GFP_ATOMIC);
380 if (!nskb) {
381 dev_err(&hif_dev->udev->dev,
382 "ath9k_htc: RX memory allocation"
383 " error\n");
384 goto err;
385 }
386 skb_reserve(nskb, 32);
387 RX_STAT_INC(skb_allocated);
388
389 memcpy(nskb->data, &(skb->data[chk_idx+4]),
390 hif_dev->rx_transfer_len);
391
392 /* Record the buffer pointer */
393 hif_dev->remain_skb = nskb;
394 } else {
395 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
396 if (!nskb) {
397 dev_err(&hif_dev->udev->dev,
398 "ath9k_htc: RX memory allocation"
399 " error\n");
400 goto err;
401 }
402 skb_reserve(nskb, 32);
403 RX_STAT_INC(skb_allocated);
404
405 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
406 skb_put(nskb, pkt_len);
407 skb_pool[pool_index++] = nskb;
408 }
409 } else {
410 RX_STAT_INC(skb_dropped);
411 dev_kfree_skb_any(skb);
412 return;
413 }
414 }
415
416err:
417 dev_kfree_skb_any(skb);
418
419 for (i = 0; i < pool_index; i++) {
420 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
421 skb_pool[i]->len, USB_WLAN_RX_PIPE);
422 RX_STAT_INC(skb_completed);
423 }
424}
425
426static void ath9k_hif_usb_rx_cb(struct urb *urb)
427{
428 struct sk_buff *skb = (struct sk_buff *) urb->context;
429 struct sk_buff *nskb;
430 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
431 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
432 int ret;
433
434 if (!hif_dev)
435 goto free;
436
437 switch (urb->status) {
438 case 0:
439 break;
440 case -ENOENT:
441 case -ECONNRESET:
442 case -ENODEV:
443 case -ESHUTDOWN:
444 goto free;
445 default:
446 goto resubmit;
447 }
448
449 if (likely(urb->actual_length != 0)) {
450 skb_put(skb, urb->actual_length);
451
452 nskb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_ATOMIC);
453 if (!nskb)
454 goto resubmit;
455
456 usb_fill_bulk_urb(urb, hif_dev->udev,
457 usb_rcvbulkpipe(hif_dev->udev,
458 USB_WLAN_RX_PIPE),
459 nskb->data, MAX_RX_BUF_SIZE,
460 ath9k_hif_usb_rx_cb, nskb);
461
462 ret = usb_submit_urb(urb, GFP_ATOMIC);
463 if (ret) {
464 dev_kfree_skb_any(nskb);
465 goto free;
466 }
467
468 ath9k_hif_usb_rx_stream(hif_dev, skb);
469 return;
470 }
471
472resubmit:
473 skb_reset_tail_pointer(skb);
474 skb_trim(skb, 0);
475
476 ret = usb_submit_urb(urb, GFP_ATOMIC);
477 if (ret)
478 goto free;
479
480 return;
481free:
482 dev_kfree_skb_any(skb);
483}
484
485static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
486{
487 struct sk_buff *skb = (struct sk_buff *) urb->context;
488 struct sk_buff *nskb;
489 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
490 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
491 int ret;
492
493 if (!hif_dev)
494 goto free;
495
496 switch (urb->status) {
497 case 0:
498 break;
499 case -ENOENT:
500 case -ECONNRESET:
501 case -ENODEV:
502 case -ESHUTDOWN:
503 goto free;
504 default:
505 goto resubmit;
506 }
507
508 if (likely(urb->actual_length != 0)) {
509 skb_put(skb, urb->actual_length);
510
511 nskb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
512 if (!nskb)
513 goto resubmit;
514
515 usb_fill_int_urb(urb, hif_dev->udev,
516 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
517 nskb->data, MAX_REG_IN_BUF_SIZE,
518 ath9k_hif_usb_reg_in_cb, nskb, 1);
519
520 ret = usb_submit_urb(urb, GFP_ATOMIC);
521 if (ret) {
522 dev_kfree_skb_any(nskb);
523 goto free;
524 }
525
526 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
527 skb->len, USB_REG_IN_PIPE);
528
529 return;
530 }
531
532resubmit:
533 skb_reset_tail_pointer(skb);
534 skb_trim(skb, 0);
535
536 ret = usb_submit_urb(urb, GFP_ATOMIC);
537 if (ret)
538 goto free;
539
540 return;
541free:
542 dev_kfree_skb_any(skb);
543}
544
545static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
546{
547 unsigned long flags;
548 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
549
550 list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
551 list_del(&tx_buf->list);
552 usb_free_urb(tx_buf->urb);
553 kfree(tx_buf->buf);
554 kfree(tx_buf);
555 }
556
557 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
558 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
559 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
560
561 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
562 &hif_dev->tx.tx_pending, list) {
563 usb_kill_urb(tx_buf->urb);
564 list_del(&tx_buf->list);
565 usb_free_urb(tx_buf->urb);
566 kfree(tx_buf->buf);
567 kfree(tx_buf);
568 }
569
570 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
571 hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
572 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
573}
574
575static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
576{
577 struct tx_buf *tx_buf;
578 int i;
579
580 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
581 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
582 spin_lock_init(&hif_dev->tx.tx_lock);
583 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
584
585 for (i = 0; i < MAX_TX_URB_NUM; i++) {
586 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
587 if (!tx_buf)
588 goto err;
589
590 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
591 if (!tx_buf->buf)
592 goto err;
593
594 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
595 if (!tx_buf->urb)
596 goto err;
597
598 tx_buf->hif_dev = hif_dev;
599 __skb_queue_head_init(&tx_buf->skb_queue);
600
601 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
602 }
603
604 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
605
606 return 0;
607err:
608 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
609 return -ENOMEM;
610}
611
612static void ath9k_hif_usb_dealloc_rx_skbs(struct hif_device_usb *hif_dev)
613{
614 int i;
615
616 for (i = 0; i < MAX_RX_URB_NUM; i++) {
617 if (hif_dev->wlan_rx_data_urb[i]) {
618 if (hif_dev->wlan_rx_data_urb[i]->transfer_buffer)
619 dev_kfree_skb_any((void *)
620 hif_dev->wlan_rx_data_urb[i]->context);
621 }
622 }
623}
624
625static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
626{
627 int i;
628
629 for (i = 0; i < MAX_RX_URB_NUM; i++) {
630 if (hif_dev->wlan_rx_data_urb[i]) {
631 usb_kill_urb(hif_dev->wlan_rx_data_urb[i]);
632 usb_free_urb(hif_dev->wlan_rx_data_urb[i]);
633 hif_dev->wlan_rx_data_urb[i] = NULL;
634 }
635 }
636}
637
638static int ath9k_hif_usb_prep_rx_urb(struct hif_device_usb *hif_dev,
639 struct urb *urb)
640{
641 struct sk_buff *skb;
642
643 skb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
644 if (!skb)
645 return -ENOMEM;
646
647 usb_fill_bulk_urb(urb, hif_dev->udev,
648 usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE),
649 skb->data, MAX_RX_BUF_SIZE,
650 ath9k_hif_usb_rx_cb, skb);
651 return 0;
652}
653
654static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
655{
656 int i, ret;
657
658 for (i = 0; i < MAX_RX_URB_NUM; i++) {
659
660 /* Allocate URB */
661 hif_dev->wlan_rx_data_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
662 if (hif_dev->wlan_rx_data_urb[i] == NULL) {
663 ret = -ENOMEM;
664 goto err_rx_urb;
665 }
666
667 /* Allocate buffer */
668 ret = ath9k_hif_usb_prep_rx_urb(hif_dev,
669 hif_dev->wlan_rx_data_urb[i]);
670 if (ret)
671 goto err_rx_urb;
672
673 /* Submit URB */
674 ret = usb_submit_urb(hif_dev->wlan_rx_data_urb[i], GFP_KERNEL);
675 if (ret)
676 goto err_rx_urb;
677
678 }
679
680 return 0;
681
682err_rx_urb:
683 ath9k_hif_usb_dealloc_rx_skbs(hif_dev);
684 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
685 return ret;
686}
687
688static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
689{
690 if (hif_dev->reg_in_urb) {
691 usb_kill_urb(hif_dev->reg_in_urb);
692 usb_free_urb(hif_dev->reg_in_urb);
693 hif_dev->reg_in_urb = NULL;
694 }
695}
696
697static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
698{
699 struct sk_buff *skb;
700
701 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
702 if (hif_dev->reg_in_urb == NULL)
703 return -ENOMEM;
704
705 skb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
706 if (!skb)
707 goto err;
708
709 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
710 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
711 skb->data, MAX_REG_IN_BUF_SIZE,
712 ath9k_hif_usb_reg_in_cb, skb, 1);
713
714 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
715 goto err_skb;
716
717 return 0;
718
719err_skb:
720 dev_kfree_skb_any(skb);
721err:
722 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
723 return -ENOMEM;
724}
725
726static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
727{
728 /* TX */
729 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
730 goto err;
731
732 /* RX */
733 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
734 goto err;
735
736 /* Register Read/Write */
737 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
738 goto err;
739
740 return 0;
741err:
742 return -ENOMEM;
743}
744
745static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
746{
747 int transfer, err;
748 const void *data = hif_dev->firmware->data;
749 size_t len = hif_dev->firmware->size;
750 u32 addr = AR9271_FIRMWARE;
751 u8 *buf = kzalloc(4096, GFP_KERNEL);
752
753 if (!buf)
754 return -ENOMEM;
755
756 while (len) {
757 transfer = min_t(int, len, 4096);
758 memcpy(buf, data, transfer);
759
760 err = usb_control_msg(hif_dev->udev,
761 usb_sndctrlpipe(hif_dev->udev, 0),
762 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
763 addr >> 8, 0, buf, transfer, HZ);
764 if (err < 0) {
765 kfree(buf);
766 return err;
767 }
768
769 len -= transfer;
770 data += transfer;
771 addr += transfer;
772 }
773 kfree(buf);
774
775 /*
776 * Issue FW download complete command to firmware.
777 */
778 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
779 FIRMWARE_DOWNLOAD_COMP,
780 0x40 | USB_DIR_OUT,
781 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
782 if (err)
783 return -EIO;
784
785 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
786 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
787
788 return 0;
789}
790
791static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
792 const char *fw_name)
793{
794 int ret;
795
796 /* Request firmware */
797 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
798 if (ret) {
799 dev_err(&hif_dev->udev->dev,
800 "ath9k_htc: Firmware - %s not found\n", fw_name);
801 goto err_fw_req;
802 }
803
804 /* Download firmware */
805 ret = ath9k_hif_usb_download_fw(hif_dev);
806 if (ret) {
807 dev_err(&hif_dev->udev->dev,
808 "ath9k_htc: Firmware - %s download failed\n", fw_name);
809 goto err_fw_download;
810 }
811
812 /* Alloc URBs */
813 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
814 if (ret) {
815 dev_err(&hif_dev->udev->dev,
816 "ath9k_htc: Unable to allocate URBs\n");
817 goto err_urb;
818 }
819
820 return 0;
821
822err_urb:
823 /* Nothing */
824err_fw_download:
825 release_firmware(hif_dev->firmware);
826err_fw_req:
827 hif_dev->firmware = NULL;
828 return ret;
829}
830
831static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
832{
833 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
834 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
835 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
836}
837
838static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
839{
840 ath9k_hif_usb_dealloc_urbs(hif_dev);
841 if (hif_dev->firmware)
842 release_firmware(hif_dev->firmware);
843}
844
845static int ath9k_hif_usb_probe(struct usb_interface *interface,
846 const struct usb_device_id *id)
847{
848 struct usb_device *udev = interface_to_usbdev(interface);
849 struct hif_device_usb *hif_dev;
850 const char *fw_name = (const char *) id->driver_info;
851 int ret = 0;
852
853 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
854 if (!hif_dev) {
855 ret = -ENOMEM;
856 goto err_alloc;
857 }
858
859 usb_get_dev(udev);
860 hif_dev->udev = udev;
861 hif_dev->interface = interface;
862 hif_dev->device_id = id->idProduct;
863#ifdef CONFIG_PM
864 udev->reset_resume = 1;
865#endif
866 usb_set_intfdata(interface, hif_dev);
867
868 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
869 if (ret) {
870 ret = -EINVAL;
871 goto err_hif_init_usb;
872 }
873
874 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
875 if (hif_dev->htc_handle == NULL) {
876 ret = -ENOMEM;
877 goto err_htc_hw_alloc;
878 }
879
880 ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
881 &hif_dev->udev->dev, hif_dev->device_id,
882 ATH9K_HIF_USB);
883 if (ret) {
884 ret = -EINVAL;
885 goto err_htc_hw_init;
886 }
887
888 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
889
890 return 0;
891
892err_htc_hw_init:
893 ath9k_htc_hw_free(hif_dev->htc_handle);
894err_htc_hw_alloc:
895 ath9k_hif_usb_dev_deinit(hif_dev);
896err_hif_init_usb:
897 usb_set_intfdata(interface, NULL);
898 kfree(hif_dev);
899 usb_put_dev(udev);
900err_alloc:
901 return ret;
902}
903
904static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
905{
906 struct usb_device *udev = interface_to_usbdev(interface);
907 struct hif_device_usb *hif_dev =
908 (struct hif_device_usb *) usb_get_intfdata(interface);
909
910 if (hif_dev) {
911 ath9k_htc_hw_deinit(hif_dev->htc_handle, true);
912 ath9k_htc_hw_free(hif_dev->htc_handle);
913 ath9k_hif_usb_dev_deinit(hif_dev);
914 usb_set_intfdata(interface, NULL);
915 }
916
917 if (hif_dev->flags & HIF_USB_START)
918 usb_reset_device(udev);
919
920 kfree(hif_dev);
921 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
922 usb_put_dev(udev);
923}
924
925#ifdef CONFIG_PM
926static int ath9k_hif_usb_suspend(struct usb_interface *interface,
927 pm_message_t message)
928{
929 struct hif_device_usb *hif_dev =
930 (struct hif_device_usb *) usb_get_intfdata(interface);
931
932 ath9k_hif_usb_dealloc_urbs(hif_dev);
933
934 return 0;
935}
936
937static int ath9k_hif_usb_resume(struct usb_interface *interface)
938{
939 struct hif_device_usb *hif_dev =
940 (struct hif_device_usb *) usb_get_intfdata(interface);
941 int ret;
942
943 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
944 if (ret)
945 return ret;
946
947 if (hif_dev->firmware) {
948 ret = ath9k_hif_usb_download_fw(hif_dev);
949 if (ret)
950 goto fail_resume;
951 } else {
952 ath9k_hif_usb_dealloc_urbs(hif_dev);
953 return -EIO;
954 }
955
956 mdelay(100);
957
958 ret = ath9k_htc_resume(hif_dev->htc_handle);
959
960 if (ret)
961 goto fail_resume;
962
963 return 0;
964
965fail_resume:
966 ath9k_hif_usb_dealloc_urbs(hif_dev);
967
968 return ret;
969}
970#endif
971
972static struct usb_driver ath9k_hif_usb_driver = {
973 .name = "ath9k_hif_usb",
974 .probe = ath9k_hif_usb_probe,
975 .disconnect = ath9k_hif_usb_disconnect,
976#ifdef CONFIG_PM
977 .suspend = ath9k_hif_usb_suspend,
978 .resume = ath9k_hif_usb_resume,
979 .reset_resume = ath9k_hif_usb_resume,
980#endif
981 .id_table = ath9k_hif_usb_ids,
982 .soft_unbind = 1,
983};
984
985int ath9k_hif_usb_init(void)
986{
987 return usb_register(&ath9k_hif_usb_driver);
988}
989
990void ath9k_hif_usb_exit(void)
991{
992 usb_deregister(&ath9k_hif_usb_driver);
993}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
new file mode 100644
index 000000000000..7cc3762a6789
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_USB_H
18#define HTC_USB_H
19
20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000
22
23#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31
25
26#define ATH_USB_RX_STREAM_MODE_TAG 0x4e00
27#define ATH_USB_TX_STREAM_MODE_TAG 0x697e
28
29/* FIXME: Verify these numbers (with Windows) */
30#define MAX_TX_URB_NUM 8
31#define MAX_TX_BUF_NUM 1024
32#define MAX_TX_BUF_SIZE 32768
33#define MAX_TX_AGGR_NUM 20
34
35#define MAX_RX_URB_NUM 8
36#define MAX_RX_BUF_SIZE 16384
37
38#define MAX_REG_OUT_URB_NUM 1
39#define MAX_REG_OUT_BUF_NUM 8
40
41#define MAX_REG_IN_BUF_SIZE 64
42
43/* USB Endpoint definition */
44#define USB_WLAN_TX_PIPE 1
45#define USB_WLAN_RX_PIPE 2
46#define USB_REG_IN_PIPE 3
47#define USB_REG_OUT_PIPE 4
48
49#define HIF_USB_MAX_RXPIPES 2
50#define HIF_USB_MAX_TXPIPES 4
51
52struct tx_buf {
53 u8 *buf;
54 u16 len;
55 u16 offset;
56 struct urb *urb;
57 struct sk_buff_head skb_queue;
58 struct hif_device_usb *hif_dev;
59 struct list_head list;
60};
61
62#define HIF_USB_TX_STOP BIT(0)
63#define HIF_USB_TX_FLUSH BIT(1)
64
65struct hif_usb_tx {
66 u8 flags;
67 u8 tx_buf_cnt;
68 u16 tx_skb_cnt;
69 struct sk_buff_head tx_skb_queue;
70 struct list_head tx_buf;
71 struct list_head tx_pending;
72 spinlock_t tx_lock;
73};
74
75struct cmd_buf {
76 struct sk_buff *skb;
77 struct hif_device_usb *hif_dev;
78};
79
80#define HIF_USB_START BIT(0)
81
82struct hif_device_usb {
83 u16 device_id;
84 struct usb_device *udev;
85 struct usb_interface *interface;
86 const struct firmware *firmware;
87 struct htc_target *htc_handle;
88 u8 flags;
89
90 struct hif_usb_tx tx;
91
92 struct urb *wlan_rx_data_urb[MAX_RX_URB_NUM];
93 struct urb *reg_in_urb;
94
95 struct sk_buff *remain_skb;
96 int rx_remain_len;
97 int rx_pkt_len;
98 int rx_transfer_len;
99 int rx_pad_len;
100};
101
102int ath9k_hif_usb_init(void);
103void ath9k_hif_usb_exit(void);
104
105#endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
new file mode 100644
index 000000000000..777064945fca
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -0,0 +1,441 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_H
18#define HTC_H
19
20#include <linux/module.h>
21#include <linux/usb.h>
22#include <linux/firmware.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/leds.h>
26#include <net/mac80211.h>
27
28#include "common.h"
29#include "htc_hst.h"
30#include "hif_usb.h"
31#include "wmi.h"
32
33#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
34#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
35#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
36#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
37
38#define ATH_DEFAULT_BMISS_LIMIT 10
39#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
40#define TSF_TO_TU(_h, _l) \
41 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
42
43extern struct ieee80211_ops ath9k_htc_ops;
44extern int htc_modparam_nohwcrypt;
45
46enum htc_phymode {
47 HTC_MODE_AUTO = 0,
48 HTC_MODE_11A = 1,
49 HTC_MODE_11B = 2,
50 HTC_MODE_11G = 3,
51 HTC_MODE_FH = 4,
52 HTC_MODE_TURBO_A = 5,
53 HTC_MODE_TURBO_G = 6,
54 HTC_MODE_11NA = 7,
55 HTC_MODE_11NG = 8
56};
57
58enum htc_opmode {
59 HTC_M_STA = 1,
60 HTC_M_IBSS = 0,
61 HTC_M_AHDEMO = 3,
62 HTC_M_HOSTAP = 6,
63 HTC_M_MONITOR = 8,
64 HTC_M_WDS = 2
65};
66
67#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
68#define ATH9K_HTC_AMPDU 1
69#define ATH9K_HTC_NORMAL 2
70
71#define ATH9K_HTC_TX_CTSONLY 0x1
72#define ATH9K_HTC_TX_RTSCTS 0x2
73#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
74
75struct tx_frame_hdr {
76 u8 data_type;
77 u8 node_idx;
78 u8 vif_idx;
79 u8 tidno;
80 u32 flags; /* ATH9K_HTC_TX_* */
81 u8 key_type;
82 u8 keyix;
83 u8 reserved[26];
84} __packed;
85
86struct tx_mgmt_hdr {
87 u8 node_idx;
88 u8 vif_idx;
89 u8 tidno;
90 u8 flags;
91 u8 key_type;
92 u8 keyix;
93 u16 reserved;
94} __packed;
95
96struct tx_beacon_header {
97 u8 len_changed;
98 u8 vif_index;
99 u16 rev;
100} __packed;
101
102struct ath9k_htc_target_hw {
103 u32 flags;
104 u32 flags_ext;
105 u32 ampdu_limit;
106 u8 ampdu_subframes;
107 u8 tx_chainmask;
108 u8 tx_chainmask_legacy;
109 u8 rtscts_ratecode;
110 u8 protmode;
111} __packed;
112
113struct ath9k_htc_cap_target {
114 u32 flags;
115 u32 flags_ext;
116 u32 ampdu_limit;
117 u8 ampdu_subframes;
118 u8 tx_chainmask;
119 u8 tx_chainmask_legacy;
120 u8 rtscts_ratecode;
121 u8 protmode;
122} __packed;
123
124struct ath9k_htc_target_vif {
125 u8 index;
126 u8 des_bssid[ETH_ALEN];
127 enum htc_opmode opmode;
128 u8 myaddr[ETH_ALEN];
129 u8 bssid[ETH_ALEN];
130 u32 flags;
131 u32 flags_ext;
132 u16 ps_sta;
133 u16 rtsthreshold;
134 u8 ath_cap;
135 u8 node;
136 s8 mcast_rate;
137} __packed;
138
139#define ATH_HTC_STA_AUTH 0x0001
140#define ATH_HTC_STA_QOS 0x0002
141#define ATH_HTC_STA_ERP 0x0004
142#define ATH_HTC_STA_HT 0x0008
143
144/* FIXME: UAPSD variables */
145struct ath9k_htc_target_sta {
146 u16 associd;
147 u16 txpower;
148 u32 ucastkey;
149 u8 macaddr[ETH_ALEN];
150 u8 bssid[ETH_ALEN];
151 u8 sta_index;
152 u8 vif_index;
153 u8 vif_sta;
154 u16 flags; /* ATH_HTC_STA_* */
155 u16 htcap;
156 u8 valid;
157 u16 capinfo;
158 struct ath9k_htc_target_hw *hw;
159 struct ath9k_htc_target_vif *vif;
160 u16 txseqmgmt;
161 u8 is_vif_sta;
162 u16 maxampdu;
163 u16 iv16;
164 u32 iv32;
165} __packed;
166
167struct ath9k_htc_target_aggr {
168 u8 sta_index;
169 u8 tidno;
170 u8 aggr_enable;
171 u8 padding;
172} __packed;
173
174#define ATH_HTC_RATE_MAX 30
175
176#define WLAN_RC_DS_FLAG 0x01
177#define WLAN_RC_40_FLAG 0x02
178#define WLAN_RC_SGI_FLAG 0x04
179#define WLAN_RC_HT_FLAG 0x08
180
181struct ath9k_htc_rateset {
182 u8 rs_nrates;
183 u8 rs_rates[ATH_HTC_RATE_MAX];
184};
185
186struct ath9k_htc_rate {
187 struct ath9k_htc_rateset legacy_rates;
188 struct ath9k_htc_rateset ht_rates;
189} __packed;
190
191struct ath9k_htc_target_rate {
192 u8 sta_index;
193 u8 isnew;
194 u32 capflags;
195 struct ath9k_htc_rate rates;
196};
197
198struct ath9k_htc_target_stats {
199 u32 tx_shortretry;
200 u32 tx_longretry;
201 u32 tx_xretries;
202 u32 ht_txunaggr_xretry;
203 u32 ht_tx_xretries;
204} __packed;
205
206struct ath9k_htc_vif {
207 u8 index;
208};
209
210#define ATH9K_HTC_MAX_STA 8
211#define ATH9K_HTC_MAX_TID 8
212
213enum tid_aggr_state {
214 AGGR_STOP = 0,
215 AGGR_PROGRESS,
216 AGGR_START,
217 AGGR_OPERATIONAL
218};
219
220struct ath9k_htc_sta {
221 u8 index;
222 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
223};
224
225struct ath9k_htc_aggr_work {
226 u16 tid;
227 u8 sta_addr[ETH_ALEN];
228 struct ieee80211_hw *hw;
229 struct ieee80211_vif *vif;
230 enum ieee80211_ampdu_mlme_action action;
231 struct mutex mutex;
232};
233
234#define ATH9K_HTC_RXBUF 256
235#define HTC_RX_FRAME_HEADER_SIZE 40
236
237struct ath9k_htc_rxbuf {
238 bool in_process;
239 struct sk_buff *skb;
240 struct ath_htc_rx_status rxstatus;
241 struct list_head list;
242};
243
244struct ath9k_htc_rx {
245 int last_rssi; /* FIXME: per-STA */
246 struct list_head rxbuf;
247 spinlock_t rxbuflock;
248};
249
250struct ath9k_htc_tx_ctl {
251 u8 type; /* ATH9K_HTC_* */
252};
253
254#ifdef CONFIG_ATH9K_HTC_DEBUGFS
255
256#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
257#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
258
259struct ath_tx_stats {
260 u32 buf_queued;
261 u32 buf_completed;
262 u32 skb_queued;
263 u32 skb_completed;
264};
265
266struct ath_rx_stats {
267 u32 skb_allocated;
268 u32 skb_completed;
269 u32 skb_dropped;
270};
271
272struct ath9k_debug {
273 struct dentry *debugfs_phy;
274 struct dentry *debugfs_tgt_stats;
275 struct dentry *debugfs_xmit;
276 struct dentry *debugfs_recv;
277 struct ath_tx_stats tx_stats;
278 struct ath_rx_stats rx_stats;
279 u32 txrate;
280};
281
282#else
283
284#define TX_STAT_INC(c) do { } while (0)
285#define RX_STAT_INC(c) do { } while (0)
286
287#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
288
289#define ATH_LED_PIN_DEF 1
290#define ATH_LED_PIN_9287 8
291#define ATH_LED_PIN_9271 15
292#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
293#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
294
295enum ath_led_type {
296 ATH_LED_RADIO,
297 ATH_LED_ASSOC,
298 ATH_LED_TX,
299 ATH_LED_RX
300};
301
302struct ath_led {
303 struct ath9k_htc_priv *priv;
304 struct led_classdev led_cdev;
305 enum ath_led_type led_type;
306 struct delayed_work brightness_work;
307 char name[32];
308 bool registered;
309 int brightness;
310};
311
312#define OP_INVALID BIT(0)
313#define OP_SCANNING BIT(1)
314#define OP_FULL_RESET BIT(2)
315#define OP_LED_ASSOCIATED BIT(3)
316#define OP_LED_ON BIT(4)
317#define OP_PREAMBLE_SHORT BIT(5)
318#define OP_PROTECT_ENABLE BIT(6)
319#define OP_TXAGGR BIT(7)
320#define OP_ASSOCIATED BIT(8)
321#define OP_ENABLE_BEACON BIT(9)
322#define OP_LED_DEINIT BIT(10)
323
324struct ath9k_htc_priv {
325 struct device *dev;
326 struct ieee80211_hw *hw;
327 struct ath_hw *ah;
328 struct htc_target *htc;
329 struct wmi *wmi;
330
331 enum htc_endpoint_id wmi_cmd_ep;
332 enum htc_endpoint_id beacon_ep;
333 enum htc_endpoint_id cab_ep;
334 enum htc_endpoint_id uapsd_ep;
335 enum htc_endpoint_id mgmt_ep;
336 enum htc_endpoint_id data_be_ep;
337 enum htc_endpoint_id data_bk_ep;
338 enum htc_endpoint_id data_vi_ep;
339 enum htc_endpoint_id data_vo_ep;
340
341 u16 op_flags;
342 u16 curtxpow;
343 u16 txpowlimit;
344 u16 nvifs;
345 u16 nstations;
346 u16 seq_no;
347 u32 bmiss_cnt;
348
349 struct sk_buff *beacon;
350 spinlock_t beacon_lock;
351
352 struct ieee80211_vif *vif;
353 unsigned int rxfilter;
354 struct tasklet_struct wmi_tasklet;
355 struct tasklet_struct rx_tasklet;
356 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
357 struct ath9k_htc_rx rx;
358 struct tasklet_struct tx_tasklet;
359 struct sk_buff_head tx_queue;
360 struct ath9k_htc_aggr_work aggr_work;
361 struct delayed_work ath9k_aggr_work;
362 struct delayed_work ath9k_ani_work;
363
364 struct ath_led radio_led;
365 struct ath_led assoc_led;
366 struct ath_led tx_led;
367 struct ath_led rx_led;
368 struct delayed_work ath9k_led_blink_work;
369 int led_on_duration;
370 int led_off_duration;
371 int led_on_cnt;
372 int led_off_cnt;
373 int hwq_map[ATH9K_WME_AC_VO+1];
374
375#ifdef CONFIG_ATH9K_HTC_DEBUGFS
376 struct ath9k_debug debug;
377#endif
378 struct ath9k_htc_target_rate tgt_rate;
379
380 struct mutex mutex;
381};
382
383static inline void ath_read_cachesize(struct ath_common *common, int *csz)
384{
385 common->bus_ops->read_cachesize(common, csz);
386}
387
388void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
389 struct ieee80211_vif *vif,
390 struct ieee80211_bss_conf *bss_conf);
391void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
392void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
393 struct ieee80211_vif *vif);
394
395void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
396 enum htc_endpoint_id ep_id);
397void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
398 bool txok);
399
400void ath9k_htc_station_work(struct work_struct *work);
401void ath9k_htc_aggr_work(struct work_struct *work);
402void ath9k_ani_work(struct work_struct *work);;
403
404int ath9k_tx_init(struct ath9k_htc_priv *priv);
405void ath9k_tx_tasklet(unsigned long data);
406int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
407void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
408bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
409 enum ath9k_tx_queue_subtype qtype);
410int get_hw_qnum(u16 queue, int *hwq_map);
411int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
412 struct ath9k_tx_queue_info *qinfo);
413
414int ath9k_rx_init(struct ath9k_htc_priv *priv);
415void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
416void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
417void ath9k_rx_tasklet(unsigned long data);
418
419void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
420void ath9k_init_leds(struct ath9k_htc_priv *priv);
421void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
422
423int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
424 u16 devid);
425void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
426#ifdef CONFIG_PM
427int ath9k_htc_resume(struct htc_target *htc_handle);
428#endif
429#ifdef CONFIG_ATH9K_HTC_DEBUGFS
430int ath9k_htc_debug_create_root(void);
431void ath9k_htc_debug_remove_root(void);
432int ath9k_htc_init_debug(struct ath_hw *ah);
433void ath9k_htc_exit_debug(struct ath_hw *ah);
434#else
435static inline int ath9k_htc_debug_create_root(void) { return 0; };
436static inline void ath9k_htc_debug_remove_root(void) {};
437static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
438static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
439#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
440
441#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
new file mode 100644
index 000000000000..25f5b5377bac
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -0,0 +1,260 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19#define FUDGE 2
20
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct ieee80211_bss_conf *bss_conf)
23{
24 struct ath_common *common = ath9k_hw_common(priv->ah);
25 struct ath9k_beacon_state bs;
26 enum ath9k_int imask = 0;
27 int dtimperiod, dtimcount, sleepduration;
28 int cfpperiod, cfpcount, bmiss_timeout;
29 u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
30 u64 tsf;
31 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
32 int ret;
33 u8 cmd_rsp;
34
35 memset(&bs, 0, sizeof(bs));
36
37 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
38 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_int);
39
40 /*
41 * Setup dtim and cfp parameters according to
42 * last beacon we received (which may be none).
43 */
44 dtimperiod = bss_conf->dtim_period;
45 if (dtimperiod <= 0) /* NB: 0 if not known */
46 dtimperiod = 1;
47 dtimcount = 1;
48 if (dtimcount >= dtimperiod) /* NB: sanity check */
49 dtimcount = 0;
50 cfpperiod = 1; /* NB: no PCF support yet */
51 cfpcount = 0;
52
53 sleepduration = intval;
54 if (sleepduration <= 0)
55 sleepduration = intval;
56
57 /*
58 * Pull nexttbtt forward to reflect the current
59 * TSF and calculate dtim+cfp state for the result.
60 */
61 tsf = ath9k_hw_gettsf64(priv->ah);
62 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
63
64 num_beacons = tsftu / intval + 1;
65 offset = tsftu % intval;
66 nexttbtt = tsftu - offset;
67 if (offset)
68 nexttbtt += intval;
69
70 /* DTIM Beacon every dtimperiod Beacon */
71 dtim_dec_count = num_beacons % dtimperiod;
72 /* CFP every cfpperiod DTIM Beacon */
73 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
74 if (dtim_dec_count)
75 cfp_dec_count++;
76
77 dtimcount -= dtim_dec_count;
78 if (dtimcount < 0)
79 dtimcount += dtimperiod;
80
81 cfpcount -= cfp_dec_count;
82 if (cfpcount < 0)
83 cfpcount += cfpperiod;
84
85 bs.bs_intval = intval;
86 bs.bs_nexttbtt = nexttbtt;
87 bs.bs_dtimperiod = dtimperiod*intval;
88 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
89 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
90 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
91 bs.bs_cfpmaxduration = 0;
92
93 /*
94 * Calculate the number of consecutive beacons to miss* before taking
95 * a BMISS interrupt. The configuration is specified in TU so we only
96 * need calculate based on the beacon interval. Note that we clamp the
97 * result to at most 15 beacons.
98 */
99 if (sleepduration > intval) {
100 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
101 } else {
102 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
103 if (bs.bs_bmissthreshold > 15)
104 bs.bs_bmissthreshold = 15;
105 else if (bs.bs_bmissthreshold <= 0)
106 bs.bs_bmissthreshold = 1;
107 }
108
109 /*
110 * Calculate sleep duration. The configuration is given in ms.
111 * We ensure a multiple of the beacon period is used. Also, if the sleep
112 * duration is greater than the DTIM period then it makes senses
113 * to make it a multiple of that.
114 *
115 * XXX fixed at 100ms
116 */
117
118 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
119 if (bs.bs_sleepduration > bs.bs_dtimperiod)
120 bs.bs_sleepduration = bs.bs_dtimperiod;
121
122 /* TSF out of range threshold fixed at 1 second */
123 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
124
125 ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
126 ath_print(common, ATH_DBG_BEACON,
127 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
128 bs.bs_bmissthreshold, bs.bs_sleepduration,
129 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
130
131 /* Set the computed STA beacon timers */
132
133 WMI_CMD(WMI_DISABLE_INTR_CMDID);
134 ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
135 imask |= ATH9K_INT_BMISS;
136 htc_imask = cpu_to_be32(imask);
137 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
138}
139
140static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
141 struct ieee80211_bss_conf *bss_conf)
142{
143 struct ath_common *common = ath9k_hw_common(priv->ah);
144 enum ath9k_int imask = 0;
145 u32 nexttbtt, intval, htc_imask = 0;
146 int ret;
147 u8 cmd_rsp;
148
149 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
150 nexttbtt = intval;
151 intval |= ATH9K_BEACON_ENA;
152 if (priv->op_flags & OP_ENABLE_BEACON)
153 imask |= ATH9K_INT_SWBA;
154
155 ath_print(common, ATH_DBG_BEACON,
156 "IBSS Beacon config, intval: %d, imask: 0x%x\n",
157 bss_conf->beacon_int, imask);
158
159 WMI_CMD(WMI_DISABLE_INTR_CMDID);
160 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
161 priv->bmiss_cnt = 0;
162 htc_imask = cpu_to_be32(imask);
163 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
164}
165
166void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
167 struct ieee80211_vif *vif)
168{
169 struct ath_common *common = ath9k_hw_common(priv->ah);
170
171 spin_lock_bh(&priv->beacon_lock);
172
173 if (priv->beacon)
174 dev_kfree_skb_any(priv->beacon);
175
176 priv->beacon = ieee80211_beacon_get(priv->hw, vif);
177 if (!priv->beacon)
178 ath_print(common, ATH_DBG_BEACON,
179 "Unable to allocate beacon\n");
180
181 spin_unlock_bh(&priv->beacon_lock);
182}
183
184void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
185{
186 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
187 struct tx_beacon_header beacon_hdr;
188 struct ath9k_htc_tx_ctl tx_ctl;
189 struct ieee80211_tx_info *info;
190 u8 *tx_fhdr;
191
192 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
193 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
194
195 /* FIXME: Handle BMISS */
196 if (beacon_pending != 0) {
197 priv->bmiss_cnt++;
198 return;
199 }
200
201 spin_lock_bh(&priv->beacon_lock);
202
203 if (unlikely(priv->op_flags & OP_SCANNING)) {
204 spin_unlock_bh(&priv->beacon_lock);
205 return;
206 }
207
208 if (unlikely(priv->beacon == NULL)) {
209 spin_unlock_bh(&priv->beacon_lock);
210 return;
211 }
212
213 /* Free the old SKB first */
214 dev_kfree_skb_any(priv->beacon);
215
216 /* Get a new beacon */
217 priv->beacon = ieee80211_beacon_get(priv->hw, priv->vif);
218 if (!priv->beacon) {
219 spin_unlock_bh(&priv->beacon_lock);
220 return;
221 }
222
223 info = IEEE80211_SKB_CB(priv->beacon);
224 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
225 struct ieee80211_hdr *hdr =
226 (struct ieee80211_hdr *) priv->beacon->data;
227 priv->seq_no += 0x10;
228 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
229 hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
230 }
231
232 tx_ctl.type = ATH9K_HTC_NORMAL;
233 beacon_hdr.vif_index = avp->index;
234 tx_fhdr = skb_push(priv->beacon, sizeof(beacon_hdr));
235 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
236
237 htc_send(priv->htc, priv->beacon, priv->beacon_ep, &tx_ctl);
238
239 spin_unlock_bh(&priv->beacon_lock);
240}
241
242void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
243 struct ieee80211_vif *vif,
244 struct ieee80211_bss_conf *bss_conf)
245{
246 struct ath_common *common = ath9k_hw_common(priv->ah);
247
248 switch (vif->type) {
249 case NL80211_IFTYPE_STATION:
250 ath9k_htc_beacon_config_sta(priv, bss_conf);
251 break;
252 case NL80211_IFTYPE_ADHOC:
253 ath9k_htc_beacon_config_adhoc(priv, bss_conf);
254 break;
255 default:
256 ath_print(common, ATH_DBG_CONFIG,
257 "Unsupported beaconing mode\n");
258 return;
259 }
260}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
new file mode 100644
index 000000000000..10c87605d2c4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -0,0 +1,713 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19MODULE_AUTHOR("Atheros Communications");
20MODULE_LICENSE("Dual BSD/GPL");
21MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22
23static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24module_param_named(debug, ath9k_debug, uint, 0);
25MODULE_PARM_DESC(debug, "Debugging mask");
26
27int htc_modparam_nohwcrypt;
28module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
29MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30
31#define CHAN2G(_freq, _idx) { \
32 .center_freq = (_freq), \
33 .hw_value = (_idx), \
34 .max_power = 20, \
35}
36
37static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */
40 CHAN2G(2422, 2), /* Channel 3 */
41 CHAN2G(2427, 3), /* Channel 4 */
42 CHAN2G(2432, 4), /* Channel 5 */
43 CHAN2G(2437, 5), /* Channel 6 */
44 CHAN2G(2442, 6), /* Channel 7 */
45 CHAN2G(2447, 7), /* Channel 8 */
46 CHAN2G(2452, 8), /* Channel 9 */
47 CHAN2G(2457, 9), /* Channel 10 */
48 CHAN2G(2462, 10), /* Channel 11 */
49 CHAN2G(2467, 11), /* Channel 12 */
50 CHAN2G(2472, 12), /* Channel 13 */
51 CHAN2G(2484, 13), /* Channel 14 */
52};
53
54/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
57
58#define RATE(_bitrate, _hw_rate, _flags) { \
59 .bitrate = (_bitrate), \
60 .flags = (_flags), \
61 .hw_value = (_hw_rate), \
62 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
63}
64
65static struct ieee80211_rate ath9k_legacy_rates[] = {
66 RATE(10, 0x1b, 0),
67 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
68 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
69 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
70 RATE(60, 0x0b, 0),
71 RATE(90, 0x0f, 0),
72 RATE(120, 0x0a, 0),
73 RATE(180, 0x0e, 0),
74 RATE(240, 0x09, 0),
75 RATE(360, 0x0d, 0),
76 RATE(480, 0x08, 0),
77 RATE(540, 0x0c, 0),
78};
79
80static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
81{
82 int time_left;
83
84 /* Firmware can take up to 50ms to get ready, to be safe use 1 second */
85 time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
86 if (!time_left) {
87 dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
88 return -ETIMEDOUT;
89 }
90
91 return 0;
92}
93
94static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
95{
96 ath9k_htc_exit_debug(priv->ah);
97 ath9k_hw_deinit(priv->ah);
98 tasklet_kill(&priv->wmi_tasklet);
99 tasklet_kill(&priv->rx_tasklet);
100 tasklet_kill(&priv->tx_tasklet);
101 kfree(priv->ah);
102 priv->ah = NULL;
103}
104
105static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
106{
107 struct ieee80211_hw *hw = priv->hw;
108
109 wiphy_rfkill_stop_polling(hw->wiphy);
110 ath9k_deinit_leds(priv);
111 ieee80211_unregister_hw(hw);
112 ath9k_rx_cleanup(priv);
113 ath9k_tx_cleanup(priv);
114 ath9k_deinit_priv(priv);
115}
116
117static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
118 u16 service_id,
119 void (*tx) (void *,
120 struct sk_buff *,
121 enum htc_endpoint_id,
122 bool txok),
123 enum htc_endpoint_id *ep_id)
124{
125 struct htc_service_connreq req;
126
127 memset(&req, 0, sizeof(struct htc_service_connreq));
128
129 req.service_id = service_id;
130 req.ep_callbacks.priv = priv;
131 req.ep_callbacks.rx = ath9k_htc_rxep;
132 req.ep_callbacks.tx = tx;
133
134 return htc_connect_service(priv->htc, &req, ep_id);
135}
136
137static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
138{
139 int ret;
140
141 /* WMI CMD*/
142 ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
143 if (ret)
144 goto err;
145
146 /* Beacon */
147 ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, NULL,
148 &priv->beacon_ep);
149 if (ret)
150 goto err;
151
152 /* CAB */
153 ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
154 &priv->cab_ep);
155 if (ret)
156 goto err;
157
158
159 /* UAPSD */
160 ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
161 &priv->uapsd_ep);
162 if (ret)
163 goto err;
164
165 /* MGMT */
166 ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
167 &priv->mgmt_ep);
168 if (ret)
169 goto err;
170
171 /* DATA BE */
172 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
173 &priv->data_be_ep);
174 if (ret)
175 goto err;
176
177 /* DATA BK */
178 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
179 &priv->data_bk_ep);
180 if (ret)
181 goto err;
182
183 /* DATA VI */
184 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
185 &priv->data_vi_ep);
186 if (ret)
187 goto err;
188
189 /* DATA VO */
190 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
191 &priv->data_vo_ep);
192 if (ret)
193 goto err;
194
195 ret = htc_init(priv->htc);
196 if (ret)
197 goto err;
198
199 return 0;
200
201err:
202 dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
203 return ret;
204}
205
206static int ath9k_reg_notifier(struct wiphy *wiphy,
207 struct regulatory_request *request)
208{
209 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
210 struct ath9k_htc_priv *priv = hw->priv;
211
212 return ath_reg_notifier_apply(wiphy, request,
213 ath9k_hw_regulatory(priv->ah));
214}
215
216static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
217{
218 struct ath_hw *ah = (struct ath_hw *) hw_priv;
219 struct ath_common *common = ath9k_hw_common(ah);
220 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
221 __be32 val, reg = cpu_to_be32(reg_offset);
222 int r;
223
224 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
225 (u8 *) &reg, sizeof(reg),
226 (u8 *) &val, sizeof(val),
227 100);
228 if (unlikely(r)) {
229 ath_print(common, ATH_DBG_WMI,
230 "REGISTER READ FAILED: (0x%04x, %d)\n",
231 reg_offset, r);
232 return -EIO;
233 }
234
235 return be32_to_cpu(val);
236}
237
238static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
239{
240 struct ath_hw *ah = (struct ath_hw *) hw_priv;
241 struct ath_common *common = ath9k_hw_common(ah);
242 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
243 __be32 buf[2] = {
244 cpu_to_be32(reg_offset),
245 cpu_to_be32(val),
246 };
247 int r;
248
249 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
250 (u8 *) &buf, sizeof(buf),
251 (u8 *) &val, sizeof(val),
252 100);
253 if (unlikely(r)) {
254 ath_print(common, ATH_DBG_WMI,
255 "REGISTER WRITE FAILED:(0x%04x, %d)\n",
256 reg_offset, r);
257 }
258}
259
260static const struct ath_ops ath9k_common_ops = {
261 .read = ath9k_ioread32,
262 .write = ath9k_iowrite32,
263};
264
265static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
266{
267 *csz = L1_CACHE_BYTES >> 2;
268}
269
270static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
271{
272 struct ath_hw *ah = (struct ath_hw *) common->ah;
273
274 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
275
276 if (!ath9k_hw_wait(ah,
277 AR_EEPROM_STATUS_DATA,
278 AR_EEPROM_STATUS_DATA_BUSY |
279 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
280 AH_WAIT_TIMEOUT))
281 return false;
282
283 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
284 AR_EEPROM_STATUS_DATA_VAL);
285
286 return true;
287}
288
289static const struct ath_bus_ops ath9k_usb_bus_ops = {
290 .read_cachesize = ath_usb_read_cachesize,
291 .eeprom_read = ath_usb_eeprom_read,
292};
293
294static void setup_ht_cap(struct ath9k_htc_priv *priv,
295 struct ieee80211_sta_ht_cap *ht_info)
296{
297 ht_info->ht_supported = true;
298 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
299 IEEE80211_HT_CAP_SM_PS |
300 IEEE80211_HT_CAP_SGI_40 |
301 IEEE80211_HT_CAP_DSSSCCK40;
302
303 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
304 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
305
306 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
307 ht_info->mcs.rx_mask[0] = 0xff;
308 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
309}
310
311static int ath9k_init_queues(struct ath9k_htc_priv *priv)
312{
313 struct ath_common *common = ath9k_hw_common(priv->ah);
314 int i;
315
316 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
317 priv->hwq_map[i] = -1;
318
319 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
320 ath_print(common, ATH_DBG_FATAL,
321 "Unable to setup xmit queue for BE traffic\n");
322 goto err;
323 }
324
325 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
326 ath_print(common, ATH_DBG_FATAL,
327 "Unable to setup xmit queue for BK traffic\n");
328 goto err;
329 }
330 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
331 ath_print(common, ATH_DBG_FATAL,
332 "Unable to setup xmit queue for VI traffic\n");
333 goto err;
334 }
335 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
336 ath_print(common, ATH_DBG_FATAL,
337 "Unable to setup xmit queue for VO traffic\n");
338 goto err;
339 }
340
341 return 0;
342
343err:
344 return -EINVAL;
345}
346
347static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
348{
349 struct ath_common *common = ath9k_hw_common(priv->ah);
350 int i = 0;
351
352 /* Get the hardware key cache size. */
353 common->keymax = priv->ah->caps.keycache_size;
354 if (common->keymax > ATH_KEYMAX) {
355 ath_print(common, ATH_DBG_ANY,
356 "Warning, using only %u entries in %u key cache\n",
357 ATH_KEYMAX, common->keymax);
358 common->keymax = ATH_KEYMAX;
359 }
360
361 /*
362 * Reset the key cache since some parts do not
363 * reset the contents on initial power up.
364 */
365 for (i = 0; i < common->keymax; i++)
366 ath9k_hw_keyreset(priv->ah, (u16) i);
367
368 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
369 ATH9K_CIPHER_TKIP, NULL)) {
370 /*
371 * Whether we should enable h/w TKIP MIC.
372 * XXX: if we don't support WME TKIP MIC, then we wouldn't
373 * report WMM capable, so it's always safe to turn on
374 * TKIP MIC in this case.
375 */
376 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
377 }
378
379 /*
380 * Check whether the separate key cache entries
381 * are required to handle both tx+rx MIC keys.
382 * With split mic keys the number of stations is limited
383 * to 27 otherwise 59.
384 */
385 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
386 ATH9K_CIPHER_TKIP, NULL)
387 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
388 ATH9K_CIPHER_MIC, NULL)
389 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
390 0, NULL))
391 common->splitmic = 1;
392
393 /* turn on mcast key search if possible */
394 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
395 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
396 1, 1, NULL);
397}
398
399static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
400{
401 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
402 priv->sbands[IEEE80211_BAND_2GHZ].channels =
403 ath9k_2ghz_channels;
404 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
405 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
406 ARRAY_SIZE(ath9k_2ghz_channels);
407 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
408 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
409 ARRAY_SIZE(ath9k_legacy_rates);
410 }
411}
412
413static void ath9k_init_misc(struct ath9k_htc_priv *priv)
414{
415 struct ath_common *common = ath9k_hw_common(priv->ah);
416
417 common->tx_chainmask = priv->ah->caps.tx_chainmask;
418 common->rx_chainmask = priv->ah->caps.rx_chainmask;
419
420 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
421 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
422
423 priv->op_flags |= OP_TXAGGR;
424}
425
426static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
427{
428 struct ath_hw *ah = NULL;
429 struct ath_common *common;
430 int ret = 0, csz = 0;
431
432 priv->op_flags |= OP_INVALID;
433
434 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
435 if (!ah)
436 return -ENOMEM;
437
438 ah->hw_version.devid = devid;
439 ah->hw_version.subsysid = 0; /* FIXME */
440 priv->ah = ah;
441
442 common = ath9k_hw_common(ah);
443 common->ops = &ath9k_common_ops;
444 common->bus_ops = &ath9k_usb_bus_ops;
445 common->ah = ah;
446 common->hw = priv->hw;
447 common->priv = priv;
448 common->debug_mask = ath9k_debug;
449
450 spin_lock_init(&priv->wmi->wmi_lock);
451 spin_lock_init(&priv->beacon_lock);
452 mutex_init(&priv->mutex);
453 mutex_init(&priv->aggr_work.mutex);
454 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
455 (unsigned long)priv);
456 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
457 (unsigned long)priv);
458 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
459 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
460 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
461
462 /*
463 * Cache line size is used to size and align various
464 * structures used to communicate with the hardware.
465 */
466 ath_read_cachesize(common, &csz);
467 common->cachelsz = csz << 2; /* convert to bytes */
468
469 ret = ath9k_hw_init(ah);
470 if (ret) {
471 ath_print(common, ATH_DBG_FATAL,
472 "Unable to initialize hardware; "
473 "initialization status: %d\n", ret);
474 goto err_hw;
475 }
476
477 ret = ath9k_htc_init_debug(ah);
478 if (ret) {
479 ath_print(common, ATH_DBG_FATAL,
480 "Unable to create debugfs files\n");
481 goto err_debug;
482 }
483
484 ret = ath9k_init_queues(priv);
485 if (ret)
486 goto err_queues;
487
488 ath9k_init_crypto(priv);
489 ath9k_init_channels_rates(priv);
490 ath9k_init_misc(priv);
491
492 return 0;
493
494err_queues:
495 ath9k_htc_exit_debug(ah);
496err_debug:
497 ath9k_hw_deinit(ah);
498err_hw:
499
500 kfree(ah);
501 priv->ah = NULL;
502
503 return ret;
504}
505
506static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
507 struct ieee80211_hw *hw)
508{
509 struct ath_common *common = ath9k_hw_common(priv->ah);
510
511 hw->flags = IEEE80211_HW_SIGNAL_DBM |
512 IEEE80211_HW_AMPDU_AGGREGATION |
513 IEEE80211_HW_SPECTRUM_MGMT |
514 IEEE80211_HW_HAS_RATE_CONTROL;
515
516 hw->wiphy->interface_modes =
517 BIT(NL80211_IFTYPE_STATION) |
518 BIT(NL80211_IFTYPE_ADHOC);
519
520 hw->queues = 4;
521 hw->channel_change_time = 5000;
522 hw->max_listen_interval = 10;
523 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
524 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
525
526 /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
527 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
528 sizeof(struct htc_frame_hdr) + 4;
529
530 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
531 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
532 &priv->sbands[IEEE80211_BAND_2GHZ];
533
534 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
535 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
536 setup_ht_cap(priv,
537 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
538 }
539
540 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
541}
542
543static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
544{
545 struct ieee80211_hw *hw = priv->hw;
546 struct ath_common *common;
547 struct ath_hw *ah;
548 int error = 0;
549 struct ath_regulatory *reg;
550
551 /* Bring up device */
552 error = ath9k_init_priv(priv, devid);
553 if (error != 0)
554 goto err_init;
555
556 ah = priv->ah;
557 common = ath9k_hw_common(ah);
558 ath9k_set_hw_capab(priv, hw);
559
560 /* Initialize regulatory */
561 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
562 ath9k_reg_notifier);
563 if (error)
564 goto err_regd;
565
566 reg = &common->regulatory;
567
568 /* Setup TX */
569 error = ath9k_tx_init(priv);
570 if (error != 0)
571 goto err_tx;
572
573 /* Setup RX */
574 error = ath9k_rx_init(priv);
575 if (error != 0)
576 goto err_rx;
577
578 /* Register with mac80211 */
579 error = ieee80211_register_hw(hw);
580 if (error)
581 goto err_register;
582
583 /* Handle world regulatory */
584 if (!ath_is_world_regd(reg)) {
585 error = regulatory_hint(hw->wiphy, reg->alpha2);
586 if (error)
587 goto err_world;
588 }
589
590 ath9k_init_leds(priv);
591 ath9k_start_rfkill_poll(priv);
592
593 return 0;
594
595err_world:
596 ieee80211_unregister_hw(hw);
597err_register:
598 ath9k_rx_cleanup(priv);
599err_rx:
600 ath9k_tx_cleanup(priv);
601err_tx:
602 /* Nothing */
603err_regd:
604 ath9k_deinit_priv(priv);
605err_init:
606 return error;
607}
608
609int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
610 u16 devid)
611{
612 struct ieee80211_hw *hw;
613 struct ath9k_htc_priv *priv;
614 int ret;
615
616 hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
617 if (!hw)
618 return -ENOMEM;
619
620 priv = hw->priv;
621 priv->hw = hw;
622 priv->htc = htc_handle;
623 priv->dev = dev;
624 htc_handle->drv_priv = priv;
625 SET_IEEE80211_DEV(hw, priv->dev);
626
627 ret = ath9k_htc_wait_for_target(priv);
628 if (ret)
629 goto err_free;
630
631 priv->wmi = ath9k_init_wmi(priv);
632 if (!priv->wmi) {
633 ret = -EINVAL;
634 goto err_free;
635 }
636
637 ret = ath9k_init_htc_services(priv);
638 if (ret)
639 goto err_init;
640
641 ret = ath9k_init_device(priv, devid);
642 if (ret)
643 goto err_init;
644
645 return 0;
646
647err_init:
648 ath9k_deinit_wmi(priv);
649err_free:
650 ieee80211_free_hw(hw);
651 return ret;
652}
653
654void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
655{
656 if (htc_handle->drv_priv) {
657 ath9k_deinit_device(htc_handle->drv_priv);
658 ath9k_deinit_wmi(htc_handle->drv_priv);
659 ieee80211_free_hw(htc_handle->drv_priv->hw);
660 }
661}
662
663#ifdef CONFIG_PM
664int ath9k_htc_resume(struct htc_target *htc_handle)
665{
666 int ret;
667
668 ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
669 if (ret)
670 return ret;
671
672 ret = ath9k_init_htc_services(htc_handle->drv_priv);
673 return ret;
674}
675#endif
676
677static int __init ath9k_htc_init(void)
678{
679 int error;
680
681 error = ath9k_htc_debug_create_root();
682 if (error < 0) {
683 printk(KERN_ERR
684 "ath9k_htc: Unable to create debugfs root: %d\n",
685 error);
686 goto err_dbg;
687 }
688
689 error = ath9k_hif_usb_init();
690 if (error < 0) {
691 printk(KERN_ERR
692 "ath9k_htc: No USB devices found,"
693 " driver not installed.\n");
694 error = -ENODEV;
695 goto err_usb;
696 }
697
698 return 0;
699
700err_usb:
701 ath9k_htc_debug_remove_root();
702err_dbg:
703 return error;
704}
705module_init(ath9k_htc_init);
706
707static void __exit ath9k_htc_exit(void)
708{
709 ath9k_hif_usb_exit();
710 ath9k_htc_debug_remove_root();
711 printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
712}
713module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
new file mode 100644
index 000000000000..20a2c1341e20
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -0,0 +1,1626 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31
32 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
36 priv->curtxpow = txpow;
37 }
38}
39
40/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
41static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
42 struct ath9k_channel *ichan)
43{
44 enum htc_phymode mode;
45
46 mode = HTC_MODE_AUTO;
47
48 switch (ichan->chanmode) {
49 case CHANNEL_G:
50 case CHANNEL_G_HT20:
51 case CHANNEL_G_HT40PLUS:
52 case CHANNEL_G_HT40MINUS:
53 mode = HTC_MODE_11NG;
54 break;
55 case CHANNEL_A:
56 case CHANNEL_A_HT20:
57 case CHANNEL_A_HT40PLUS:
58 case CHANNEL_A_HT40MINUS:
59 mode = HTC_MODE_11NA;
60 break;
61 default:
62 break;
63 }
64
65 return mode;
66}
67
68static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
69 struct ieee80211_hw *hw,
70 struct ath9k_channel *hchan)
71{
72 struct ath_hw *ah = priv->ah;
73 struct ath_common *common = ath9k_hw_common(ah);
74 struct ieee80211_conf *conf = &common->hw->conf;
75 bool fastcc = true;
76 struct ieee80211_channel *channel = hw->conf.channel;
77 enum htc_phymode mode;
78 u16 htc_mode;
79 u8 cmd_rsp;
80 int ret;
81
82 if (priv->op_flags & OP_INVALID)
83 return -EIO;
84
85 if (priv->op_flags & OP_FULL_RESET)
86 fastcc = false;
87
88 /* Fiddle around with fastcc later on, for now just use full reset */
89 fastcc = false;
90
91 htc_stop(priv->htc);
92 WMI_CMD(WMI_DISABLE_INTR_CMDID);
93 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
94 WMI_CMD(WMI_STOP_RECV_CMDID);
95
96 ath_print(common, ATH_DBG_CONFIG,
97 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
98 priv->ah->curchan->channel,
99 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
100
101 ret = ath9k_hw_reset(ah, hchan, fastcc);
102 if (ret) {
103 ath_print(common, ATH_DBG_FATAL,
104 "Unable to reset channel (%u Mhz) "
105 "reset status %d\n", channel->center_freq, ret);
106 goto err;
107 }
108
109 ath_update_txpow(priv);
110
111 WMI_CMD(WMI_START_RECV_CMDID);
112 if (ret)
113 goto err;
114
115 ath9k_host_rx_init(priv);
116
117 mode = ath9k_htc_get_curmode(priv, hchan);
118 htc_mode = cpu_to_be16(mode);
119 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
120 if (ret)
121 goto err;
122
123 WMI_CMD(WMI_ENABLE_INTR_CMDID);
124 if (ret)
125 goto err;
126
127 htc_start(priv->htc);
128
129 priv->op_flags &= ~OP_FULL_RESET;
130err:
131 return ret;
132}
133
134static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
135{
136 struct ath_common *common = ath9k_hw_common(priv->ah);
137 struct ath9k_htc_target_vif hvif;
138 int ret = 0;
139 u8 cmd_rsp;
140
141 if (priv->nvifs > 0)
142 return -ENOBUFS;
143
144 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
145 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
146
147 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
148 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
149 hvif.index = priv->nvifs;
150
151 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
152 if (ret)
153 return ret;
154
155 priv->nvifs++;
156 return 0;
157}
158
159static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
160{
161 struct ath_common *common = ath9k_hw_common(priv->ah);
162 struct ath9k_htc_target_vif hvif;
163 int ret = 0;
164 u8 cmd_rsp;
165
166 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
167 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
168 hvif.index = 0; /* Should do for now */
169 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
170 priv->nvifs--;
171
172 return ret;
173}
174
175static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
176 struct ieee80211_vif *vif,
177 struct ieee80211_sta *sta)
178{
179 struct ath_common *common = ath9k_hw_common(priv->ah);
180 struct ath9k_htc_target_sta tsta;
181 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
182 struct ath9k_htc_sta *ista;
183 int ret;
184 u8 cmd_rsp;
185
186 if (priv->nstations >= ATH9K_HTC_MAX_STA)
187 return -ENOBUFS;
188
189 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
190
191 if (sta) {
192 ista = (struct ath9k_htc_sta *) sta->drv_priv;
193 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
194 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
195 tsta.associd = common->curaid;
196 tsta.is_vif_sta = 0;
197 tsta.valid = true;
198 ista->index = priv->nstations;
199 } else {
200 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
201 tsta.is_vif_sta = 1;
202 }
203
204 tsta.sta_index = priv->nstations;
205 tsta.vif_index = avp->index;
206 tsta.maxampdu = 0xffff;
207 if (sta && sta->ht_cap.ht_supported)
208 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
209
210 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
211 if (ret) {
212 if (sta)
213 ath_print(common, ATH_DBG_FATAL,
214 "Unable to add station entry for: %pM\n", sta->addr);
215 return ret;
216 }
217
218 if (sta)
219 ath_print(common, ATH_DBG_CONFIG,
220 "Added a station entry for: %pM (idx: %d)\n",
221 sta->addr, tsta.sta_index);
222
223 priv->nstations++;
224 return 0;
225}
226
227static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
228 struct ieee80211_vif *vif,
229 struct ieee80211_sta *sta)
230{
231 struct ath_common *common = ath9k_hw_common(priv->ah);
232 struct ath9k_htc_sta *ista;
233 int ret;
234 u8 cmd_rsp, sta_idx;
235
236 if (sta) {
237 ista = (struct ath9k_htc_sta *) sta->drv_priv;
238 sta_idx = ista->index;
239 } else {
240 sta_idx = 0;
241 }
242
243 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
244 if (ret) {
245 if (sta)
246 ath_print(common, ATH_DBG_FATAL,
247 "Unable to remove station entry for: %pM\n",
248 sta->addr);
249 return ret;
250 }
251
252 if (sta)
253 ath_print(common, ATH_DBG_CONFIG,
254 "Removed a station entry for: %pM (idx: %d)\n",
255 sta->addr, sta_idx);
256
257 priv->nstations--;
258 return 0;
259}
260
261static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
262{
263 struct ath9k_htc_cap_target tcap;
264 int ret;
265 u8 cmd_rsp;
266
267 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
268
269 /* FIXME: Values are hardcoded */
270 tcap.flags = 0x240c40;
271 tcap.flags_ext = 0x80601000;
272 tcap.ampdu_limit = 0xffff0000;
273 tcap.ampdu_subframes = 20;
274 tcap.tx_chainmask_legacy = 1;
275 tcap.protmode = 1;
276 tcap.tx_chainmask = 1;
277
278 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
279
280 return ret;
281}
282
283static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
284 struct ieee80211_vif *vif,
285 struct ieee80211_sta *sta)
286{
287 struct ath_common *common = ath9k_hw_common(priv->ah);
288 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
289 struct ieee80211_supported_band *sband;
290 struct ath9k_htc_target_rate trate;
291 u32 caps = 0;
292 u8 cmd_rsp;
293 int i, j, ret;
294
295 memset(&trate, 0, sizeof(trate));
296
297 /* Only 2GHz is supported */
298 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
299
300 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
301 if (sta->supp_rates[sband->band] & BIT(i)) {
302 priv->tgt_rate.rates.legacy_rates.rs_rates[j]
303 = (sband->bitrates[i].bitrate * 2) / 10;
304 j++;
305 }
306 }
307 priv->tgt_rate.rates.legacy_rates.rs_nrates = j;
308
309 if (sta->ht_cap.ht_supported) {
310 for (i = 0, j = 0; i < 77; i++) {
311 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
312 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i;
313 if (j == ATH_HTC_RATE_MAX)
314 break;
315 }
316 priv->tgt_rate.rates.ht_rates.rs_nrates = j;
317
318 caps = WLAN_RC_HT_FLAG;
319 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
320 caps |= WLAN_RC_40_FLAG;
321 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
322 caps |= WLAN_RC_SGI_FLAG;
323
324 }
325
326 priv->tgt_rate.sta_index = ista->index;
327 priv->tgt_rate.isnew = 1;
328 trate = priv->tgt_rate;
329 priv->tgt_rate.capflags = caps;
330 trate.capflags = cpu_to_be32(caps);
331
332 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
333 if (ret) {
334 ath_print(common, ATH_DBG_FATAL,
335 "Unable to initialize Rate information on target\n");
336 return ret;
337 }
338
339 ath_print(common, ATH_DBG_CONFIG,
340 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
341 return 0;
342}
343
344static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40)
345{
346 struct ath9k_htc_priv *priv = hw->priv;
347 struct ieee80211_conf *conf = &hw->conf;
348
349 if (!conf_is_ht(conf))
350 return false;
351
352 if (!(priv->op_flags & OP_ASSOCIATED) ||
353 (priv->op_flags & OP_SCANNING))
354 return false;
355
356 if (conf_is_ht40(conf)) {
357 if (priv->ah->curchan->chanmode &
358 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) {
359 return false;
360 } else {
361 *cw40 = true;
362 return true;
363 }
364 } else { /* ht20 */
365 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
366 return false;
367 else
368 return true;
369 }
370}
371
372static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
373{
374 struct ath9k_htc_target_rate trate;
375 struct ath_common *common = ath9k_hw_common(priv->ah);
376 int ret;
377 u8 cmd_rsp;
378
379 memset(&trate, 0, sizeof(trate));
380
381 trate = priv->tgt_rate;
382
383 if (is_cw40)
384 priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
385 else
386 priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
387
388 trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
389
390 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
391 if (ret) {
392 ath_print(common, ATH_DBG_FATAL,
393 "Unable to update Rate information on target\n");
394 return;
395 }
396
397 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with "
398 "caps:0x%x on target\n", priv->tgt_rate.capflags);
399}
400
401static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
402 struct ieee80211_vif *vif,
403 u8 *sta_addr, u8 tid, bool oper)
404{
405 struct ath_common *common = ath9k_hw_common(priv->ah);
406 struct ath9k_htc_target_aggr aggr;
407 struct ieee80211_sta *sta = NULL;
408 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
409 int ret = 0;
410 u8 cmd_rsp;
411
412 if (tid > ATH9K_HTC_MAX_TID)
413 return -EINVAL;
414
415 rcu_read_lock();
416 sta = ieee80211_find_sta(vif, sta_addr);
417 if (sta) {
418 ista = (struct ath9k_htc_sta *) sta->drv_priv;
419 } else {
420 rcu_read_unlock();
421 return -EINVAL;
422 }
423
424 if (!ista) {
425 rcu_read_unlock();
426 return -EINVAL;
427 }
428
429 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
430
431 aggr.sta_index = ista->index;
432 rcu_read_unlock();
433 aggr.tidno = tid;
434 aggr.aggr_enable = oper;
435
436 if (oper)
437 ista->tid_state[tid] = AGGR_START;
438 else
439 ista->tid_state[tid] = AGGR_STOP;
440
441 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
442 if (ret)
443 ath_print(common, ATH_DBG_CONFIG,
444 "Unable to %s TX aggregation for (%pM, %d)\n",
445 (oper) ? "start" : "stop", sta->addr, tid);
446 else
447 ath_print(common, ATH_DBG_CONFIG,
448 "%s aggregation for (%pM, %d)\n",
449 (oper) ? "Starting" : "Stopping", sta->addr, tid);
450
451 return ret;
452}
453
454void ath9k_htc_aggr_work(struct work_struct *work)
455{
456 int ret = 0;
457 struct ath9k_htc_priv *priv =
458 container_of(work, struct ath9k_htc_priv,
459 ath9k_aggr_work.work);
460 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
461
462 mutex_lock(&wk->mutex);
463
464 switch (wk->action) {
465 case IEEE80211_AMPDU_TX_START:
466 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
467 wk->tid, true);
468 if (!ret)
469 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
470 wk->tid);
471 break;
472 case IEEE80211_AMPDU_TX_STOP:
473 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
474 wk->tid, false);
475 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
476 break;
477 default:
478 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
479 "Unknown AMPDU action\n");
480 }
481
482 mutex_unlock(&wk->mutex);
483}
484
485/*********/
486/* DEBUG */
487/*********/
488
489#ifdef CONFIG_ATH9K_HTC_DEBUGFS
490
491static int ath9k_debugfs_open(struct inode *inode, struct file *file)
492{
493 file->private_data = inode->i_private;
494 return 0;
495}
496
497static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
498 size_t count, loff_t *ppos)
499{
500 struct ath9k_htc_priv *priv =
501 (struct ath9k_htc_priv *) file->private_data;
502 struct ath9k_htc_target_stats cmd_rsp;
503 char buf[512];
504 unsigned int len = 0;
505 int ret = 0;
506
507 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
508
509 WMI_CMD(WMI_TGT_STATS_CMDID);
510 if (ret)
511 return -EINVAL;
512
513
514 len += snprintf(buf + len, sizeof(buf) - len,
515 "%19s : %10u\n", "TX Short Retries",
516 be32_to_cpu(cmd_rsp.tx_shortretry));
517 len += snprintf(buf + len, sizeof(buf) - len,
518 "%19s : %10u\n", "TX Long Retries",
519 be32_to_cpu(cmd_rsp.tx_longretry));
520 len += snprintf(buf + len, sizeof(buf) - len,
521 "%19s : %10u\n", "TX Xretries",
522 be32_to_cpu(cmd_rsp.tx_xretries));
523 len += snprintf(buf + len, sizeof(buf) - len,
524 "%19s : %10u\n", "TX Unaggr. Xretries",
525 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
526 len += snprintf(buf + len, sizeof(buf) - len,
527 "%19s : %10u\n", "TX Xretries (HT)",
528 be32_to_cpu(cmd_rsp.ht_tx_xretries));
529 len += snprintf(buf + len, sizeof(buf) - len,
530 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
531
532 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
533}
534
535static const struct file_operations fops_tgt_stats = {
536 .read = read_file_tgt_stats,
537 .open = ath9k_debugfs_open,
538 .owner = THIS_MODULE
539};
540
541static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
542 size_t count, loff_t *ppos)
543{
544 struct ath9k_htc_priv *priv =
545 (struct ath9k_htc_priv *) file->private_data;
546 char buf[512];
547 unsigned int len = 0;
548
549 len += snprintf(buf + len, sizeof(buf) - len,
550 "%20s : %10u\n", "Buffers queued",
551 priv->debug.tx_stats.buf_queued);
552 len += snprintf(buf + len, sizeof(buf) - len,
553 "%20s : %10u\n", "Buffers completed",
554 priv->debug.tx_stats.buf_completed);
555 len += snprintf(buf + len, sizeof(buf) - len,
556 "%20s : %10u\n", "SKBs queued",
557 priv->debug.tx_stats.skb_queued);
558 len += snprintf(buf + len, sizeof(buf) - len,
559 "%20s : %10u\n", "SKBs completed",
560 priv->debug.tx_stats.skb_completed);
561
562 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
563}
564
565static const struct file_operations fops_xmit = {
566 .read = read_file_xmit,
567 .open = ath9k_debugfs_open,
568 .owner = THIS_MODULE
569};
570
571static ssize_t read_file_recv(struct file *file, char __user *user_buf,
572 size_t count, loff_t *ppos)
573{
574 struct ath9k_htc_priv *priv =
575 (struct ath9k_htc_priv *) file->private_data;
576 char buf[512];
577 unsigned int len = 0;
578
579 len += snprintf(buf + len, sizeof(buf) - len,
580 "%20s : %10u\n", "SKBs allocated",
581 priv->debug.rx_stats.skb_allocated);
582 len += snprintf(buf + len, sizeof(buf) - len,
583 "%20s : %10u\n", "SKBs completed",
584 priv->debug.rx_stats.skb_completed);
585 len += snprintf(buf + len, sizeof(buf) - len,
586 "%20s : %10u\n", "SKBs Dropped",
587 priv->debug.rx_stats.skb_dropped);
588
589 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
590}
591
592static const struct file_operations fops_recv = {
593 .read = read_file_recv,
594 .open = ath9k_debugfs_open,
595 .owner = THIS_MODULE
596};
597
598int ath9k_htc_init_debug(struct ath_hw *ah)
599{
600 struct ath_common *common = ath9k_hw_common(ah);
601 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
602
603 if (!ath9k_debugfs_root)
604 return -ENOENT;
605
606 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
607 ath9k_debugfs_root);
608 if (!priv->debug.debugfs_phy)
609 goto err;
610
611 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
612 priv->debug.debugfs_phy,
613 priv, &fops_tgt_stats);
614 if (!priv->debug.debugfs_tgt_stats)
615 goto err;
616
617
618 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
619 priv->debug.debugfs_phy,
620 priv, &fops_xmit);
621 if (!priv->debug.debugfs_xmit)
622 goto err;
623
624 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
625 priv->debug.debugfs_phy,
626 priv, &fops_recv);
627 if (!priv->debug.debugfs_recv)
628 goto err;
629
630 return 0;
631
632err:
633 ath9k_htc_exit_debug(ah);
634 return -ENOMEM;
635}
636
637void ath9k_htc_exit_debug(struct ath_hw *ah)
638{
639 struct ath_common *common = ath9k_hw_common(ah);
640 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
641
642 debugfs_remove(priv->debug.debugfs_recv);
643 debugfs_remove(priv->debug.debugfs_xmit);
644 debugfs_remove(priv->debug.debugfs_tgt_stats);
645 debugfs_remove(priv->debug.debugfs_phy);
646}
647
648int ath9k_htc_debug_create_root(void)
649{
650 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
651 if (!ath9k_debugfs_root)
652 return -ENOENT;
653
654 return 0;
655}
656
657void ath9k_htc_debug_remove_root(void)
658{
659 debugfs_remove(ath9k_debugfs_root);
660 ath9k_debugfs_root = NULL;
661}
662
663#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
664
665/*******/
666/* ANI */
667/*******/
668
669static void ath_start_ani(struct ath9k_htc_priv *priv)
670{
671 struct ath_common *common = ath9k_hw_common(priv->ah);
672 unsigned long timestamp = jiffies_to_msecs(jiffies);
673
674 common->ani.longcal_timer = timestamp;
675 common->ani.shortcal_timer = timestamp;
676 common->ani.checkani_timer = timestamp;
677
678 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
679 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
680}
681
682void ath9k_ani_work(struct work_struct *work)
683{
684 struct ath9k_htc_priv *priv =
685 container_of(work, struct ath9k_htc_priv,
686 ath9k_ani_work.work);
687 struct ath_hw *ah = priv->ah;
688 struct ath_common *common = ath9k_hw_common(ah);
689 bool longcal = false;
690 bool shortcal = false;
691 bool aniflag = false;
692 unsigned int timestamp = jiffies_to_msecs(jiffies);
693 u32 cal_interval, short_cal_interval;
694
695 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
696
697 /* Long calibration runs independently of short calibration. */
698 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
699 longcal = true;
700 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
701 common->ani.longcal_timer = timestamp;
702 }
703
704 /* Short calibration applies only while caldone is false */
705 if (!common->ani.caldone) {
706 if ((timestamp - common->ani.shortcal_timer) >=
707 short_cal_interval) {
708 shortcal = true;
709 ath_print(common, ATH_DBG_ANI,
710 "shortcal @%lu\n", jiffies);
711 common->ani.shortcal_timer = timestamp;
712 common->ani.resetcal_timer = timestamp;
713 }
714 } else {
715 if ((timestamp - common->ani.resetcal_timer) >=
716 ATH_RESTART_CALINTERVAL) {
717 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
718 if (common->ani.caldone)
719 common->ani.resetcal_timer = timestamp;
720 }
721 }
722
723 /* Verify whether we must check ANI */
724 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
725 aniflag = true;
726 common->ani.checkani_timer = timestamp;
727 }
728
729 /* Skip all processing if there's nothing to do. */
730 if (longcal || shortcal || aniflag) {
731 /* Call ANI routine if necessary */
732 if (aniflag)
733 ath9k_hw_ani_monitor(ah, ah->curchan);
734
735 /* Perform calibration if necessary */
736 if (longcal || shortcal) {
737 common->ani.caldone =
738 ath9k_hw_calibrate(ah, ah->curchan,
739 common->rx_chainmask,
740 longcal);
741
742 if (longcal)
743 common->ani.noise_floor =
744 ath9k_hw_getchan_noise(ah, ah->curchan);
745
746 ath_print(common, ATH_DBG_ANI,
747 " calibrate chan %u/%x nf: %d\n",
748 ah->curchan->channel,
749 ah->curchan->channelFlags,
750 common->ani.noise_floor);
751 }
752 }
753
754 /*
755 * Set timer interval based on previous results.
756 * The interval must be the shortest necessary to satisfy ANI,
757 * short calibration and long calibration.
758 */
759 cal_interval = ATH_LONG_CALINTERVAL;
760 if (priv->ah->config.enable_ani)
761 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
762 if (!common->ani.caldone)
763 cal_interval = min(cal_interval, (u32)short_cal_interval);
764
765 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
766 msecs_to_jiffies(cal_interval));
767}
768
769/*******/
770/* LED */
771/*******/
772
773static void ath9k_led_blink_work(struct work_struct *work)
774{
775 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
776 ath9k_led_blink_work.work);
777
778 if (!(priv->op_flags & OP_LED_ASSOCIATED))
779 return;
780
781 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
782 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
783 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
784 else
785 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
786 (priv->op_flags & OP_LED_ON) ? 1 : 0);
787
788 ieee80211_queue_delayed_work(priv->hw,
789 &priv->ath9k_led_blink_work,
790 (priv->op_flags & OP_LED_ON) ?
791 msecs_to_jiffies(priv->led_off_duration) :
792 msecs_to_jiffies(priv->led_on_duration));
793
794 priv->led_on_duration = priv->led_on_cnt ?
795 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
796 ATH_LED_ON_DURATION_IDLE;
797 priv->led_off_duration = priv->led_off_cnt ?
798 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
799 ATH_LED_OFF_DURATION_IDLE;
800 priv->led_on_cnt = priv->led_off_cnt = 0;
801
802 if (priv->op_flags & OP_LED_ON)
803 priv->op_flags &= ~OP_LED_ON;
804 else
805 priv->op_flags |= OP_LED_ON;
806}
807
808static void ath9k_led_brightness_work(struct work_struct *work)
809{
810 struct ath_led *led = container_of(work, struct ath_led,
811 brightness_work.work);
812 struct ath9k_htc_priv *priv = led->priv;
813
814 switch (led->brightness) {
815 case LED_OFF:
816 if (led->led_type == ATH_LED_ASSOC ||
817 led->led_type == ATH_LED_RADIO) {
818 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
819 (led->led_type == ATH_LED_RADIO));
820 priv->op_flags &= ~OP_LED_ASSOCIATED;
821 if (led->led_type == ATH_LED_RADIO)
822 priv->op_flags &= ~OP_LED_ON;
823 } else {
824 priv->led_off_cnt++;
825 }
826 break;
827 case LED_FULL:
828 if (led->led_type == ATH_LED_ASSOC) {
829 priv->op_flags |= OP_LED_ASSOCIATED;
830 ieee80211_queue_delayed_work(priv->hw,
831 &priv->ath9k_led_blink_work, 0);
832 } else if (led->led_type == ATH_LED_RADIO) {
833 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
834 priv->op_flags |= OP_LED_ON;
835 } else {
836 priv->led_on_cnt++;
837 }
838 break;
839 default:
840 break;
841 }
842}
843
844static void ath9k_led_brightness(struct led_classdev *led_cdev,
845 enum led_brightness brightness)
846{
847 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
848 struct ath9k_htc_priv *priv = led->priv;
849
850 led->brightness = brightness;
851 if (!(priv->op_flags & OP_LED_DEINIT))
852 ieee80211_queue_delayed_work(priv->hw,
853 &led->brightness_work, 0);
854}
855
856static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
857{
858 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
859 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
860 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
861 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
862}
863
864static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
865 char *trigger)
866{
867 int ret;
868
869 led->priv = priv;
870 led->led_cdev.name = led->name;
871 led->led_cdev.default_trigger = trigger;
872 led->led_cdev.brightness_set = ath9k_led_brightness;
873
874 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
875 if (ret)
876 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
877 "Failed to register led:%s", led->name);
878 else
879 led->registered = 1;
880
881 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
882
883 return ret;
884}
885
886static void ath9k_unregister_led(struct ath_led *led)
887{
888 if (led->registered) {
889 led_classdev_unregister(&led->led_cdev);
890 led->registered = 0;
891 }
892}
893
894void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
895{
896 priv->op_flags |= OP_LED_DEINIT;
897 ath9k_unregister_led(&priv->assoc_led);
898 priv->op_flags &= ~OP_LED_ASSOCIATED;
899 ath9k_unregister_led(&priv->tx_led);
900 ath9k_unregister_led(&priv->rx_led);
901 ath9k_unregister_led(&priv->radio_led);
902 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
903}
904
905void ath9k_init_leds(struct ath9k_htc_priv *priv)
906{
907 char *trigger;
908 int ret;
909
910 if (AR_SREV_9287(priv->ah))
911 priv->ah->led_pin = ATH_LED_PIN_9287;
912 else if (AR_SREV_9271(priv->ah))
913 priv->ah->led_pin = ATH_LED_PIN_9271;
914 else
915 priv->ah->led_pin = ATH_LED_PIN_DEF;
916
917 /* Configure gpio 1 for output */
918 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
919 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
920 /* LED off, active low */
921 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
922
923 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
924
925 trigger = ieee80211_get_radio_led_name(priv->hw);
926 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
927 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
928 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
929 priv->radio_led.led_type = ATH_LED_RADIO;
930 if (ret)
931 goto fail;
932
933 trigger = ieee80211_get_assoc_led_name(priv->hw);
934 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
935 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
936 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
937 priv->assoc_led.led_type = ATH_LED_ASSOC;
938 if (ret)
939 goto fail;
940
941 trigger = ieee80211_get_tx_led_name(priv->hw);
942 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
943 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
944 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
945 priv->tx_led.led_type = ATH_LED_TX;
946 if (ret)
947 goto fail;
948
949 trigger = ieee80211_get_rx_led_name(priv->hw);
950 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
951 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
952 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
953 priv->rx_led.led_type = ATH_LED_RX;
954 if (ret)
955 goto fail;
956
957 priv->op_flags &= ~OP_LED_DEINIT;
958
959 return;
960
961fail:
962 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
963 ath9k_deinit_leds(priv);
964}
965
966/*******************/
967/* Rfkill */
968/*******************/
969
970static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
971{
972 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
973 priv->ah->rfkill_polarity;
974}
975
976static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
977{
978 struct ath9k_htc_priv *priv = hw->priv;
979 bool blocked = !!ath_is_rfkill_set(priv);
980
981 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
982}
983
984void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
985{
986 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
987 wiphy_rfkill_start_polling(priv->hw->wiphy);
988}
989
990/**********************/
991/* mac80211 Callbacks */
992/**********************/
993
994static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
995{
996 struct ieee80211_hdr *hdr;
997 struct ath9k_htc_priv *priv = hw->priv;
998 int padpos, padsize;
999
1000 hdr = (struct ieee80211_hdr *) skb->data;
1001
1002 /* Add the padding after the header if this is not already done */
1003 padpos = ath9k_cmn_padpos(hdr->frame_control);
1004 padsize = padpos & 3;
1005 if (padsize && skb->len > padpos) {
1006 if (skb_headroom(skb) < padsize)
1007 return -1;
1008 skb_push(skb, padsize);
1009 memmove(skb->data, skb->data + padsize, padpos);
1010 }
1011
1012 if (ath9k_htc_tx_start(priv, skb) != 0) {
1013 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed");
1014 goto fail_tx;
1015 }
1016
1017 return 0;
1018
1019fail_tx:
1020 dev_kfree_skb_any(skb);
1021 return 0;
1022}
1023
1024static int ath9k_htc_start(struct ieee80211_hw *hw)
1025{
1026 struct ath9k_htc_priv *priv = hw->priv;
1027 struct ath_hw *ah = priv->ah;
1028 struct ath_common *common = ath9k_hw_common(ah);
1029 struct ieee80211_channel *curchan = hw->conf.channel;
1030 struct ath9k_channel *init_channel;
1031 int ret = 0;
1032 enum htc_phymode mode;
1033 u16 htc_mode;
1034 u8 cmd_rsp;
1035
1036 ath_print(common, ATH_DBG_CONFIG,
1037 "Starting driver with initial channel: %d MHz\n",
1038 curchan->center_freq);
1039
1040 mutex_lock(&priv->mutex);
1041
1042 /* setup initial channel */
1043 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1044
1045 /* Reset SERDES registers */
1046 ath9k_hw_configpcipowersave(ah, 0, 0);
1047
1048 ath9k_hw_htc_resetinit(ah);
1049 ret = ath9k_hw_reset(ah, init_channel, false);
1050 if (ret) {
1051 ath_print(common, ATH_DBG_FATAL,
1052 "Unable to reset hardware; reset status %d "
1053 "(freq %u MHz)\n", ret, curchan->center_freq);
1054 goto mutex_unlock;
1055 }
1056
1057 ath_update_txpow(priv);
1058
1059 mode = ath9k_htc_get_curmode(priv, init_channel);
1060 htc_mode = cpu_to_be16(mode);
1061 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1062 if (ret)
1063 goto mutex_unlock;
1064
1065 WMI_CMD(WMI_ATH_INIT_CMDID);
1066 if (ret)
1067 goto mutex_unlock;
1068
1069 WMI_CMD(WMI_START_RECV_CMDID);
1070 if (ret)
1071 goto mutex_unlock;
1072
1073 ath9k_host_rx_init(priv);
1074
1075 priv->op_flags &= ~OP_INVALID;
1076 htc_start(priv->htc);
1077
1078mutex_unlock:
1079 mutex_unlock(&priv->mutex);
1080 return ret;
1081}
1082
1083static void ath9k_htc_stop(struct ieee80211_hw *hw)
1084{
1085 struct ath9k_htc_priv *priv = hw->priv;
1086 struct ath_hw *ah = priv->ah;
1087 struct ath_common *common = ath9k_hw_common(ah);
1088 int ret = 0;
1089 u8 cmd_rsp;
1090
1091 mutex_lock(&priv->mutex);
1092
1093 if (priv->op_flags & OP_INVALID) {
1094 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1095 mutex_unlock(&priv->mutex);
1096 return;
1097 }
1098
1099 htc_stop(priv->htc);
1100 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1101 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1102 WMI_CMD(WMI_STOP_RECV_CMDID);
1103 ath9k_hw_phy_disable(ah);
1104 ath9k_hw_disable(ah);
1105 ath9k_hw_configpcipowersave(ah, 1, 1);
1106 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1107
1108 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1109 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1110 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1111 ath9k_led_stop_brightness(priv);
1112 skb_queue_purge(&priv->tx_queue);
1113
1114 /* Remove monitor interface here */
1115 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1116 if (ath9k_htc_remove_monitor_interface(priv))
1117 ath_print(common, ATH_DBG_FATAL,
1118 "Unable to remove monitor interface\n");
1119 else
1120 ath_print(common, ATH_DBG_CONFIG,
1121 "Monitor interface removed\n");
1122 }
1123
1124 priv->op_flags |= OP_INVALID;
1125 mutex_unlock(&priv->mutex);
1126
1127 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1128}
1129
1130static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1131 struct ieee80211_vif *vif)
1132{
1133 struct ath9k_htc_priv *priv = hw->priv;
1134 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1135 struct ath_common *common = ath9k_hw_common(priv->ah);
1136 struct ath9k_htc_target_vif hvif;
1137 int ret = 0;
1138 u8 cmd_rsp;
1139
1140 mutex_lock(&priv->mutex);
1141
1142 /* Only one interface for now */
1143 if (priv->nvifs > 0) {
1144 ret = -ENOBUFS;
1145 goto out;
1146 }
1147
1148 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1149 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1150
1151 switch (vif->type) {
1152 case NL80211_IFTYPE_STATION:
1153 hvif.opmode = cpu_to_be32(HTC_M_STA);
1154 break;
1155 case NL80211_IFTYPE_ADHOC:
1156 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1157 break;
1158 default:
1159 ath_print(common, ATH_DBG_FATAL,
1160 "Interface type %d not yet supported\n", vif->type);
1161 ret = -EOPNOTSUPP;
1162 goto out;
1163 }
1164
1165 ath_print(common, ATH_DBG_CONFIG,
1166 "Attach a VIF of type: %d\n", vif->type);
1167
1168 priv->ah->opmode = vif->type;
1169
1170 /* Index starts from zero on the target */
1171 avp->index = hvif.index = priv->nvifs;
1172 hvif.rtsthreshold = cpu_to_be16(2304);
1173 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1174 if (ret)
1175 goto out;
1176
1177 priv->nvifs++;
1178
1179 /*
1180 * We need a node in target to tx mgmt frames
1181 * before association.
1182 */
1183 ret = ath9k_htc_add_station(priv, vif, NULL);
1184 if (ret)
1185 goto out;
1186
1187 ret = ath9k_htc_update_cap_target(priv);
1188 if (ret)
1189 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1190 " capability in target \n");
1191
1192 priv->vif = vif;
1193out:
1194 mutex_unlock(&priv->mutex);
1195 return ret;
1196}
1197
1198static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1199 struct ieee80211_vif *vif)
1200{
1201 struct ath9k_htc_priv *priv = hw->priv;
1202 struct ath_common *common = ath9k_hw_common(priv->ah);
1203 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1204 struct ath9k_htc_target_vif hvif;
1205 int ret = 0;
1206 u8 cmd_rsp;
1207
1208 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1209
1210 mutex_lock(&priv->mutex);
1211
1212 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1213 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1214 hvif.index = avp->index;
1215 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1216 priv->nvifs--;
1217
1218 ath9k_htc_remove_station(priv, vif, NULL);
1219
1220 if (vif->type == NL80211_IFTYPE_ADHOC) {
1221 spin_lock_bh(&priv->beacon_lock);
1222 if (priv->beacon)
1223 dev_kfree_skb_any(priv->beacon);
1224 priv->beacon = NULL;
1225 spin_unlock_bh(&priv->beacon_lock);
1226 }
1227
1228 priv->vif = NULL;
1229
1230 mutex_unlock(&priv->mutex);
1231}
1232
1233static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1234{
1235 struct ath9k_htc_priv *priv = hw->priv;
1236 struct ath_common *common = ath9k_hw_common(priv->ah);
1237 struct ieee80211_conf *conf = &hw->conf;
1238
1239 mutex_lock(&priv->mutex);
1240
1241 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1242 struct ieee80211_channel *curchan = hw->conf.channel;
1243 int pos = curchan->hw_value;
1244 bool is_cw40 = false;
1245
1246 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1247 curchan->center_freq);
1248
1249 if (check_rc_update(hw, &is_cw40))
1250 ath9k_htc_rc_update(priv, is_cw40);
1251
1252 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1253
1254 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1255 ath_print(common, ATH_DBG_FATAL,
1256 "Unable to set channel\n");
1257 mutex_unlock(&priv->mutex);
1258 return -EINVAL;
1259 }
1260
1261 }
1262
1263 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1264 if (conf->flags & IEEE80211_CONF_MONITOR) {
1265 if (ath9k_htc_add_monitor_interface(priv))
1266 ath_print(common, ATH_DBG_FATAL,
1267 "Failed to set monitor mode\n");
1268 else
1269 ath_print(common, ATH_DBG_CONFIG,
1270 "HW opmode set to Monitor mode\n");
1271 }
1272 }
1273
1274 mutex_unlock(&priv->mutex);
1275
1276 return 0;
1277}
1278
1279#define SUPPORTED_FILTERS \
1280 (FIF_PROMISC_IN_BSS | \
1281 FIF_ALLMULTI | \
1282 FIF_CONTROL | \
1283 FIF_PSPOLL | \
1284 FIF_OTHER_BSS | \
1285 FIF_BCN_PRBRESP_PROMISC | \
1286 FIF_FCSFAIL)
1287
1288static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1289 unsigned int changed_flags,
1290 unsigned int *total_flags,
1291 u64 multicast)
1292{
1293 struct ath9k_htc_priv *priv = hw->priv;
1294 u32 rfilt;
1295
1296 mutex_lock(&priv->mutex);
1297
1298 changed_flags &= SUPPORTED_FILTERS;
1299 *total_flags &= SUPPORTED_FILTERS;
1300
1301 priv->rxfilter = *total_flags;
1302 rfilt = ath9k_cmn_calcrxfilter(hw, priv->ah, priv->rxfilter);
1303 ath9k_hw_setrxfilter(priv->ah, rfilt);
1304
1305 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1306 "Set HW RX filter: 0x%x\n", rfilt);
1307
1308 mutex_unlock(&priv->mutex);
1309}
1310
1311static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
1312 struct ieee80211_vif *vif,
1313 enum sta_notify_cmd cmd,
1314 struct ieee80211_sta *sta)
1315{
1316 struct ath9k_htc_priv *priv = hw->priv;
1317 int ret;
1318
1319 switch (cmd) {
1320 case STA_NOTIFY_ADD:
1321 ret = ath9k_htc_add_station(priv, vif, sta);
1322 if (!ret)
1323 ath9k_htc_init_rate(priv, vif, sta);
1324 break;
1325 case STA_NOTIFY_REMOVE:
1326 ath9k_htc_remove_station(priv, vif, sta);
1327 break;
1328 default:
1329 break;
1330 }
1331}
1332
1333static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1334 const struct ieee80211_tx_queue_params *params)
1335{
1336 struct ath9k_htc_priv *priv = hw->priv;
1337 struct ath_common *common = ath9k_hw_common(priv->ah);
1338 struct ath9k_tx_queue_info qi;
1339 int ret = 0, qnum;
1340
1341 if (queue >= WME_NUM_AC)
1342 return 0;
1343
1344 mutex_lock(&priv->mutex);
1345
1346 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1347
1348 qi.tqi_aifs = params->aifs;
1349 qi.tqi_cwmin = params->cw_min;
1350 qi.tqi_cwmax = params->cw_max;
1351 qi.tqi_burstTime = params->txop;
1352
1353 qnum = get_hw_qnum(queue, priv->hwq_map);
1354
1355 ath_print(common, ATH_DBG_CONFIG,
1356 "Configure tx [queue/hwq] [%d/%d], "
1357 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1358 queue, qnum, params->aifs, params->cw_min,
1359 params->cw_max, params->txop);
1360
1361 ret = ath_htc_txq_update(priv, qnum, &qi);
1362 if (ret)
1363 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1364
1365 mutex_unlock(&priv->mutex);
1366
1367 return ret;
1368}
1369
1370static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1371 enum set_key_cmd cmd,
1372 struct ieee80211_vif *vif,
1373 struct ieee80211_sta *sta,
1374 struct ieee80211_key_conf *key)
1375{
1376 struct ath9k_htc_priv *priv = hw->priv;
1377 struct ath_common *common = ath9k_hw_common(priv->ah);
1378 int ret = 0;
1379
1380 if (htc_modparam_nohwcrypt)
1381 return -ENOSPC;
1382
1383 mutex_lock(&priv->mutex);
1384 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1385
1386 switch (cmd) {
1387 case SET_KEY:
1388 ret = ath9k_cmn_key_config(common, vif, sta, key);
1389 if (ret >= 0) {
1390 key->hw_key_idx = ret;
1391 /* push IV and Michael MIC generation to stack */
1392 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1393 if (key->alg == ALG_TKIP)
1394 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1395 if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
1396 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1397 ret = 0;
1398 }
1399 break;
1400 case DISABLE_KEY:
1401 ath9k_cmn_key_delete(common, key);
1402 break;
1403 default:
1404 ret = -EINVAL;
1405 }
1406
1407 mutex_unlock(&priv->mutex);
1408
1409 return ret;
1410}
1411
1412static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1413 struct ieee80211_vif *vif,
1414 struct ieee80211_bss_conf *bss_conf,
1415 u32 changed)
1416{
1417 struct ath9k_htc_priv *priv = hw->priv;
1418 struct ath_hw *ah = priv->ah;
1419 struct ath_common *common = ath9k_hw_common(ah);
1420
1421 mutex_lock(&priv->mutex);
1422
1423 if (changed & BSS_CHANGED_ASSOC) {
1424 common->curaid = bss_conf->assoc ?
1425 bss_conf->aid : 0;
1426 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1427 bss_conf->assoc);
1428
1429 if (bss_conf->assoc) {
1430 priv->op_flags |= OP_ASSOCIATED;
1431 ath_start_ani(priv);
1432 } else {
1433 priv->op_flags &= ~OP_ASSOCIATED;
1434 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1435 }
1436 }
1437
1438 if (changed & BSS_CHANGED_BSSID) {
1439 /* Set BSSID */
1440 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1441 ath9k_hw_write_associd(ah);
1442
1443 ath_print(common, ATH_DBG_CONFIG,
1444 "BSSID: %pM aid: 0x%x\n",
1445 common->curbssid, common->curaid);
1446 }
1447
1448 if ((changed & BSS_CHANGED_BEACON_INT) ||
1449 (changed & BSS_CHANGED_BEACON) ||
1450 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1451 bss_conf->enable_beacon)) {
1452 priv->op_flags |= OP_ENABLE_BEACON;
1453 ath9k_htc_beacon_config(priv, vif, bss_conf);
1454 }
1455
1456 if (changed & BSS_CHANGED_BEACON)
1457 ath9k_htc_beacon_update(priv, vif);
1458
1459 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1460 !bss_conf->enable_beacon) {
1461 priv->op_flags &= ~OP_ENABLE_BEACON;
1462 ath9k_htc_beacon_config(priv, vif, bss_conf);
1463 }
1464
1465 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1466 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1467 bss_conf->use_short_preamble);
1468 if (bss_conf->use_short_preamble)
1469 priv->op_flags |= OP_PREAMBLE_SHORT;
1470 else
1471 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1472 }
1473
1474 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1475 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1476 bss_conf->use_cts_prot);
1477 if (bss_conf->use_cts_prot &&
1478 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1479 priv->op_flags |= OP_PROTECT_ENABLE;
1480 else
1481 priv->op_flags &= ~OP_PROTECT_ENABLE;
1482 }
1483
1484 if (changed & BSS_CHANGED_ERP_SLOT) {
1485 if (bss_conf->use_short_slot)
1486 ah->slottime = 9;
1487 else
1488 ah->slottime = 20;
1489
1490 ath9k_hw_init_global_settings(ah);
1491 }
1492
1493 mutex_unlock(&priv->mutex);
1494}
1495
1496static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1497{
1498 struct ath9k_htc_priv *priv = hw->priv;
1499 u64 tsf;
1500
1501 mutex_lock(&priv->mutex);
1502 tsf = ath9k_hw_gettsf64(priv->ah);
1503 mutex_unlock(&priv->mutex);
1504
1505 return tsf;
1506}
1507
1508static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1509{
1510 struct ath9k_htc_priv *priv = hw->priv;
1511
1512 mutex_lock(&priv->mutex);
1513 ath9k_hw_settsf64(priv->ah, tsf);
1514 mutex_unlock(&priv->mutex);
1515}
1516
1517static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1518{
1519 struct ath9k_htc_priv *priv = hw->priv;
1520
1521 mutex_lock(&priv->mutex);
1522 ath9k_hw_reset_tsf(priv->ah);
1523 mutex_unlock(&priv->mutex);
1524}
1525
1526static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1527 struct ieee80211_vif *vif,
1528 enum ieee80211_ampdu_mlme_action action,
1529 struct ieee80211_sta *sta,
1530 u16 tid, u16 *ssn)
1531{
1532 struct ath9k_htc_priv *priv = hw->priv;
1533 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1534 struct ath9k_htc_sta *ista;
1535
1536 switch (action) {
1537 case IEEE80211_AMPDU_RX_START:
1538 break;
1539 case IEEE80211_AMPDU_RX_STOP:
1540 break;
1541 case IEEE80211_AMPDU_TX_START:
1542 case IEEE80211_AMPDU_TX_STOP:
1543 if (!(priv->op_flags & OP_TXAGGR))
1544 return -ENOTSUPP;
1545 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1546 work->hw = hw;
1547 work->vif = vif;
1548 work->action = action;
1549 work->tid = tid;
1550 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1551 break;
1552 case IEEE80211_AMPDU_TX_OPERATIONAL:
1553 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1554 ista->tid_state[tid] = AGGR_OPERATIONAL;
1555 break;
1556 default:
1557 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1558 "Unknown AMPDU action\n");
1559 }
1560
1561 return 0;
1562}
1563
1564static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1565{
1566 struct ath9k_htc_priv *priv = hw->priv;
1567
1568 mutex_lock(&priv->mutex);
1569 spin_lock_bh(&priv->beacon_lock);
1570 priv->op_flags |= OP_SCANNING;
1571 spin_unlock_bh(&priv->beacon_lock);
1572 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1573 mutex_unlock(&priv->mutex);
1574}
1575
1576static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1577{
1578 struct ath9k_htc_priv *priv = hw->priv;
1579
1580 mutex_lock(&priv->mutex);
1581 spin_lock_bh(&priv->beacon_lock);
1582 priv->op_flags &= ~OP_SCANNING;
1583 spin_unlock_bh(&priv->beacon_lock);
1584 priv->op_flags |= OP_FULL_RESET;
1585 ath_start_ani(priv);
1586 mutex_unlock(&priv->mutex);
1587}
1588
1589static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1590{
1591 return 0;
1592}
1593
1594static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1595 u8 coverage_class)
1596{
1597 struct ath9k_htc_priv *priv = hw->priv;
1598
1599 mutex_lock(&priv->mutex);
1600 priv->ah->coverage_class = coverage_class;
1601 ath9k_hw_init_global_settings(priv->ah);
1602 mutex_unlock(&priv->mutex);
1603}
1604
1605struct ieee80211_ops ath9k_htc_ops = {
1606 .tx = ath9k_htc_tx,
1607 .start = ath9k_htc_start,
1608 .stop = ath9k_htc_stop,
1609 .add_interface = ath9k_htc_add_interface,
1610 .remove_interface = ath9k_htc_remove_interface,
1611 .config = ath9k_htc_config,
1612 .configure_filter = ath9k_htc_configure_filter,
1613 .sta_notify = ath9k_htc_sta_notify,
1614 .conf_tx = ath9k_htc_conf_tx,
1615 .bss_info_changed = ath9k_htc_bss_info_changed,
1616 .set_key = ath9k_htc_set_key,
1617 .get_tsf = ath9k_htc_get_tsf,
1618 .set_tsf = ath9k_htc_set_tsf,
1619 .reset_tsf = ath9k_htc_reset_tsf,
1620 .ampdu_action = ath9k_htc_ampdu_action,
1621 .sw_scan_start = ath9k_htc_sw_scan_start,
1622 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1623 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1624 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1625 .set_coverage_class = ath9k_htc_set_coverage_class,
1626};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
new file mode 100644
index 000000000000..ac66cf0b2d53
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -0,0 +1,604 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19/******/
20/* TX */
21/******/
22
23int get_hw_qnum(u16 queue, int *hwq_map)
24{
25 switch (queue) {
26 case 0:
27 return hwq_map[ATH9K_WME_AC_VO];
28 case 1:
29 return hwq_map[ATH9K_WME_AC_VI];
30 case 2:
31 return hwq_map[ATH9K_WME_AC_BE];
32 case 3:
33 return hwq_map[ATH9K_WME_AC_BK];
34 default:
35 return hwq_map[ATH9K_WME_AC_BE];
36 }
37}
38
39int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
40 struct ath9k_tx_queue_info *qinfo)
41{
42 struct ath_hw *ah = priv->ah;
43 int error = 0;
44 struct ath9k_tx_queue_info qi;
45
46 ath9k_hw_get_txq_props(ah, qnum, &qi);
47
48 qi.tqi_aifs = qinfo->tqi_aifs;
49 qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
50 qi.tqi_cwmax = qinfo->tqi_cwmax;
51 qi.tqi_burstTime = qinfo->tqi_burstTime;
52 qi.tqi_readyTime = qinfo->tqi_readyTime;
53
54 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
55 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
56 "Unable to update hardware queue %u!\n", qnum);
57 error = -EIO;
58 } else {
59 ath9k_hw_resettxqueue(ah, qnum);
60 }
61
62 return error;
63}
64
65int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
66{
67 struct ieee80211_hdr *hdr;
68 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
69 struct ieee80211_sta *sta = tx_info->control.sta;
70 struct ath9k_htc_sta *ista;
71 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum;
75 __le16 fc;
76 u8 *tx_fhdr;
77 u8 sta_idx;
78
79 hdr = (struct ieee80211_hdr *) skb->data;
80 fc = hdr->frame_control;
81
82 avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
83 if (sta) {
84 ista = (struct ath9k_htc_sta *) sta->drv_priv;
85 sta_idx = ista->index;
86 } else {
87 sta_idx = 0;
88 }
89
90 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
91
92 if (ieee80211_is_data(fc)) {
93 struct tx_frame_hdr tx_hdr;
94 u8 *qc;
95
96 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
97
98 tx_hdr.node_idx = sta_idx;
99 tx_hdr.vif_idx = avp->index;
100
101 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
102 tx_ctl.type = ATH9K_HTC_AMPDU;
103 tx_hdr.data_type = ATH9K_HTC_AMPDU;
104 } else {
105 tx_ctl.type = ATH9K_HTC_NORMAL;
106 tx_hdr.data_type = ATH9K_HTC_NORMAL;
107 }
108
109 if (ieee80211_is_data(fc)) {
110 qc = ieee80211_get_qos_ctl(hdr);
111 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
112 }
113
114 /* Check for RTS protection */
115 if (priv->hw->wiphy->rts_threshold != (u32) -1)
116 if (skb->len > priv->hw->wiphy->rts_threshold)
117 tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
118
119 /* CTS-to-self */
120 if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
121 (priv->op_flags & OP_PROTECT_ENABLE))
122 tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
123
124 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
125 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
126 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
127 else
128 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
129
130 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132
133 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135
136 switch (hw_qnum) {
137 case 0:
138 epid = priv->data_be_ep;
139 break;
140 case 2:
141 epid = priv->data_vi_ep;
142 break;
143 case 3:
144 epid = priv->data_vo_ep;
145 break;
146 case 1:
147 default:
148 epid = priv->data_bk_ep;
149 break;
150 }
151 } else {
152 struct tx_mgmt_hdr mgmt_hdr;
153
154 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
155
156 tx_ctl.type = ATH9K_HTC_NORMAL;
157
158 mgmt_hdr.node_idx = sta_idx;
159 mgmt_hdr.vif_idx = avp->index;
160 mgmt_hdr.tidno = 0;
161 mgmt_hdr.flags = 0;
162
163 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
164 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
165 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
166 else
167 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168
169 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
170 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
171 epid = priv->mgmt_ep;
172 }
173
174 return htc_send(priv->htc, skb, epid, &tx_ctl);
175}
176
177void ath9k_tx_tasklet(unsigned long data)
178{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
180 struct ieee80211_sta *sta;
181 struct ieee80211_hdr *hdr;
182 struct ieee80211_tx_info *tx_info;
183 struct sk_buff *skb = NULL;
184 __le16 fc;
185
186 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
187
188 hdr = (struct ieee80211_hdr *) skb->data;
189 fc = hdr->frame_control;
190 tx_info = IEEE80211_SKB_CB(skb);
191 sta = tx_info->control.sta;
192
193 rcu_read_lock();
194
195 if (sta && conf_is_ht(&priv->hw->conf) &&
196 (priv->op_flags & OP_TXAGGR)
197 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
198 if (ieee80211_is_data_qos(fc)) {
199 u8 *qc, tid;
200 struct ath9k_htc_sta *ista;
201
202 qc = ieee80211_get_qos_ctl(hdr);
203 tid = qc[0] & 0xf;
204 ista = (struct ath9k_htc_sta *)sta->drv_priv;
205
206 if ((tid < ATH9K_HTC_MAX_TID) &&
207 ista->tid_state[tid] == AGGR_STOP) {
208 ieee80211_start_tx_ba_session(sta, tid);
209 ista->tid_state[tid] = AGGR_PROGRESS;
210 }
211 }
212 }
213
214 rcu_read_unlock();
215
216 memset(&tx_info->status, 0, sizeof(tx_info->status));
217 ieee80211_tx_status(priv->hw, skb);
218 }
219}
220
221void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
222 enum htc_endpoint_id ep_id, bool txok)
223{
224 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
225 struct ieee80211_tx_info *tx_info;
226
227 if (!skb)
228 return;
229
230 if (ep_id == priv->mgmt_ep)
231 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
232 else
233 /* TODO: Check for cab/uapsd/data */
234 skb_pull(skb, sizeof(struct tx_frame_hdr));
235
236 tx_info = IEEE80211_SKB_CB(skb);
237
238 if (txok)
239 tx_info->flags |= IEEE80211_TX_STAT_ACK;
240
241 skb_queue_tail(&priv->tx_queue, skb);
242 tasklet_schedule(&priv->tx_tasklet);
243}
244
245int ath9k_tx_init(struct ath9k_htc_priv *priv)
246{
247 skb_queue_head_init(&priv->tx_queue);
248 return 0;
249}
250
251void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
252{
253
254}
255
256bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
257 enum ath9k_tx_queue_subtype subtype)
258{
259 struct ath_hw *ah = priv->ah;
260 struct ath_common *common = ath9k_hw_common(ah);
261 struct ath9k_tx_queue_info qi;
262 int qnum;
263
264 memset(&qi, 0, sizeof(qi));
265
266 qi.tqi_subtype = subtype;
267 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
268 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
269 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
270 qi.tqi_physCompBuf = 0;
271 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
272
273 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
274 if (qnum == -1)
275 return false;
276
277 if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
278 ath_print(common, ATH_DBG_FATAL,
279 "qnum %u out of range, max %u!\n",
280 qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
281 ath9k_hw_releasetxqueue(ah, qnum);
282 return false;
283 }
284
285 priv->hwq_map[subtype] = qnum;
286 return true;
287}
288
289/******/
290/* RX */
291/******/
292
293void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
294{
295 ath9k_hw_rxena(priv->ah);
296 ath9k_cmn_opmode_init(priv->hw, priv->ah, priv->rxfilter);
297 ath9k_hw_startpcureceive(priv->ah);
298 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
299}
300
301static void ath9k_process_rate(struct ieee80211_hw *hw,
302 struct ieee80211_rx_status *rxs,
303 u8 rx_rate, u8 rs_flags)
304{
305 struct ieee80211_supported_band *sband;
306 enum ieee80211_band band;
307 unsigned int i = 0;
308
309 if (rx_rate & 0x80) {
310 /* HT rate */
311 rxs->flag |= RX_FLAG_HT;
312 if (rs_flags & ATH9K_RX_2040)
313 rxs->flag |= RX_FLAG_40MHZ;
314 if (rs_flags & ATH9K_RX_GI)
315 rxs->flag |= RX_FLAG_SHORT_GI;
316 rxs->rate_idx = rx_rate & 0x7f;
317 return;
318 }
319
320 band = hw->conf.channel->band;
321 sband = hw->wiphy->bands[band];
322
323 for (i = 0; i < sband->n_bitrates; i++) {
324 if (sband->bitrates[i].hw_value == rx_rate) {
325 rxs->rate_idx = i;
326 return;
327 }
328 if (sband->bitrates[i].hw_value_short == rx_rate) {
329 rxs->rate_idx = i;
330 rxs->flag |= RX_FLAG_SHORTPRE;
331 return;
332 }
333 }
334
335}
336
337static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
338 struct ath9k_htc_rxbuf *rxbuf,
339 struct ieee80211_rx_status *rx_status)
340
341{
342 struct ieee80211_hdr *hdr;
343 struct ieee80211_hw *hw = priv->hw;
344 struct sk_buff *skb = rxbuf->skb;
345 struct ath_common *common = ath9k_hw_common(priv->ah);
346 int hdrlen, padpos, padsize;
347 int last_rssi = ATH_RSSI_DUMMY_MARKER;
348 __le16 fc;
349
350 hdr = (struct ieee80211_hdr *)skb->data;
351 fc = hdr->frame_control;
352 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
353
354 padpos = ath9k_cmn_padpos(fc);
355
356 padsize = padpos & 3;
357 if (padsize && skb->len >= padpos+padsize) {
358 memmove(skb->data + padsize, skb->data, padpos);
359 skb_pull(skb, padsize);
360 }
361
362 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
363
364 if (rxbuf->rxstatus.rs_status != 0) {
365 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC)
366 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
367 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY)
368 goto rx_next;
369
370 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) {
371 /* FIXME */
372 } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) {
373 if (ieee80211_is_ctl(fc))
374 /*
375 * Sometimes, we get invalid
376 * MIC failures on valid control frames.
377 * Remove these mic errors.
378 */
379 rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC;
380 else
381 rx_status->flag |= RX_FLAG_MMIC_ERROR;
382 }
383
384 /*
385 * Reject error frames with the exception of
386 * decryption and MIC failures. For monitor mode,
387 * we also ignore the CRC error.
388 */
389 if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) {
390 if (rxbuf->rxstatus.rs_status &
391 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
392 ATH9K_RXERR_CRC))
393 goto rx_next;
394 } else {
395 if (rxbuf->rxstatus.rs_status &
396 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
397 goto rx_next;
398 }
399 }
400 }
401
402 if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) {
403 u8 keyix;
404 keyix = rxbuf->rxstatus.rs_keyix;
405 if (keyix != ATH9K_RXKEYIX_INVALID) {
406 rx_status->flag |= RX_FLAG_DECRYPTED;
407 } else if (ieee80211_has_protected(fc) &&
408 skb->len >= hdrlen + 4) {
409 keyix = skb->data[hdrlen + 3] >> 6;
410 if (test_bit(keyix, common->keymap))
411 rx_status->flag |= RX_FLAG_DECRYPTED;
412 }
413 }
414
415 ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
416 rxbuf->rxstatus.rs_flags);
417
418 if (priv->op_flags & OP_ASSOCIATED) {
419 if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
420 !rxbuf->rxstatus.rs_moreaggr)
421 ATH_RSSI_LPF(priv->rx.last_rssi,
422 rxbuf->rxstatus.rs_rssi);
423
424 last_rssi = priv->rx.last_rssi;
425
426 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
427 rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
428 ATH_RSSI_EP_MULTIPLIER);
429
430 if (rxbuf->rxstatus.rs_rssi < 0)
431 rxbuf->rxstatus.rs_rssi = 0;
432
433 if (ieee80211_is_beacon(fc))
434 priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
435 }
436
437 rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
438 rx_status->band = hw->conf.channel->band;
439 rx_status->freq = hw->conf.channel->center_freq;
440 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
441 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
442 rx_status->flag |= RX_FLAG_TSFT;
443
444 return true;
445
446rx_next:
447 return false;
448}
449
450/*
451 * FIXME: Handle FLUSH later on.
452 */
453void ath9k_rx_tasklet(unsigned long data)
454{
455 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
456 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
457 struct ieee80211_rx_status rx_status;
458 struct sk_buff *skb;
459 unsigned long flags;
460
461
462 do {
463 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
464 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
465 if (tmp_buf->in_process) {
466 rxbuf = tmp_buf;
467 break;
468 }
469 }
470
471 if (rxbuf == NULL) {
472 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
473 break;
474 }
475
476 if (!rxbuf->skb)
477 goto requeue;
478
479 if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
480 dev_kfree_skb_any(rxbuf->skb);
481 goto requeue;
482 }
483
484 memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
485 sizeof(struct ieee80211_rx_status));
486 skb = rxbuf->skb;
487 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
488
489 ieee80211_rx(priv->hw, skb);
490
491 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
492requeue:
493 rxbuf->in_process = false;
494 rxbuf->skb = NULL;
495 list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
496 rxbuf = NULL;
497 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
498 } while (1);
499
500}
501
502void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
503 enum htc_endpoint_id ep_id)
504{
505 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv;
506 struct ath_hw *ah = priv->ah;
507 struct ath_common *common = ath9k_hw_common(ah);
508 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
509 struct ath_htc_rx_status *rxstatus;
510 u32 len = 0;
511
512 spin_lock(&priv->rx.rxbuflock);
513 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
514 if (!tmp_buf->in_process) {
515 rxbuf = tmp_buf;
516 break;
517 }
518 }
519 spin_unlock(&priv->rx.rxbuflock);
520
521 if (rxbuf == NULL) {
522 ath_print(common, ATH_DBG_ANY,
523 "No free RX buffer\n");
524 goto err;
525 }
526
527 len = skb->len;
528 if (len <= HTC_RX_FRAME_HEADER_SIZE) {
529 ath_print(common, ATH_DBG_FATAL,
530 "Corrupted RX frame, dropping\n");
531 goto err;
532 }
533
534 rxstatus = (struct ath_htc_rx_status *)skb->data;
535
536 rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
537 rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
538 rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
539 rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
540 rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
541
542 if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
543 ath_print(common, ATH_DBG_FATAL,
544 "Corrupted RX data len, dropping "
545 "(epid: %d, dlen: %d, skblen: %d)\n",
546 ep_id, rxstatus->rs_datalen, len);
547 goto err;
548 }
549
550 spin_lock(&priv->rx.rxbuflock);
551 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
552 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
553 skb->len = rxstatus->rs_datalen;
554 rxbuf->skb = skb;
555 rxbuf->in_process = true;
556 spin_unlock(&priv->rx.rxbuflock);
557
558 tasklet_schedule(&priv->rx_tasklet);
559 return;
560err:
561 dev_kfree_skb_any(skb);
562 return;
563}
564
565/* FIXME: Locking for cleanup/init */
566
567void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
568{
569 struct ath9k_htc_rxbuf *rxbuf, *tbuf;
570
571 list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
572 list_del(&rxbuf->list);
573 if (rxbuf->skb)
574 dev_kfree_skb_any(rxbuf->skb);
575 kfree(rxbuf);
576 }
577}
578
579int ath9k_rx_init(struct ath9k_htc_priv *priv)
580{
581 struct ath_hw *ah = priv->ah;
582 struct ath_common *common = ath9k_hw_common(ah);
583 struct ath9k_htc_rxbuf *rxbuf;
584 int i = 0;
585
586 INIT_LIST_HEAD(&priv->rx.rxbuf);
587 spin_lock_init(&priv->rx.rxbuflock);
588
589 for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
590 rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
591 if (rxbuf == NULL) {
592 ath_print(common, ATH_DBG_FATAL,
593 "Unable to allocate RX buffers\n");
594 goto err;
595 }
596 list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
597 }
598
599 return 0;
600
601err:
602 ath9k_rx_cleanup(priv);
603 return -ENOMEM;
604}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
new file mode 100644
index 000000000000..9a48999d0979
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -0,0 +1,463 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid,
21 struct ath9k_htc_tx_ctl *tx_ctl)
22{
23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid];
25 int status;
26
27 hdr = (struct htc_frame_hdr *)
28 skb_push(skb, sizeof(struct htc_frame_hdr));
29 hdr->endpoint_id = epid;
30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len);
32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
34 tx_ctl);
35 return status;
36}
37
38static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
39{
40 enum htc_endpoint_id avail_epid;
41
42 for (avail_epid = ENDPOINT_MAX; avail_epid > ENDPOINT0; avail_epid--)
43 if (endpoint[avail_epid].service_id == 0)
44 return &endpoint[avail_epid];
45 return NULL;
46}
47
48static u8 service_to_ulpipe(u16 service_id)
49{
50 switch (service_id) {
51 case WMI_CONTROL_SVC:
52 return 4;
53 case WMI_BEACON_SVC:
54 case WMI_CAB_SVC:
55 case WMI_UAPSD_SVC:
56 case WMI_MGMT_SVC:
57 case WMI_DATA_VO_SVC:
58 case WMI_DATA_VI_SVC:
59 case WMI_DATA_BE_SVC:
60 case WMI_DATA_BK_SVC:
61 return 1;
62 default:
63 return 0;
64 }
65}
66
67static u8 service_to_dlpipe(u16 service_id)
68{
69 switch (service_id) {
70 case WMI_CONTROL_SVC:
71 return 3;
72 case WMI_BEACON_SVC:
73 case WMI_CAB_SVC:
74 case WMI_UAPSD_SVC:
75 case WMI_MGMT_SVC:
76 case WMI_DATA_VO_SVC:
77 case WMI_DATA_VI_SVC:
78 case WMI_DATA_BE_SVC:
79 case WMI_DATA_BK_SVC:
80 return 2;
81 default:
82 return 0;
83 }
84}
85
86static void htc_process_target_rdy(struct htc_target *target,
87 void *buf)
88{
89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94
95 endpoint = &target->endpoint[ENDPOINT0];
96 endpoint->service_id = HTC_CTRL_RSVD_SVC;
97 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
98 complete(&target->target_wait);
99}
100
101static void htc_process_conn_rsp(struct htc_target *target,
102 struct htc_frame_hdr *htc_hdr)
103{
104 struct htc_conn_svc_rspmsg *svc_rspmsg;
105 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
106 u16 service_id;
107 u16 max_msglen;
108 enum htc_endpoint_id epid, tepid;
109
110 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
111 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
112
113 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
114 epid = svc_rspmsg->endpoint_id;
115 service_id = be16_to_cpu(svc_rspmsg->service_id);
116 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
117 endpoint = &target->endpoint[epid];
118
119 for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
120 tmp_endpoint = &target->endpoint[tepid];
121 if (tmp_endpoint->service_id == service_id) {
122 tmp_endpoint->service_id = 0;
123 break;
124 }
125 }
126
127 if (!tmp_endpoint)
128 return;
129
130 endpoint->service_id = service_id;
131 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
132 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
133 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
134 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
135 endpoint->max_msglen = max_msglen;
136 target->conn_rsp_epid = epid;
137 complete(&target->cmd_wait);
138 } else {
139 target->conn_rsp_epid = ENDPOINT_UNUSED;
140 }
141}
142
143static int htc_config_pipe_credits(struct htc_target *target)
144{
145 struct sk_buff *skb;
146 struct htc_config_pipe_msg *cp_msg;
147 int ret, time_left;
148
149 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
150 if (!skb) {
151 dev_err(target->dev, "failed to allocate send buffer\n");
152 return -ENOMEM;
153 }
154 skb_reserve(skb, sizeof(struct htc_frame_hdr));
155
156 cp_msg = (struct htc_config_pipe_msg *)
157 skb_put(skb, sizeof(struct htc_config_pipe_msg));
158
159 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
160 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
161 cp_msg->credits = 28;
162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
166 if (ret)
167 goto err;
168
169 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
170 if (!time_left) {
171 dev_err(target->dev, "HTC credit config timeout\n");
172 return -ETIMEDOUT;
173 }
174
175 return 0;
176err:
177 dev_kfree_skb(skb);
178 return -EINVAL;
179}
180
181static int htc_setup_complete(struct htc_target *target)
182{
183 struct sk_buff *skb;
184 struct htc_comp_msg *comp_msg;
185 int ret = 0, time_left;
186
187 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
188 if (!skb) {
189 dev_err(target->dev, "failed to allocate send buffer\n");
190 return -ENOMEM;
191 }
192 skb_reserve(skb, sizeof(struct htc_frame_hdr));
193
194 comp_msg = (struct htc_comp_msg *)
195 skb_put(skb, sizeof(struct htc_comp_msg));
196 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
197
198 target->htc_flags |= HTC_OP_START_WAIT;
199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
201 if (ret)
202 goto err;
203
204 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
205 if (!time_left) {
206 dev_err(target->dev, "HTC start timeout\n");
207 return -ETIMEDOUT;
208 }
209
210 return 0;
211
212err:
213 dev_kfree_skb(skb);
214 return -EINVAL;
215}
216
217/* HTC APIs */
218
219int htc_init(struct htc_target *target)
220{
221 int ret;
222
223 ret = htc_config_pipe_credits(target);
224 if (ret)
225 return ret;
226
227 return htc_setup_complete(target);
228}
229
230int htc_connect_service(struct htc_target *target,
231 struct htc_service_connreq *service_connreq,
232 enum htc_endpoint_id *conn_rsp_epid)
233{
234 struct sk_buff *skb;
235 struct htc_endpoint *endpoint;
236 struct htc_conn_svc_msg *conn_msg;
237 int ret, time_left;
238
239 /* Find an available endpoint */
240 endpoint = get_next_avail_ep(target->endpoint);
241 if (!endpoint) {
242 dev_err(target->dev, "Endpoint is not available for"
243 "service %d\n", service_connreq->service_id);
244 return -EINVAL;
245 }
246
247 endpoint->service_id = service_connreq->service_id;
248 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
249 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
250 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
251 endpoint->ep_callbacks = service_connreq->ep_callbacks;
252
253 skb = dev_alloc_skb(sizeof(struct htc_conn_svc_msg) +
254 sizeof(struct htc_frame_hdr));
255 if (!skb) {
256 dev_err(target->dev, "Failed to allocate buf to send"
257 "service connect req\n");
258 return -ENOMEM;
259 }
260
261 skb_reserve(skb, sizeof(struct htc_frame_hdr));
262
263 conn_msg = (struct htc_conn_svc_msg *)
264 skb_put(skb, sizeof(struct htc_conn_svc_msg));
265 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
266 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
267 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
272 if (ret)
273 goto err;
274
275 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
276 if (!time_left) {
277 dev_err(target->dev, "Service connection timeout for: %d\n",
278 service_connreq->service_id);
279 return -ETIMEDOUT;
280 }
281
282 *conn_rsp_epid = target->conn_rsp_epid;
283 return 0;
284err:
285 dev_kfree_skb(skb);
286 return ret;
287}
288
289int htc_send(struct htc_target *target, struct sk_buff *skb,
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
291{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
293}
294
295void htc_stop(struct htc_target *target)
296{
297 enum htc_endpoint_id epid;
298 struct htc_endpoint *endpoint;
299
300 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
301 endpoint = &target->endpoint[epid];
302 if (endpoint->service_id != 0)
303 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
304 }
305}
306
307void htc_start(struct htc_target *target)
308{
309 enum htc_endpoint_id epid;
310 struct htc_endpoint *endpoint;
311
312 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
313 endpoint = &target->endpoint[epid];
314 if (endpoint->service_id != 0)
315 target->hif->start(target->hif_dev,
316 endpoint->ul_pipeid);
317 }
318}
319
320void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
321 struct sk_buff *skb, bool txok)
322{
323 struct htc_endpoint *endpoint;
324 struct htc_frame_hdr *htc_hdr;
325
326 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
327 complete(&htc_handle->cmd_wait);
328 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
329 }
330
331 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
332 complete(&htc_handle->cmd_wait);
333 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
334 }
335
336 if (skb) {
337 htc_hdr = (struct htc_frame_hdr *) skb->data;
338 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
339 skb_pull(skb, sizeof(struct htc_frame_hdr));
340
341 if (endpoint->ep_callbacks.tx) {
342 endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb,
343 htc_hdr->endpoint_id, txok);
344 }
345 }
346}
347
348/*
349 * HTC Messages are handled directly here and the obtained SKB
350 * is freed.
351 *
352 * Sevice messages (Data, WMI) passed to the corresponding
353 * endpoint RX handlers, which have to free the SKB.
354 */
355void ath9k_htc_rx_msg(struct htc_target *htc_handle,
356 struct sk_buff *skb, u32 len, u8 pipe_id)
357{
358 struct htc_frame_hdr *htc_hdr;
359 enum htc_endpoint_id epid;
360 struct htc_endpoint *endpoint;
361 u16 *msg_id;
362
363 if (!htc_handle || !skb)
364 return;
365
366 htc_hdr = (struct htc_frame_hdr *) skb->data;
367 epid = htc_hdr->endpoint_id;
368
369 if (epid >= ENDPOINT_MAX) {
370 dev_kfree_skb_any(skb);
371 return;
372 }
373
374 if (epid == ENDPOINT0) {
375
376 /* Handle trailer */
377 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
378 if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
379 /* Move past the Watchdog pattern */
380 htc_hdr = (struct htc_frame_hdr *) skb->data + 4;
381 }
382
383 /* Get the message ID */
384 msg_id = (u16 *) ((void *) htc_hdr +
385 sizeof(struct htc_frame_hdr));
386
387 /* Now process HTC messages */
388 switch (be16_to_cpu(*msg_id)) {
389 case HTC_MSG_READY_ID:
390 htc_process_target_rdy(htc_handle, htc_hdr);
391 break;
392 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
393 htc_process_conn_rsp(htc_handle, htc_hdr);
394 break;
395 default:
396 break;
397 }
398
399 dev_kfree_skb_any(skb);
400
401 } else {
402 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
403 skb_trim(skb, len - htc_hdr->control[0]);
404
405 skb_pull(skb, sizeof(struct htc_frame_hdr));
406
407 endpoint = &htc_handle->endpoint[epid];
408 if (endpoint->ep_callbacks.rx)
409 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
410 skb, epid);
411 }
412}
413
414struct htc_target *ath9k_htc_hw_alloc(void *hif_handle)
415{
416 struct htc_target *target;
417
418 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
419 if (!target)
420 printk(KERN_ERR "Unable to allocate memory for"
421 "target device\n");
422
423 return target;
424}
425
426void ath9k_htc_hw_free(struct htc_target *htc)
427{
428 kfree(htc);
429}
430
431int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
432 void *hif_handle, struct device *dev, u16 devid,
433 enum ath9k_hif_transports transport)
434{
435 struct htc_endpoint *endpoint;
436 int err = 0;
437
438 init_completion(&target->target_wait);
439 init_completion(&target->cmd_wait);
440
441 target->hif = hif;
442 target->hif_dev = hif_handle;
443 target->dev = dev;
444
445 /* Assign control endpoint pipe IDs */
446 endpoint = &target->endpoint[ENDPOINT0];
447 endpoint->ul_pipeid = hif->control_ul_pipe;
448 endpoint->dl_pipeid = hif->control_dl_pipe;
449
450 err = ath9k_htc_probe_device(target, dev, devid);
451 if (err) {
452 printk(KERN_ERR "Failed to initialize the device\n");
453 return -ENODEV;
454 }
455
456 return 0;
457}
458
459void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
460{
461 if (target)
462 ath9k_htc_disconnect_device(target, hot_unplug);
463}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
new file mode 100644
index 000000000000..cd7048ffd239
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -0,0 +1,246 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef HTC_HST_H
18#define HTC_HST_H
19
20struct ath9k_htc_priv;
21struct htc_target;
22struct ath9k_htc_tx_ctl;
23
24enum ath9k_hif_transports {
25 ATH9K_HIF_USB,
26};
27
28struct ath9k_htc_hif {
29 struct list_head list;
30 const enum ath9k_hif_transports transport;
31 const char *name;
32
33 u8 control_dl_pipe;
34 u8 control_ul_pipe;
35
36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
39 struct ath9k_htc_tx_ctl *tx_ctl);
40};
41
42enum htc_endpoint_id {
43 ENDPOINT_UNUSED = -1,
44 ENDPOINT0 = 0,
45 ENDPOINT1 = 1,
46 ENDPOINT2 = 2,
47 ENDPOINT3 = 3,
48 ENDPOINT4 = 4,
49 ENDPOINT5 = 5,
50 ENDPOINT6 = 6,
51 ENDPOINT7 = 7,
52 ENDPOINT8 = 8,
53 ENDPOINT_MAX = 22
54};
55
56/* Htc frame hdr flags */
57#define HTC_FLAGS_RECV_TRAILER (1 << 1)
58
59struct htc_frame_hdr {
60 u8 endpoint_id;
61 u8 flags;
62 u16 payload_len;
63 u8 control[4];
64} __packed;
65
66struct htc_ready_msg {
67 u16 message_id;
68 u16 credits;
69 u16 credit_size;
70 u8 max_endpoints;
71 u8 pad;
72} __packed;
73
74struct htc_config_pipe_msg {
75 u16 message_id;
76 u8 pipe_id;
77 u8 credits;
78} __packed;
79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks {
95 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
97 void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
98};
99
100#define HTC_TX_QUEUE_SIZE 256
101
102struct htc_txq {
103 struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
104 u32 txqdepth;
105 u16 txbuf_cnt;
106 u16 txq_head;
107 u16 txq_tail;
108};
109
110struct htc_endpoint {
111 u16 service_id;
112
113 struct htc_ep_callbacks ep_callbacks;
114 struct htc_txq htc_txq;
115 u32 max_txqdepth;
116 int max_msglen;
117
118 u8 ul_pipeid;
119 u8 dl_pipeid;
120};
121
122#define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
123#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125
126#define NUM_CONTROL_BUFFERS 8
127#define HST_ENDPOINT_MAX 8
128
129struct htc_control_buf {
130 struct htc_packet htc_pkt;
131 u8 buf[HTC_CONTROL_BUFFER_SIZE];
132};
133
134#define HTC_OP_START_WAIT BIT(0)
135#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
136
137struct htc_target {
138 void *hif_dev;
139 struct ath9k_htc_priv *drv_priv;
140 struct device *dev;
141 struct ath9k_htc_hif *hif;
142 struct htc_endpoint endpoint[HST_ENDPOINT_MAX];
143 struct completion target_wait;
144 struct completion cmd_wait;
145 struct list_head list;
146 enum htc_endpoint_id conn_rsp_epid;
147 u16 credits;
148 u16 credit_size;
149 u8 htc_flags;
150};
151
152enum htc_msg_id {
153 HTC_MSG_READY_ID = 1,
154 HTC_MSG_CONNECT_SERVICE_ID,
155 HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
156 HTC_MSG_SETUP_COMPLETE_ID,
157 HTC_MSG_CONFIG_PIPE_ID,
158 HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
159};
160
161struct htc_service_connreq {
162 u16 service_id;
163 u16 con_flags;
164 u32 max_send_qdepth;
165 struct htc_ep_callbacks ep_callbacks;
166};
167
168/* Current service IDs */
169
170enum htc_service_group_ids{
171 RSVD_SERVICE_GROUP = 0,
172 WMI_SERVICE_GROUP = 1,
173
174 HTC_SERVICE_GROUP_LAST = 255
175};
176
177#define MAKE_SERVICE_ID(group, index) \
178 (int)(((int)group << 8) | (int)(index))
179
180/* NOTE: service ID of 0x0000 is reserved and should never be used */
181#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
182#define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
183
184#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
185#define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
186#define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
187#define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
188#define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
189#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
190#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
191#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
192#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
193
194struct htc_conn_svc_msg {
195 u16 msg_id;
196 u16 service_id;
197 u16 con_flags;
198 u8 dl_pipeid;
199 u8 ul_pipeid;
200 u8 svc_meta_len;
201 u8 pad;
202} __packed;
203
204/* connect response status codes */
205#define HTC_SERVICE_SUCCESS 0
206#define HTC_SERVICE_NOT_FOUND 1
207#define HTC_SERVICE_FAILED 2
208#define HTC_SERVICE_NO_RESOURCES 3
209#define HTC_SERVICE_NO_MORE_EP 4
210
211struct htc_conn_svc_rspmsg {
212 u16 msg_id;
213 u16 service_id;
214 u8 status;
215 u8 endpoint_id;
216 u16 max_msg_len;
217 u8 svc_meta_len;
218 u8 pad;
219} __packed;
220
221struct htc_comp_msg {
222 u16 msg_id;
223} __packed;
224
225int htc_init(struct htc_target *target);
226int htc_connect_service(struct htc_target *target,
227 struct htc_service_connreq *service_connreq,
228 enum htc_endpoint_id *conn_rsp_eid);
229int htc_send(struct htc_target *target, struct sk_buff *skb,
230 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
231void htc_stop(struct htc_target *target);
232void htc_start(struct htc_target *target);
233
234void ath9k_htc_rx_msg(struct htc_target *htc_handle,
235 struct sk_buff *skb, u32 len, u8 pipe_id);
236void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
237 struct sk_buff *skb, bool txok);
238
239struct htc_target *ath9k_htc_hw_alloc(void *hif_handle);
240void ath9k_htc_hw_free(struct htc_target *htc);
241int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
242 void *hif_handle, struct device *dev, u16 devid,
243 enum ath9k_hif_transports transport);
244void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
245
246#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1fb14edfcb2a..77db932c3137 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -499,8 +499,10 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
499{ 499{
500 int ecode; 500 int ecode;
501 501
502 if (!ath9k_hw_chip_test(ah)) 502 if (!AR_SREV_9271(ah)) {
503 return -ENODEV; 503 if (!ath9k_hw_chip_test(ah))
504 return -ENODEV;
505 }
504 506
505 ecode = ath9k_hw_rf_claim(ah); 507 ecode = ath9k_hw_rf_claim(ah);
506 if (ecode != 0) 508 if (ecode != 0)
@@ -603,9 +605,23 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
603 ARRAY_SIZE(ar9271Modes_9271), 6); 605 ARRAY_SIZE(ar9271Modes_9271), 6);
604 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, 606 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
605 ARRAY_SIZE(ar9271Common_9271), 2); 607 ARRAY_SIZE(ar9271Common_9271), 2);
608 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
609 ar9271Common_normal_cck_fir_coeff_9271,
610 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
611 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
612 ar9271Common_japan_2484_cck_fir_coeff_9271,
613 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
606 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, 614 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
607 ar9271Modes_9271_1_0_only, 615 ar9271Modes_9271_1_0_only,
608 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); 616 ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
617 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
618 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
619 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
620 ar9271Modes_high_power_tx_gain_9271,
621 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
622 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
623 ar9271Modes_normal_power_tx_gain_9271,
624 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
609 return; 625 return;
610 } 626 }
611 627
@@ -990,22 +1006,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
990 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); 1006 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
991} 1007}
992 1008
993static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud)
994{
995 u32 lcr;
996 u32 baud_divider = freq * 1000 * 1000 / 16 / baud;
997
998 lcr = REG_READ(ah , 0x5100c);
999 lcr |= 0x80;
1000
1001 REG_WRITE(ah, 0x5100c, lcr);
1002 REG_WRITE(ah, 0x51004, (baud_divider >> 8));
1003 REG_WRITE(ah, 0x51000, (baud_divider & 0xff));
1004
1005 lcr &= ~0x80;
1006 REG_WRITE(ah, 0x5100c, lcr);
1007}
1008
1009static void ath9k_hw_init_pll(struct ath_hw *ah, 1009static void ath9k_hw_init_pll(struct ath_hw *ah,
1010 struct ath9k_channel *chan) 1010 struct ath9k_channel *chan)
1011{ 1011{
@@ -1071,22 +1071,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
1071 1071
1072 /* Switch the core clock for ar9271 to 117Mhz */ 1072 /* Switch the core clock for ar9271 to 117Mhz */
1073 if (AR_SREV_9271(ah)) { 1073 if (AR_SREV_9271(ah)) {
1074 if ((pll == 0x142c) || (pll == 0x2850) ) { 1074 udelay(500);
1075 udelay(500); 1075 REG_WRITE(ah, 0x50040, 0x304);
1076 /* set CLKOBS to output AHB clock */
1077 REG_WRITE(ah, 0x7020, 0xe);
1078 /*
1079 * 0x304: 117Mhz, ahb_ratio: 1x1
1080 * 0x306: 40Mhz, ahb_ratio: 1x1
1081 */
1082 REG_WRITE(ah, 0x50040, 0x304);
1083 /*
1084 * makes adjustments for the baud dividor to keep the
1085 * targetted baud rate based on the used core clock.
1086 */
1087 ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK,
1088 AR9271_TARGET_BAUD_RATE);
1089 }
1090 } 1076 }
1091 1077
1092 udelay(RTC_PLL_SETTLE_DELAY); 1078 udelay(RTC_PLL_SETTLE_DELAY);
@@ -1241,7 +1227,7 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1241{ 1227{
1242 struct ath_common *common = ath9k_hw_common(ah); 1228 struct ath_common *common = ath9k_hw_common(ah);
1243 1229
1244 if (common->state <= ATH_HW_INITIALIZED) 1230 if (common->state < ATH_HW_INITIALIZED)
1245 goto free_hw; 1231 goto free_hw;
1246 1232
1247 if (!AR_SREV_9100(ah)) 1233 if (!AR_SREV_9100(ah))
@@ -1252,8 +1238,6 @@ void ath9k_hw_deinit(struct ath_hw *ah)
1252free_hw: 1238free_hw:
1253 if (!AR_SREV_9280_10_OR_LATER(ah)) 1239 if (!AR_SREV_9280_10_OR_LATER(ah))
1254 ath9k_hw_rf_free_ext_banks(ah); 1240 ath9k_hw_rf_free_ext_banks(ah);
1255 kfree(ah);
1256 ah = NULL;
1257} 1241}
1258EXPORT_SYMBOL(ath9k_hw_deinit); 1242EXPORT_SYMBOL(ath9k_hw_deinit);
1259 1243
@@ -1266,26 +1250,6 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1266{ 1250{
1267 u32 val; 1251 u32 val;
1268 1252
1269 if (AR_SREV_9271(ah)) {
1270 /*
1271 * Enable spectral scan to solution for issues with stuck
1272 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
1273 * AR9271 1.1
1274 */
1275 if (AR_SREV_9271_10(ah)) {
1276 val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) |
1277 AR_PHY_SPECTRAL_SCAN_ENABLE;
1278 REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
1279 }
1280 else if (AR_SREV_9271_11(ah))
1281 /*
1282 * change AR_PHY_RF_CTL3 setting to fix MAC issue
1283 * present on AR9271 1.1
1284 */
1285 REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
1286 return;
1287 }
1288
1289 /* 1253 /*
1290 * Set the RX_ABORT and RX_DIS and clear if off only after 1254 * Set the RX_ABORT and RX_DIS and clear if off only after
1291 * RXE is set for MAC. This prevents frames with corrupted 1255 * RXE is set for MAC. This prevents frames with corrupted
@@ -1294,8 +1258,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1294 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 1258 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
1295 1259
1296 if (AR_SREV_9280_10_OR_LATER(ah)) { 1260 if (AR_SREV_9280_10_OR_LATER(ah)) {
1297 val = REG_READ(ah, AR_PCU_MISC_MODE2) & 1261 val = REG_READ(ah, AR_PCU_MISC_MODE2);
1298 (~AR_PCU_MISC_MODE2_HWWAR1); 1262
1263 if (!AR_SREV_9271(ah))
1264 val &= ~AR_PCU_MISC_MODE2_HWWAR1;
1299 1265
1300 if (AR_SREV_9287_10_OR_LATER(ah)) 1266 if (AR_SREV_9287_10_OR_LATER(ah))
1301 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 1267 val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
@@ -1439,7 +1405,10 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1439 return -EINVAL; 1405 return -EINVAL;
1440 } 1406 }
1441 1407
1408 /* Set correct baseband to analog shift setting to access analog chips */
1442 REG_WRITE(ah, AR_PHY(0), 0x00000007); 1409 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1410
1411 /* Write ADDAC shifts */
1443 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 1412 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
1444 ah->eep_ops->set_addac(ah, chan); 1413 ah->eep_ops->set_addac(ah, chan);
1445 1414
@@ -1451,9 +1420,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1451 sizeof(u32) * ah->iniAddac.ia_rows * 1420 sizeof(u32) * ah->iniAddac.ia_rows *
1452 ah->iniAddac.ia_columns; 1421 ah->iniAddac.ia_columns;
1453 1422
1423 /* For AR5416 2.0/2.1 */
1454 memcpy(ah->addac5416_21, 1424 memcpy(ah->addac5416_21,
1455 ah->iniAddac.ia_array, addacSize); 1425 ah->iniAddac.ia_array, addacSize);
1456 1426
1427 /* override CLKDRV value at [row, column] = [31, 1] */
1457 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; 1428 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
1458 1429
1459 temp.ia_array = ah->addac5416_21; 1430 temp.ia_array = ah->addac5416_21;
@@ -1485,6 +1456,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1485 AR_SREV_9287_10_OR_LATER(ah)) 1456 AR_SREV_9287_10_OR_LATER(ah))
1486 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1457 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1487 1458
1459 if (AR_SREV_9271_10(ah))
1460 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1461 modesIndex, regWrites);
1462
1463 /* Write common array parameters */
1488 for (i = 0; i < ah->iniCommon.ia_rows; i++) { 1464 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
1489 u32 reg = INI_RA(&ah->iniCommon, i, 0); 1465 u32 reg = INI_RA(&ah->iniCommon, i, 0);
1490 u32 val = INI_RA(&ah->iniCommon, i, 1); 1466 u32 val = INI_RA(&ah->iniCommon, i, 1);
@@ -1499,11 +1475,16 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1499 DO_DELAY(regWrites); 1475 DO_DELAY(regWrites);
1500 } 1476 }
1501 1477
1502 ath9k_hw_write_regs(ah, freqIndex, regWrites); 1478 if (AR_SREV_9271(ah)) {
1479 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1)
1480 REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
1481 modesIndex, regWrites);
1482 else
1483 REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
1484 modesIndex, regWrites);
1485 }
1503 1486
1504 if (AR_SREV_9271_10(ah)) 1487 ath9k_hw_write_regs(ah, freqIndex, regWrites);
1505 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only,
1506 modesIndex, regWrites);
1507 1488
1508 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { 1489 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
1509 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, 1490 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
@@ -1517,6 +1498,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1517 if (OLC_FOR_AR9280_20_LATER) 1498 if (OLC_FOR_AR9280_20_LATER)
1518 ath9k_olc_init(ah); 1499 ath9k_olc_init(ah);
1519 1500
1501 /* Set TX power */
1520 ah->eep_ops->set_txpower(ah, chan, 1502 ah->eep_ops->set_txpower(ah, chan,
1521 ath9k_regd_get_ctl(regulatory, chan), 1503 ath9k_regd_get_ctl(regulatory, chan),
1522 channel->max_antenna_gain * 2, 1504 channel->max_antenna_gain * 2,
@@ -1524,6 +1506,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1524 min((u32) MAX_RATE_POWER, 1506 min((u32) MAX_RATE_POWER,
1525 (u32) regulatory->power_limit)); 1507 (u32) regulatory->power_limit));
1526 1508
1509 /* Write analog registers */
1527 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 1510 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1528 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 1511 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
1529 "ar5416SetRfRegs failed\n"); 1512 "ar5416SetRfRegs failed\n");
@@ -1966,6 +1949,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1966 1949
1967 ath9k_hw_mark_phy_inactive(ah); 1950 ath9k_hw_mark_phy_inactive(ah);
1968 1951
1952 /* Only required on the first reset */
1969 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1953 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1970 REG_WRITE(ah, 1954 REG_WRITE(ah,
1971 AR9271_RESET_POWER_DOWN_CONTROL, 1955 AR9271_RESET_POWER_DOWN_CONTROL,
@@ -1978,6 +1962,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1978 return -EINVAL; 1962 return -EINVAL;
1979 } 1963 }
1980 1964
1965 /* Only required on the first reset */
1981 if (AR_SREV_9271(ah) && ah->htc_reset_init) { 1966 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
1982 ah->htc_reset_init = false; 1967 ah->htc_reset_init = false;
1983 REG_WRITE(ah, 1968 REG_WRITE(ah,
@@ -2438,7 +2423,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
2438 if (!AR_SREV_9100(ah)) 2423 if (!AR_SREV_9100(ah))
2439 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); 2424 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
2440 2425
2441 if(!AR_SREV_5416(ah)) 2426 if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
2442 REG_CLR_BIT(ah, (AR_RTC_RESET), 2427 REG_CLR_BIT(ah, (AR_RTC_RESET),
2443 AR_RTC_RESET_EN); 2428 AR_RTC_RESET_EN);
2444 } 2429 }
@@ -3216,7 +3201,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
3216 else 3201 else
3217 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; 3202 pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3218 3203
3219 if (AR_SREV_9285_10_OR_LATER(ah)) 3204 if (AR_SREV_9271(ah))
3205 pCap->num_gpio_pins = AR9271_NUM_GPIO;
3206 else if (AR_SREV_9285_10_OR_LATER(ah))
3220 pCap->num_gpio_pins = AR9285_NUM_GPIO; 3207 pCap->num_gpio_pins = AR9285_NUM_GPIO;
3221 else if (AR_SREV_9280_10_OR_LATER(ah)) 3208 else if (AR_SREV_9280_10_OR_LATER(ah))
3222 pCap->num_gpio_pins = AR928X_NUM_GPIO; 3209 pCap->num_gpio_pins = AR928X_NUM_GPIO;
@@ -3452,7 +3439,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3452 if (gpio >= ah->caps.num_gpio_pins) 3439 if (gpio >= ah->caps.num_gpio_pins)
3453 return 0xffffffff; 3440 return 0xffffffff;
3454 3441
3455 if (AR_SREV_9287_10_OR_LATER(ah)) 3442 if (AR_SREV_9271(ah))
3443 return MS_REG_READ(AR9271, gpio) != 0;
3444 else if (AR_SREV_9287_10_OR_LATER(ah))
3456 return MS_REG_READ(AR9287, gpio) != 0; 3445 return MS_REG_READ(AR9287, gpio) != 0;
3457 else if (AR_SREV_9285_10_OR_LATER(ah)) 3446 else if (AR_SREV_9285_10_OR_LATER(ah))
3458 return MS_REG_READ(AR9285, gpio) != 0; 3447 return MS_REG_READ(AR9285, gpio) != 0;
@@ -3481,6 +3470,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output);
3481 3470
3482void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) 3471void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
3483{ 3472{
3473 if (AR_SREV_9271(ah))
3474 val = ~val;
3475
3484 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), 3476 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
3485 AR_GPIO_BIT(gpio)); 3477 AR_GPIO_BIT(gpio));
3486} 3478}
@@ -3865,6 +3857,16 @@ void ath_gen_timer_isr(struct ath_hw *ah)
3865} 3857}
3866EXPORT_SYMBOL(ath_gen_timer_isr); 3858EXPORT_SYMBOL(ath_gen_timer_isr);
3867 3859
3860/********/
3861/* HTC */
3862/********/
3863
3864void ath9k_hw_htc_resetinit(struct ath_hw *ah)
3865{
3866 ah->htc_reset_init = true;
3867}
3868EXPORT_SYMBOL(ath9k_hw_htc_resetinit);
3869
3868static struct { 3870static struct {
3869 u32 version; 3871 u32 version;
3870 const char * name; 3872 const char * name;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 20d90268ce31..6b03e1688b22 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -599,6 +599,11 @@ struct ath_hw {
599 struct ar5416IniArray iniModes_9271_1_0_only; 599 struct ar5416IniArray iniModes_9271_1_0_only;
600 struct ar5416IniArray iniCckfirNormal; 600 struct ar5416IniArray iniCckfirNormal;
601 struct ar5416IniArray iniCckfirJapan2484; 601 struct ar5416IniArray iniCckfirJapan2484;
602 struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
603 struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
604 struct ar5416IniArray iniModes_9271_ANI_reg;
605 struct ar5416IniArray iniModes_high_power_tx_gain_9271;
606 struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
602 607
603 u32 intr_gen_timer_trigger; 608 u32 intr_gen_timer_trigger;
604 u32 intr_gen_timer_thresh; 609 u32 intr_gen_timer_thresh;
@@ -702,6 +707,9 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
702 707
703void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); 708void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
704 709
710/* HTC */
711void ath9k_hw_htc_resetinit(struct ath_hw *ah);
712
705#define ATH_PCIE_CAP_LINK_CTRL 0x70 713#define ATH_PCIE_CAP_LINK_CTRL 0x70
706#define ATH_PCIE_CAP_LINK_L0S 1 714#define ATH_PCIE_CAP_LINK_L0S 1
707#define ATH_PCIE_CAP_LINK_L1 2 715#define ATH_PCIE_CAP_LINK_L1 2
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 623c2f884987..6063f5463708 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -758,6 +758,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
758 758
759 tasklet_kill(&sc->intr_tq); 759 tasklet_kill(&sc->intr_tq);
760 tasklet_kill(&sc->bcon_tasklet); 760 tasklet_kill(&sc->bcon_tasklet);
761
762 kfree(sc->sc_ah);
763 sc->sc_ah = NULL;
761} 764}
762 765
763void ath9k_deinit_device(struct ath_softc *sc) 766void ath9k_deinit_device(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index 8a3bf3ab998d..177bdeb84ad7 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -6441,7 +6441,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6441 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6442 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6443 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6444 { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6445 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6446 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6447 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6455,8 +6455,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6455 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6456 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6457 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6458 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6459 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6460 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6461 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6462 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6569,7 +6569,7 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, 6569 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, 6570 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, 6571 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, 6572 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 },
6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, 6573 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, 6574 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, 6575 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
@@ -6583,8 +6583,8 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, 6583 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, 6584 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, 6585 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, 6586 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 },
6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6587 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, 6588 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, 6589 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, 6590 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
@@ -6683,25 +6683,6 @@ static const u_int32_t ar9271Modes_9271[][6] = {
6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, 6683 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, 6684 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, 6685 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
6686 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
6687 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6688 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
6689 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
6690 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
6691 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
6692 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
6693 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
6694 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
6695 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
6696 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
6697 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
6698 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
6699 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
6700 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
6701 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
6702 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
6703 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6704 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6705 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, 6686 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
6706}; 6687};
6707 6688
@@ -6879,7 +6860,7 @@ static const u_int32_t ar9271Common_9271[][2] = {
6879 { 0x00008258, 0x00000000 }, 6860 { 0x00008258, 0x00000000 },
6880 { 0x0000825c, 0x400000ff }, 6861 { 0x0000825c, 0x400000ff },
6881 { 0x00008260, 0x00080922 }, 6862 { 0x00008260, 0x00080922 },
6882 { 0x00008264, 0x88a00010 }, 6863 { 0x00008264, 0xa8a00010 },
6883 { 0x00008270, 0x00000000 }, 6864 { 0x00008270, 0x00000000 },
6884 { 0x00008274, 0x40000000 }, 6865 { 0x00008274, 0x40000000 },
6885 { 0x00008278, 0x003e4180 }, 6866 { 0x00008278, 0x003e4180 },
@@ -6910,13 +6891,10 @@ static const u_int32_t ar9271Common_9271[][2] = {
6910 { 0x00007810, 0x71c0d388 }, 6891 { 0x00007810, 0x71c0d388 },
6911 { 0x00007814, 0x924934a8 }, 6892 { 0x00007814, 0x924934a8 },
6912 { 0x0000781c, 0x00000000 }, 6893 { 0x0000781c, 0x00000000 },
6913 { 0x00007820, 0x00000c04 },
6914 { 0x00007824, 0x00d8abff },
6915 { 0x00007828, 0x66964300 }, 6894 { 0x00007828, 0x66964300 },
6916 { 0x0000782c, 0x8db6d961 }, 6895 { 0x0000782c, 0x8db6d961 },
6917 { 0x00007830, 0x8db6d96c }, 6896 { 0x00007830, 0x8db6d96c },
6918 { 0x00007834, 0x6140008b }, 6897 { 0x00007834, 0x6140008b },
6919 { 0x00007838, 0x00000029 },
6920 { 0x0000783c, 0x72ee0a72 }, 6898 { 0x0000783c, 0x72ee0a72 },
6921 { 0x00007840, 0xbbfffffc }, 6899 { 0x00007840, 0xbbfffffc },
6922 { 0x00007844, 0x000c0db6 }, 6900 { 0x00007844, 0x000c0db6 },
@@ -6929,7 +6907,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6929 { 0x00007860, 0x21084210 }, 6907 { 0x00007860, 0x21084210 },
6930 { 0x00007864, 0xf7d7ffde }, 6908 { 0x00007864, 0xf7d7ffde },
6931 { 0x00007868, 0xc2034080 }, 6909 { 0x00007868, 0xc2034080 },
6932 { 0x0000786c, 0x48609eb4 },
6933 { 0x00007870, 0x10142c00 }, 6910 { 0x00007870, 0x10142c00 },
6934 { 0x00009808, 0x00000000 }, 6911 { 0x00009808, 0x00000000 },
6935 { 0x0000980c, 0xafe68e30 }, 6912 { 0x0000980c, 0xafe68e30 },
@@ -6982,9 +6959,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
6982 { 0x000099e8, 0x3c466478 }, 6959 { 0x000099e8, 0x3c466478 },
6983 { 0x000099ec, 0x0cc80caa }, 6960 { 0x000099ec, 0x0cc80caa },
6984 { 0x000099f0, 0x00000000 }, 6961 { 0x000099f0, 0x00000000 },
6985 { 0x0000a1f4, 0x00000000 },
6986 { 0x0000a1f8, 0x71733d01 },
6987 { 0x0000a1fc, 0xd0ad5c12 },
6988 { 0x0000a208, 0x803e68c8 }, 6962 { 0x0000a208, 0x803e68c8 },
6989 { 0x0000a210, 0x4080a333 }, 6963 { 0x0000a210, 0x4080a333 },
6990 { 0x0000a214, 0x00206c10 }, 6964 { 0x0000a214, 0x00206c10 },
@@ -7004,13 +6978,9 @@ static const u_int32_t ar9271Common_9271[][2] = {
7004 { 0x0000a260, 0xdfa90f01 }, 6978 { 0x0000a260, 0xdfa90f01 },
7005 { 0x0000a268, 0x00000000 }, 6979 { 0x0000a268, 0x00000000 },
7006 { 0x0000a26c, 0x0ebae9e6 }, 6980 { 0x0000a26c, 0x0ebae9e6 },
7007 { 0x0000a278, 0x3bdef7bd },
7008 { 0x0000a27c, 0x050e83bd },
7009 { 0x0000a388, 0x0c000000 }, 6981 { 0x0000a388, 0x0c000000 },
7010 { 0x0000a38c, 0x20202020 }, 6982 { 0x0000a38c, 0x20202020 },
7011 { 0x0000a390, 0x20202020 }, 6983 { 0x0000a390, 0x20202020 },
7012 { 0x0000a394, 0x3bdef7bd },
7013 { 0x0000a398, 0x000003bd },
7014 { 0x0000a39c, 0x00000001 }, 6984 { 0x0000a39c, 0x00000001 },
7015 { 0x0000a3a0, 0x00000000 }, 6985 { 0x0000a3a0, 0x00000000 },
7016 { 0x0000a3a4, 0x00000000 }, 6986 { 0x0000a3a4, 0x00000000 },
@@ -7025,8 +6995,6 @@ static const u_int32_t ar9271Common_9271[][2] = {
7025 { 0x0000a3cc, 0x20202020 }, 6995 { 0x0000a3cc, 0x20202020 },
7026 { 0x0000a3d0, 0x20202020 }, 6996 { 0x0000a3d0, 0x20202020 },
7027 { 0x0000a3d4, 0x20202020 }, 6997 { 0x0000a3d4, 0x20202020 },
7028 { 0x0000a3dc, 0x3bdef7bd },
7029 { 0x0000a3e0, 0x000003bd },
7030 { 0x0000a3e4, 0x00000000 }, 6998 { 0x0000a3e4, 0x00000000 },
7031 { 0x0000a3e8, 0x18c43433 }, 6999 { 0x0000a3e8, 0x18c43433 },
7032 { 0x0000a3ec, 0x00f70081 }, 7000 { 0x0000a3ec, 0x00f70081 },
@@ -7046,7 +7014,102 @@ static const u_int32_t ar9271Common_9271[][2] = {
7046 { 0x0000d384, 0xf3307ff0 }, 7014 { 0x0000d384, 0xf3307ff0 },
7047}; 7015};
7048 7016
7017static const u_int32_t ar9271Common_normal_cck_fir_coeff_9271[][2] = {
7018 { 0x0000a1f4, 0x00fffeff },
7019 { 0x0000a1f8, 0x00f5f9ff },
7020 { 0x0000a1fc, 0xb79f6427 },
7021};
7022
7023static const u_int32_t ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = {
7024 { 0x0000a1f4, 0x00000000 },
7025 { 0x0000a1f8, 0xefff0301 },
7026 { 0x0000a1fc, 0xca9228ee },
7027};
7028
7049static const u_int32_t ar9271Modes_9271_1_0_only[][6] = { 7029static const u_int32_t ar9271Modes_9271_1_0_only[][6] = {
7050 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, 7030 { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 },
7051 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, 7031 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
7052}; 7032};
7033
7034static const u_int32_t ar9271Modes_9271_ANI_reg[][6] = {
7035 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
7036 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
7037 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
7038 { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 },
7039 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
7040 { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 },
7041 { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
7042 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
7043};
7044
7045static const u_int32_t ar9271Modes_normal_power_tx_gain_9271[][6] = {
7046 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
7047 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
7048 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
7049 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
7050 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
7051 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
7052 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
7053 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
7054 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
7055 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
7056 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
7057 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
7058 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
7059 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7060 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7061 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7062 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7063 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7064 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7065 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7066 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7067 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7068 { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 },
7069 { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff },
7070 { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
7071 { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
7072 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
7073 { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7074 { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd },
7075 { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7076 { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7077 { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd },
7078 { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd },
7079};
7080
7081static const u_int32_t ar9271Modes_high_power_tx_gain_9271[][6] = {
7082 { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 },
7083 { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 },
7084 { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 },
7085 { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 },
7086 { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 },
7087 { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 },
7088 { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 },
7089 { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 },
7090 { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 },
7091 { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 },
7092 { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 },
7093 { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 },
7094 { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 },
7095 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
7096 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
7097 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
7098 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7099 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7100 { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7101 { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7102 { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7103 { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
7104 { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b },
7105 { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff },
7106 { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 },
7107 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
7108 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 },
7109 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
7110 { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 },
7111 { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7112 { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7113 { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 },
7114 { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 },
7115};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 589490b69ddc..7af823a1527d 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -351,7 +351,7 @@ void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
351 351
352 ads->ds_ctl6 = SM(keyType, AR_EncrType); 352 ads->ds_ctl6 = SM(keyType, AR_EncrType);
353 353
354 if (AR_SREV_9285(ah)) { 354 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
355 ads->ds_ctl8 = 0; 355 ads->ds_ctl8 = 0;
356 ads->ds_ctl9 = 0; 356 ads->ds_ctl9 = 0;
357 ads->ds_ctl10 = 0; 357 ads->ds_ctl10 = 0;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 29851e6376a9..a5e543bd2271 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -150,6 +150,32 @@ struct ath_rx_status {
150 u32 evm2; 150 u32 evm2;
151}; 151};
152 152
153struct ath_htc_rx_status {
154 u64 rs_tstamp;
155 u16 rs_datalen;
156 u8 rs_status;
157 u8 rs_phyerr;
158 int8_t rs_rssi;
159 int8_t rs_rssi_ctl0;
160 int8_t rs_rssi_ctl1;
161 int8_t rs_rssi_ctl2;
162 int8_t rs_rssi_ext0;
163 int8_t rs_rssi_ext1;
164 int8_t rs_rssi_ext2;
165 u8 rs_keyix;
166 u8 rs_rate;
167 u8 rs_antenna;
168 u8 rs_more;
169 u8 rs_isaggr;
170 u8 rs_moreaggr;
171 u8 rs_num_delims;
172 u8 rs_flags;
173 u8 rs_dummy;
174 u32 evm0;
175 u32 evm1;
176 u32 evm2;
177};
178
153#define ATH9K_RXERR_CRC 0x01 179#define ATH9K_RXERR_CRC 0x01
154#define ATH9K_RXERR_PHY 0x02 180#define ATH9K_RXERR_PHY 0x02
155#define ATH9K_RXERR_FIFO 0x04 181#define ATH9K_RXERR_FIFO 0x04
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index f4818e4fa4b0..36083dde863d 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -110,8 +110,8 @@ struct ath_rate_table {
110 int rate_cnt; 110 int rate_cnt;
111 int mcs_start; 111 int mcs_start;
112 struct { 112 struct {
113 int valid; 113 u8 valid;
114 int valid_single_stream; 114 u8 valid_single_stream;
115 u8 phy; 115 u8 phy;
116 u32 ratekbps; 116 u32 ratekbps;
117 u32 user_ratekbps; 117 u32 user_ratekbps;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 72cfa8ebd9ae..198e41dd38a6 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -940,6 +940,7 @@ enum {
940#define AR928X_NUM_GPIO 10 940#define AR928X_NUM_GPIO 10
941#define AR9285_NUM_GPIO 12 941#define AR9285_NUM_GPIO 12
942#define AR9287_NUM_GPIO 11 942#define AR9287_NUM_GPIO 11
943#define AR9271_NUM_GPIO 16
943 944
944#define AR_GPIO_IN_OUT 0x4048 945#define AR_GPIO_IN_OUT 0x4048
945#define AR_GPIO_IN_VAL 0x0FFFC000 946#define AR_GPIO_IN_VAL 0x0FFFC000
@@ -950,6 +951,8 @@ enum {
950#define AR9285_GPIO_IN_VAL_S 12 951#define AR9285_GPIO_IN_VAL_S 12
951#define AR9287_GPIO_IN_VAL 0x003FF800 952#define AR9287_GPIO_IN_VAL 0x003FF800
952#define AR9287_GPIO_IN_VAL_S 11 953#define AR9287_GPIO_IN_VAL_S 11
954#define AR9271_GPIO_IN_VAL 0xFFFF0000
955#define AR9271_GPIO_IN_VAL_S 16
953 956
954#define AR_GPIO_OE_OUT 0x404c 957#define AR_GPIO_OE_OUT 0x404c
955#define AR_GPIO_OE_OUT_DRV 0x3 958#define AR_GPIO_OE_OUT_DRV 0x3
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
new file mode 100644
index 000000000000..818dea0164ec
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -0,0 +1,319 @@
1/*
2 * Copyright (c) 2010 Atheros Communications 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 "htc.h"
18
19static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
20{
21 switch (wmi_cmd) {
22 case WMI_ECHO_CMDID:
23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID:
43 return "WMI_DRAIN_TXQ_CMDID";
44 case WMI_DRAIN_TXQ_ALL_CMDID:
45 return "WMI_DRAIN_TXQ_ALL_CMDID";
46 case WMI_START_RECV_CMDID:
47 return "WMI_START_RECV_CMDID";
48 case WMI_STOP_RECV_CMDID:
49 return "WMI_STOP_RECV_CMDID";
50 case WMI_FLUSH_RECV_CMDID:
51 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID:
59 return "WMI_NODE_REMOVE_CMDID";
60 case WMI_VAP_REMOVE_CMDID:
61 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID:
69 return "WMI_REG_WRITE_CMDID";
70 case WMI_RC_STATE_CHANGE_CMDID:
71 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID";
88 }
89
90 return "Bogus";
91}
92
93struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
94{
95 struct wmi *wmi;
96
97 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
98 if (!wmi)
99 return NULL;
100
101 wmi->drv_priv = priv;
102 wmi->stopped = false;
103 mutex_init(&wmi->op_mutex);
104 init_completion(&wmi->cmd_wait);
105
106 return wmi;
107}
108
109void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
110{
111 struct wmi *wmi = priv->wmi;
112
113 mutex_lock(&wmi->op_mutex);
114 wmi->stopped = true;
115 mutex_unlock(&wmi->op_mutex);
116
117 kfree(priv->wmi);
118}
119
120void ath9k_wmi_tasklet(unsigned long data)
121{
122 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
123 struct ath_common *common = ath9k_hw_common(priv->ah);
124 struct wmi_cmd_hdr *hdr;
125 struct wmi_swba *swba_hdr;
126 enum wmi_event_id event;
127 struct sk_buff *skb;
128 void *wmi_event;
129 unsigned long flags;
130#ifdef CONFIG_ATH9K_HTC_DEBUGFS
131 u32 txrate;
132#endif
133
134 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
135 skb = priv->wmi->wmi_skb;
136 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
137
138 hdr = (struct wmi_cmd_hdr *) skb->data;
139 event = be16_to_cpu(hdr->command_id);
140 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
141
142 ath_print(common, ATH_DBG_WMI,
143 "WMI Event: 0x%x\n", event);
144
145 switch (event) {
146 case WMI_TGT_RDY_EVENTID:
147 break;
148 case WMI_SWBA_EVENTID:
149 swba_hdr = (struct wmi_swba *) wmi_event;
150 ath9k_htc_swba(priv, swba_hdr->beacon_pending);
151 break;
152 case WMI_FATAL_EVENTID:
153 break;
154 case WMI_TXTO_EVENTID:
155 break;
156 case WMI_BMISS_EVENTID:
157 break;
158 case WMI_WLAN_TXCOMP_EVENTID:
159 break;
160 case WMI_DELBA_EVENTID:
161 break;
162 case WMI_TXRATE_EVENTID:
163#ifdef CONFIG_ATH9K_HTC_DEBUGFS
164 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
165 priv->debug.txrate = be32_to_cpu(txrate);
166#endif
167 break;
168 default:
169 break;
170 }
171
172 dev_kfree_skb_any(skb);
173}
174
175static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
176{
177 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
178
179 if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
180 memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
181
182 complete(&wmi->cmd_wait);
183}
184
185static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
186 enum htc_endpoint_id epid)
187{
188 struct wmi *wmi = (struct wmi *) priv;
189 struct wmi_cmd_hdr *hdr;
190 u16 cmd_id;
191
192 if (unlikely(wmi->stopped))
193 goto free_skb;
194
195 hdr = (struct wmi_cmd_hdr *) skb->data;
196 cmd_id = be16_to_cpu(hdr->command_id);
197
198 if (cmd_id & 0x1000) {
199 spin_lock(&wmi->wmi_lock);
200 wmi->wmi_skb = skb;
201 spin_unlock(&wmi->wmi_lock);
202 tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
203 return;
204 }
205
206 /* WMI command response */
207 ath9k_wmi_rsp_callback(wmi, skb);
208
209free_skb:
210 dev_kfree_skb_any(skb);
211}
212
213static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb,
214 enum htc_endpoint_id epid, bool txok)
215{
216 dev_kfree_skb_any(skb);
217}
218
219int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
220 enum htc_endpoint_id *wmi_ctrl_epid)
221{
222 struct htc_service_connreq connect;
223 int ret;
224
225 wmi->htc = htc;
226
227 memset(&connect, 0, sizeof(connect));
228
229 connect.ep_callbacks.priv = wmi;
230 connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx;
231 connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx;
232 connect.service_id = WMI_CONTROL_SVC;
233
234 ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid);
235 if (ret)
236 return ret;
237
238 *wmi_ctrl_epid = wmi->ctrl_epid;
239
240 return 0;
241}
242
243static int ath9k_wmi_cmd_issue(struct wmi *wmi,
244 struct sk_buff *skb,
245 enum wmi_cmd_id cmd, u16 len)
246{
247 struct wmi_cmd_hdr *hdr;
248
249 hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr));
250 hdr->command_id = cpu_to_be16(cmd);
251 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
252
253 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
254}
255
256int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
257 u8 *cmd_buf, u32 cmd_len,
258 u8 *rsp_buf, u32 rsp_len,
259 u32 timeout)
260{
261 struct ath_hw *ah = wmi->drv_priv->ah;
262 struct ath_common *common = ath9k_hw_common(ah);
263 u16 headroom = sizeof(struct htc_frame_hdr) +
264 sizeof(struct wmi_cmd_hdr);
265 struct sk_buff *skb;
266 u8 *data;
267 int time_left, ret = 0;
268
269 if (!wmi)
270 return -EINVAL;
271
272 skb = dev_alloc_skb(headroom + cmd_len);
273 if (!skb)
274 return -ENOMEM;
275
276 skb_reserve(skb, headroom);
277
278 if (cmd_len != 0 && cmd_buf != NULL) {
279 data = (u8 *) skb_put(skb, cmd_len);
280 memcpy(data, cmd_buf, cmd_len);
281 }
282
283 mutex_lock(&wmi->op_mutex);
284
285 /* check if wmi stopped flag is set */
286 if (unlikely(wmi->stopped)) {
287 ret = -EPROTO;
288 goto out;
289 }
290
291 /* record the rsp buffer and length */
292 wmi->cmd_rsp_buf = rsp_buf;
293 wmi->cmd_rsp_len = rsp_len;
294
295 ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
296 if (ret)
297 goto out;
298
299 time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
300 if (!time_left) {
301 ath_print(common, ATH_DBG_WMI,
302 "Timeout waiting for WMI command: %s\n",
303 wmi_cmd_to_name(cmd_id));
304 mutex_unlock(&wmi->op_mutex);
305 return -ETIMEDOUT;
306 }
307
308 mutex_unlock(&wmi->op_mutex);
309
310 return 0;
311
312out:
313 ath_print(common, ATH_DBG_WMI,
314 "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
315 mutex_unlock(&wmi->op_mutex);
316 dev_kfree_skb_any(skb);
317
318 return ret;
319}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
new file mode 100644
index 000000000000..39ef926f27c2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef WMI_H
18#define WMI_H
19
20
21struct wmi_event_txrate {
22 u32 txrate;
23 struct {
24 u8 rssi_thresh;
25 u8 per;
26 } rc_stats;
27} __packed;
28
29struct wmi_cmd_hdr {
30 u16 command_id;
31 u16 seq_no;
32} __packed;
33
34struct wmi_swba {
35 u8 beacon_pending;
36} __packed;
37
38enum wmi_cmd_id {
39 WMI_ECHO_CMDID = 0x0001,
40 WMI_ACCESS_MEMORY_CMDID,
41
42 /* Commands to Target */
43 WMI_DISABLE_INTR_CMDID,
44 WMI_ENABLE_INTR_CMDID,
45 WMI_RX_LINK_CMDID,
46 WMI_ATH_INIT_CMDID,
47 WMI_ABORT_TXQ_CMDID,
48 WMI_STOP_TX_DMA_CMDID,
49 WMI_STOP_DMA_RECV_CMDID,
50 WMI_ABORT_TX_DMA_CMDID,
51 WMI_DRAIN_TXQ_CMDID,
52 WMI_DRAIN_TXQ_ALL_CMDID,
53 WMI_START_RECV_CMDID,
54 WMI_STOP_RECV_CMDID,
55 WMI_FLUSH_RECV_CMDID,
56 WMI_SET_MODE_CMDID,
57 WMI_RESET_CMDID,
58 WMI_NODE_CREATE_CMDID,
59 WMI_NODE_REMOVE_CMDID,
60 WMI_VAP_REMOVE_CMDID,
61 WMI_VAP_CREATE_CMDID,
62 WMI_BEACON_UPDATE_CMDID,
63 WMI_REG_READ_CMDID,
64 WMI_REG_WRITE_CMDID,
65 WMI_RC_STATE_CHANGE_CMDID,
66 WMI_RC_RATE_UPDATE_CMDID,
67 WMI_DEBUG_INFO_CMDID,
68 WMI_HOST_ATTACH,
69 WMI_TARGET_IC_UPDATE_CMDID,
70 WMI_TGT_STATS_CMDID,
71 WMI_TX_AGGR_ENABLE_CMDID,
72 WMI_TGT_DETACH_CMDID,
73 WMI_TGT_TXQ_ENABLE_CMDID,
74};
75
76enum wmi_event_id {
77 WMI_TGT_RDY_EVENTID = 0x1001,
78 WMI_SWBA_EVENTID,
79 WMI_FATAL_EVENTID,
80 WMI_TXTO_EVENTID,
81 WMI_BMISS_EVENTID,
82 WMI_WLAN_TXCOMP_EVENTID,
83 WMI_DELBA_EVENTID,
84 WMI_TXRATE_EVENTID,
85};
86
87struct wmi {
88 struct ath9k_htc_priv *drv_priv;
89 struct htc_target *htc;
90 enum htc_endpoint_id ctrl_epid;
91 struct mutex op_mutex;
92 struct completion cmd_wait;
93 u16 tx_seq_id;
94 u8 *cmd_rsp_buf;
95 u32 cmd_rsp_len;
96 bool stopped;
97
98 struct sk_buff *wmi_skb;
99 spinlock_t wmi_lock;
100};
101
102struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
103void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
104int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
105 enum htc_endpoint_id *wmi_ctrl_epid);
106int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
107 u8 *cmd_buf, u32 cmd_len,
108 u8 *rsp_buf, u32 rsp_len,
109 u32 timeout);
110void ath9k_wmi_tasklet(unsigned long data);
111
112#define WMI_CMD(_wmi_cmd) \
113 do { \
114 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \
115 (u8 *) &cmd_rsp, \
116 sizeof(cmd_rsp), HZ); \
117 } while (0)
118
119#define WMI_CMD_BUF(_wmi_cmd, _buf) \
120 do { \
121 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \
122 (u8 *) _buf, sizeof(*_buf), \
123 &cmd_rsp, sizeof(cmd_rsp), HZ); \
124 } while (0)
125
126#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 8263633c003c..873bf526e11f 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -59,6 +59,7 @@ enum ATH_DEBUG {
59 ATH_DBG_PS = 0x00000800, 59 ATH_DBG_PS = 0x00000800,
60 ATH_DBG_HWTIMER = 0x00001000, 60 ATH_DBG_HWTIMER = 0x00001000,
61 ATH_DBG_BTCOEX = 0x00002000, 61 ATH_DBG_BTCOEX = 0x00002000,
62 ATH_DBG_WMI = 0x00004000,
62 ATH_DBG_ANY = 0xffffffff 63 ATH_DBG_ANY = 0xffffffff
63}; 64};
64 65
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 1521b1e78d21..14cf3bd7ea51 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4348,11 +4348,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4348 b43_set_phytxctl_defaults(dev); 4348 b43_set_phytxctl_defaults(dev);
4349 4349
4350 /* Minimum Contention Window */ 4350 /* Minimum Contention Window */
4351 if (phy->type == B43_PHYTYPE_B) { 4351 if (phy->type == B43_PHYTYPE_B)
4352 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F); 4352 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F);
4353 } else { 4353 else
4354 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF); 4354 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF);
4355 }
4356 /* Maximum Contention Window */ 4355 /* Maximum Contention Window */
4357 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4356 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4358 4357
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 6dc0733df46b..cb3ba134865e 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -9995,49 +9995,48 @@ static int ipw_wx_sw_reset(struct net_device *dev,
9995} 9995}
9996 9996
9997/* Rebase the WE IOCTLs to zero for the handler array */ 9997/* Rebase the WE IOCTLs to zero for the handler array */
9998#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
9999static iw_handler ipw_wx_handlers[] = { 9998static iw_handler ipw_wx_handlers[] = {
10000 IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname, 9999 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
10001 IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq, 10000 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),
10002 IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq, 10001 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),
10003 IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode, 10002 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),
10004 IW_IOCTL(SIOCGIWMODE) = ipw_wx_get_mode, 10003 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),
10005 IW_IOCTL(SIOCSIWSENS) = ipw_wx_set_sens, 10004 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),
10006 IW_IOCTL(SIOCGIWSENS) = ipw_wx_get_sens, 10005 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),
10007 IW_IOCTL(SIOCGIWRANGE) = ipw_wx_get_range, 10006 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),
10008 IW_IOCTL(SIOCSIWAP) = ipw_wx_set_wap, 10007 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),
10009 IW_IOCTL(SIOCGIWAP) = ipw_wx_get_wap, 10008 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),
10010 IW_IOCTL(SIOCSIWSCAN) = ipw_wx_set_scan, 10009 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),
10011 IW_IOCTL(SIOCGIWSCAN) = ipw_wx_get_scan, 10010 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),
10012 IW_IOCTL(SIOCSIWESSID) = ipw_wx_set_essid, 10011 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),
10013 IW_IOCTL(SIOCGIWESSID) = ipw_wx_get_essid, 10012 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),
10014 IW_IOCTL(SIOCSIWNICKN) = ipw_wx_set_nick, 10013 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),
10015 IW_IOCTL(SIOCGIWNICKN) = ipw_wx_get_nick, 10014 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),
10016 IW_IOCTL(SIOCSIWRATE) = ipw_wx_set_rate, 10015 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),
10017 IW_IOCTL(SIOCGIWRATE) = ipw_wx_get_rate, 10016 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),
10018 IW_IOCTL(SIOCSIWRTS) = ipw_wx_set_rts, 10017 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),
10019 IW_IOCTL(SIOCGIWRTS) = ipw_wx_get_rts, 10018 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),
10020 IW_IOCTL(SIOCSIWFRAG) = ipw_wx_set_frag, 10019 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),
10021 IW_IOCTL(SIOCGIWFRAG) = ipw_wx_get_frag, 10020 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),
10022 IW_IOCTL(SIOCSIWTXPOW) = ipw_wx_set_txpow, 10021 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),
10023 IW_IOCTL(SIOCGIWTXPOW) = ipw_wx_get_txpow, 10022 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),
10024 IW_IOCTL(SIOCSIWRETRY) = ipw_wx_set_retry, 10023 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),
10025 IW_IOCTL(SIOCGIWRETRY) = ipw_wx_get_retry, 10024 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),
10026 IW_IOCTL(SIOCSIWENCODE) = ipw_wx_set_encode, 10025 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),
10027 IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode, 10026 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),
10028 IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power, 10027 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),
10029 IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power, 10028 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),
10030 IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy, 10029 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
10031 IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy, 10030 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
10032 IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy, 10031 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
10033 IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy, 10032 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
10034 IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie, 10033 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),
10035 IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie, 10034 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),
10036 IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme, 10035 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),
10037 IW_IOCTL(SIOCSIWAUTH) = ipw_wx_set_auth, 10036 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),
10038 IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth, 10037 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),
10039 IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext, 10038 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),
10040 IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext, 10039 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),
10041}; 10040};
10042 10041
10043enum { 10042enum {
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 59b092eaa829..9e392896005d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -212,6 +212,9 @@ static struct iwl_lib_ops iwl1000_lib = {
212 .set_ct_kill = iwl1000_set_ct_threshold, 212 .set_ct_kill = iwl1000_set_ct_threshold,
213 }, 213 },
214 .add_bcast_station = iwl_add_bcast_station, 214 .add_bcast_station = iwl_add_bcast_station,
215 .recover_from_tx_stall = iwl_bg_monitor_recover,
216 .check_plcp_health = iwl_good_plcp_health,
217 .check_ack_health = iwl_good_ack_health,
215}; 218};
216 219
217static const struct iwl_ops iwl1000_ops = { 220static const struct iwl_ops iwl1000_ops = {
@@ -223,7 +226,7 @@ static const struct iwl_ops iwl1000_ops = {
223}; 226};
224 227
225struct iwl_cfg iwl1000_bgn_cfg = { 228struct iwl_cfg iwl1000_bgn_cfg = {
226 .name = "1000 Series BGN", 229 .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN",
227 .fw_name_pre = IWL1000_FW_PRE, 230 .fw_name_pre = IWL1000_FW_PRE,
228 .ucode_api_max = IWL1000_UCODE_API_MAX, 231 .ucode_api_max = IWL1000_UCODE_API_MAX,
229 .ucode_api_min = IWL1000_UCODE_API_MIN, 232 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -249,10 +252,11 @@ struct iwl_cfg iwl1000_bgn_cfg = {
249 .support_ct_kill_exit = true, 252 .support_ct_kill_exit = true,
250 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 253 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
251 .chain_noise_scale = 1000, 254 .chain_noise_scale = 1000,
255 .monitor_recover_period = IWL_MONITORING_PERIOD,
252}; 256};
253 257
254struct iwl_cfg iwl1000_bg_cfg = { 258struct iwl_cfg iwl1000_bg_cfg = {
255 .name = "1000 Series BG", 259 .name = "Intel(R) Centrino(R) Wireless-N 1000 BG",
256 .fw_name_pre = IWL1000_FW_PRE, 260 .fw_name_pre = IWL1000_FW_PRE,
257 .ucode_api_max = IWL1000_UCODE_API_MAX, 261 .ucode_api_max = IWL1000_UCODE_API_MAX,
258 .ucode_api_min = IWL1000_UCODE_API_MIN, 262 .ucode_api_min = IWL1000_UCODE_API_MIN,
@@ -277,6 +281,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
277 .support_ct_kill_exit = true, 281 .support_ct_kill_exit = true,
278 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, 282 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF,
279 .chain_noise_scale = 1000, 283 .chain_noise_scale = 1000,
284 .monitor_recover_period = IWL_MONITORING_PERIOD,
280}; 285};
281 286
282MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); 287MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index b588cb69536a..605aca4c78c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -329,16 +329,25 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
329 329
330} 330}
331 331
332static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 332/*
333 struct ieee80211_sta *sta, void *priv_sta) 333 * Called after adding a new station to initialize rate scaling
334 */
335void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
334{ 336{
335 struct iwl3945_rs_sta *rs_sta = priv_sta; 337 struct ieee80211_hw *hw = priv->hw;
336 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 338 struct ieee80211_conf *conf = &priv->hw->conf;
339 struct iwl3945_sta_priv *psta;
340 struct iwl3945_rs_sta *rs_sta;
341 struct ieee80211_supported_band *sband;
337 int i; 342 int i;
338 343
339 IWL_DEBUG_RATE(priv, "enter\n"); 344 IWL_DEBUG_INFO(priv, "enter \n");
345 if (sta_id == priv->hw_params.bcast_sta_id)
346 goto out;
340 347
341 spin_lock_init(&rs_sta->lock); 348 psta = (struct iwl3945_sta_priv *) sta->drv_priv;
349 rs_sta = &psta->rs_sta;
350 sband = hw->wiphy->bands[conf->channel->band];
342 351
343 rs_sta->priv = priv; 352 rs_sta->priv = priv;
344 353
@@ -351,9 +360,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
351 rs_sta->last_flush = jiffies; 360 rs_sta->last_flush = jiffies;
352 rs_sta->flush_time = IWL_RATE_FLUSH; 361 rs_sta->flush_time = IWL_RATE_FLUSH;
353 rs_sta->last_tx_packets = 0; 362 rs_sta->last_tx_packets = 0;
354 rs_sta->ibss_sta_added = 0;
355 363
356 init_timer(&rs_sta->rate_scale_flush);
357 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; 364 rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
358 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush; 365 rs_sta->rate_scale_flush.function = iwl3945_bg_rate_scale_flush;
359 366
@@ -380,8 +387,10 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
380 IWL_FIRST_OFDM_RATE; 387 IWL_FIRST_OFDM_RATE;
381 } 388 }
382 389
390out:
391 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
383 392
384 IWL_DEBUG_RATE(priv, "leave\n"); 393 IWL_DEBUG_INFO(priv, "leave\n");
385} 394}
386 395
387static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 396static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -405,6 +414,9 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
405 414
406 rs_sta = &psta->rs_sta; 415 rs_sta = &psta->rs_sta;
407 416
417 spin_lock_init(&rs_sta->lock);
418 init_timer(&rs_sta->rate_scale_flush);
419
408 IWL_DEBUG_RATE(priv, "leave\n"); 420 IWL_DEBUG_RATE(priv, "leave\n");
409 421
410 return rs_sta; 422 return rs_sta;
@@ -413,13 +425,14 @@ static void *rs_alloc_sta(void *iwl_priv, struct ieee80211_sta *sta, gfp_t gfp)
413static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta, 425static void rs_free_sta(void *iwl_priv, struct ieee80211_sta *sta,
414 void *priv_sta) 426 void *priv_sta)
415{ 427{
416 struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; 428 struct iwl3945_rs_sta *rs_sta = priv_sta;
417 struct iwl3945_rs_sta *rs_sta = &psta->rs_sta;
418 struct iwl_priv *priv __maybe_unused = rs_sta->priv;
419 429
420 IWL_DEBUG_RATE(priv, "enter\n"); 430 /*
431 * Be careful not to use any members of iwl3945_rs_sta (like trying
432 * to use iwl_priv to print out debugging) since it may not be fully
433 * initialized at this point.
434 */
421 del_timer_sync(&rs_sta->rate_scale_flush); 435 del_timer_sync(&rs_sta->rate_scale_flush);
422 IWL_DEBUG_RATE(priv, "leave\n");
423} 436}
424 437
425 438
@@ -458,6 +471,13 @@ static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband
458 return; 471 return;
459 } 472 }
460 473
474 /* Treat uninitialized rate scaling data same as non-existing. */
475 if (!rs_sta->priv) {
476 IWL_DEBUG_RATE(priv, "leave: STA priv data uninitialized!\n");
477 return;
478 }
479
480
461 rs_sta->tx_packets++; 481 rs_sta->tx_packets++;
462 482
463 scale_rate_index = first_index; 483 scale_rate_index = first_index;
@@ -625,7 +645,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
625 u32 fail_count; 645 u32 fail_count;
626 s8 scale_action = 0; 646 s8 scale_action = 0;
627 unsigned long flags; 647 unsigned long flags;
628 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
629 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0; 648 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
630 s8 max_rate_idx = -1; 649 s8 max_rate_idx = -1;
631 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 650 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
@@ -633,6 +652,12 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
633 652
634 IWL_DEBUG_RATE(priv, "enter\n"); 653 IWL_DEBUG_RATE(priv, "enter\n");
635 654
655 /* Treat uninitialized rate scaling data same as non-existing. */
656 if (rs_sta && !rs_sta->priv) {
657 IWL_DEBUG_RATE(priv, "Rate scaling information not initialized yet.\n");
658 priv_sta = NULL;
659 }
660
636 if (rate_control_send_low(sta, priv_sta, txrc)) 661 if (rate_control_send_low(sta, priv_sta, txrc))
637 return; 662 return;
638 663
@@ -650,20 +675,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
650 if (sband->band == IEEE80211_BAND_5GHZ) 675 if (sband->band == IEEE80211_BAND_5GHZ)
651 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE; 676 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
652 677
653 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
654 !rs_sta->ibss_sta_added) {
655 u8 sta_id = iwl_find_station(priv, hdr->addr1);
656
657 if (sta_id == IWL_INVALID_STATION) {
658 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
659 hdr->addr1);
660 sta_id = iwl_add_station(priv, hdr->addr1, false,
661 CMD_ASYNC, NULL);
662 }
663 if (sta_id != IWL_INVALID_STATION)
664 rs_sta->ibss_sta_added = 1;
665 }
666
667 spin_lock_irqsave(&rs_sta->lock, flags); 678 spin_lock_irqsave(&rs_sta->lock, flags);
668 679
669 /* for recent assoc, choose best rate regarding 680 /* for recent assoc, choose best rate regarding
@@ -883,12 +894,22 @@ static void iwl3945_remove_debugfs(void *priv, void *priv_sta)
883} 894}
884#endif 895#endif
885 896
897/*
898 * Initialization of rate scaling information is done by driver after
899 * the station is added. Since mac80211 calls this function before a
900 * station is added we ignore it.
901 */
902static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
903 struct ieee80211_sta *sta, void *priv_sta)
904{
905}
906
886static struct rate_control_ops rs_ops = { 907static struct rate_control_ops rs_ops = {
887 .module = NULL, 908 .module = NULL,
888 .name = RS_NAME, 909 .name = RS_NAME,
889 .tx_status = rs_tx_status, 910 .tx_status = rs_tx_status,
890 .get_rate = rs_get_rate, 911 .get_rate = rs_get_rate,
891 .rate_init = rs_rate_init, 912 .rate_init = rs_rate_init_stub,
892 .alloc = rs_alloc, 913 .alloc = rs_alloc,
893 .free = rs_free, 914 .free = rs_free,
894 .alloc_sta = rs_alloc_sta, 915 .alloc_sta = rs_alloc_sta,
@@ -899,7 +920,6 @@ static struct rate_control_ops rs_ops = {
899#endif 920#endif
900 921
901}; 922};
902
903void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) 923void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
904{ 924{
905 struct iwl_priv *priv = hw->priv; 925 struct iwl_priv *priv = hw->priv;
@@ -916,6 +936,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
916 sta = ieee80211_find_sta(priv->vif, 936 sta = ieee80211_find_sta(priv->vif,
917 priv->stations[sta_id].sta.sta.addr); 937 priv->stations[sta_id].sta.sta.addr);
918 if (!sta) { 938 if (!sta) {
939 IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
919 rcu_read_unlock(); 940 rcu_read_unlock();
920 return; 941 return;
921 } 942 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 12a42fc743d7..3b5889d8d662 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1911,6 +1911,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1911 "configuration (%d).\n", rc); 1911 "configuration (%d).\n", rc);
1912 return rc; 1912 return rc;
1913 } 1913 }
1914 iwl_clear_ucode_stations(priv, false);
1915 iwl_restore_stations(priv);
1914 } 1916 }
1915 1917
1916 IWL_DEBUG_INFO(priv, "Sending RXON\n" 1918 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -1941,7 +1943,10 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1941 1943
1942 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 1944 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
1943 1945
1944 iwl_clear_stations_table(priv); 1946 if (!new_assoc) {
1947 iwl_clear_ucode_stations(priv, false);
1948 iwl_restore_stations(priv);
1949 }
1945 1950
1946 /* If we issue a new RXON command which required a tune then we must 1951 /* If we issue a new RXON command which required a tune then we must
1947 * send a new TXPOWER command or we won't be able to Tx any frames */ 1952 * send a new TXPOWER command or we won't be able to Tx any frames */
@@ -1951,19 +1956,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1951 return rc; 1956 return rc;
1952 } 1957 }
1953 1958
1954 /* Add the broadcast address so we can send broadcast frames */
1955 priv->cfg->ops->lib->add_bcast_station(priv);
1956
1957 /* If we have set the ASSOC_MSK and we are in BSS mode then
1958 * add the IWL_AP_ID to the station rate table */
1959 if (iwl_is_associated(priv) &&
1960 (priv->iw_mode == NL80211_IFTYPE_STATION))
1961 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
1962 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
1963 IWL_ERR(priv, "Error adding AP address for transmit\n");
1964 return -EIO;
1965 }
1966
1967 /* Init the hardware's rate fallback order based on the band */ 1959 /* Init the hardware's rate fallback order based on the band */
1968 rc = iwl3945_init_hw_rate_table(priv); 1960 rc = iwl3945_init_hw_rate_table(priv);
1969 if (rc) { 1961 if (rc) {
@@ -2828,6 +2820,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2828 .led_compensation = 64, 2820 .led_compensation = 64,
2829 .broken_powersave = true, 2821 .broken_powersave = true,
2830 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2822 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2823 .monitor_recover_period = IWL_MONITORING_PERIOD,
2831}; 2824};
2832 2825
2833static struct iwl_cfg iwl3945_abg_cfg = { 2826static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2846,6 +2839,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2846 .led_compensation = 64, 2839 .led_compensation = 64,
2847 .broken_powersave = true, 2840 .broken_powersave = true,
2848 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2841 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2842 .monitor_recover_period = IWL_MONITORING_PERIOD,
2849}; 2843};
2850 2844
2851DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { 2845DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 452dfd5456c6..b89219573b91 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -95,7 +95,6 @@ struct iwl3945_rs_sta {
95 u8 tgg; 95 u8 tgg;
96 u8 flush_pending; 96 u8 flush_pending;
97 u8 start_rate; 97 u8 start_rate;
98 u8 ibss_sta_added;
99 struct timer_list rate_scale_flush; 98 struct timer_list rate_scale_flush;
100 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945]; 99 struct iwl3945_rate_scale_data win[IWL_RATE_COUNT_3945];
101#ifdef CONFIG_MAC80211_DEBUGFS 100#ifdef CONFIG_MAC80211_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 644aacfbd7df..3949133d9ee2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2187,6 +2187,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2187 .load_ucode = iwl4965_load_bsm, 2187 .load_ucode = iwl4965_load_bsm,
2188 .dump_nic_event_log = iwl_dump_nic_event_log, 2188 .dump_nic_event_log = iwl_dump_nic_event_log,
2189 .dump_nic_error_log = iwl_dump_nic_error_log, 2189 .dump_nic_error_log = iwl_dump_nic_error_log,
2190 .dump_fh = iwl_dump_fh,
2190 .set_channel_switch = iwl4965_hw_channel_switch, 2191 .set_channel_switch = iwl4965_hw_channel_switch,
2191 .apm_ops = { 2192 .apm_ops = {
2192 .init = iwl_apm_init, 2193 .init = iwl_apm_init,
@@ -2220,6 +2221,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2220 .set_ct_kill = iwl4965_set_ct_threshold, 2221 .set_ct_kill = iwl4965_set_ct_threshold,
2221 }, 2222 },
2222 .add_bcast_station = iwl_add_bcast_station, 2223 .add_bcast_station = iwl_add_bcast_station,
2224 .check_plcp_health = iwl_good_plcp_health,
2223}; 2225};
2224 2226
2225static const struct iwl_ops iwl4965_ops = { 2227static const struct iwl_ops iwl4965_ops = {
@@ -2231,7 +2233,7 @@ static const struct iwl_ops iwl4965_ops = {
2231}; 2233};
2232 2234
2233struct iwl_cfg iwl4965_agn_cfg = { 2235struct iwl_cfg iwl4965_agn_cfg = {
2234 .name = "4965AGN", 2236 .name = "Intel(R) Wireless WiFi Link 4965AGN",
2235 .fw_name_pre = IWL4965_FW_PRE, 2237 .fw_name_pre = IWL4965_FW_PRE,
2236 .ucode_api_max = IWL4965_UCODE_API_MAX, 2238 .ucode_api_max = IWL4965_UCODE_API_MAX,
2237 .ucode_api_min = IWL4965_UCODE_API_MIN, 2239 .ucode_api_min = IWL4965_UCODE_API_MIN,
@@ -2254,6 +2256,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
2254 .led_compensation = 61, 2256 .led_compensation = 61,
2255 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, 2257 .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2256 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 2258 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2259 .monitor_recover_period = IWL_MONITORING_PERIOD,
2257}; 2260};
2258 2261
2259/* Module firmware */ 2262/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 37e1e77f513d..2267cad49cbf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -544,7 +544,6 @@ void iwl5000_init_alive_start(struct iwl_priv *priv)
544 goto restart; 544 goto restart;
545 } 545 }
546 546
547 iwl_clear_stations_table(priv);
548 ret = priv->cfg->ops->lib->alive_notify(priv); 547 ret = priv->cfg->ops->lib->alive_notify(priv);
549 if (ret) { 548 if (ret) {
550 IWL_WARN(priv, 549 IWL_WARN(priv,
@@ -1500,6 +1499,9 @@ struct iwl_lib_ops iwl5000_lib = {
1500 .set_ct_kill = iwl5000_set_ct_threshold, 1499 .set_ct_kill = iwl5000_set_ct_threshold,
1501 }, 1500 },
1502 .add_bcast_station = iwl_add_bcast_station, 1501 .add_bcast_station = iwl_add_bcast_station,
1502 .recover_from_tx_stall = iwl_bg_monitor_recover,
1503 .check_plcp_health = iwl_good_plcp_health,
1504 .check_ack_health = iwl_good_ack_health,
1503}; 1505};
1504 1506
1505static struct iwl_lib_ops iwl5150_lib = { 1507static struct iwl_lib_ops iwl5150_lib = {
@@ -1554,6 +1556,9 @@ static struct iwl_lib_ops iwl5150_lib = {
1554 .set_ct_kill = iwl5150_set_ct_threshold, 1556 .set_ct_kill = iwl5150_set_ct_threshold,
1555 }, 1557 },
1556 .add_bcast_station = iwl_add_bcast_station, 1558 .add_bcast_station = iwl_add_bcast_station,
1559 .recover_from_tx_stall = iwl_bg_monitor_recover,
1560 .check_plcp_health = iwl_good_plcp_health,
1561 .check_ack_health = iwl_good_ack_health,
1557}; 1562};
1558 1563
1559static const struct iwl_ops iwl5000_ops = { 1564static const struct iwl_ops iwl5000_ops = {
@@ -1580,7 +1585,7 @@ struct iwl_mod_params iwl50_mod_params = {
1580 1585
1581 1586
1582struct iwl_cfg iwl5300_agn_cfg = { 1587struct iwl_cfg iwl5300_agn_cfg = {
1583 .name = "5300AGN", 1588 .name = "Intel(R) Ultimate N WiFi Link 5300 AGN",
1584 .fw_name_pre = IWL5000_FW_PRE, 1589 .fw_name_pre = IWL5000_FW_PRE,
1585 .ucode_api_max = IWL5000_UCODE_API_MAX, 1590 .ucode_api_max = IWL5000_UCODE_API_MAX,
1586 .ucode_api_min = IWL5000_UCODE_API_MIN, 1591 .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1603,10 +1608,11 @@ struct iwl_cfg iwl5300_agn_cfg = {
1603 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1608 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1604 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1609 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1605 .chain_noise_scale = 1000, 1610 .chain_noise_scale = 1000,
1611 .monitor_recover_period = IWL_MONITORING_PERIOD,
1606}; 1612};
1607 1613
1608struct iwl_cfg iwl5100_bgn_cfg = { 1614struct iwl_cfg iwl5100_bgn_cfg = {
1609 .name = "5100BGN", 1615 .name = "Intel(R) WiFi Link 5100 BGN",
1610 .fw_name_pre = IWL5000_FW_PRE, 1616 .fw_name_pre = IWL5000_FW_PRE,
1611 .ucode_api_max = IWL5000_UCODE_API_MAX, 1617 .ucode_api_max = IWL5000_UCODE_API_MAX,
1612 .ucode_api_min = IWL5000_UCODE_API_MIN, 1618 .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1629,10 +1635,11 @@ struct iwl_cfg iwl5100_bgn_cfg = {
1629 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1635 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1630 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1636 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1631 .chain_noise_scale = 1000, 1637 .chain_noise_scale = 1000,
1638 .monitor_recover_period = IWL_MONITORING_PERIOD,
1632}; 1639};
1633 1640
1634struct iwl_cfg iwl5100_abg_cfg = { 1641struct iwl_cfg iwl5100_abg_cfg = {
1635 .name = "5100ABG", 1642 .name = "Intel(R) WiFi Link 5100 ABG",
1636 .fw_name_pre = IWL5000_FW_PRE, 1643 .fw_name_pre = IWL5000_FW_PRE,
1637 .ucode_api_max = IWL5000_UCODE_API_MAX, 1644 .ucode_api_max = IWL5000_UCODE_API_MAX,
1638 .ucode_api_min = IWL5000_UCODE_API_MIN, 1645 .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1653,10 +1660,11 @@ struct iwl_cfg iwl5100_abg_cfg = {
1653 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1660 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1654 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1661 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1655 .chain_noise_scale = 1000, 1662 .chain_noise_scale = 1000,
1663 .monitor_recover_period = IWL_MONITORING_PERIOD,
1656}; 1664};
1657 1665
1658struct iwl_cfg iwl5100_agn_cfg = { 1666struct iwl_cfg iwl5100_agn_cfg = {
1659 .name = "5100AGN", 1667 .name = "Intel(R) WiFi Link 5100 AGN",
1660 .fw_name_pre = IWL5000_FW_PRE, 1668 .fw_name_pre = IWL5000_FW_PRE,
1661 .ucode_api_max = IWL5000_UCODE_API_MAX, 1669 .ucode_api_max = IWL5000_UCODE_API_MAX,
1662 .ucode_api_min = IWL5000_UCODE_API_MIN, 1670 .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1679,10 +1687,11 @@ struct iwl_cfg iwl5100_agn_cfg = {
1679 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1687 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1680 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1688 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1681 .chain_noise_scale = 1000, 1689 .chain_noise_scale = 1000,
1690 .monitor_recover_period = IWL_MONITORING_PERIOD,
1682}; 1691};
1683 1692
1684struct iwl_cfg iwl5350_agn_cfg = { 1693struct iwl_cfg iwl5350_agn_cfg = {
1685 .name = "5350AGN", 1694 .name = "Intel(R) WiMAX/WiFi Link 5350 AGN",
1686 .fw_name_pre = IWL5000_FW_PRE, 1695 .fw_name_pre = IWL5000_FW_PRE,
1687 .ucode_api_max = IWL5000_UCODE_API_MAX, 1696 .ucode_api_max = IWL5000_UCODE_API_MAX,
1688 .ucode_api_min = IWL5000_UCODE_API_MIN, 1697 .ucode_api_min = IWL5000_UCODE_API_MIN,
@@ -1705,10 +1714,11 @@ struct iwl_cfg iwl5350_agn_cfg = {
1705 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1714 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1706 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1715 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1707 .chain_noise_scale = 1000, 1716 .chain_noise_scale = 1000,
1717 .monitor_recover_period = IWL_MONITORING_PERIOD,
1708}; 1718};
1709 1719
1710struct iwl_cfg iwl5150_agn_cfg = { 1720struct iwl_cfg iwl5150_agn_cfg = {
1711 .name = "5150AGN", 1721 .name = "Intel(R) WiMAX/WiFi Link 5150 AGN",
1712 .fw_name_pre = IWL5150_FW_PRE, 1722 .fw_name_pre = IWL5150_FW_PRE,
1713 .ucode_api_max = IWL5150_UCODE_API_MAX, 1723 .ucode_api_max = IWL5150_UCODE_API_MAX,
1714 .ucode_api_min = IWL5150_UCODE_API_MIN, 1724 .ucode_api_min = IWL5150_UCODE_API_MIN,
@@ -1731,10 +1741,11 @@ struct iwl_cfg iwl5150_agn_cfg = {
1731 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1741 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1732 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1742 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1733 .chain_noise_scale = 1000, 1743 .chain_noise_scale = 1000,
1744 .monitor_recover_period = IWL_MONITORING_PERIOD,
1734}; 1745};
1735 1746
1736struct iwl_cfg iwl5150_abg_cfg = { 1747struct iwl_cfg iwl5150_abg_cfg = {
1737 .name = "5150ABG", 1748 .name = "Intel(R) WiMAX/WiFi Link 5150 ABG",
1738 .fw_name_pre = IWL5150_FW_PRE, 1749 .fw_name_pre = IWL5150_FW_PRE,
1739 .ucode_api_max = IWL5150_UCODE_API_MAX, 1750 .ucode_api_max = IWL5150_UCODE_API_MAX,
1740 .ucode_api_min = IWL5150_UCODE_API_MIN, 1751 .ucode_api_min = IWL5150_UCODE_API_MIN,
@@ -1755,6 +1766,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
1755 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, 1766 .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
1756 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, 1767 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
1757 .chain_noise_scale = 1000, 1768 .chain_noise_scale = 1000,
1769 .monitor_recover_period = IWL_MONITORING_PERIOD,
1758}; 1770};
1759 1771
1760MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1772MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 4b7bc008220f..d75799946a7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -278,6 +278,9 @@ static struct iwl_lib_ops iwl6000_lib = {
278 .set_ct_kill = iwl6000_set_ct_threshold, 278 .set_ct_kill = iwl6000_set_ct_threshold,
279 }, 279 },
280 .add_bcast_station = iwl_add_bcast_station, 280 .add_bcast_station = iwl_add_bcast_station,
281 .recover_from_tx_stall = iwl_bg_monitor_recover,
282 .check_plcp_health = iwl_good_plcp_health,
283 .check_ack_health = iwl_good_ack_health,
281}; 284};
282 285
283static const struct iwl_ops iwl6000_ops = { 286static const struct iwl_ops iwl6000_ops = {
@@ -343,6 +346,9 @@ static struct iwl_lib_ops iwl6050_lib = {
343 .set_calib_version = iwl6050_set_calib_version, 346 .set_calib_version = iwl6050_set_calib_version,
344 }, 347 },
345 .add_bcast_station = iwl_add_bcast_station, 348 .add_bcast_station = iwl_add_bcast_station,
349 .recover_from_tx_stall = iwl_bg_monitor_recover,
350 .check_plcp_health = iwl_good_plcp_health,
351 .check_ack_health = iwl_good_ack_health,
346}; 352};
347 353
348static const struct iwl_ops iwl6050_ops = { 354static const struct iwl_ops iwl6050_ops = {
@@ -357,7 +363,7 @@ static const struct iwl_ops iwl6050_ops = {
357 * "i": Internal configuration, use internal Power Amplifier 363 * "i": Internal configuration, use internal Power Amplifier
358 */ 364 */
359struct iwl_cfg iwl6000i_2agn_cfg = { 365struct iwl_cfg iwl6000i_2agn_cfg = {
360 .name = "6000 Series 2x2 AGN", 366 .name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
361 .fw_name_pre = IWL6000_FW_PRE, 367 .fw_name_pre = IWL6000_FW_PRE,
362 .ucode_api_max = IWL6000_UCODE_API_MAX, 368 .ucode_api_max = IWL6000_UCODE_API_MAX,
363 .ucode_api_min = IWL6000_UCODE_API_MIN, 369 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -386,10 +392,11 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
386 .support_ct_kill_exit = true, 392 .support_ct_kill_exit = true,
387 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 393 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
388 .chain_noise_scale = 1000, 394 .chain_noise_scale = 1000,
395 .monitor_recover_period = IWL_MONITORING_PERIOD,
389}; 396};
390 397
391struct iwl_cfg iwl6000i_2abg_cfg = { 398struct iwl_cfg iwl6000i_2abg_cfg = {
392 .name = "6000 Series 2x2 ABG", 399 .name = "Intel(R) Centrino(R) Advanced-N 6200 ABG",
393 .fw_name_pre = IWL6000_FW_PRE, 400 .fw_name_pre = IWL6000_FW_PRE,
394 .ucode_api_max = IWL6000_UCODE_API_MAX, 401 .ucode_api_max = IWL6000_UCODE_API_MAX,
395 .ucode_api_min = IWL6000_UCODE_API_MIN, 402 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -417,10 +424,11 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
417 .support_ct_kill_exit = true, 424 .support_ct_kill_exit = true,
418 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 425 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
419 .chain_noise_scale = 1000, 426 .chain_noise_scale = 1000,
427 .monitor_recover_period = IWL_MONITORING_PERIOD,
420}; 428};
421 429
422struct iwl_cfg iwl6000i_2bg_cfg = { 430struct iwl_cfg iwl6000i_2bg_cfg = {
423 .name = "6000 Series 2x2 BG", 431 .name = "Intel(R) Centrino(R) Advanced-N 6200 BG",
424 .fw_name_pre = IWL6000_FW_PRE, 432 .fw_name_pre = IWL6000_FW_PRE,
425 .ucode_api_max = IWL6000_UCODE_API_MAX, 433 .ucode_api_max = IWL6000_UCODE_API_MAX,
426 .ucode_api_min = IWL6000_UCODE_API_MIN, 434 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -448,10 +456,11 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
448 .support_ct_kill_exit = true, 456 .support_ct_kill_exit = true,
449 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 457 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
450 .chain_noise_scale = 1000, 458 .chain_noise_scale = 1000,
459 .monitor_recover_period = IWL_MONITORING_PERIOD,
451}; 460};
452 461
453struct iwl_cfg iwl6050_2agn_cfg = { 462struct iwl_cfg iwl6050_2agn_cfg = {
454 .name = "6050 Series 2x2 AGN", 463 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 AGN",
455 .fw_name_pre = IWL6050_FW_PRE, 464 .fw_name_pre = IWL6050_FW_PRE,
456 .ucode_api_max = IWL6050_UCODE_API_MAX, 465 .ucode_api_max = IWL6050_UCODE_API_MAX,
457 .ucode_api_min = IWL6050_UCODE_API_MIN, 466 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -480,10 +489,11 @@ struct iwl_cfg iwl6050_2agn_cfg = {
480 .support_ct_kill_exit = true, 489 .support_ct_kill_exit = true,
481 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 490 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
482 .chain_noise_scale = 1500, 491 .chain_noise_scale = 1500,
492 .monitor_recover_period = IWL_MONITORING_PERIOD,
483}; 493};
484 494
485struct iwl_cfg iwl6050_2abg_cfg = { 495struct iwl_cfg iwl6050_2abg_cfg = {
486 .name = "6050 Series 2x2 ABG", 496 .name = "Intel(R) Centrino(R) Advanced-N + WiMAX 6250 ABG",
487 .fw_name_pre = IWL6050_FW_PRE, 497 .fw_name_pre = IWL6050_FW_PRE,
488 .ucode_api_max = IWL6050_UCODE_API_MAX, 498 .ucode_api_max = IWL6050_UCODE_API_MAX,
489 .ucode_api_min = IWL6050_UCODE_API_MIN, 499 .ucode_api_min = IWL6050_UCODE_API_MIN,
@@ -511,10 +521,11 @@ struct iwl_cfg iwl6050_2abg_cfg = {
511 .support_ct_kill_exit = true, 521 .support_ct_kill_exit = true,
512 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 522 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
513 .chain_noise_scale = 1500, 523 .chain_noise_scale = 1500,
524 .monitor_recover_period = IWL_MONITORING_PERIOD,
514}; 525};
515 526
516struct iwl_cfg iwl6000_3agn_cfg = { 527struct iwl_cfg iwl6000_3agn_cfg = {
517 .name = "6000 Series 3x3 AGN", 528 .name = "Intel(R) Centrino(R) Ultimate-N 6300 AGN",
518 .fw_name_pre = IWL6000_FW_PRE, 529 .fw_name_pre = IWL6000_FW_PRE,
519 .ucode_api_max = IWL6000_UCODE_API_MAX, 530 .ucode_api_max = IWL6000_UCODE_API_MAX,
520 .ucode_api_min = IWL6000_UCODE_API_MIN, 531 .ucode_api_min = IWL6000_UCODE_API_MIN,
@@ -543,6 +554,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
543 .support_ct_kill_exit = true, 554 .support_ct_kill_exit = true,
544 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, 555 .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
545 .chain_noise_scale = 1000, 556 .chain_noise_scale = 1000,
557 .monitor_recover_period = IWL_MONITORING_PERIOD,
546}; 558};
547 559
548MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 560MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 84271cc62afa..5155b1a027eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -769,6 +769,15 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
769 769
770 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); 770 IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
771 771
772 /* Treat uninitialized rate scaling data same as non-existing. */
773 if (!lq_sta) {
774 IWL_DEBUG_RATE(priv, "Station rate scaling not created yet.\n");
775 return;
776 } else if (!lq_sta->drv) {
777 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
778 return;
779 }
780
772 if (!ieee80211_is_data(hdr->frame_control) || 781 if (!ieee80211_is_data(hdr->frame_control) ||
773 info->flags & IEEE80211_TX_CTL_NO_ACK) 782 info->flags & IEEE80211_TX_CTL_NO_ACK)
774 return; 783 return;
@@ -778,10 +787,6 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
778 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 787 !(info->flags & IEEE80211_TX_STAT_AMPDU))
779 return; 788 return;
780 789
781 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
782 !lq_sta->ibss_sta_added)
783 return;
784
785 /* 790 /*
786 * Ignore this Tx frame response if its initial rate doesn't match 791 * Ignore this Tx frame response if its initial rate doesn't match
787 * that of latest Link Quality command. There may be stragglers 792 * that of latest Link Quality command. There may be stragglers
@@ -827,7 +832,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
827 lq_sta->missed_rate_counter++; 832 lq_sta->missed_rate_counter++;
828 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { 833 if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) {
829 lq_sta->missed_rate_counter = 0; 834 lq_sta->missed_rate_counter = 0;
830 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 835 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
831 } 836 }
832 /* Regardless, ignore this status info for outdated rate */ 837 /* Regardless, ignore this status info for outdated rate */
833 return; 838 return;
@@ -1915,7 +1920,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
1915 /* Update uCode's rate table. */ 1920 /* Update uCode's rate table. */
1916 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 1921 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
1917 rs_fill_link_cmd(priv, lq_sta, rate); 1922 rs_fill_link_cmd(priv, lq_sta, rate);
1918 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1923 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
1919 1924
1920 return rate; 1925 return rate;
1921} 1926}
@@ -2291,7 +2296,7 @@ lq_update:
2291 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", 2296 IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n",
2292 tbl->current_rate, index); 2297 tbl->current_rate, index);
2293 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); 2298 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
2294 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2299 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false);
2295 } else 2300 } else
2296 done_search = 1; 2301 done_search = 1;
2297 } 2302 }
@@ -2340,7 +2345,20 @@ out:
2340 return; 2345 return;
2341} 2346}
2342 2347
2343 2348/**
2349 * rs_initialize_lq - Initialize a station's hardware rate table
2350 *
2351 * The uCode's station table contains a table of fallback rates
2352 * for automatic fallback during transmission.
2353 *
2354 * NOTE: This sets up a default set of values. These will be replaced later
2355 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
2356 * rc80211_simple.
2357 *
2358 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
2359 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
2360 * which requires station table entry to exist).
2361 */
2344static void rs_initialize_lq(struct iwl_priv *priv, 2362static void rs_initialize_lq(struct iwl_priv *priv,
2345 struct ieee80211_conf *conf, 2363 struct ieee80211_conf *conf,
2346 struct ieee80211_sta *sta, 2364 struct ieee80211_sta *sta,
@@ -2359,10 +2377,6 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2359 2377
2360 i = lq_sta->last_txrate_idx; 2378 i = lq_sta->last_txrate_idx;
2361 2379
2362 if ((lq_sta->lq.sta_id == 0xff) &&
2363 (priv->iw_mode == NL80211_IFTYPE_ADHOC))
2364 goto out;
2365
2366 valid_tx_ant = priv->hw_params.valid_tx_ant; 2380 valid_tx_ant = priv->hw_params.valid_tx_ant;
2367 2381
2368 if (!lq_sta->search_better_tbl) 2382 if (!lq_sta->search_better_tbl)
@@ -2390,7 +2404,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2390 tbl->current_rate = rate; 2404 tbl->current_rate = rate;
2391 rs_set_expected_tpt_table(lq_sta, tbl); 2405 rs_set_expected_tpt_table(lq_sta, tbl);
2392 rs_fill_link_cmd(NULL, lq_sta, rate); 2406 rs_fill_link_cmd(NULL, lq_sta, rate);
2393 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2407 priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
2408 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true);
2394 out: 2409 out:
2395 return; 2410 return;
2396} 2411}
@@ -2402,9 +2417,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2402 struct sk_buff *skb = txrc->skb; 2417 struct sk_buff *skb = txrc->skb;
2403 struct ieee80211_supported_band *sband = txrc->sband; 2418 struct ieee80211_supported_band *sband = txrc->sband;
2404 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2419 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2405 struct ieee80211_conf *conf = &priv->hw->conf;
2406 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2407 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2408 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2420 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2409 struct iwl_lq_sta *lq_sta = priv_sta; 2421 struct iwl_lq_sta *lq_sta = priv_sta;
2410 int rate_idx; 2422 int rate_idx;
@@ -2422,30 +2434,18 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2422 lq_sta->max_rate_idx = -1; 2434 lq_sta->max_rate_idx = -1;
2423 } 2435 }
2424 2436
2437 /* Treat uninitialized rate scaling data same as non-existing. */
2438 if (lq_sta && !lq_sta->drv) {
2439 IWL_DEBUG_RATE(priv, "Rate scaling not initialized yet.\n");
2440 priv_sta = NULL;
2441 }
2442
2425 /* Send management frames and NO_ACK data using lowest rate. */ 2443 /* Send management frames and NO_ACK data using lowest rate. */
2426 if (rate_control_send_low(sta, priv_sta, txrc)) 2444 if (rate_control_send_low(sta, priv_sta, txrc))
2427 return; 2445 return;
2428 2446
2429 rate_idx = lq_sta->last_txrate_idx; 2447 rate_idx = lq_sta->last_txrate_idx;
2430 2448
2431 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
2432 !lq_sta->ibss_sta_added) {
2433 u8 sta_id = iwl_find_station(priv, hdr->addr1);
2434
2435 if (sta_id == IWL_INVALID_STATION) {
2436 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2437 hdr->addr1);
2438 sta_id = iwl_add_station(priv, hdr->addr1,
2439 false, CMD_ASYNC, ht_cap);
2440 }
2441 if ((sta_id != IWL_INVALID_STATION)) {
2442 lq_sta->lq.sta_id = sta_id;
2443 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2444 lq_sta->ibss_sta_added = 1;
2445 rs_initialize_lq(priv, conf, sta, lq_sta);
2446 }
2447 }
2448
2449 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { 2449 if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
2450 rate_idx -= IWL_FIRST_OFDM_RATE; 2450 rate_idx -= IWL_FIRST_OFDM_RATE;
2451 /* 6M and 9M shared same MCS index */ 2451 /* 6M and 9M shared same MCS index */
@@ -2495,16 +2495,25 @@ static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
2495 return lq_sta; 2495 return lq_sta;
2496} 2496}
2497 2497
2498static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, 2498/*
2499 struct ieee80211_sta *sta, void *priv_sta) 2499 * Called after adding a new station to initialize rate scaling
2500 */
2501void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_id)
2500{ 2502{
2501 int i, j; 2503 int i, j;
2502 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2504 struct ieee80211_hw *hw = priv->hw;
2503 struct ieee80211_conf *conf = &priv->hw->conf; 2505 struct ieee80211_conf *conf = &priv->hw->conf;
2504 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; 2506 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2505 struct iwl_lq_sta *lq_sta = priv_sta; 2507 struct iwl_station_priv *sta_priv;
2508 struct iwl_lq_sta *lq_sta;
2509 struct ieee80211_supported_band *sband;
2510
2511 sta_priv = (struct iwl_station_priv *) sta->drv_priv;
2512 lq_sta = &sta_priv->lq_sta;
2513 sband = hw->wiphy->bands[conf->channel->band];
2514
2506 2515
2507 lq_sta->lq.sta_id = 0xff; 2516 lq_sta->lq.sta_id = sta_id;
2508 2517
2509 for (j = 0; j < LQ_SIZE; j++) 2518 for (j = 0; j < LQ_SIZE; j++)
2510 for (i = 0; i < IWL_RATE_COUNT; i++) 2519 for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -2516,33 +2525,13 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2516 for (i = 0; i < IWL_RATE_COUNT; i++) 2525 for (i = 0; i < IWL_RATE_COUNT; i++)
2517 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2526 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2518 2527
2519 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init ***\n"); 2528 IWL_DEBUG_RATE(priv, "LQ: *** rate scale station global init for station %d ***\n",
2529 sta_id);
2520 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2530 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2521 * the lowest or the highest rate.. Could consider using RSSI from 2531 * the lowest or the highest rate.. Could consider using RSSI from
2522 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2532 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2523 * after assoc.. */ 2533 * after assoc.. */
2524 2534
2525 lq_sta->ibss_sta_added = 0;
2526 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2527 u8 sta_id = iwl_find_station(priv,
2528 sta->addr);
2529
2530 /* for IBSS the call are from tasklet */
2531 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2532
2533 if (sta_id == IWL_INVALID_STATION) {
2534 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2535 sta_id = iwl_add_station(priv, sta->addr, false,
2536 CMD_ASYNC, ht_cap);
2537 }
2538 if ((sta_id != IWL_INVALID_STATION)) {
2539 lq_sta->lq.sta_id = sta_id;
2540 lq_sta->lq.rs_table[0].rate_n_flags = 0;
2541 }
2542 /* FIXME: this is w/a remove it later */
2543 priv->assoc_station_added = 1;
2544 }
2545
2546 lq_sta->is_dup = 0; 2535 lq_sta->is_dup = 0;
2547 lq_sta->max_rate_idx = -1; 2536 lq_sta->max_rate_idx = -1;
2548 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2537 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
@@ -2795,7 +2784,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2795 2784
2796 if (lq_sta->dbg_fixed_rate) { 2785 if (lq_sta->dbg_fixed_rate) {
2797 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); 2786 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
2798 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2787 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
2799 } 2788 }
2800 2789
2801 return count; 2790 return count;
@@ -2992,12 +2981,21 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
2992} 2981}
2993#endif 2982#endif
2994 2983
2984/*
2985 * Initialization of rate scaling information is done by driver after
2986 * the station is added. Since mac80211 calls this function before a
2987 * station is added we ignore it.
2988 */
2989static void rs_rate_init_stub(void *priv_r, struct ieee80211_supported_band *sband,
2990 struct ieee80211_sta *sta, void *priv_sta)
2991{
2992}
2995static struct rate_control_ops rs_ops = { 2993static struct rate_control_ops rs_ops = {
2996 .module = NULL, 2994 .module = NULL,
2997 .name = RS_NAME, 2995 .name = RS_NAME,
2998 .tx_status = rs_tx_status, 2996 .tx_status = rs_tx_status,
2999 .get_rate = rs_get_rate, 2997 .get_rate = rs_get_rate,
3000 .rate_init = rs_rate_init, 2998 .rate_init = rs_rate_init_stub,
3001 .alloc = rs_alloc, 2999 .alloc = rs_alloc,
3002 .free = rs_free, 3000 .free = rs_free,
3003 .alloc_sta = rs_alloc_sta, 3001 .alloc_sta = rs_alloc_sta,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index e182f5a0f736..8292f6d48ec6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -403,7 +403,6 @@ struct iwl_lq_sta {
403 u8 is_green; 403 u8 is_green;
404 u8 is_dup; 404 u8 is_dup;
405 enum ieee80211_band band; 405 enum ieee80211_band band;
406 u8 ibss_sta_added;
407 406
408 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 407 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
409 u32 supp_rates; 408 u32 supp_rates;
@@ -478,6 +477,12 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
478 */ 477 */
479extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); 478extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
480 479
480/* Initialize station's rate scaling information after adding station */
481extern void iwl_rs_rate_init(struct iwl_priv *priv,
482 struct ieee80211_sta *sta, u8 sta_id);
483extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
484 struct ieee80211_sta *sta, u8 sta_id);
485
481/** 486/**
482 * iwl_rate_control_register - Register the rate control algorithm callbacks 487 * iwl_rate_control_register - Register the rate control algorithm callbacks
483 * 488 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index efee4e39d282..0a376f720d78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -144,9 +144,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
144 return 0; 144 return 0;
145 } 145 }
146 146
147 /* station table will be cleared */
148 priv->assoc_station_added = 0;
149
150 /* If we are currently associated and the new config requires 147 /* If we are currently associated and the new config requires
151 * an RXON_ASSOC and the new config wants the associated mask enabled, 148 * an RXON_ASSOC and the new config wants the associated mask enabled,
152 * we must clear the associated from the active configuration 149 * we must clear the associated from the active configuration
@@ -166,6 +163,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
166 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); 163 IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
167 return ret; 164 return ret;
168 } 165 }
166 iwl_clear_ucode_stations(priv, false);
167 iwl_restore_stations(priv);
169 } 168 }
170 169
171 IWL_DEBUG_INFO(priv, "Sending RXON\n" 170 IWL_DEBUG_INFO(priv, "Sending RXON\n"
@@ -179,9 +178,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
179 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); 178 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
180 179
181 /* Apply the new configuration 180 /* Apply the new configuration
182 * RXON unassoc clears the station table in uCode, send it before 181 * RXON unassoc clears the station table in uCode so restoration of
183 * we add the bcast station. If assoc bit is set, we will send RXON 182 * stations is needed after it (the RXON command) completes
184 * after having added the bcast and bssid station.
185 */ 183 */
186 if (!new_assoc) { 184 if (!new_assoc) {
187 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 185 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -190,35 +188,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
190 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 188 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
191 return ret; 189 return ret;
192 } 190 }
191 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON. \n");
193 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 192 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
193 iwl_clear_ucode_stations(priv, false);
194 iwl_restore_stations(priv);
194 } 195 }
195 196
196 iwl_clear_stations_table(priv);
197
198 priv->start_calib = 0; 197 priv->start_calib = 0;
199
200 /* Add the broadcast address so we can send broadcast frames */
201 priv->cfg->ops->lib->add_bcast_station(priv);
202
203
204 /* If we have set the ASSOC_MSK and we are in BSS mode then
205 * add the IWL_AP_ID to the station rate table */
206 if (new_assoc) { 198 if (new_assoc) {
207 if (priv->iw_mode == NL80211_IFTYPE_STATION) {
208 ret = iwl_rxon_add_station(priv,
209 priv->active_rxon.bssid_addr, 1);
210 if (ret == IWL_INVALID_STATION) {
211 IWL_ERR(priv,
212 "Error adding AP address for TX.\n");
213 return -EIO;
214 }
215 priv->assoc_station_added = 1;
216 if (priv->default_wep_key &&
217 iwl_send_static_wepkey_cmd(priv, 0))
218 IWL_ERR(priv,
219 "Could not send WEP static key.\n");
220 }
221
222 /* 199 /*
223 * allow CTS-to-self if possible for new association. 200 * allow CTS-to-self if possible for new association.
224 * this is relevant only for 5000 series and up, 201 * this is relevant only for 5000 series and up,
@@ -2087,7 +2064,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
2087 goto restart; 2064 goto restart;
2088 } 2065 }
2089 2066
2090 iwl_clear_stations_table(priv);
2091 ret = priv->cfg->ops->lib->alive_notify(priv); 2067 ret = priv->cfg->ops->lib->alive_notify(priv);
2092 if (ret) { 2068 if (ret) {
2093 IWL_WARN(priv, 2069 IWL_WARN(priv,
@@ -2098,6 +2074,13 @@ static void iwl_alive_start(struct iwl_priv *priv)
2098 /* After the ALIVE response, we can send host commands to the uCode */ 2074 /* After the ALIVE response, we can send host commands to the uCode */
2099 set_bit(STATUS_ALIVE, &priv->status); 2075 set_bit(STATUS_ALIVE, &priv->status);
2100 2076
2077 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2078 /* Enable timer to monitor the driver queues */
2079 mod_timer(&priv->monitor_recover,
2080 jiffies +
2081 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2082 }
2083
2101 if (iwl_is_rfkill(priv)) 2084 if (iwl_is_rfkill(priv))
2102 return; 2085 return;
2103 2086
@@ -2143,6 +2126,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
2143 wake_up_interruptible(&priv->wait_command_queue); 2126 wake_up_interruptible(&priv->wait_command_queue);
2144 2127
2145 iwl_power_update_mode(priv, true); 2128 iwl_power_update_mode(priv, true);
2129 IWL_DEBUG_INFO(priv, "Updated power mode\n");
2130
2146 2131
2147 return; 2132 return;
2148 2133
@@ -2162,7 +2147,7 @@ static void __iwl_down(struct iwl_priv *priv)
2162 if (!exit_pending) 2147 if (!exit_pending)
2163 set_bit(STATUS_EXIT_PENDING, &priv->status); 2148 set_bit(STATUS_EXIT_PENDING, &priv->status);
2164 2149
2165 iwl_clear_stations_table(priv); 2150 iwl_clear_ucode_stations(priv, true);
2166 2151
2167 /* Unblock any waiting calls */ 2152 /* Unblock any waiting calls */
2168 wake_up_interruptible_all(&priv->wait_command_queue); 2153 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2359,8 +2344,6 @@ static int __iwl_up(struct iwl_priv *priv)
2359 2344
2360 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2345 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2361 2346
2362 iwl_clear_stations_table(priv);
2363
2364 /* load bootstrap state machine, 2347 /* load bootstrap state machine,
2365 * load bootstrap program into processor's memory, 2348 * load bootstrap program into processor's memory,
2366 * prepare to load the "initialize" uCode */ 2349 * prepare to load the "initialize" uCode */
@@ -2501,10 +2484,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2501 return; 2484 return;
2502 } 2485 }
2503 2486
2504 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2505 priv->assoc_id, priv->active_rxon.bssid_addr);
2506
2507
2508 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2487 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2509 return; 2488 return;
2510 2489
@@ -2556,6 +2535,9 @@ void iwl_post_associate(struct iwl_priv *priv)
2556 2535
2557 iwlcore_commit_rxon(priv); 2536 iwlcore_commit_rxon(priv);
2558 2537
2538 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2539 priv->assoc_id, priv->active_rxon.bssid_addr);
2540
2559 switch (priv->iw_mode) { 2541 switch (priv->iw_mode) {
2560 case NL80211_IFTYPE_STATION: 2542 case NL80211_IFTYPE_STATION:
2561 break; 2543 break;
@@ -2565,7 +2547,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2565 /* assume default assoc id */ 2547 /* assume default assoc id */
2566 priv->assoc_id = 1; 2548 priv->assoc_id = 1;
2567 2549
2568 iwl_rxon_add_station(priv, priv->bssid, 0); 2550 iwl_add_local_station(priv, priv->bssid, true);
2569 iwl_send_beacon_cmd(priv); 2551 iwl_send_beacon_cmd(priv);
2570 2552
2571 break; 2553 break;
@@ -2576,9 +2558,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2576 break; 2558 break;
2577 } 2559 }
2578 2560
2579 if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
2580 priv->assoc_station_added = 1;
2581
2582 spin_lock_irqsave(&priv->lock, flags); 2561 spin_lock_irqsave(&priv->lock, flags);
2583 iwl_activate_qos(priv, 0); 2562 iwl_activate_qos(priv, 0);
2584 spin_unlock_irqrestore(&priv->lock, flags); 2563 spin_unlock_irqrestore(&priv->lock, flags);
@@ -2937,10 +2916,21 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2937 return ret; 2916 return ret;
2938 case IEEE80211_AMPDU_TX_START: 2917 case IEEE80211_AMPDU_TX_START:
2939 IWL_DEBUG_HT(priv, "start Tx\n"); 2918 IWL_DEBUG_HT(priv, "start Tx\n");
2940 return iwl_tx_agg_start(priv, sta->addr, tid, ssn); 2919 ret = iwl_tx_agg_start(priv, sta->addr, tid, ssn);
2920 if (ret == 0) {
2921 priv->_agn.agg_tids_count++;
2922 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
2923 priv->_agn.agg_tids_count);
2924 }
2925 return ret;
2941 case IEEE80211_AMPDU_TX_STOP: 2926 case IEEE80211_AMPDU_TX_STOP:
2942 IWL_DEBUG_HT(priv, "stop Tx\n"); 2927 IWL_DEBUG_HT(priv, "stop Tx\n");
2943 ret = iwl_tx_agg_stop(priv, sta->addr, tid); 2928 ret = iwl_tx_agg_stop(priv, sta->addr, tid);
2929 if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
2930 priv->_agn.agg_tids_count--;
2931 IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
2932 priv->_agn.agg_tids_count);
2933 }
2944 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2934 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2945 return 0; 2935 return 0;
2946 else 2936 else
@@ -2977,18 +2967,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
2977 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 2967 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2978 int sta_id; 2968 int sta_id;
2979 2969
2980 /*
2981 * TODO: We really should use this callback to
2982 * actually maintain the station table in
2983 * the device.
2984 */
2985
2986 switch (cmd) { 2970 switch (cmd) {
2987 case STA_NOTIFY_ADD:
2988 atomic_set(&sta_priv->pending_frames, 0);
2989 if (vif->type == NL80211_IFTYPE_AP)
2990 sta_priv->client = true;
2991 break;
2992 case STA_NOTIFY_SLEEP: 2971 case STA_NOTIFY_SLEEP:
2993 WARN_ON(!sta_priv->client); 2972 WARN_ON(!sta_priv->client);
2994 sta_priv->asleep = true; 2973 sta_priv->asleep = true;
@@ -3009,6 +2988,55 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
3009 } 2988 }
3010} 2989}
3011 2990
2991/**
2992 * iwl_restore_wepkeys - Restore WEP keys to device
2993 */
2994static void iwl_restore_wepkeys(struct iwl_priv *priv)
2995{
2996 mutex_lock(&priv->mutex);
2997 if (priv->iw_mode == NL80211_IFTYPE_STATION &&
2998 priv->default_wep_key &&
2999 iwl_send_static_wepkey_cmd(priv, 0))
3000 IWL_ERR(priv, "Could not send WEP static key\n");
3001 mutex_unlock(&priv->mutex);
3002}
3003
3004static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3005 struct ieee80211_vif *vif,
3006 struct ieee80211_sta *sta)
3007{
3008 struct iwl_priv *priv = hw->priv;
3009 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
3010 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
3011 int ret;
3012 u8 sta_id;
3013
3014 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3015 sta->addr);
3016
3017 atomic_set(&sta_priv->pending_frames, 0);
3018 if (vif->type == NL80211_IFTYPE_AP)
3019 sta_priv->client = true;
3020
3021 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3022 &sta_id);
3023 if (ret) {
3024 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3025 sta->addr, ret);
3026 /* Should we return success if return code is EEXIST ? */
3027 return ret;
3028 }
3029
3030 iwl_restore_wepkeys(priv);
3031
3032 /* Initialize rate scaling */
3033 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM \n",
3034 sta->addr);
3035 iwl_rs_rate_init(priv, sta, sta_id);
3036
3037 return ret;
3038}
3039
3012/***************************************************************************** 3040/*****************************************************************************
3013 * 3041 *
3014 * sysfs attributes 3042 * sysfs attributes
@@ -3214,6 +3242,13 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
3214 priv->ucode_trace.data = (unsigned long)priv; 3242 priv->ucode_trace.data = (unsigned long)priv;
3215 priv->ucode_trace.function = iwl_bg_ucode_trace; 3243 priv->ucode_trace.function = iwl_bg_ucode_trace;
3216 3244
3245 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3246 init_timer(&priv->monitor_recover);
3247 priv->monitor_recover.data = (unsigned long)priv;
3248 priv->monitor_recover.function =
3249 priv->cfg->ops->lib->recover_from_tx_stall;
3250 }
3251
3217 if (!priv->cfg->use_isr_legacy) 3252 if (!priv->cfg->use_isr_legacy)
3218 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3253 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3219 iwl_irq_tasklet, (unsigned long)priv); 3254 iwl_irq_tasklet, (unsigned long)priv);
@@ -3233,6 +3268,8 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
3233 cancel_work_sync(&priv->beacon_update); 3268 cancel_work_sync(&priv->beacon_update);
3234 del_timer_sync(&priv->statistics_periodic); 3269 del_timer_sync(&priv->statistics_periodic);
3235 del_timer_sync(&priv->ucode_trace); 3270 del_timer_sync(&priv->ucode_trace);
3271 if (priv->cfg->ops->lib->recover_from_tx_stall)
3272 del_timer_sync(&priv->monitor_recover);
3236} 3273}
3237 3274
3238static void iwl_init_hw_rates(struct iwl_priv *priv, 3275static void iwl_init_hw_rates(struct iwl_priv *priv,
@@ -3270,9 +3307,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
3270 mutex_init(&priv->mutex); 3307 mutex_init(&priv->mutex);
3271 mutex_init(&priv->sync_cmd_mutex); 3308 mutex_init(&priv->sync_cmd_mutex);
3272 3309
3273 /* Clear the driver's (not device's) station table */
3274 iwl_clear_stations_table(priv);
3275
3276 priv->ieee_channels = NULL; 3310 priv->ieee_channels = NULL;
3277 priv->ieee_rates = NULL; 3311 priv->ieee_rates = NULL;
3278 priv->band = IEEE80211_BAND_2GHZ; 3312 priv->band = IEEE80211_BAND_2GHZ;
@@ -3280,6 +3314,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
3280 priv->iw_mode = NL80211_IFTYPE_STATION; 3314 priv->iw_mode = NL80211_IFTYPE_STATION;
3281 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC; 3315 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
3282 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 3316 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
3317 priv->_agn.agg_tids_count = 0;
3283 3318
3284 /* initialize force reset */ 3319 /* initialize force reset */
3285 priv->force_reset[IWL_RF_RESET].reset_duration = 3320 priv->force_reset[IWL_RF_RESET].reset_duration =
@@ -3365,6 +3400,8 @@ static struct ieee80211_ops iwl_hw_ops = {
3365 .ampdu_action = iwl_mac_ampdu_action, 3400 .ampdu_action = iwl_mac_ampdu_action,
3366 .hw_scan = iwl_mac_hw_scan, 3401 .hw_scan = iwl_mac_hw_scan,
3367 .sta_notify = iwl_mac_sta_notify, 3402 .sta_notify = iwl_mac_sta_notify,
3403 .sta_add = iwlagn_mac_sta_add,
3404 .sta_remove = iwl_mac_sta_remove,
3368}; 3405};
3369 3406
3370static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3407static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -3468,7 +3505,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3468 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); 3505 iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
3469 3506
3470 iwl_hw_detect(priv); 3507 iwl_hw_detect(priv);
3471 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n", 3508 IWL_INFO(priv, "Detected %s, REV=0x%X\n",
3472 priv->cfg->name, priv->hw_rev); 3509 priv->cfg->name, priv->hw_rev);
3473 3510
3474 /* We disable the RETRY_TIMEOUT register (0x41) to keep 3511 /* We disable the RETRY_TIMEOUT register (0x41) to keep
@@ -3649,7 +3686,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3649 iwl_rx_queue_free(priv, &priv->rxq); 3686 iwl_rx_queue_free(priv, &priv->rxq);
3650 iwl_hw_txq_ctx_free(priv); 3687 iwl_hw_txq_ctx_free(priv);
3651 3688
3652 iwl_clear_stations_table(priv);
3653 iwl_eeprom_free(priv); 3689 iwl_eeprom_free(priv);
3654 3690
3655 3691
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index ec435e5491d9..5180fb24cd38 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2283,8 +2283,6 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
2283 2283
2284 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 2284 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2285 2285
2286 iwl_clear_stations_table(priv);
2287
2288 return iwlcore_commit_rxon(priv); 2286 return iwlcore_commit_rxon(priv);
2289} 2287}
2290 2288
@@ -2317,6 +2315,10 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2317 err = iwl_set_mode(priv, vif); 2315 err = iwl_set_mode(priv, vif);
2318 if (err) 2316 if (err)
2319 goto out_err; 2317 goto out_err;
2318
2319 /* Add the broadcast address so we can send broadcast frames */
2320 priv->cfg->ops->lib->add_bcast_station(priv);
2321
2320 goto out; 2322 goto out;
2321 2323
2322 out_err: 2324 out_err:
@@ -2339,6 +2341,8 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
2339 2341
2340 mutex_lock(&priv->mutex); 2342 mutex_lock(&priv->mutex);
2341 2343
2344 iwl_clear_ucode_stations(priv, true);
2345
2342 if (iwl_is_ready_rf(priv)) { 2346 if (iwl_is_ready_rf(priv)) {
2343 iwl_scan_cancel_timeout(priv, 100); 2347 iwl_scan_cancel_timeout(priv, 100);
2344 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2348 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -2526,7 +2530,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2526 spin_lock_irqsave(&priv->lock, flags); 2530 spin_lock_irqsave(&priv->lock, flags);
2527 priv->assoc_id = 0; 2531 priv->assoc_id = 0;
2528 priv->assoc_capability = 0; 2532 priv->assoc_capability = 0;
2529 priv->assoc_station_added = 0;
2530 2533
2531 /* new association get rid of ibss beacon skb */ 2534 /* new association get rid of ibss beacon skb */
2532 if (priv->ibss_beacon) 2535 if (priv->ibss_beacon)
@@ -3048,6 +3051,99 @@ int iwl_force_reset(struct iwl_priv *priv, int mode)
3048 } 3051 }
3049 return 0; 3052 return 0;
3050} 3053}
3054EXPORT_SYMBOL(iwl_force_reset);
3055
3056/**
3057 * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover
3058 *
3059 * During normal condition (no queue is stuck), the timer is continually set to
3060 * execute every monitor_recover_period milliseconds after the last timer
3061 * expired. When the queue read_ptr is at the same place, the timer is
3062 * shorten to 100mSecs. This is
3063 * 1) to reduce the chance that the read_ptr may wrap around (not stuck)
3064 * 2) to detect the stuck queues quicker before the station and AP can
3065 * disassociate each other.
3066 *
3067 * This function monitors all the tx queues and recover from it if any
3068 * of the queues are stuck.
3069 * 1. It first check the cmd queue for stuck conditions. If it is stuck,
3070 * it will recover by resetting the firmware and return.
3071 * 2. Then, it checks for station association. If it associates it will check
3072 * other queues. If any queue is stuck, it will recover by resetting
3073 * the firmware.
3074 * Note: It the number of times the queue read_ptr to be at the same place to
3075 * be MAX_REPEAT+1 in order to consider to be stuck.
3076 */
3077/*
3078 * The maximum number of times the read pointer of the tx queue at the
3079 * same place without considering to be stuck.
3080 */
3081#define MAX_REPEAT (2)
3082static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt)
3083{
3084 struct iwl_tx_queue *txq;
3085 struct iwl_queue *q;
3086
3087 txq = &priv->txq[cnt];
3088 q = &txq->q;
3089 /* queue is empty, skip */
3090 if (q->read_ptr != q->write_ptr) {
3091 if (q->read_ptr == q->last_read_ptr) {
3092 /* a queue has not been read from last time */
3093 if (q->repeat_same_read_ptr > MAX_REPEAT) {
3094 IWL_ERR(priv,
3095 "queue %d stuck %d time. Fw reload.\n",
3096 q->id, q->repeat_same_read_ptr);
3097 q->repeat_same_read_ptr = 0;
3098 iwl_force_reset(priv, IWL_FW_RESET);
3099 } else {
3100 q->repeat_same_read_ptr++;
3101 IWL_DEBUG_RADIO(priv,
3102 "queue %d, not read %d time\n",
3103 q->id,
3104 q->repeat_same_read_ptr);
3105 mod_timer(&priv->monitor_recover, jiffies +
3106 msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS));
3107 }
3108 return 1;
3109 } else {
3110 q->last_read_ptr = q->read_ptr;
3111 q->repeat_same_read_ptr = 0;
3112 }
3113 }
3114 return 0;
3115}
3116
3117void iwl_bg_monitor_recover(unsigned long data)
3118{
3119 struct iwl_priv *priv = (struct iwl_priv *)data;
3120 int cnt;
3121
3122 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3123 return;
3124
3125 /* monitor and check for stuck cmd queue */
3126 if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM))
3127 return;
3128
3129 /* monitor and check for other stuck queues */
3130 if (iwl_is_associated(priv)) {
3131 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
3132 /* skip as we already checked the command queue */
3133 if (cnt == IWL_CMD_QUEUE_NUM)
3134 continue;
3135 if (iwl_check_stuck_queue(priv, cnt))
3136 return;
3137 }
3138 }
3139 /*
3140 * Reschedule the timer to occur in
3141 * priv->cfg->monitor_recover_period
3142 */
3143 mod_timer(&priv->monitor_recover,
3144 jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period));
3145}
3146EXPORT_SYMBOL(iwl_bg_monitor_recover);
3051 3147
3052#ifdef CONFIG_PM 3148#ifdef CONFIG_PM
3053 3149
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index aced12f1611e..b3e698b576e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -191,6 +191,14 @@ struct iwl_lib_ops {
191 struct iwl_temp_ops temp_ops; 191 struct iwl_temp_ops temp_ops;
192 /* station management */ 192 /* station management */
193 void (*add_bcast_station)(struct iwl_priv *priv); 193 void (*add_bcast_station)(struct iwl_priv *priv);
194 /* recover from tx queue stall */
195 void (*recover_from_tx_stall)(unsigned long data);
196 /* check for plcp health */
197 bool (*check_plcp_health)(struct iwl_priv *priv,
198 struct iwl_rx_packet *pkt);
199 /* check for ack health */
200 bool (*check_ack_health)(struct iwl_priv *priv,
201 struct iwl_rx_packet *pkt);
194}; 202};
195 203
196struct iwl_led_ops { 204struct iwl_led_ops {
@@ -295,6 +303,8 @@ struct iwl_cfg {
295 const bool support_wimax_coexist; 303 const bool support_wimax_coexist;
296 u8 plcp_delta_threshold; 304 u8 plcp_delta_threshold;
297 s32 chain_noise_scale; 305 s32 chain_noise_scale;
306 /* timer period for monitor the driver queues */
307 u32 monitor_recover_period;
298}; 308};
299 309
300/*************************** 310/***************************
@@ -430,6 +440,10 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
430 struct iwl_rx_mem_buffer *rxb); 440 struct iwl_rx_mem_buffer *rxb);
431void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv, 441void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
432 struct iwl_rx_mem_buffer *rxb); 442 struct iwl_rx_mem_buffer *rxb);
443bool iwl_good_plcp_health(struct iwl_priv *priv,
444 struct iwl_rx_packet *pkt);
445bool iwl_good_ack_health(struct iwl_priv *priv,
446 struct iwl_rx_packet *pkt);
433void iwl_rx_statistics(struct iwl_priv *priv, 447void iwl_rx_statistics(struct iwl_priv *priv,
434 struct iwl_rx_mem_buffer *rxb); 448 struct iwl_rx_mem_buffer *rxb);
435void iwl_reply_statistics(struct iwl_priv *priv, 449void iwl_reply_statistics(struct iwl_priv *priv,
@@ -568,6 +582,9 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
568 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); 582 pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
569 return pci_lnk_ctl; 583 return pci_lnk_ctl;
570} 584}
585
586void iwl_bg_monitor_recover(unsigned long data);
587
571#ifdef CONFIG_PM 588#ifdef CONFIG_PM
572int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state); 589int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
573int iwl_pci_resume(struct pci_dev *pdev); 590int iwl_pci_resume(struct pci_dev *pdev);
@@ -667,7 +684,7 @@ extern int iwl_send_statistics_request(struct iwl_priv *priv,
667 u8 flags, bool clear); 684 u8 flags, bool clear);
668extern int iwl_verify_ucode(struct iwl_priv *priv); 685extern int iwl_verify_ucode(struct iwl_priv *priv);
669extern int iwl_send_lq_cmd(struct iwl_priv *priv, 686extern int iwl_send_lq_cmd(struct iwl_priv *priv,
670 struct iwl_link_quality_cmd *lq, u8 flags); 687 struct iwl_link_quality_cmd *lq, u8 flags, bool init);
671extern void iwl_rx_reply_rx(struct iwl_priv *priv, 688extern void iwl_rx_reply_rx(struct iwl_priv *priv,
672 struct iwl_rx_mem_buffer *rxb); 689 struct iwl_rx_mem_buffer *rxb);
673extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv, 690extern void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2e4d47c7139b..e847e6197a3d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -183,6 +183,10 @@ struct iwl_queue {
183 int n_bd; /* number of BDs in this queue */ 183 int n_bd; /* number of BDs in this queue */
184 int write_ptr; /* 1-st empty entry (index) host_w*/ 184 int write_ptr; /* 1-st empty entry (index) host_w*/
185 int read_ptr; /* last used entry (index) host_r*/ 185 int read_ptr; /* last used entry (index) host_r*/
186 /* use for monitoring and recovering the stuck queue */
187 int last_read_ptr; /* storing the last read_ptr */
188 /* number of time read_ptr and last_read_ptr are the same */
189 u8 repeat_same_read_ptr;
186 dma_addr_t dma_addr; /* physical addr for BD's */ 190 dma_addr_t dma_addr; /* physical addr for BD's */
187 int n_window; /* safe queue window */ 191 int n_window; /* safe queue window */
188 u32 id; 192 u32 id;
@@ -544,11 +548,18 @@ struct iwl_qos_info {
544 struct iwl_qosparam_cmd def_qos_parm; 548 struct iwl_qosparam_cmd def_qos_parm;
545}; 549};
546 550
551/*
552 * Structure should be accessed with sta_lock held. When station addition
553 * is in progress (IWL_STA_UCODE_INPROGRESS) it is possible to access only
554 * the commands (iwl_addsta_cmd and iwl_link_quality_cmd) without sta_lock
555 * held.
556 */
547struct iwl_station_entry { 557struct iwl_station_entry {
548 struct iwl_addsta_cmd sta; 558 struct iwl_addsta_cmd sta;
549 struct iwl_tid_data tid[MAX_TID_COUNT]; 559 struct iwl_tid_data tid[MAX_TID_COUNT];
550 u8 used; 560 u8 used;
551 struct iwl_hw_key keyinfo; 561 struct iwl_hw_key keyinfo;
562 struct iwl_link_quality_cmd *lq;
552}; 563};
553 564
554/* 565/*
@@ -1037,6 +1048,11 @@ struct iwl_event_log {
1037#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) 1048#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
1038#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) 1049#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)
1039 1050
1051/* timer constants use to monitor and recover stuck tx queues in mSecs */
1052#define IWL_MONITORING_PERIOD (1000)
1053#define IWL_ONE_HUNDRED_MSECS (100)
1054#define IWL_SIXTY_SECS (60000)
1055
1040enum iwl_reset { 1056enum iwl_reset {
1041 IWL_RF_RESET = 0, 1057 IWL_RF_RESET = 0,
1042 IWL_FW_RESET, 1058 IWL_FW_RESET,
@@ -1163,7 +1179,6 @@ struct iwl_priv {
1163 1179
1164 u16 active_rate; 1180 u16 active_rate;
1165 1181
1166 u8 assoc_station_added;
1167 u8 start_calib; 1182 u8 start_calib;
1168 struct iwl_sensitivity_data sensitivity_data; 1183 struct iwl_sensitivity_data sensitivity_data;
1169 struct iwl_chain_noise_data chain_noise_data; 1184 struct iwl_chain_noise_data chain_noise_data;
@@ -1285,6 +1300,11 @@ struct iwl_priv {
1285 int ict_index; 1300 int ict_index;
1286 u32 inta; 1301 u32 inta;
1287 bool use_ict; 1302 bool use_ict;
1303 /*
1304 * reporting the number of tids has AGG on. 0 means
1305 * no AGGREGATION
1306 */
1307 u8 agg_tids_count;
1288 } _agn; 1308 } _agn;
1289#endif 1309#endif
1290 }; 1310 };
@@ -1348,6 +1368,7 @@ struct iwl_priv {
1348 struct work_struct run_time_calib_work; 1368 struct work_struct run_time_calib_work;
1349 struct timer_list statistics_periodic; 1369 struct timer_list statistics_periodic;
1350 struct timer_list ucode_trace; 1370 struct timer_list ucode_trace;
1371 struct timer_list monitor_recover;
1351 bool hw_ready; 1372 bool hw_ready;
1352 1373
1353 struct iwl_event_log event_log; 1374 struct iwl_event_log event_log;
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 8116aa0d7678..2fa30dfb7c59 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -616,29 +616,77 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
616 616
617#define REG_RECALIB_PERIOD (60) 617#define REG_RECALIB_PERIOD (60)
618 618
619#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n" 619/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
620void iwl_rx_statistics(struct iwl_priv *priv, 620#define ACK_CNT_RATIO (50)
621 struct iwl_rx_mem_buffer *rxb) 621#define BA_TIMEOUT_CNT (5)
622#define BA_TIMEOUT_MAX (16)
623
624#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
625/**
626 * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries.
627 *
628 * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding
629 * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
630 * operation state.
631 */
632bool iwl_good_ack_health(struct iwl_priv *priv,
633 struct iwl_rx_packet *pkt)
622{ 634{
623 int change; 635 bool rc = true;
624 struct iwl_rx_packet *pkt = rxb_addr(rxb); 636 int actual_ack_cnt_delta, expected_ack_cnt_delta;
637 int ba_timeout_delta;
638
639 actual_ack_cnt_delta =
640 le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
641 le32_to_cpu(priv->statistics.tx.actual_ack_cnt);
642 expected_ack_cnt_delta =
643 le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) -
644 le32_to_cpu(priv->statistics.tx.expected_ack_cnt);
645 ba_timeout_delta =
646 le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) -
647 le32_to_cpu(priv->statistics.tx.agg.ba_timeout);
648 if ((priv->_agn.agg_tids_count > 0) &&
649 (expected_ack_cnt_delta > 0) &&
650 (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta)
651 < ACK_CNT_RATIO) &&
652 (ba_timeout_delta > BA_TIMEOUT_CNT)) {
653 IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d,"
654 " expected_ack_cnt = %d\n",
655 actual_ack_cnt_delta, expected_ack_cnt_delta);
656
657#ifdef CONFIG_IWLWIFI_DEBUG
658 IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
659 priv->delta_statistics.tx.rx_detected_cnt);
660 IWL_DEBUG_RADIO(priv,
661 "ack_or_ba_timeout_collision delta = %d\n",
662 priv->delta_statistics.tx.
663 ack_or_ba_timeout_collision);
664#endif
665 IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
666 ba_timeout_delta);
667 if (!actual_ack_cnt_delta &&
668 (ba_timeout_delta >= BA_TIMEOUT_MAX))
669 rc = false;
670 }
671 return rc;
672}
673EXPORT_SYMBOL(iwl_good_ack_health);
674#endif
675
676/**
677 * iwl_good_plcp_health - checks for plcp error.
678 *
679 * When the plcp error is exceeding the thresholds, reset the radio
680 * to improve the throughput.
681 */
682bool iwl_good_plcp_health(struct iwl_priv *priv,
683 struct iwl_rx_packet *pkt)
684{
685 bool rc = true;
625 int combined_plcp_delta; 686 int combined_plcp_delta;
626 unsigned int plcp_msec; 687 unsigned int plcp_msec;
627 unsigned long plcp_received_jiffies; 688 unsigned long plcp_received_jiffies;
628 689
629 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
630 (int)sizeof(priv->statistics),
631 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
632
633 change = ((priv->statistics.general.temperature !=
634 pkt->u.stats.general.temperature) ||
635 ((priv->statistics.flag &
636 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
637 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
638
639#ifdef CONFIG_IWLWIFI_DEBUG
640 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
641#endif
642 /* 690 /*
643 * check for plcp_err and trigger radio reset if it exceeds 691 * check for plcp_err and trigger radio reset if it exceeds
644 * the plcp error threshold plcp_delta. 692 * the plcp error threshold plcp_delta.
@@ -659,11 +707,11 @@ void iwl_rx_statistics(struct iwl_priv *priv,
659 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err)); 707 le32_to_cpu(priv->statistics.rx.ofdm_ht.plcp_err));
660 708
661 if ((combined_plcp_delta > 0) && 709 if ((combined_plcp_delta > 0) &&
662 ((combined_plcp_delta * 100) / plcp_msec) > 710 ((combined_plcp_delta * 100) / plcp_msec) >
663 priv->cfg->plcp_delta_threshold) { 711 priv->cfg->plcp_delta_threshold) {
664 /* 712 /*
665 * if plcp_err exceed the threshold, the following 713 * if plcp_err exceed the threshold,
666 * data is printed in csv format: 714 * the following data is printed in csv format:
667 * Text: plcp_err exceeded %d, 715 * Text: plcp_err exceeded %d,
668 * Received ofdm.plcp_err, 716 * Received ofdm.plcp_err,
669 * Current ofdm.plcp_err, 717 * Current ofdm.plcp_err,
@@ -672,22 +720,73 @@ void iwl_rx_statistics(struct iwl_priv *priv,
672 * combined_plcp_delta, 720 * combined_plcp_delta,
673 * plcp_msec 721 * plcp_msec
674 */ 722 */
675 IWL_DEBUG_RADIO(priv, PLCP_MSG, 723 IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
724 "%u, %u, %u, %u, %d, %u mSecs\n",
676 priv->cfg->plcp_delta_threshold, 725 priv->cfg->plcp_delta_threshold,
677 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err), 726 le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
678 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err), 727 le32_to_cpu(priv->statistics.rx.ofdm.plcp_err),
679 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err), 728 le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
680 le32_to_cpu( 729 le32_to_cpu(
681 priv->statistics.rx.ofdm_ht.plcp_err), 730 priv->statistics.rx.ofdm_ht.plcp_err),
682 combined_plcp_delta, plcp_msec); 731 combined_plcp_delta, plcp_msec);
732 rc = false;
733 }
734 }
735 return rc;
736}
737EXPORT_SYMBOL(iwl_good_plcp_health);
683 738
684 /* 739static void iwl_recover_from_statistics(struct iwl_priv *priv,
685 * Reset the RF radio due to the high plcp 740 struct iwl_rx_packet *pkt)
686 * error rate 741{
687 */ 742 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
688 iwl_force_reset(priv, IWL_RF_RESET); 743 return;
744 if (iwl_is_associated(priv)) {
745 if (priv->cfg->ops->lib->check_ack_health) {
746 if (!priv->cfg->ops->lib->check_ack_health(
747 priv, pkt)) {
748 /*
749 * low ack count detected
750 * restart Firmware
751 */
752 IWL_ERR(priv, "low ack count detected, "
753 "restart firmware\n");
754 iwl_force_reset(priv, IWL_FW_RESET);
755 }
756 } else if (priv->cfg->ops->lib->check_plcp_health) {
757 if (!priv->cfg->ops->lib->check_plcp_health(
758 priv, pkt)) {
759 /*
760 * high plcp error detected
761 * reset Radio
762 */
763 iwl_force_reset(priv, IWL_RF_RESET);
764 }
689 } 765 }
690 } 766 }
767}
768
769void iwl_rx_statistics(struct iwl_priv *priv,
770 struct iwl_rx_mem_buffer *rxb)
771{
772 int change;
773 struct iwl_rx_packet *pkt = rxb_addr(rxb);
774
775
776 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
777 (int)sizeof(priv->statistics),
778 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
779
780 change = ((priv->statistics.general.temperature !=
781 pkt->u.stats.general.temperature) ||
782 ((priv->statistics.flag &
783 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
784 (pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
785
786#ifdef CONFIG_IWLWIFI_DEBUG
787 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
788#endif
789 iwl_recover_from_statistics(priv, pkt);
691 790
692 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics)); 791 memcpy(&priv->statistics, &pkt->u.stats, sizeof(priv->statistics));
693 792
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index b1aad306efa9..d401b6f226f9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -29,14 +29,12 @@
29 29
30#include <net/mac80211.h> 30#include <net/mac80211.h>
31#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
32#include <linux/sched.h>
32 33
33#include "iwl-dev.h" 34#include "iwl-dev.h"
34#include "iwl-core.h" 35#include "iwl-core.h"
35#include "iwl-sta.h" 36#include "iwl-sta.h"
36 37
37#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
38#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
39
40u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) 38u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
41{ 39{
42 int i; 40 int i;
@@ -64,6 +62,19 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
64 addr, priv->num_stations); 62 addr, priv->num_stations);
65 63
66 out: 64 out:
65 /*
66 * It may be possible that more commands interacting with stations
67 * arrive before we completed processing the adding of
68 * station
69 */
70 if (ret != IWL_INVALID_STATION &&
71 (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
72 ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
73 (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
74 IWL_ERR(priv, "Requested station info for sta %d before ready. \n",
75 ret);
76 ret = IWL_INVALID_STATION;
77 }
67 spin_unlock_irqrestore(&priv->sta_lock, flags); 78 spin_unlock_irqrestore(&priv->sta_lock, flags);
68 return ret; 79 return ret;
69} 80}
@@ -158,13 +169,6 @@ static void iwl_process_add_sta_resp(struct iwl_priv *priv,
158 priv->stations[sta_id].sta.mode == 169 priv->stations[sta_id].sta.mode ==
159 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added", 170 STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",
160 addsta->sta.addr); 171 addsta->sta.addr);
161
162 /*
163 * Determine if we wanted to modify or add a station,
164 * if adding a station succeeded we have some more initialization
165 * to do when using station notification. TODO
166 */
167
168 spin_unlock_irqrestore(&priv->sta_lock, flags); 172 spin_unlock_irqrestore(&priv->sta_lock, flags);
169} 173}
170 174
@@ -190,6 +194,10 @@ int iwl_send_add_sta(struct iwl_priv *priv,
190 .flags = flags, 194 .flags = flags,
191 .data = data, 195 .data = data,
192 }; 196 };
197 u8 sta_id = sta->sta.sta_id;
198
199 IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
200 sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");
193 201
194 if (flags & CMD_ASYNC) 202 if (flags & CMD_ASYNC)
195 cmd.callback = iwl_add_sta_callback; 203 cmd.callback = iwl_add_sta_callback;
@@ -263,18 +271,19 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
263} 271}
264 272
265/** 273/**
266 * iwl_add_station - Add station to tables in driver and device 274 * iwl_prep_station - Prepare station information for addition
275 *
276 * should be called with sta_lock held
267 */ 277 */
268u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 278static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
269 struct ieee80211_sta_ht_cap *ht_info) 279 bool is_ap,
280 struct ieee80211_sta_ht_cap *ht_info)
270{ 281{
271 struct iwl_station_entry *station; 282 struct iwl_station_entry *station;
272 unsigned long flags_spin;
273 int i; 283 int i;
274 int sta_id = IWL_INVALID_STATION; 284 u8 sta_id = IWL_INVALID_STATION;
275 u16 rate; 285 u16 rate;
276 286
277 spin_lock_irqsave(&priv->sta_lock, flags_spin);
278 if (is_ap) 287 if (is_ap)
279 sta_id = IWL_AP_ID; 288 sta_id = IWL_AP_ID;
280 else if (is_broadcast_ether_addr(addr)) 289 else if (is_broadcast_ether_addr(addr))
@@ -292,20 +301,32 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
292 sta_id = i; 301 sta_id = i;
293 } 302 }
294 303
295 /* These two conditions have the same outcome, but keep them separate 304 /*
296 since they have different meanings */ 305 * These two conditions have the same outcome, but keep them
297 if (unlikely(sta_id == IWL_INVALID_STATION)) { 306 * separate
298 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 307 */
308 if (unlikely(sta_id == IWL_INVALID_STATION))
309 return sta_id;
310
311 /*
312 * uCode is not able to deal with multiple requests to add a
313 * station. Keep track if one is in progress so that we do not send
314 * another.
315 */
316 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
317 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
318 sta_id);
299 return sta_id; 319 return sta_id;
300 } 320 }
301 321
302 if (priv->stations[sta_id].used && 322 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
323 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE) &&
303 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) { 324 !compare_ether_addr(priv->stations[sta_id].sta.sta.addr, addr)) {
304 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 325 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
326 sta_id, addr);
305 return sta_id; 327 return sta_id;
306 } 328 }
307 329
308
309 station = &priv->stations[sta_id]; 330 station = &priv->stations[sta_id];
310 station->used = IWL_STA_DRIVER_ACTIVE; 331 station->used = IWL_STA_DRIVER_ACTIVE;
311 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n", 332 IWL_DEBUG_ASSOC(priv, "Add STA to driver ID %d: %pM\n",
@@ -330,86 +351,185 @@ u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
330 /* Turn on both antennas for the station... */ 351 /* Turn on both antennas for the station... */
331 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK); 352 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
332 353
354 return sta_id;
355
356}
357
358#define STA_WAIT_TIMEOUT (HZ/2)
359
360/**
361 * iwl_add_station_common -
362 */
363int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
364 bool is_ap,
365 struct ieee80211_sta_ht_cap *ht_info,
366 u8 *sta_id_r)
367{
368 struct iwl_station_entry *station;
369 unsigned long flags_spin;
370 int ret = 0;
371 u8 sta_id;
372
373 *sta_id_r = 0;
374 spin_lock_irqsave(&priv->sta_lock, flags_spin);
375 sta_id = iwl_prep_station(priv, addr, is_ap, ht_info);
376 if (sta_id == IWL_INVALID_STATION) {
377 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
378 addr);
379 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
380 return -EINVAL;
381 }
382
383 /*
384 * uCode is not able to deal with multiple requests to add a
385 * station. Keep track if one is in progress so that we do not send
386 * another.
387 */
388 if (priv->stations[sta_id].used & IWL_STA_UCODE_INPROGRESS) {
389 IWL_DEBUG_INFO(priv, "STA %d already in process of being added.\n",
390 sta_id);
391 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
392 return -EEXIST;
393 }
394
395 if ((priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
396 (priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
397 IWL_DEBUG_ASSOC(priv, "STA %d (%pM) already added, not adding again.\n",
398 sta_id, addr);
399 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
400 return -EEXIST;
401 }
402
403 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
404 station = &priv->stations[sta_id];
333 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 405 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
334 406
335 /* Add station to device's station table */ 407 /* Add station to device's station table */
336 iwl_send_add_sta(priv, &station->sta, flags); 408 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC);
337 return sta_id; 409 if (ret) {
338 410 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
411 spin_lock_irqsave(&priv->sta_lock, flags_spin);
412 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
413 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
414 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
415 }
416 *sta_id_r = sta_id;
417 return ret;
339} 418}
340EXPORT_SYMBOL(iwl_add_station); 419EXPORT_SYMBOL(iwl_add_station_common);
341 420
342static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const u8 *addr) 421static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
343{ 422{
344 unsigned long flags; 423 int i, r;
345 u8 sta_id = iwl_find_station(priv, addr); 424 struct iwl_link_quality_cmd link_cmd = {
425 .reserved1 = 0,
426 };
427 u32 rate_flags;
346 428
347 BUG_ON(sta_id == IWL_INVALID_STATION); 429 /* Set up the rate scaling to start at selected rate, fall back
430 * all the way down to 1M in IEEE order, and then spin on 1M */
431 if (is_ap)
432 r = IWL_RATE_54M_INDEX;
433 else if (priv->band == IEEE80211_BAND_5GHZ)
434 r = IWL_RATE_6M_INDEX;
435 else
436 r = IWL_RATE_1M_INDEX;
437
438 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
439 rate_flags = 0;
440 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
441 rate_flags |= RATE_MCS_CCK_MSK;
348 442
349 IWL_DEBUG_ASSOC(priv, "Removed STA from Ucode: %pM\n", addr); 443 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
444 RATE_MCS_ANT_POS;
350 445
351 spin_lock_irqsave(&priv->sta_lock, flags); 446 link_cmd.rs_table[i].rate_n_flags =
447 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
448 r = iwl_get_prev_ieee_rate(r);
449 }
352 450
353 /* Ucode must be active and driver must be non active */ 451 link_cmd.general_params.single_stream_ant_msk =
354 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE) 452 first_antenna(priv->hw_params.valid_tx_ant);
355 IWL_ERR(priv, "removed non active STA %d\n", sta_id); 453 link_cmd.general_params.dual_stream_ant_msk = 3;
454 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
455 link_cmd.agg_params.agg_time_limit =
456 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
356 457
357 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE; 458 /* Update the rate scaling for control frame Tx to AP */
459 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
358 460
359 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry)); 461 iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD,
360 spin_unlock_irqrestore(&priv->sta_lock, flags); 462 sizeof(link_cmd), &link_cmd);
361} 463}
362 464
363static void iwl_remove_sta_callback(struct iwl_priv *priv, 465/*
364 struct iwl_device_cmd *cmd, 466 * iwl_add_local_stations - Add stations not requested by mac80211
365 struct iwl_rx_packet *pkt) 467 *
468 * This will be either the broadcast station or the bssid station needed by
469 * ad-hoc.
470 *
471 * Function sleeps.
472 */
473int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
366{ 474{
367 struct iwl_rem_sta_cmd *rm_sta = 475 int ret;
368 (struct iwl_rem_sta_cmd *)cmd->cmd.payload; 476 u8 sta_id;
369 const u8 *addr = rm_sta->addr;
370 477
371 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 478 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
372 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 479 if (ret) {
373 pkt->hdr.flags); 480 IWL_ERR(priv, "Unable to add station %pM\n", addr);
374 return; 481 return ret;
375 } 482 }
376 483
377 switch (pkt->u.rem_sta.status) { 484 if (init_rs)
378 case REM_STA_SUCCESS_MSK: 485 /* Set up default rate scaling table in device's station table */
379 iwl_sta_ucode_deactivate(priv, addr); 486 iwl_sta_init_lq(priv, addr, false);
380 break; 487 return 0;
381 default: 488}
382 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); 489EXPORT_SYMBOL(iwl_add_local_station);
383 break; 490
384 } 491/**
492 * iwl_sta_ucode_deactivate - deactivate ucode status for a station
493 *
494 * priv->sta_lock must be held
495 */
496static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
497{
498 /* Ucode must be active and driver must be non active */
499 if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
500 IWL_ERR(priv, "removed non active STA %u\n", sta_id);
501
502 priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
503
504 memset(&priv->stations[sta_id], 0, sizeof(struct iwl_station_entry));
505 IWL_DEBUG_ASSOC(priv, "Removed STA %u\n", sta_id);
385} 506}
386 507
387static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, 508static int iwl_send_remove_station(struct iwl_priv *priv,
388 u8 flags) 509 struct iwl_station_entry *station)
389{ 510{
390 struct iwl_rx_packet *pkt; 511 struct iwl_rx_packet *pkt;
391 int ret; 512 int ret;
392 513
514 unsigned long flags_spin;
393 struct iwl_rem_sta_cmd rm_sta_cmd; 515 struct iwl_rem_sta_cmd rm_sta_cmd;
394 516
395 struct iwl_host_cmd cmd = { 517 struct iwl_host_cmd cmd = {
396 .id = REPLY_REMOVE_STA, 518 .id = REPLY_REMOVE_STA,
397 .len = sizeof(struct iwl_rem_sta_cmd), 519 .len = sizeof(struct iwl_rem_sta_cmd),
398 .flags = flags, 520 .flags = CMD_SYNC,
399 .data = &rm_sta_cmd, 521 .data = &rm_sta_cmd,
400 }; 522 };
401 523
402 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 524 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
403 rm_sta_cmd.num_sta = 1; 525 rm_sta_cmd.num_sta = 1;
404 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 526 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN);
527
528 cmd.flags |= CMD_WANT_SKB;
405 529
406 if (flags & CMD_ASYNC)
407 cmd.callback = iwl_remove_sta_callback;
408 else
409 cmd.flags |= CMD_WANT_SKB;
410 ret = iwl_send_cmd(priv, &cmd); 530 ret = iwl_send_cmd(priv, &cmd);
411 531
412 if (ret || (flags & CMD_ASYNC)) 532 if (ret)
413 return ret; 533 return ret;
414 534
415 pkt = (struct iwl_rx_packet *)cmd.reply_page; 535 pkt = (struct iwl_rx_packet *)cmd.reply_page;
@@ -422,7 +542,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
422 if (!ret) { 542 if (!ret) {
423 switch (pkt->u.rem_sta.status) { 543 switch (pkt->u.rem_sta.status) {
424 case REM_STA_SUCCESS_MSK: 544 case REM_STA_SUCCESS_MSK:
425 iwl_sta_ucode_deactivate(priv, addr); 545 spin_lock_irqsave(&priv->sta_lock, flags_spin);
546 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id);
547 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
426 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 548 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
427 break; 549 break;
428 default: 550 default:
@@ -439,23 +561,35 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
439/** 561/**
440 * iwl_remove_station - Remove driver's knowledge of station. 562 * iwl_remove_station - Remove driver's knowledge of station.
441 */ 563 */
442int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap) 564static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
443{ 565{
444 int sta_id = IWL_INVALID_STATION; 566 int sta_id = IWL_INVALID_STATION;
445 int i, ret = -EINVAL; 567 int i, ret = -EINVAL;
446 unsigned long flags; 568 unsigned long flags;
569 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
570 struct iwl_station_entry *station;
571
572 if (!iwl_is_ready(priv)) {
573 IWL_DEBUG_INFO(priv,
574 "Unable to remove station %pM, device not ready. \n",
575 sta->addr);
576 /*
577 * It is typical for stations to be removed when we are
578 * going down. Return success since device will be down
579 * soon anyway
580 */
581 return 0;
582 }
447 583
448 spin_lock_irqsave(&priv->sta_lock, flags); 584 spin_lock_irqsave(&priv->sta_lock, flags);
449 585
450 if (is_ap) 586 if (is_ap)
451 sta_id = IWL_AP_ID; 587 sta_id = IWL_AP_ID;
452 else if (is_broadcast_ether_addr(addr))
453 sta_id = priv->hw_params.bcast_sta_id;
454 else 588 else
455 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) 589 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
456 if (priv->stations[i].used && 590 if (priv->stations[i].used &&
457 !compare_ether_addr(priv->stations[i].sta.sta.addr, 591 !compare_ether_addr(priv->stations[i].sta.sta.addr,
458 addr)) { 592 sta->addr)) {
459 sta_id = i; 593 sta_id = i;
460 break; 594 break;
461 } 595 }
@@ -464,17 +598,17 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
464 goto out; 598 goto out;
465 599
466 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 600 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
467 sta_id, addr); 601 sta_id, sta->addr);
468 602
469 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 603 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
470 IWL_ERR(priv, "Removing %pM but non DRIVER active\n", 604 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
471 addr); 605 sta->addr);
472 goto out; 606 goto out;
473 } 607 }
474 608
475 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 609 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
476 IWL_ERR(priv, "Removing %pM but non UCODE active\n", 610 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
477 addr); 611 sta->addr);
478 goto out; 612 goto out;
479 } 613 }
480 614
@@ -485,9 +619,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
485 619
486 BUG_ON(priv->num_stations < 0); 620 BUG_ON(priv->num_stations < 0);
487 621
622 station = &priv->stations[sta_id];
488 spin_unlock_irqrestore(&priv->sta_lock, flags); 623 spin_unlock_irqrestore(&priv->sta_lock, flags);
489 624
490 ret = iwl_send_remove_station(priv, addr, CMD_ASYNC); 625 ret = iwl_send_remove_station(priv, station);
491 return ret; 626 return ret;
492out: 627out:
493 spin_unlock_irqrestore(&priv->sta_lock, flags); 628 spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -495,37 +630,122 @@ out:
495} 630}
496 631
497/** 632/**
498 * iwl_clear_stations_table - Clear the driver's station table 633 * iwl_clear_ucode_stations() - clear entire station table driver and/or ucode
499 * 634 * @priv:
500 * NOTE: This does not clear or otherwise alter the device's station table. 635 * @force: If set then the uCode station table needs to be cleared here. If
636 * not set then the uCode station table has already been cleared,
637 * for example after sending it a RXON command without ASSOC bit
638 * set, and we just need to change driver state here.
501 */ 639 */
502void iwl_clear_stations_table(struct iwl_priv *priv) 640void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force)
503{ 641{
504 unsigned long flags;
505 int i; 642 int i;
643 unsigned long flags_spin;
644 bool cleared = false;
645
646 IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver%s\n",
647 force ? " and ucode" : "");
648
649 if (force) {
650 if (!iwl_is_ready(priv)) {
651 /*
652 * If device is not ready at this point the station
653 * table is likely already empty (uCode not ready
654 * to receive station requests) or will soon be
655 * due to interface going down.
656 */
657 IWL_DEBUG_INFO(priv, "Unable to remove stations from device - device not ready\n");
658 } else {
659 iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL);
660 }
661 }
506 662
507 spin_lock_irqsave(&priv->sta_lock, flags); 663 spin_lock_irqsave(&priv->sta_lock, flags_spin);
664 if (force) {
665 IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n");
666 priv->num_stations = 0;
667 memset(priv->stations, 0, sizeof(priv->stations));
668 } else {
669 for (i = 0; i < priv->hw_params.max_stations; i++) {
670 if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
671 IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d \n", i);
672 priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
673 cleared = true;
674 }
675 }
676 }
677 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
508 678
509 if (iwl_is_alive(priv) && 679 if (!cleared)
510 !test_bit(STATUS_EXIT_PENDING, &priv->status) && 680 IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
511 iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL)) 681}
512 IWL_ERR(priv, "Couldn't clear the station table\n"); 682EXPORT_SYMBOL(iwl_clear_ucode_stations);
513 683
514 priv->num_stations = 0; 684/**
515 memset(priv->stations, 0, sizeof(priv->stations)); 685 * iwl_restore_stations() - Restore driver known stations to device
686 *
687 * All stations considered active by driver, but not present in ucode, is
688 * restored.
689 *
690 * Function sleeps.
691 */
692void iwl_restore_stations(struct iwl_priv *priv)
693{
694 struct iwl_station_entry *station;
695 unsigned long flags_spin;
696 int i;
697 bool found = false;
698 int ret;
516 699
517 /* clean ucode key table bit map */ 700 if (!iwl_is_ready(priv)) {
518 priv->ucode_key_table = 0; 701 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
702 return;
703 }
519 704
520 /* keep track of static keys */ 705 IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
521 for (i = 0; i < WEP_KEYS_MAX ; i++) { 706 spin_lock_irqsave(&priv->sta_lock, flags_spin);
522 if (priv->wep_keys[i].key_size) 707 for (i = 0; i < priv->hw_params.max_stations; i++) {
523 set_bit(i, &priv->ucode_key_table); 708 if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
709 !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
710 IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
711 priv->stations[i].sta.sta.addr);
712 priv->stations[i].sta.mode = 0;
713 priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
714 found = true;
715 }
524 } 716 }
525 717
526 spin_unlock_irqrestore(&priv->sta_lock, flags); 718 for (i = 0; i < priv->hw_params.max_stations; i++) {
719 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
720 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
721 station = &priv->stations[i];
722 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
723 if (ret) {
724 IWL_ERR(priv, "Adding station %pM failed.\n",
725 station->sta.sta.addr);
726 spin_lock_irqsave(&priv->sta_lock, flags_spin);
727 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
728 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
729 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
730 }
731 /*
732 * Rate scaling has already been initialized, send
733 * current LQ command
734 */
735 if (station->lq)
736 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true);
737 spin_lock_irqsave(&priv->sta_lock, flags_spin);
738 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
739 }
740 }
741
742 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
743 if (!found)
744 IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
745 else
746 IWL_DEBUG_INFO(priv, "Restoring all known stations .... complete.\n");
527} 747}
528EXPORT_SYMBOL(iwl_clear_stations_table); 748EXPORT_SYMBOL(iwl_restore_stations);
529 749
530int iwl_get_free_ucode_key_index(struct iwl_priv *priv) 750int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
531{ 751{
@@ -948,9 +1168,22 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
948} 1168}
949#endif 1169#endif
950 1170
1171/**
1172 * iwl_send_lq_cmd() - Send link quality command
1173 * @init: This command is sent as part of station initialization right
1174 * after station has been added.
1175 *
1176 * The link quality command is sent as the last step of station creation.
1177 * This is the special case in which init is set and we call a callback in
1178 * this case to clear the state indicating that station creation is in
1179 * progress.
1180 */
951int iwl_send_lq_cmd(struct iwl_priv *priv, 1181int iwl_send_lq_cmd(struct iwl_priv *priv,
952 struct iwl_link_quality_cmd *lq, u8 flags) 1182 struct iwl_link_quality_cmd *lq, u8 flags, bool init)
953{ 1183{
1184 int ret = 0;
1185 unsigned long flags_spin;
1186
954 struct iwl_host_cmd cmd = { 1187 struct iwl_host_cmd cmd = {
955 .id = REPLY_TX_LINK_QUALITY_CMD, 1188 .id = REPLY_TX_LINK_QUALITY_CMD,
956 .len = sizeof(struct iwl_link_quality_cmd), 1189 .len = sizeof(struct iwl_link_quality_cmd),
@@ -966,167 +1199,31 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
966 lq->sta_id = IWL_AP_ID; 1199 lq->sta_id = IWL_AP_ID;
967 1200
968 iwl_dump_lq_cmd(priv, lq); 1201 iwl_dump_lq_cmd(priv, lq);
1202 BUG_ON(init && (cmd.flags & CMD_ASYNC));
969 1203
970 if (iwl_is_associated(priv) && priv->assoc_station_added) 1204 iwl_dump_lq_cmd(priv, lq);
971 return iwl_send_cmd(priv, &cmd); 1205 ret = iwl_send_cmd(priv, &cmd);
1206 if (ret || (cmd.flags & CMD_ASYNC))
1207 return ret;
972 1208
1209 if (init) {
1210 IWL_DEBUG_INFO(priv, "init LQ command complete, clearing sta addition status for sta %d \n",
1211 lq->sta_id);
1212 spin_lock_irqsave(&priv->sta_lock, flags_spin);
1213 priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1214 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
1215 }
973 return 0; 1216 return 0;
974} 1217}
975EXPORT_SYMBOL(iwl_send_lq_cmd); 1218EXPORT_SYMBOL(iwl_send_lq_cmd);
976 1219
977/** 1220/**
978 * iwl_sta_init_lq - Initialize a station's hardware rate table
979 *
980 * The uCode's station table contains a table of fallback rates
981 * for automatic fallback during transmission.
982 *
983 * NOTE: This sets up a default set of values. These will be replaced later
984 * if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
985 * rc80211_simple.
986 *
987 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
988 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
989 * which requires station table entry to exist).
990 */
991static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
992{
993 int i, r;
994 struct iwl_link_quality_cmd link_cmd = {
995 .reserved1 = 0,
996 };
997 u32 rate_flags;
998
999 /* Set up the rate scaling to start at selected rate, fall back
1000 * all the way down to 1M in IEEE order, and then spin on 1M */
1001 if (is_ap)
1002 r = IWL_RATE_54M_INDEX;
1003 else if (priv->band == IEEE80211_BAND_5GHZ)
1004 r = IWL_RATE_6M_INDEX;
1005 else
1006 r = IWL_RATE_1M_INDEX;
1007
1008 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1009 rate_flags = 0;
1010 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1011 rate_flags |= RATE_MCS_CCK_MSK;
1012
1013 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1014 RATE_MCS_ANT_POS;
1015
1016 link_cmd.rs_table[i].rate_n_flags =
1017 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1018 r = iwl_get_prev_ieee_rate(r);
1019 }
1020
1021 link_cmd.general_params.single_stream_ant_msk =
1022 first_antenna(priv->hw_params.valid_tx_ant);
1023 link_cmd.general_params.dual_stream_ant_msk = 3;
1024 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1025 link_cmd.agg_params.agg_time_limit =
1026 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1027
1028 /* Update the rate scaling for control frame Tx to AP */
1029 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
1030
1031 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1032 sizeof(link_cmd), &link_cmd, NULL);
1033}
1034
1035/**
1036 * iwl_rxon_add_station - add station into station table.
1037 *
1038 * there is only one AP station with id= IWL_AP_ID
1039 * NOTE: mutex must be held before calling this function
1040 */
1041int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
1042{
1043 struct ieee80211_sta *sta;
1044 struct ieee80211_sta_ht_cap ht_config;
1045 struct ieee80211_sta_ht_cap *cur_ht_config = NULL;
1046 u8 sta_id;
1047
1048 /*
1049 * Set HT capabilities. It is ok to set this struct even if not using
1050 * HT config: the priv->current_ht_config.is_ht flag will just be false
1051 */
1052 rcu_read_lock();
1053 sta = ieee80211_find_sta(priv->vif, addr);
1054 if (sta) {
1055 memcpy(&ht_config, &sta->ht_cap, sizeof(ht_config));
1056 cur_ht_config = &ht_config;
1057 }
1058 rcu_read_unlock();
1059
1060 /* Add station to device's station table */
1061 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1062
1063 /* Set up default rate scaling table in device's station table */
1064 iwl_sta_init_lq(priv, addr, is_ap);
1065
1066 return sta_id;
1067}
1068EXPORT_SYMBOL(iwl_rxon_add_station);
1069
1070/**
1071 * iwl_sta_init_bcast_lq - Initialize a bcast station's hardware rate table
1072 *
1073 * NOTE: Run REPLY_ADD_STA command to set up station table entry, before
1074 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
1075 * which requires station table entry to exist).
1076 */
1077static void iwl_sta_init_bcast_lq(struct iwl_priv *priv)
1078{
1079 int i, r;
1080 struct iwl_link_quality_cmd link_cmd = {
1081 .reserved1 = 0,
1082 };
1083 u32 rate_flags;
1084
1085 /* Set up the rate scaling to start at selected rate, fall back
1086 * all the way down to 1M in IEEE order, and then spin on 1M */
1087 if (priv->band == IEEE80211_BAND_5GHZ)
1088 r = IWL_RATE_6M_INDEX;
1089 else
1090 r = IWL_RATE_1M_INDEX;
1091
1092 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1093 rate_flags = 0;
1094 if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE)
1095 rate_flags |= RATE_MCS_CCK_MSK;
1096
1097 rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
1098 RATE_MCS_ANT_POS;
1099
1100 link_cmd.rs_table[i].rate_n_flags =
1101 iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
1102 r = iwl_get_prev_ieee_rate(r);
1103 }
1104
1105 link_cmd.general_params.single_stream_ant_msk =
1106 first_antenna(priv->hw_params.valid_tx_ant);
1107 link_cmd.general_params.dual_stream_ant_msk = 3;
1108 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1109 link_cmd.agg_params.agg_time_limit =
1110 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1111
1112 /* Update the rate scaling for control frame Tx to AP */
1113 link_cmd.sta_id = priv->hw_params.bcast_sta_id;
1114
1115 iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
1116 sizeof(link_cmd), &link_cmd, NULL);
1117}
1118
1119
1120/**
1121 * iwl_add_bcast_station - add broadcast station into station table. 1221 * iwl_add_bcast_station - add broadcast station into station table.
1122 */ 1222 */
1123void iwl_add_bcast_station(struct iwl_priv *priv) 1223void iwl_add_bcast_station(struct iwl_priv *priv)
1124{ 1224{
1125 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1225 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1126 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1226 iwl_add_local_station(priv, iwl_bcast_addr, true);
1127
1128 /* Set up default rate scaling table in device's station table */
1129 iwl_sta_init_bcast_lq(priv);
1130} 1227}
1131EXPORT_SYMBOL(iwl_add_bcast_station); 1228EXPORT_SYMBOL(iwl_add_bcast_station);
1132 1229
@@ -1136,7 +1233,14 @@ EXPORT_SYMBOL(iwl_add_bcast_station);
1136void iwl3945_add_bcast_station(struct iwl_priv *priv) 1233void iwl3945_add_bcast_station(struct iwl_priv *priv)
1137{ 1234{
1138 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); 1235 IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
1139 iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL); 1236 iwl_add_local_station(priv, iwl_bcast_addr, false);
1237 /*
1238 * It is assumed that when station is added more initialization
1239 * needs to be done, but for 3945 it is not the case and we can
1240 * just release station table access right here.
1241 */
1242 priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
1243
1140} 1244}
1141EXPORT_SYMBOL(iwl3945_add_bcast_station); 1245EXPORT_SYMBOL(iwl3945_add_bcast_station);
1142 1246
@@ -1159,6 +1263,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1159 /* If we are a client station in a BSS network, use the special 1263 /* If we are a client station in a BSS network, use the special
1160 * AP station entry (that's the only station we communicate with) */ 1264 * AP station entry (that's the only station we communicate with) */
1161 case NL80211_IFTYPE_STATION: 1265 case NL80211_IFTYPE_STATION:
1266 /*
1267 * If addition of station not complete yet, which means
1268 * that rate scaling has not been initialized, then return
1269 * the broadcast station.
1270 */
1271 if (!(priv->stations[IWL_AP_ID].used & IWL_STA_UCODE_ACTIVE))
1272 return priv->hw_params.bcast_sta_id;
1162 return IWL_AP_ID; 1273 return IWL_AP_ID;
1163 1274
1164 /* If we are an AP, then find the station, or use BCAST */ 1275 /* If we are an AP, then find the station, or use BCAST */
@@ -1175,13 +1286,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1175 if (sta_id != IWL_INVALID_STATION) 1286 if (sta_id != IWL_INVALID_STATION)
1176 return sta_id; 1287 return sta_id;
1177 1288
1178 /* Create new station table entry */
1179 sta_id = iwl_add_station(priv, hdr->addr1, false,
1180 CMD_ASYNC, NULL);
1181
1182 if (sta_id != IWL_INVALID_STATION)
1183 return sta_id;
1184
1185 IWL_DEBUG_DROP(priv, "Station %pM not in station map. " 1289 IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
1186 "Defaulting to broadcast...\n", 1290 "Defaulting to broadcast...\n",
1187 hdr->addr1); 1291 hdr->addr1);
@@ -1291,3 +1395,19 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1291 1395
1292 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1396 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1293} 1397}
1398
1399int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1400 struct ieee80211_vif *vif,
1401 struct ieee80211_sta *sta)
1402{
1403 int ret;
1404 struct iwl_priv *priv = hw->priv;
1405 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
1406 sta->addr);
1407 ret = iwl_remove_station(priv, sta);
1408 if (ret)
1409 IWL_ERR(priv, "Error removing station %pM\n",
1410 sta->addr);
1411 return ret;
1412}
1413EXPORT_SYMBOL(iwl_mac_sta_remove);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 2dc35fe28f56..87a34997a758 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -32,6 +32,12 @@
32#define HW_KEY_DYNAMIC 0 32#define HW_KEY_DYNAMIC 0
33#define HW_KEY_DEFAULT 1 33#define HW_KEY_DEFAULT 1
34 34
35#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
36#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
37#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
38 being activated */
39
40
35/** 41/**
36 * iwl_find_station - Find station id for a given BSSID 42 * iwl_find_station - Find station id for a given BSSID
37 * @bssid: MAC address of station ID to find 43 * @bssid: MAC address of station ID to find
@@ -51,18 +57,22 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
51 struct ieee80211_key_conf *keyconf, 57 struct ieee80211_key_conf *keyconf,
52 const u8 *addr, u32 iv32, u16 *phase1key); 58 const u8 *addr, u32 iv32, u16 *phase1key);
53 59
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55void iwl_add_bcast_station(struct iwl_priv *priv); 60void iwl_add_bcast_station(struct iwl_priv *priv);
56void iwl3945_add_bcast_station(struct iwl_priv *priv); 61void iwl3945_add_bcast_station(struct iwl_priv *priv);
57int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); 62void iwl_restore_stations(struct iwl_priv *priv);
58void iwl_clear_stations_table(struct iwl_priv *priv); 63void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force);
59int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 64int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
60int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 65int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
61int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 66int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
62int iwl_send_add_sta(struct iwl_priv *priv, 67int iwl_send_add_sta(struct iwl_priv *priv,
63 struct iwl_addsta_cmd *sta, u8 flags); 68 struct iwl_addsta_cmd *sta, u8 flags);
64u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags, 69int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs);
65 struct ieee80211_sta_ht_cap *ht_info); 70int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
71 bool is_ap,
72 struct ieee80211_sta_ht_cap *ht_info,
73 u8 *sta_id_r);
74int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
75 struct ieee80211_sta *sta);
66void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 76void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
67int iwl_sta_rx_agg_start(struct iwl_priv *priv, 77int iwl_sta_rx_agg_start(struct iwl_priv *priv,
68 const u8 *addr, int tid, u16 ssn); 78 const u8 *addr, int tid, u16 ssn);
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index d6222aabe6ed..1e481f3fcabf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -322,6 +322,8 @@ static int iwl_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
322 q->high_mark = 2; 322 q->high_mark = 2;
323 323
324 q->write_ptr = q->read_ptr = 0; 324 q->write_ptr = q->read_ptr = 0;
325 q->last_read_ptr = 0;
326 q->repeat_same_read_ptr = 0;
325 327
326 return 0; 328 return 0;
327} 329}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 2579bbcaab36..4995134d7e4a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2480,8 +2480,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2480 goto restart; 2480 goto restart;
2481 } 2481 }
2482 2482
2483 iwl_clear_stations_table(priv);
2484
2485 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2483 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2486 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2484 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
2487 2485
@@ -2503,6 +2501,13 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2503 /* After the ALIVE response, we can send commands to 3945 uCode */ 2501 /* After the ALIVE response, we can send commands to 3945 uCode */
2504 set_bit(STATUS_ALIVE, &priv->status); 2502 set_bit(STATUS_ALIVE, &priv->status);
2505 2503
2504 if (priv->cfg->ops->lib->recover_from_tx_stall) {
2505 /* Enable timer to monitor the driver queues */
2506 mod_timer(&priv->monitor_recover,
2507 jiffies +
2508 msecs_to_jiffies(priv->cfg->monitor_recover_period));
2509 }
2510
2506 if (iwl_is_rfkill(priv)) 2511 if (iwl_is_rfkill(priv))
2507 return; 2512 return;
2508 2513
@@ -2558,7 +2563,8 @@ static void __iwl3945_down(struct iwl_priv *priv)
2558 if (!exit_pending) 2563 if (!exit_pending)
2559 set_bit(STATUS_EXIT_PENDING, &priv->status); 2564 set_bit(STATUS_EXIT_PENDING, &priv->status);
2560 2565
2561 iwl_clear_stations_table(priv); 2566 /* Station information will now be cleared in device */
2567 iwl_clear_ucode_stations(priv, true);
2562 2568
2563 /* Unblock any waiting calls */ 2569 /* Unblock any waiting calls */
2564 wake_up_interruptible_all(&priv->wait_command_queue); 2570 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2692,8 +2698,6 @@ static int __iwl3945_up(struct iwl_priv *priv)
2692 2698
2693 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2699 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2694 2700
2695 iwl_clear_stations_table(priv);
2696
2697 /* load bootstrap state machine, 2701 /* load bootstrap state machine,
2698 * load bootstrap program into processor's memory, 2702 * load bootstrap program into processor's memory,
2699 * prepare to load the "initialize" uCode */ 2703 * prepare to load the "initialize" uCode */
@@ -3119,12 +3123,13 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3119 case NL80211_IFTYPE_ADHOC: 3123 case NL80211_IFTYPE_ADHOC:
3120 3124
3121 priv->assoc_id = 1; 3125 priv->assoc_id = 1;
3122 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL); 3126 iwl_add_local_station(priv, priv->bssid, false);
3123 iwl3945_sync_sta(priv, IWL_STA_ID, 3127 iwl3945_sync_sta(priv, IWL_STA_ID,
3124 (priv->band == IEEE80211_BAND_5GHZ) ? 3128 (priv->band == IEEE80211_BAND_5GHZ) ?
3125 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 3129 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
3126 CMD_ASYNC); 3130 CMD_ASYNC);
3127 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID); 3131 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
3132
3128 iwl3945_send_beacon_cmd(priv); 3133 iwl3945_send_beacon_cmd(priv);
3129 3134
3130 break; 3135 break;
@@ -3309,7 +3314,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3309 /* restore RXON assoc */ 3314 /* restore RXON assoc */
3310 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3315 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3311 iwlcore_commit_rxon(priv); 3316 iwlcore_commit_rxon(priv);
3312 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL); 3317 iwl_add_local_station(priv, iwl_bcast_addr, false);
3313 } 3318 }
3314 iwl3945_send_beacon_cmd(priv); 3319 iwl3945_send_beacon_cmd(priv);
3315 3320
@@ -3376,6 +3381,38 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3376 return ret; 3381 return ret;
3377} 3382}
3378 3383
3384static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3385 struct ieee80211_vif *vif,
3386 struct ieee80211_sta *sta)
3387{
3388 struct iwl_priv *priv = hw->priv;
3389 int ret;
3390 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
3391 u8 sta_id;
3392
3393 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3394 sta->addr);
3395
3396 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap,
3397 &sta_id);
3398 if (ret) {
3399 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3400 sta->addr, ret);
3401 /* Should we return success if return code is EEXIST ? */
3402 return ret;
3403 }
3404
3405 /* Initialize rate scaling */
3406 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM \n",
3407 sta->addr);
3408 iwl3945_rs_rate_init(priv, sta, sta_id);
3409
3410 return 0;
3411
3412
3413
3414 return ret;
3415}
3379/***************************************************************************** 3416/*****************************************************************************
3380 * 3417 *
3381 * sysfs attributes 3418 * sysfs attributes
@@ -3766,6 +3803,13 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3766 3803
3767 iwl3945_hw_setup_deferred_work(priv); 3804 iwl3945_hw_setup_deferred_work(priv);
3768 3805
3806 if (priv->cfg->ops->lib->recover_from_tx_stall) {
3807 init_timer(&priv->monitor_recover);
3808 priv->monitor_recover.data = (unsigned long)priv;
3809 priv->monitor_recover.function =
3810 priv->cfg->ops->lib->recover_from_tx_stall;
3811 }
3812
3769 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) 3813 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
3770 iwl3945_irq_tasklet, (unsigned long)priv); 3814 iwl3945_irq_tasklet, (unsigned long)priv);
3771} 3815}
@@ -3778,6 +3822,8 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3778 cancel_delayed_work(&priv->scan_check); 3822 cancel_delayed_work(&priv->scan_check);
3779 cancel_delayed_work(&priv->alive_start); 3823 cancel_delayed_work(&priv->alive_start);
3780 cancel_work_sync(&priv->beacon_update); 3824 cancel_work_sync(&priv->beacon_update);
3825 if (priv->cfg->ops->lib->recover_from_tx_stall)
3826 del_timer_sync(&priv->monitor_recover);
3781} 3827}
3782 3828
3783static struct attribute *iwl3945_sysfs_entries[] = { 3829static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3815,7 +3861,9 @@ static struct ieee80211_ops iwl3945_hw_ops = {
3815 .conf_tx = iwl_mac_conf_tx, 3861 .conf_tx = iwl_mac_conf_tx,
3816 .reset_tsf = iwl_mac_reset_tsf, 3862 .reset_tsf = iwl_mac_reset_tsf,
3817 .bss_info_changed = iwl_bss_info_changed, 3863 .bss_info_changed = iwl_bss_info_changed,
3818 .hw_scan = iwl_mac_hw_scan 3864 .hw_scan = iwl_mac_hw_scan,
3865 .sta_add = iwl3945_mac_sta_add,
3866 .sta_remove = iwl_mac_sta_remove,
3819}; 3867};
3820 3868
3821static int iwl3945_init_drv(struct iwl_priv *priv) 3869static int iwl3945_init_drv(struct iwl_priv *priv)
@@ -3834,9 +3882,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
3834 mutex_init(&priv->mutex); 3882 mutex_init(&priv->mutex);
3835 mutex_init(&priv->sync_cmd_mutex); 3883 mutex_init(&priv->sync_cmd_mutex);
3836 3884
3837 /* Clear the driver's (not device's) station table */
3838 iwl_clear_stations_table(priv);
3839
3840 priv->ieee_channels = NULL; 3885 priv->ieee_channels = NULL;
3841 priv->ieee_rates = NULL; 3886 priv->ieee_rates = NULL;
3842 priv->band = IEEE80211_BAND_2GHZ; 3887 priv->band = IEEE80211_BAND_2GHZ;
@@ -4196,7 +4241,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4196 iwl3945_hw_txq_ctx_free(priv); 4241 iwl3945_hw_txq_ctx_free(priv);
4197 4242
4198 iwl3945_unset_hw_params(priv); 4243 iwl3945_unset_hw_params(priv);
4199 iwl_clear_stations_table(priv);
4200 4244
4201 /*netif_stop_queue(dev); */ 4245 /*netif_stop_queue(dev); */
4202 flush_workqueue(priv->workqueue); 4246 flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index f03d5e4e59c3..95d3d4c5e08b 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -31,6 +31,9 @@ u8 lbs_bg_rates[MAX_RATES] =
310x00, 0x00 }; 310x00, 0x00 };
32 32
33 33
34static int assoc_helper_wep_keys(struct lbs_private *priv,
35 struct assoc_request *assoc_req);
36
34/** 37/**
35 * @brief This function finds common rates between rates and card rates. 38 * @brief This function finds common rates between rates and card rates.
36 * 39 *
@@ -610,7 +613,7 @@ static int lbs_assoc_post(struct lbs_private *priv,
610 613
611 if (status_code) { 614 if (status_code) {
612 lbs_mac_event_disconnected(priv); 615 lbs_mac_event_disconnected(priv);
613 ret = -1; 616 ret = status_code;
614 goto done; 617 goto done;
615 } 618 }
616 619
@@ -813,7 +816,24 @@ static int lbs_try_associate(struct lbs_private *priv,
813 goto out; 816 goto out;
814 817
815 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE); 818 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
819 /* If the association fails with current auth mode, let's
820 * try by changing the auth mode
821 */
822 if ((priv->authtype_auto) &&
823 (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) &&
824 (assoc_req->secinfo.wep_enabled) &&
825 (priv->connect_status != LBS_CONNECTED)) {
826 if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM)
827 priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
828 else
829 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
830 if (!assoc_helper_wep_keys(priv, assoc_req))
831 ret = lbs_associate(priv, assoc_req,
832 CMD_802_11_ASSOCIATE);
833 }
816 834
835 if (ret)
836 ret = -1;
817out: 837out:
818 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 838 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
819 return ret; 839 return ret;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 6977ee820214..058d1720242e 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -133,6 +133,7 @@ struct lbs_private {
133 u8 wpa_ie_len; 133 u8 wpa_ie_len;
134 u16 wep_tx_keyidx; 134 u16 wep_tx_keyidx;
135 struct enc_key wep_keys[4]; 135 struct enc_key wep_keys[4];
136 u8 authtype_auto;
136 137
137 /* Wake On LAN */ 138 /* Wake On LAN */
138 uint32_t wol_criteria; 139 uint32_t wol_criteria;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 28a1c9d1627a..3c889f43d909 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -835,6 +835,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
835 priv->is_auto_deep_sleep_enabled = 0; 835 priv->is_auto_deep_sleep_enabled = 0;
836 priv->wakeup_dev_required = 0; 836 priv->wakeup_dev_required = 0;
837 init_waitqueue_head(&priv->ds_awake_q); 837 init_waitqueue_head(&priv->ds_awake_q);
838 priv->authtype_auto = 1;
838 839
839 mutex_init(&priv->lock); 840 mutex_init(&priv->lock);
840 841
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 71f88a08e090..aad6263dee6d 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1440,8 +1440,10 @@ static int lbs_set_encode(struct net_device *dev,
1440 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags); 1440 set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
1441 1441
1442 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1442 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1443 priv->authtype_auto = 0;
1443 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1444 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1444 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1445 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1446 priv->authtype_auto = 0;
1445 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1447 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1446 } 1448 }
1447 1449
@@ -1620,8 +1622,10 @@ static int lbs_set_encodeext(struct net_device *dev,
1620 goto out; 1622 goto out;
1621 1623
1622 if (dwrq->flags & IW_ENCODE_RESTRICTED) { 1624 if (dwrq->flags & IW_ENCODE_RESTRICTED) {
1625 priv->authtype_auto = 0;
1623 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY; 1626 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
1624 } else if (dwrq->flags & IW_ENCODE_OPEN) { 1627 } else if (dwrq->flags & IW_ENCODE_OPEN) {
1628 priv->authtype_auto = 0;
1625 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1629 assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1626 } 1630 }
1627 1631
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 31ca241f7753..29f9bc03190a 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1505,46 +1505,44 @@ static const struct iw_priv_args orinoco_privtab[] = {
1505 * Structures to export the Wireless Handlers 1505 * Structures to export the Wireless Handlers
1506 */ 1506 */
1507 1507
1508#define STD_IW_HANDLER(id, func) \
1509 [IW_IOCTL_IDX(id)] = (iw_handler) func
1510static const iw_handler orinoco_handler[] = { 1508static const iw_handler orinoco_handler[] = {
1511 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit), 1509 IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit),
1512 STD_IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname), 1510 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
1513 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq), 1511 IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq),
1514 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq), 1512 IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq),
1515 STD_IW_HANDLER(SIOCSIWMODE, cfg80211_wext_siwmode), 1513 IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode),
1516 STD_IW_HANDLER(SIOCGIWMODE, cfg80211_wext_giwmode), 1514 IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode),
1517 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens), 1515 IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens),
1518 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens), 1516 IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens),
1519 STD_IW_HANDLER(SIOCGIWRANGE, cfg80211_wext_giwrange), 1517 IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange),
1520 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy), 1518 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1521 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy), 1519 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1522 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy), 1520 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1523 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy), 1521 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1524 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap), 1522 IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap),
1525 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap), 1523 IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap),
1526 STD_IW_HANDLER(SIOCSIWSCAN, cfg80211_wext_siwscan), 1524 IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan),
1527 STD_IW_HANDLER(SIOCGIWSCAN, cfg80211_wext_giwscan), 1525 IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan),
1528 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid), 1526 IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid),
1529 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid), 1527 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1530 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate), 1528 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1531 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate), 1529 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1532 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts), 1530 IW_HANDLER(SIOCSIWRTS, (iw_handler)orinoco_ioctl_setrts),
1533 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts), 1531 IW_HANDLER(SIOCGIWRTS, (iw_handler)orinoco_ioctl_getrts),
1534 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag), 1532 IW_HANDLER(SIOCSIWFRAG, (iw_handler)orinoco_ioctl_setfrag),
1535 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag), 1533 IW_HANDLER(SIOCGIWFRAG, (iw_handler)orinoco_ioctl_getfrag),
1536 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry), 1534 IW_HANDLER(SIOCGIWRETRY, (iw_handler)orinoco_ioctl_getretry),
1537 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode), 1535 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1538 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode), 1536 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1539 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower), 1537 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),
1540 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower), 1538 IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower),
1541 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie), 1539 IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
1542 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie), 1540 IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
1543 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme), 1541 IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
1544 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth), 1542 IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
1545 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth), 1543 IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
1546 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext), 1544 IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
1547 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext), 1545 IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
1548}; 1546};
1549 1547
1550 1548
@@ -1552,15 +1550,15 @@ static const iw_handler orinoco_handler[] = {
1552 Added typecasting since we no longer use iwreq_data -- Moustafa 1550 Added typecasting since we no longer use iwreq_data -- Moustafa
1553 */ 1551 */
1554static const iw_handler orinoco_private_handler[] = { 1552static const iw_handler orinoco_private_handler[] = {
1555 [0] = (iw_handler) orinoco_ioctl_reset, 1553 [0] = (iw_handler)orinoco_ioctl_reset,
1556 [1] = (iw_handler) orinoco_ioctl_reset, 1554 [1] = (iw_handler)orinoco_ioctl_reset,
1557 [2] = (iw_handler) orinoco_ioctl_setport3, 1555 [2] = (iw_handler)orinoco_ioctl_setport3,
1558 [3] = (iw_handler) orinoco_ioctl_getport3, 1556 [3] = (iw_handler)orinoco_ioctl_getport3,
1559 [4] = (iw_handler) orinoco_ioctl_setpreamble, 1557 [4] = (iw_handler)orinoco_ioctl_setpreamble,
1560 [5] = (iw_handler) orinoco_ioctl_getpreamble, 1558 [5] = (iw_handler)orinoco_ioctl_getpreamble,
1561 [6] = (iw_handler) orinoco_ioctl_setibssport, 1559 [6] = (iw_handler)orinoco_ioctl_setibssport,
1562 [7] = (iw_handler) orinoco_ioctl_getibssport, 1560 [7] = (iw_handler)orinoco_ioctl_getibssport,
1563 [9] = (iw_handler) orinoco_ioctl_getrid, 1561 [9] = (iw_handler)orinoco_ioctl_getrid,
1564}; 1562};
1565 1563
1566const struct iw_handler_def orinoco_handler_def = { 1564const struct iw_handler_def orinoco_handler_def = {
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 84c530aa52f9..4f5bdb528ef7 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1113,10 +1113,10 @@ static const struct ethtool_ops netdev_ethtool_ops = {
1113/* 1113/*
1114 * Wireless Handler : get protocol name 1114 * Wireless Handler : get protocol name
1115 */ 1115 */
1116static int ray_get_name(struct net_device *dev, 1116static int ray_get_name(struct net_device *dev, struct iw_request_info *info,
1117 struct iw_request_info *info, char *cwrq, char *extra) 1117 union iwreq_data *wrqu, char *extra)
1118{ 1118{
1119 strcpy(cwrq, "IEEE 802.11-FH"); 1119 strcpy(wrqu->name, "IEEE 802.11-FH");
1120 return 0; 1120 return 0;
1121} 1121}
1122 1122
@@ -1124,9 +1124,8 @@ static int ray_get_name(struct net_device *dev,
1124/* 1124/*
1125 * Wireless Handler : set frequency 1125 * Wireless Handler : set frequency
1126 */ 1126 */
1127static int ray_set_freq(struct net_device *dev, 1127static int ray_set_freq(struct net_device *dev, struct iw_request_info *info,
1128 struct iw_request_info *info, 1128 union iwreq_data *wrqu, char *extra)
1129 struct iw_freq *fwrq, char *extra)
1130{ 1129{
1131 ray_dev_t *local = netdev_priv(dev); 1130 ray_dev_t *local = netdev_priv(dev);
1132 int err = -EINPROGRESS; /* Call commit handler */ 1131 int err = -EINPROGRESS; /* Call commit handler */
@@ -1136,10 +1135,10 @@ static int ray_set_freq(struct net_device *dev,
1136 return -EBUSY; 1135 return -EBUSY;
1137 1136
1138 /* Setting by channel number */ 1137 /* Setting by channel number */
1139 if ((fwrq->m > USA_HOP_MOD) || (fwrq->e > 0)) 1138 if ((wrqu->freq.m > USA_HOP_MOD) || (wrqu->freq.e > 0))
1140 err = -EOPNOTSUPP; 1139 err = -EOPNOTSUPP;
1141 else 1140 else
1142 local->sparm.b5.a_hop_pattern = fwrq->m; 1141 local->sparm.b5.a_hop_pattern = wrqu->freq.m;
1143 1142
1144 return err; 1143 return err;
1145} 1144}
@@ -1148,14 +1147,13 @@ static int ray_set_freq(struct net_device *dev,
1148/* 1147/*
1149 * Wireless Handler : get frequency 1148 * Wireless Handler : get frequency
1150 */ 1149 */
1151static int ray_get_freq(struct net_device *dev, 1150static int ray_get_freq(struct net_device *dev, struct iw_request_info *info,
1152 struct iw_request_info *info, 1151 union iwreq_data *wrqu, char *extra)
1153 struct iw_freq *fwrq, char *extra)
1154{ 1152{
1155 ray_dev_t *local = netdev_priv(dev); 1153 ray_dev_t *local = netdev_priv(dev);
1156 1154
1157 fwrq->m = local->sparm.b5.a_hop_pattern; 1155 wrqu->freq.m = local->sparm.b5.a_hop_pattern;
1158 fwrq->e = 0; 1156 wrqu->freq.e = 0;
1159 return 0; 1157 return 0;
1160} 1158}
1161 1159
@@ -1163,9 +1161,8 @@ static int ray_get_freq(struct net_device *dev,
1163/* 1161/*
1164 * Wireless Handler : set ESSID 1162 * Wireless Handler : set ESSID
1165 */ 1163 */
1166static int ray_set_essid(struct net_device *dev, 1164static int ray_set_essid(struct net_device *dev, struct iw_request_info *info,
1167 struct iw_request_info *info, 1165 union iwreq_data *wrqu, char *extra)
1168 struct iw_point *dwrq, char *extra)
1169{ 1166{
1170 ray_dev_t *local = netdev_priv(dev); 1167 ray_dev_t *local = netdev_priv(dev);
1171 1168
@@ -1174,19 +1171,17 @@ static int ray_set_essid(struct net_device *dev,
1174 return -EBUSY; 1171 return -EBUSY;
1175 1172
1176 /* Check if we asked for `any' */ 1173 /* Check if we asked for `any' */
1177 if (dwrq->flags == 0) { 1174 if (wrqu->essid.flags == 0)
1178 /* Corey : can you do that ? */ 1175 /* Corey : can you do that ? */
1179 return -EOPNOTSUPP; 1176 return -EOPNOTSUPP;
1180 } else {
1181 /* Check the size of the string */
1182 if (dwrq->length > IW_ESSID_MAX_SIZE) {
1183 return -E2BIG;
1184 }
1185 1177
1186 /* Set the ESSID in the card */ 1178 /* Check the size of the string */
1187 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE); 1179 if (wrqu->essid.length > IW_ESSID_MAX_SIZE)
1188 memcpy(local->sparm.b5.a_current_ess_id, extra, dwrq->length); 1180 return -E2BIG;
1189 } 1181
1182 /* Set the ESSID in the card */
1183 memset(local->sparm.b5.a_current_ess_id, 0, IW_ESSID_MAX_SIZE);
1184 memcpy(local->sparm.b5.a_current_ess_id, extra, wrqu->essid.length);
1190 1185
1191 return -EINPROGRESS; /* Call commit handler */ 1186 return -EINPROGRESS; /* Call commit handler */
1192} 1187}
@@ -1195,9 +1190,8 @@ static int ray_set_essid(struct net_device *dev,
1195/* 1190/*
1196 * Wireless Handler : get ESSID 1191 * Wireless Handler : get ESSID
1197 */ 1192 */
1198static int ray_get_essid(struct net_device *dev, 1193static int ray_get_essid(struct net_device *dev, struct iw_request_info *info,
1199 struct iw_request_info *info, 1194 union iwreq_data *wrqu, char *extra)
1200 struct iw_point *dwrq, char *extra)
1201{ 1195{
1202 ray_dev_t *local = netdev_priv(dev); 1196 ray_dev_t *local = netdev_priv(dev);
1203 1197
@@ -1205,8 +1199,8 @@ static int ray_get_essid(struct net_device *dev,
1205 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); 1199 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE);
1206 1200
1207 /* Push it out ! */ 1201 /* Push it out ! */
1208 dwrq->length = strlen(extra); 1202 wrqu->essid.length = strlen(extra);
1209 dwrq->flags = 1; /* active */ 1203 wrqu->essid.flags = 1; /* active */
1210 1204
1211 return 0; 1205 return 0;
1212} 1206}
@@ -1215,14 +1209,13 @@ static int ray_get_essid(struct net_device *dev,
1215/* 1209/*
1216 * Wireless Handler : get AP address 1210 * Wireless Handler : get AP address
1217 */ 1211 */
1218static int ray_get_wap(struct net_device *dev, 1212static int ray_get_wap(struct net_device *dev, struct iw_request_info *info,
1219 struct iw_request_info *info, 1213 union iwreq_data *wrqu, char *extra)
1220 struct sockaddr *awrq, char *extra)
1221{ 1214{
1222 ray_dev_t *local = netdev_priv(dev); 1215 ray_dev_t *local = netdev_priv(dev);
1223 1216
1224 memcpy(awrq->sa_data, local->bss_id, ETH_ALEN); 1217 memcpy(wrqu->ap_addr.sa_data, local->bss_id, ETH_ALEN);
1225 awrq->sa_family = ARPHRD_ETHER; 1218 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1226 1219
1227 return 0; 1220 return 0;
1228} 1221}
@@ -1231,9 +1224,8 @@ static int ray_get_wap(struct net_device *dev,
1231/* 1224/*
1232 * Wireless Handler : set Bit-Rate 1225 * Wireless Handler : set Bit-Rate
1233 */ 1226 */
1234static int ray_set_rate(struct net_device *dev, 1227static int ray_set_rate(struct net_device *dev, struct iw_request_info *info,
1235 struct iw_request_info *info, 1228 union iwreq_data *wrqu, char *extra)
1236 struct iw_param *vwrq, char *extra)
1237{ 1229{
1238 ray_dev_t *local = netdev_priv(dev); 1230 ray_dev_t *local = netdev_priv(dev);
1239 1231
@@ -1242,15 +1234,15 @@ static int ray_set_rate(struct net_device *dev,
1242 return -EBUSY; 1234 return -EBUSY;
1243 1235
1244 /* Check if rate is in range */ 1236 /* Check if rate is in range */
1245 if ((vwrq->value != 1000000) && (vwrq->value != 2000000)) 1237 if ((wrqu->bitrate.value != 1000000) && (wrqu->bitrate.value != 2000000))
1246 return -EINVAL; 1238 return -EINVAL;
1247 1239
1248 /* Hack for 1.5 Mb/s instead of 2 Mb/s */ 1240 /* Hack for 1.5 Mb/s instead of 2 Mb/s */
1249 if ((local->fw_ver == 0x55) && /* Please check */ 1241 if ((local->fw_ver == 0x55) && /* Please check */
1250 (vwrq->value == 2000000)) 1242 (wrqu->bitrate.value == 2000000))
1251 local->net_default_tx_rate = 3; 1243 local->net_default_tx_rate = 3;
1252 else 1244 else
1253 local->net_default_tx_rate = vwrq->value / 500000; 1245 local->net_default_tx_rate = wrqu->bitrate.value / 500000;
1254 1246
1255 return 0; 1247 return 0;
1256} 1248}
@@ -1259,17 +1251,16 @@ static int ray_set_rate(struct net_device *dev,
1259/* 1251/*
1260 * Wireless Handler : get Bit-Rate 1252 * Wireless Handler : get Bit-Rate
1261 */ 1253 */
1262static int ray_get_rate(struct net_device *dev, 1254static int ray_get_rate(struct net_device *dev, struct iw_request_info *info,
1263 struct iw_request_info *info, 1255 union iwreq_data *wrqu, char *extra)
1264 struct iw_param *vwrq, char *extra)
1265{ 1256{
1266 ray_dev_t *local = netdev_priv(dev); 1257 ray_dev_t *local = netdev_priv(dev);
1267 1258
1268 if (local->net_default_tx_rate == 3) 1259 if (local->net_default_tx_rate == 3)
1269 vwrq->value = 2000000; /* Hum... */ 1260 wrqu->bitrate.value = 2000000; /* Hum... */
1270 else 1261 else
1271 vwrq->value = local->net_default_tx_rate * 500000; 1262 wrqu->bitrate.value = local->net_default_tx_rate * 500000;
1272 vwrq->fixed = 0; /* We are in auto mode */ 1263 wrqu->bitrate.fixed = 0; /* We are in auto mode */
1273 1264
1274 return 0; 1265 return 0;
1275} 1266}
@@ -1278,19 +1269,18 @@ static int ray_get_rate(struct net_device *dev,
1278/* 1269/*
1279 * Wireless Handler : set RTS threshold 1270 * Wireless Handler : set RTS threshold
1280 */ 1271 */
1281static int ray_set_rts(struct net_device *dev, 1272static int ray_set_rts(struct net_device *dev, struct iw_request_info *info,
1282 struct iw_request_info *info, 1273 union iwreq_data *wrqu, char *extra)
1283 struct iw_param *vwrq, char *extra)
1284{ 1274{
1285 ray_dev_t *local = netdev_priv(dev); 1275 ray_dev_t *local = netdev_priv(dev);
1286 int rthr = vwrq->value; 1276 int rthr = wrqu->rts.value;
1287 1277
1288 /* Reject if card is already initialised */ 1278 /* Reject if card is already initialised */
1289 if (local->card_status != CARD_AWAITING_PARAM) 1279 if (local->card_status != CARD_AWAITING_PARAM)
1290 return -EBUSY; 1280 return -EBUSY;
1291 1281
1292 /* if(wrq->u.rts.fixed == 0) we should complain */ 1282 /* if(wrq->u.rts.fixed == 0) we should complain */
1293 if (vwrq->disabled) 1283 if (wrqu->rts.disabled)
1294 rthr = 32767; 1284 rthr = 32767;
1295 else { 1285 else {
1296 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */ 1286 if ((rthr < 0) || (rthr > 2347)) /* What's the max packet size ??? */
@@ -1306,16 +1296,15 @@ static int ray_set_rts(struct net_device *dev,
1306/* 1296/*
1307 * Wireless Handler : get RTS threshold 1297 * Wireless Handler : get RTS threshold
1308 */ 1298 */
1309static int ray_get_rts(struct net_device *dev, 1299static int ray_get_rts(struct net_device *dev, struct iw_request_info *info,
1310 struct iw_request_info *info, 1300 union iwreq_data *wrqu, char *extra)
1311 struct iw_param *vwrq, char *extra)
1312{ 1301{
1313 ray_dev_t *local = netdev_priv(dev); 1302 ray_dev_t *local = netdev_priv(dev);
1314 1303
1315 vwrq->value = (local->sparm.b5.a_rts_threshold[0] << 8) 1304 wrqu->rts.value = (local->sparm.b5.a_rts_threshold[0] << 8)
1316 + local->sparm.b5.a_rts_threshold[1]; 1305 + local->sparm.b5.a_rts_threshold[1];
1317 vwrq->disabled = (vwrq->value == 32767); 1306 wrqu->rts.disabled = (wrqu->rts.value == 32767);
1318 vwrq->fixed = 1; 1307 wrqu->rts.fixed = 1;
1319 1308
1320 return 0; 1309 return 0;
1321} 1310}
@@ -1324,19 +1313,18 @@ static int ray_get_rts(struct net_device *dev,
1324/* 1313/*
1325 * Wireless Handler : set Fragmentation threshold 1314 * Wireless Handler : set Fragmentation threshold
1326 */ 1315 */
1327static int ray_set_frag(struct net_device *dev, 1316static int ray_set_frag(struct net_device *dev, struct iw_request_info *info,
1328 struct iw_request_info *info, 1317 union iwreq_data *wrqu, char *extra)
1329 struct iw_param *vwrq, char *extra)
1330{ 1318{
1331 ray_dev_t *local = netdev_priv(dev); 1319 ray_dev_t *local = netdev_priv(dev);
1332 int fthr = vwrq->value; 1320 int fthr = wrqu->frag.value;
1333 1321
1334 /* Reject if card is already initialised */ 1322 /* Reject if card is already initialised */
1335 if (local->card_status != CARD_AWAITING_PARAM) 1323 if (local->card_status != CARD_AWAITING_PARAM)
1336 return -EBUSY; 1324 return -EBUSY;
1337 1325
1338 /* if(wrq->u.frag.fixed == 0) should complain */ 1326 /* if(wrq->u.frag.fixed == 0) should complain */
1339 if (vwrq->disabled) 1327 if (wrqu->frag.disabled)
1340 fthr = 32767; 1328 fthr = 32767;
1341 else { 1329 else {
1342 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */ 1330 if ((fthr < 256) || (fthr > 2347)) /* To check out ! */
@@ -1352,16 +1340,15 @@ static int ray_set_frag(struct net_device *dev,
1352/* 1340/*
1353 * Wireless Handler : get Fragmentation threshold 1341 * Wireless Handler : get Fragmentation threshold
1354 */ 1342 */
1355static int ray_get_frag(struct net_device *dev, 1343static int ray_get_frag(struct net_device *dev, struct iw_request_info *info,
1356 struct iw_request_info *info, 1344 union iwreq_data *wrqu, char *extra)
1357 struct iw_param *vwrq, char *extra)
1358{ 1345{
1359 ray_dev_t *local = netdev_priv(dev); 1346 ray_dev_t *local = netdev_priv(dev);
1360 1347
1361 vwrq->value = (local->sparm.b5.a_frag_threshold[0] << 8) 1348 wrqu->frag.value = (local->sparm.b5.a_frag_threshold[0] << 8)
1362 + local->sparm.b5.a_frag_threshold[1]; 1349 + local->sparm.b5.a_frag_threshold[1];
1363 vwrq->disabled = (vwrq->value == 32767); 1350 wrqu->frag.disabled = (wrqu->frag.value == 32767);
1364 vwrq->fixed = 1; 1351 wrqu->frag.fixed = 1;
1365 1352
1366 return 0; 1353 return 0;
1367} 1354}
@@ -1370,8 +1357,8 @@ static int ray_get_frag(struct net_device *dev,
1370/* 1357/*
1371 * Wireless Handler : set Mode of Operation 1358 * Wireless Handler : set Mode of Operation
1372 */ 1359 */
1373static int ray_set_mode(struct net_device *dev, 1360static int ray_set_mode(struct net_device *dev, struct iw_request_info *info,
1374 struct iw_request_info *info, __u32 *uwrq, char *extra) 1361 union iwreq_data *wrqu, char *extra)
1375{ 1362{
1376 ray_dev_t *local = netdev_priv(dev); 1363 ray_dev_t *local = netdev_priv(dev);
1377 int err = -EINPROGRESS; /* Call commit handler */ 1364 int err = -EINPROGRESS; /* Call commit handler */
@@ -1381,7 +1368,7 @@ static int ray_set_mode(struct net_device *dev,
1381 if (local->card_status != CARD_AWAITING_PARAM) 1368 if (local->card_status != CARD_AWAITING_PARAM)
1382 return -EBUSY; 1369 return -EBUSY;
1383 1370
1384 switch (*uwrq) { 1371 switch (wrqu->mode) {
1385 case IW_MODE_ADHOC: 1372 case IW_MODE_ADHOC:
1386 card_mode = 0; 1373 card_mode = 0;
1387 /* Fall through */ 1374 /* Fall through */
@@ -1399,15 +1386,15 @@ static int ray_set_mode(struct net_device *dev,
1399/* 1386/*
1400 * Wireless Handler : get Mode of Operation 1387 * Wireless Handler : get Mode of Operation
1401 */ 1388 */
1402static int ray_get_mode(struct net_device *dev, 1389static int ray_get_mode(struct net_device *dev, struct iw_request_info *info,
1403 struct iw_request_info *info, __u32 *uwrq, char *extra) 1390 union iwreq_data *wrqu, char *extra)
1404{ 1391{
1405 ray_dev_t *local = netdev_priv(dev); 1392 ray_dev_t *local = netdev_priv(dev);
1406 1393
1407 if (local->sparm.b5.a_network_type) 1394 if (local->sparm.b5.a_network_type)
1408 *uwrq = IW_MODE_INFRA; 1395 wrqu->mode = IW_MODE_INFRA;
1409 else 1396 else
1410 *uwrq = IW_MODE_ADHOC; 1397 wrqu->mode = IW_MODE_ADHOC;
1411 1398
1412 return 0; 1399 return 0;
1413} 1400}
@@ -1416,16 +1403,15 @@ static int ray_get_mode(struct net_device *dev,
1416/* 1403/*
1417 * Wireless Handler : get range info 1404 * Wireless Handler : get range info
1418 */ 1405 */
1419static int ray_get_range(struct net_device *dev, 1406static int ray_get_range(struct net_device *dev, struct iw_request_info *info,
1420 struct iw_request_info *info, 1407 union iwreq_data *wrqu, char *extra)
1421 struct iw_point *dwrq, char *extra)
1422{ 1408{
1423 struct iw_range *range = (struct iw_range *)extra; 1409 struct iw_range *range = (struct iw_range *)extra;
1424 1410
1425 memset((char *)range, 0, sizeof(struct iw_range)); 1411 memset(range, 0, sizeof(struct iw_range));
1426 1412
1427 /* Set the length (very important for backward compatibility) */ 1413 /* Set the length (very important for backward compatibility) */
1428 dwrq->length = sizeof(struct iw_range); 1414 wrqu->data.length = sizeof(struct iw_range);
1429 1415
1430 /* Set the Wireless Extension versions */ 1416 /* Set the Wireless Extension versions */
1431 range->we_version_compiled = WIRELESS_EXT; 1417 range->we_version_compiled = WIRELESS_EXT;
@@ -1448,8 +1434,7 @@ static int ray_get_range(struct net_device *dev,
1448/* 1434/*
1449 * Wireless Private Handler : set framing mode 1435 * Wireless Private Handler : set framing mode
1450 */ 1436 */
1451static int ray_set_framing(struct net_device *dev, 1437static int ray_set_framing(struct net_device *dev, struct iw_request_info *info,
1452 struct iw_request_info *info,
1453 union iwreq_data *wrqu, char *extra) 1438 union iwreq_data *wrqu, char *extra)
1454{ 1439{
1455 translate = *(extra); /* Set framing mode */ 1440 translate = *(extra); /* Set framing mode */
@@ -1461,8 +1446,7 @@ static int ray_set_framing(struct net_device *dev,
1461/* 1446/*
1462 * Wireless Private Handler : get framing mode 1447 * Wireless Private Handler : get framing mode
1463 */ 1448 */
1464static int ray_get_framing(struct net_device *dev, 1449static int ray_get_framing(struct net_device *dev, struct iw_request_info *info,
1465 struct iw_request_info *info,
1466 union iwreq_data *wrqu, char *extra) 1450 union iwreq_data *wrqu, char *extra)
1467{ 1451{
1468 *(extra) = translate; 1452 *(extra) = translate;
@@ -1474,8 +1458,7 @@ static int ray_get_framing(struct net_device *dev,
1474/* 1458/*
1475 * Wireless Private Handler : get country 1459 * Wireless Private Handler : get country
1476 */ 1460 */
1477static int ray_get_country(struct net_device *dev, 1461static int ray_get_country(struct net_device *dev, struct iw_request_info *info,
1478 struct iw_request_info *info,
1479 union iwreq_data *wrqu, char *extra) 1462 union iwreq_data *wrqu, char *extra)
1480{ 1463{
1481 *(extra) = country; 1464 *(extra) = country;
@@ -1487,10 +1470,9 @@ static int ray_get_country(struct net_device *dev,
1487/* 1470/*
1488 * Commit handler : called after a bunch of SET operations 1471 * Commit handler : called after a bunch of SET operations
1489 */ 1472 */
1490static int ray_commit(struct net_device *dev, struct iw_request_info *info, /* NULL */ 1473static int ray_commit(struct net_device *dev, struct iw_request_info *info,
1491 void *zwrq, /* NULL */ 1474 union iwreq_data *wrqu, char *extra)
1492 char *extra) 1475{
1493{ /* NULL */
1494 return 0; 1476 return 0;
1495} 1477}
1496 1478
@@ -1531,28 +1513,28 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1531 */ 1513 */
1532 1514
1533static const iw_handler ray_handler[] = { 1515static const iw_handler ray_handler[] = {
1534 [SIOCSIWCOMMIT - SIOCIWFIRST] = (iw_handler) ray_commit, 1516 IW_HANDLER(SIOCSIWCOMMIT, ray_commit),
1535 [SIOCGIWNAME - SIOCIWFIRST] = (iw_handler) ray_get_name, 1517 IW_HANDLER(SIOCGIWNAME, ray_get_name),
1536 [SIOCSIWFREQ - SIOCIWFIRST] = (iw_handler) ray_set_freq, 1518 IW_HANDLER(SIOCSIWFREQ, ray_set_freq),
1537 [SIOCGIWFREQ - SIOCIWFIRST] = (iw_handler) ray_get_freq, 1519 IW_HANDLER(SIOCGIWFREQ, ray_get_freq),
1538 [SIOCSIWMODE - SIOCIWFIRST] = (iw_handler) ray_set_mode, 1520 IW_HANDLER(SIOCSIWMODE, ray_set_mode),
1539 [SIOCGIWMODE - SIOCIWFIRST] = (iw_handler) ray_get_mode, 1521 IW_HANDLER(SIOCGIWMODE, ray_get_mode),
1540 [SIOCGIWRANGE - SIOCIWFIRST] = (iw_handler) ray_get_range, 1522 IW_HANDLER(SIOCGIWRANGE, ray_get_range),
1541#ifdef WIRELESS_SPY 1523#ifdef WIRELESS_SPY
1542 [SIOCSIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, 1524 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1543 [SIOCGIWSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_spy, 1525 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1544 [SIOCSIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy, 1526 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1545 [SIOCGIWTHRSPY - SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy, 1527 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1546#endif /* WIRELESS_SPY */ 1528#endif /* WIRELESS_SPY */
1547 [SIOCGIWAP - SIOCIWFIRST] = (iw_handler) ray_get_wap, 1529 IW_HANDLER(SIOCGIWAP, ray_get_wap),
1548 [SIOCSIWESSID - SIOCIWFIRST] = (iw_handler) ray_set_essid, 1530 IW_HANDLER(SIOCSIWESSID, ray_set_essid),
1549 [SIOCGIWESSID - SIOCIWFIRST] = (iw_handler) ray_get_essid, 1531 IW_HANDLER(SIOCGIWESSID, ray_get_essid),
1550 [SIOCSIWRATE - SIOCIWFIRST] = (iw_handler) ray_set_rate, 1532 IW_HANDLER(SIOCSIWRATE, ray_set_rate),
1551 [SIOCGIWRATE - SIOCIWFIRST] = (iw_handler) ray_get_rate, 1533 IW_HANDLER(SIOCGIWRATE, ray_get_rate),
1552 [SIOCSIWRTS - SIOCIWFIRST] = (iw_handler) ray_set_rts, 1534 IW_HANDLER(SIOCSIWRTS, ray_set_rts),
1553 [SIOCGIWRTS - SIOCIWFIRST] = (iw_handler) ray_get_rts, 1535 IW_HANDLER(SIOCGIWRTS, ray_get_rts),
1554 [SIOCSIWFRAG - SIOCIWFIRST] = (iw_handler) ray_set_frag, 1536 IW_HANDLER(SIOCSIWFRAG, ray_set_frag),
1555 [SIOCGIWFRAG - SIOCIWFIRST] = (iw_handler) ray_get_frag, 1537 IW_HANDLER(SIOCGIWFRAG, ray_get_frag),
1556}; 1538};
1557 1539
1558#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */ 1540#define SIOCSIPFRAMING SIOCIWFIRSTPRIV /* Set framing mode */
@@ -1560,9 +1542,9 @@ static const iw_handler ray_handler[] = {
1560#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */ 1542#define SIOCGIPCOUNTRY SIOCIWFIRSTPRIV + 3 /* Get country code */
1561 1543
1562static const iw_handler ray_private_handler[] = { 1544static const iw_handler ray_private_handler[] = {
1563 [0] = (iw_handler) ray_set_framing, 1545 [0] = ray_set_framing,
1564 [1] = (iw_handler) ray_get_framing, 1546 [1] = ray_get_framing,
1565 [3] = (iw_handler) ray_get_country, 1547 [3] = ray_get_country,
1566}; 1548};
1567 1549
1568static const struct iw_priv_args ray_private_args[] = { 1550static const struct iw_priv_args ray_private_args[] = {
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index 0deb4fdf916b..8f11506f8310 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -53,6 +53,8 @@ enum {
53 DEBUG_MAC80211 = BIT(11), 53 DEBUG_MAC80211 = BIT(11),
54 DEBUG_CMD = BIT(12), 54 DEBUG_CMD = BIT(12),
55 DEBUG_ACX = BIT(13), 55 DEBUG_ACX = BIT(13),
56 DEBUG_SDIO = BIT(14),
57 DEBUG_FILTERS = BIT(15),
56 DEBUG_ALL = ~0, 58 DEBUG_ALL = ~0,
57}; 59};
58 60
@@ -344,12 +346,14 @@ struct wl1271_if_operations {
344 bool fixed); 346 bool fixed);
345 void (*reset)(struct wl1271 *wl); 347 void (*reset)(struct wl1271 *wl);
346 void (*init)(struct wl1271 *wl); 348 void (*init)(struct wl1271 *wl);
349 void (*power)(struct wl1271 *wl, bool enable);
347 struct device* (*dev)(struct wl1271 *wl); 350 struct device* (*dev)(struct wl1271 *wl);
348 void (*enable_irq)(struct wl1271 *wl); 351 void (*enable_irq)(struct wl1271 *wl);
349 void (*disable_irq)(struct wl1271 *wl); 352 void (*disable_irq)(struct wl1271 *wl);
350}; 353};
351 354
352struct wl1271 { 355struct wl1271 {
356 struct platform_device *plat_dev;
353 struct ieee80211_hw *hw; 357 struct ieee80211_hw *hw;
354 bool mac80211_registered; 358 bool mac80211_registered;
355 359
@@ -456,6 +460,7 @@ struct wl1271 {
456 /* Default key (for WEP) */ 460 /* Default key (for WEP) */
457 u32 default_key; 461 u32 default_key;
458 462
463 unsigned int filters;
459 unsigned int rx_config; 464 unsigned int rx_config;
460 unsigned int rx_filter; 465 unsigned int rx_filter;
461 466
@@ -483,6 +488,8 @@ struct wl1271 {
483 /* Current chipset configuration */ 488 /* Current chipset configuration */
484 struct conf_drv_settings conf; 489 struct conf_drv_settings conf;
485 490
491 bool sg_enabled;
492
486 struct list_head list; 493 struct list_head list;
487}; 494};
488 495
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index 60e20876e6d8..7e337cea9905 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -534,7 +534,7 @@ out:
534} 534}
535 535
536 536
537int wl1271_acx_sg_enable(struct wl1271 *wl) 537int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable)
538{ 538{
539 struct acx_bt_wlan_coex *pta; 539 struct acx_bt_wlan_coex *pta;
540 int ret; 540 int ret;
@@ -547,7 +547,10 @@ int wl1271_acx_sg_enable(struct wl1271 *wl)
547 goto out; 547 goto out;
548 } 548 }
549 549
550 pta->enable = SG_ENABLE; 550 if (enable)
551 pta->enable = wl->conf.sg.state;
552 else
553 pta->enable = CONF_SG_DISABLE;
551 554
552 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); 555 ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
553 if (ret < 0) { 556 if (ret < 0) {
@@ -564,7 +567,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
564{ 567{
565 struct acx_bt_wlan_coex_param *param; 568 struct acx_bt_wlan_coex_param *param;
566 struct conf_sg_settings *c = &wl->conf.sg; 569 struct conf_sg_settings *c = &wl->conf.sg;
567 int ret; 570 int i, ret;
568 571
569 wl1271_debug(DEBUG_ACX, "acx sg cfg"); 572 wl1271_debug(DEBUG_ACX, "acx sg cfg");
570 573
@@ -575,19 +578,9 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl)
575 } 578 }
576 579
577 /* BT-WLAN coext parameters */ 580 /* BT-WLAN coext parameters */
578 param->per_threshold = cpu_to_le32(c->per_threshold); 581 for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
579 param->max_scan_compensation_time = 582 param->params[i] = c->params[i];
580 cpu_to_le32(c->max_scan_compensation_time); 583 param->param_idx = CONF_SG_PARAMS_ALL;
581 param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval);
582 param->load_ratio = c->load_ratio;
583 param->auto_ps_mode = c->auto_ps_mode;
584 param->probe_req_compensation = c->probe_req_compensation;
585 param->scan_window_compensation = c->scan_window_compensation;
586 param->antenna_config = c->antenna_config;
587 param->beacon_miss_threshold = c->beacon_miss_threshold;
588 param->rate_adaptation_threshold =
589 cpu_to_le32(c->rate_adaptation_threshold);
590 param->rate_adaptation_snr = c->rate_adaptation_snr;
591 584
592 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); 585 ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
593 if (ret < 0) { 586 if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index aeccc98581eb..8e5870fa9609 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -392,81 +392,27 @@ struct acx_conn_monit_params {
392 __le32 bss_lose_timeout; /* number of TU's from synch fail */ 392 __le32 bss_lose_timeout; /* number of TU's from synch fail */
393} __attribute__ ((packed)); 393} __attribute__ ((packed));
394 394
395enum {
396 SG_ENABLE = 0,
397 SG_DISABLE,
398 SG_SENSE_NO_ACTIVITY,
399 SG_SENSE_ACTIVE
400};
401
402struct acx_bt_wlan_coex { 395struct acx_bt_wlan_coex {
403 struct acx_header header; 396 struct acx_header header;
404 397
405 /*
406 * 0 -> PTA enabled
407 * 1 -> PTA disabled
408 * 2 -> sense no active mode, i.e.
409 * an interrupt is sent upon
410 * BT activity.
411 * 3 -> PTA is switched on in response
412 * to the interrupt sending.
413 */
414 u8 enable; 398 u8 enable;
415 u8 pad[3]; 399 u8 pad[3];
416} __attribute__ ((packed)); 400} __attribute__ ((packed));
417 401
418struct acx_dco_itrim_params { 402struct acx_bt_wlan_coex_param {
419 struct acx_header header; 403 struct acx_header header;
420 404
421 u8 enable; 405 __le32 params[CONF_SG_PARAMS_MAX];
406 u8 param_idx;
422 u8 padding[3]; 407 u8 padding[3];
423 __le32 timeout;
424} __attribute__ ((packed)); 408} __attribute__ ((packed));
425 409
426#define PTA_ANTENNA_TYPE_DEF (0) 410struct acx_dco_itrim_params {
427#define PTA_BT_HP_MAXTIME_DEF (2000)
428#define PTA_WLAN_HP_MAX_TIME_DEF (5000)
429#define PTA_SENSE_DISABLE_TIMER_DEF (1350)
430#define PTA_PROTECTIVE_RX_TIME_DEF (1500)
431#define PTA_PROTECTIVE_TX_TIME_DEF (1500)
432#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
433#define PTA_SIGNALING_TYPE_DEF (1)
434#define PTA_AFH_LEVERAGE_ON_DEF (0)
435#define PTA_NUMBER_QUIET_CYCLE_DEF (0)
436#define PTA_MAX_NUM_CTS_DEF (3)
437#define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2)
438#define PTA_NUMBER_OF_BT_PACKETS_DEF (2)
439#define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500)
440#define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000)
441#define PTA_CYCLE_TIME_FAST_DEF (8700)
442#define PTA_RX_FOR_AVALANCHE_DEF (5)
443#define PTA_ELP_HP_DEF (0)
444#define PTA_ANTI_STARVE_PERIOD_DEF (500)
445#define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4)
446#define PTA_ALLOW_PA_SD_DEF (1)
447#define PTA_TIME_BEFORE_BEACON_DEF (6300)
448#define PTA_HPDM_MAX_TIME_DEF (1600)
449#define PTA_TIME_OUT_NEXT_WLAN_DEF (2550)
450#define PTA_AUTO_MODE_NO_CTS_DEF (0)
451#define PTA_BT_HP_RESPECTED_DEF (3)
452#define PTA_WLAN_RX_MIN_RATE_DEF (24)
453#define PTA_ACK_MODE_DEF (1)
454
455struct acx_bt_wlan_coex_param {
456 struct acx_header header; 411 struct acx_header header;
457 412
458 __le32 per_threshold; 413 u8 enable;
459 __le32 max_scan_compensation_time;
460 __le16 nfs_sample_interval;
461 u8 load_ratio;
462 u8 auto_ps_mode;
463 u8 probe_req_compensation;
464 u8 scan_window_compensation;
465 u8 antenna_config;
466 u8 beacon_miss_threshold;
467 __le32 rate_adaptation_threshold;
468 s8 rate_adaptation_snr;
469 u8 padding[3]; 414 u8 padding[3];
415 __le32 timeout;
470} __attribute__ ((packed)); 416} __attribute__ ((packed));
471 417
472struct acx_energy_detection { 418struct acx_energy_detection {
@@ -1059,7 +1005,7 @@ int wl1271_acx_dco_itrim_params(struct wl1271 *wl);
1059int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); 1005int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter);
1060int wl1271_acx_beacon_filter_table(struct wl1271 *wl); 1006int wl1271_acx_beacon_filter_table(struct wl1271 *wl);
1061int wl1271_acx_conn_monit_params(struct wl1271 *wl); 1007int wl1271_acx_conn_monit_params(struct wl1271 *wl);
1062int wl1271_acx_sg_enable(struct wl1271 *wl); 1008int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
1063int wl1271_acx_sg_cfg(struct wl1271 *wl); 1009int wl1271_acx_sg_cfg(struct wl1271 *wl);
1064int wl1271_acx_cca_threshold(struct wl1271 *wl); 1010int wl1271_acx_cca_threshold(struct wl1271 *wl);
1065int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); 1011int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c
index f88d52e87e82..41c6affbee29 100644
--- a/drivers/net/wireless/wl12xx/wl1271_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1271_boot.c
@@ -228,6 +228,14 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
228 nvs_len = sizeof(wl->nvs->nvs); 228 nvs_len = sizeof(wl->nvs->nvs);
229 nvs_ptr = (u8 *)wl->nvs->nvs; 229 nvs_ptr = (u8 *)wl->nvs->nvs;
230 230
231 /* update current MAC address to NVS */
232 nvs_ptr[11] = wl->mac_addr[0];
233 nvs_ptr[10] = wl->mac_addr[1];
234 nvs_ptr[6] = wl->mac_addr[2];
235 nvs_ptr[5] = wl->mac_addr[3];
236 nvs_ptr[4] = wl->mac_addr[4];
237 nvs_ptr[3] = wl->mac_addr[5];
238
231 /* 239 /*
232 * Layout before the actual NVS tables: 240 * Layout before the actual NVS tables:
233 * 1 byte : burst length. 241 * 1 byte : burst length.
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index d59b3830a6a5..d005729e0312 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -26,6 +26,7 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/ieee80211.h>
29 30
30#include "wl1271.h" 31#include "wl1271.h"
31#include "wl1271_reg.h" 32#include "wl1271_reg.h"
@@ -280,15 +281,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type)
280 join->rx_filter_options = cpu_to_le32(wl->rx_filter); 281 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
281 join->bss_type = bss_type; 282 join->bss_type = bss_type;
282 283
283 /*
284 * FIXME: disable temporarily all filters because after commit
285 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
286 * association. The filter logic needs to be implemented properly
287 * and once that is done, this hack can be removed.
288 */
289 join->rx_config_options = cpu_to_le32(0);
290 join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
291
292 if (wl->band == IEEE80211_BAND_2GHZ) 284 if (wl->band == IEEE80211_BAND_2GHZ)
293 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS | 285 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
294 CONF_HW_BIT_RATE_2MBPS | 286 CONF_HW_BIT_RATE_2MBPS |
@@ -546,9 +538,9 @@ out:
546 return ret; 538 return ret;
547} 539}
548 540
549int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 541int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
550 u8 active_scan, u8 high_prio, u8 band, 542 const u8 *ie, size_t ie_len, u8 active_scan,
551 u8 probe_requests) 543 u8 high_prio, u8 band, u8 probe_requests)
552{ 544{
553 545
554 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 546 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
@@ -619,12 +611,13 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
619 611
620 params->params.num_channels = j; 612 params->params.num_channels = j;
621 613
622 if (len && ssid) { 614 if (ssid_len && ssid) {
623 params->params.ssid_len = len; 615 params->params.ssid_len = ssid_len;
624 memcpy(params->params.ssid, ssid, len); 616 memcpy(params->params.ssid, ssid, ssid_len);
625 } 617 }
626 618
627 ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band); 619 ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len,
620 ie, ie_len, ieee_band);
628 if (ret < 0) { 621 if (ret < 0) {
629 wl1271_error("PROBE request template failed"); 622 wl1271_error("PROBE request template failed");
630 goto out; 623 goto out;
@@ -655,9 +648,9 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
655 wl->scan.active = active_scan; 648 wl->scan.active = active_scan;
656 wl->scan.high_prio = high_prio; 649 wl->scan.high_prio = high_prio;
657 wl->scan.probe_requests = probe_requests; 650 wl->scan.probe_requests = probe_requests;
658 if (len && ssid) { 651 if (ssid_len && ssid) {
659 wl->scan.ssid_len = len; 652 wl->scan.ssid_len = ssid_len;
660 memcpy(wl->scan.ssid, ssid, len); 653 memcpy(wl->scan.ssid, ssid, ssid_len);
661 } else 654 } else
662 wl->scan.ssid_len = 0; 655 wl->scan.ssid_len = 0;
663 } 656 }
@@ -714,155 +707,102 @@ out:
714 return ret; 707 return ret;
715} 708}
716 709
717static int wl1271_build_basic_rates(u8 *rates, u8 band) 710int wl1271_cmd_build_null_data(struct wl1271 *wl)
718{ 711{
719 u8 index = 0; 712 struct sk_buff *skb = NULL;
720 713 int size;
721 if (band == IEEE80211_BAND_2GHZ) { 714 void *ptr;
722 rates[index++] = 715 int ret = -ENOMEM;
723 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
724 rates[index++] =
725 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
726 rates[index++] =
727 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
728 rates[index++] =
729 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
730 } else if (band == IEEE80211_BAND_5GHZ) {
731 rates[index++] =
732 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
733 rates[index++] =
734 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
735 rates[index++] =
736 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
737 } else {
738 wl1271_error("build_basic_rates invalid band: %d", band);
739 }
740 716
741 return index;
742}
743 717
744static int wl1271_build_extended_rates(u8 *rates, u8 band) 718 if (wl->bss_type == BSS_TYPE_IBSS) {
745{ 719 size = sizeof(struct wl12xx_null_data_template);
746 u8 index = 0; 720 ptr = NULL;
747
748 if (band == IEEE80211_BAND_2GHZ) {
749 rates[index++] = IEEE80211_OFDM_RATE_6MB;
750 rates[index++] = IEEE80211_OFDM_RATE_9MB;
751 rates[index++] = IEEE80211_OFDM_RATE_12MB;
752 rates[index++] = IEEE80211_OFDM_RATE_18MB;
753 rates[index++] = IEEE80211_OFDM_RATE_24MB;
754 rates[index++] = IEEE80211_OFDM_RATE_36MB;
755 rates[index++] = IEEE80211_OFDM_RATE_48MB;
756 rates[index++] = IEEE80211_OFDM_RATE_54MB;
757 } else if (band == IEEE80211_BAND_5GHZ) {
758 rates[index++] =
759 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
760 rates[index++] =
761 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
762 rates[index++] =
763 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
764 rates[index++] =
765 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
766 rates[index++] =
767 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
768 rates[index++] =
769 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
770 } else { 721 } else {
771 wl1271_error("build_basic_rates invalid band: %d", band); 722 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
723 if (!skb)
724 goto out;
725 size = skb->len;
726 ptr = skb->data;
772 } 727 }
773 728
774 return index; 729 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size);
775}
776 730
777int wl1271_cmd_build_null_data(struct wl1271 *wl) 731out:
778{ 732 dev_kfree_skb(skb);
779 struct wl12xx_null_data_template template; 733 if (ret)
780 734 wl1271_warning("cmd buld null data failed %d", ret);
781 if (!is_zero_ether_addr(wl->bssid)) {
782 memcpy(template.header.da, wl->bssid, ETH_ALEN);
783 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
784 } else {
785 memset(template.header.da, 0xff, ETH_ALEN);
786 memset(template.header.bssid, 0xff, ETH_ALEN);
787 }
788
789 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
790 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
791 IEEE80211_STYPE_NULLFUNC |
792 IEEE80211_FCTL_TODS);
793 735
794 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template, 736 return ret;
795 sizeof(template));
796 737
797} 738}
798 739
799int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) 740int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
800{ 741{
801 struct wl12xx_ps_poll_template template; 742 struct sk_buff *skb;
802 743 int ret = 0;
803 memcpy(template.bssid, wl->bssid, ETH_ALEN);
804 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
805
806 /* aid in PS-Poll has its two MSBs each set to 1 */
807 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
808 744
809 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 745 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
746 if (!skb)
747 goto out;
810 748
811 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template, 749 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data,
812 sizeof(template)); 750 skb->len);
813 751
752out:
753 dev_kfree_skb(skb);
754 return ret;
814} 755}
815 756
816int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 757int wl1271_cmd_build_probe_req(struct wl1271 *wl,
817 u8 band) 758 const u8 *ssid, size_t ssid_len,
759 const u8 *ie, size_t ie_len, u8 band)
818{ 760{
819 struct wl12xx_probe_req_template template; 761 struct sk_buff *skb;
820 struct wl12xx_ie_rates *rates;
821 char *ptr;
822 u16 size;
823 int ret; 762 int ret;
824 763
825 ptr = (char *)&template; 764 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
826 size = sizeof(struct ieee80211_header); 765 ie, ie_len);
827 766 if (!skb) {
828 memset(template.header.da, 0xff, ETH_ALEN); 767 ret = -ENOMEM;
829 memset(template.header.bssid, 0xff, ETH_ALEN); 768 goto out;
830 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 769 }
831 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); 770
832 771 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
833 /* IEs */
834 /* SSID */
835 template.ssid.header.id = WLAN_EID_SSID;
836 template.ssid.header.len = ssid_len;
837 if (ssid_len && ssid)
838 memcpy(template.ssid.ssid, ssid, ssid_len);
839 size += sizeof(struct wl12xx_ie_header) + ssid_len;
840 ptr += size;
841
842 /* Basic Rates */
843 rates = (struct wl12xx_ie_rates *)ptr;
844 rates->header.id = WLAN_EID_SUPP_RATES;
845 rates->header.len = wl1271_build_basic_rates(rates->rates, band);
846 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
847 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
848
849 /* Extended rates */
850 rates = (struct wl12xx_ie_rates *)ptr;
851 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
852 rates->header.len = wl1271_build_extended_rates(rates->rates, band);
853 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
854
855 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
856 772
857 if (band == IEEE80211_BAND_2GHZ) 773 if (band == IEEE80211_BAND_2GHZ)
858 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 774 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
859 &template, size); 775 skb->data, skb->len);
860 else 776 else
861 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, 777 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
862 &template, size); 778 skb->data, skb->len);
779
780out:
781 dev_kfree_skb(skb);
863 return ret; 782 return ret;
864} 783}
865 784
785int wl1271_build_qos_null_data(struct wl1271 *wl)
786{
787 struct ieee80211_qos_hdr template;
788
789 memset(&template, 0, sizeof(template));
790
791 memcpy(template.addr1, wl->bssid, ETH_ALEN);
792 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
793 memcpy(template.addr3, wl->bssid, ETH_ALEN);
794
795 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
796 IEEE80211_STYPE_QOS_NULLFUNC |
797 IEEE80211_FCTL_TODS);
798
799 /* FIXME: not sure what priority to use here */
800 template.qos_ctrl = cpu_to_le16(0);
801
802 return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template,
803 sizeof(template));
804}
805
866int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 806int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
867{ 807{
868 struct wl1271_cmd_set_keys *cmd; 808 struct wl1271_cmd_set_keys *cmd;
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h
index 4297205b8d6d..6324bbf36843 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h
@@ -41,15 +41,17 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable);
41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); 41int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send);
42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, 42int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
43 size_t len); 43 size_t len);
44int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 44int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
45 u8 active_scan, u8 high_prio, u8 band, 45 const u8 *ie, size_t ie_len, u8 active_scan,
46 u8 probe_requests); 46 u8 high_prio, u8 band, u8 probe_requests);
47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, 47int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
48 void *buf, size_t buf_len); 48 void *buf, size_t buf_len);
49int wl1271_cmd_build_null_data(struct wl1271 *wl); 49int wl1271_cmd_build_null_data(struct wl1271 *wl);
50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); 50int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid);
51int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, 51int wl1271_cmd_build_probe_req(struct wl1271 *wl,
52 u8 band); 52 const u8 *ssid, size_t ssid_len,
53 const u8 *ie, size_t ie_len, u8 band);
54int wl1271_build_qos_null_data(struct wl1271 *wl);
53int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); 55int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id);
54int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 56int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
55 u8 key_size, const u8 *key, const u8 *addr, 57 u8 key_size, const u8 *key, const u8 *addr,
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h
index 6f9e75cc5640..7fcfe06b1412 100644
--- a/drivers/net/wireless/wl12xx/wl1271_conf.h
+++ b/drivers/net/wireless/wl12xx/wl1271_conf.h
@@ -65,110 +65,318 @@ enum {
65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, 65 CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS,
66}; 66};
67 67
68struct conf_sg_settings { 68enum {
69 CONF_SG_DISABLE = 0,
70 CONF_SG_PROTECTIVE,
71 CONF_SG_OPPORTUNISTIC
72};
73
74enum {
69 /* 75 /*
70 * Defines the PER threshold in PPM of the BT voice of which reaching 76 * PER threshold in PPM of the BT voice
71 * this value will trigger raising the priority of the BT voice by
72 * the BT IP until next NFS sample interval time as defined in
73 * nfs_sample_interval.
74 * 77 *
75 * Unit: PER value in PPM (parts per million) 78 * Range: 0 - 10000000
76 * #Error_packets / #Total_packets 79 */
80 CONF_SG_BT_PER_THRESHOLD = 0,
77 81
78 * Range: u32 82 /*
83 * Number of consequent RX_ACTIVE activities to override BT voice
84 * frames to ensure WLAN connection
85 *
86 * Range: 0 - 100
87 */
88 CONF_SG_HV3_MAX_OVERRIDE,
89
90 /*
91 * Defines the PER threshold of the BT voice
92 *
93 * Range: 0 - 65000
94 */
95 CONF_SG_BT_NFS_SAMPLE_INTERVAL,
96
97 /*
98 * Defines the load ratio of BT
99 *
100 * Range: 0 - 100 (%)
101 */
102 CONF_SG_BT_LOAD_RATIO,
103
104 /*
105 * Defines whether the SG will force WLAN host to enter/exit PSM
106 *
107 * Range: 1 - SG can force, 0 - host handles PSM
108 */
109 CONF_SG_AUTO_PS_MODE,
110
111 /*
112 * Compensation percentage of probe requests when scan initiated
113 * during BT voice/ACL link.
114 *
115 * Range: 0 - 255 (%)
116 */
117 CONF_SG_AUTO_SCAN_PROBE_REQ,
118
119 /*
120 * Compensation percentage of probe requests when active scan initiated
121 * during BT voice
122 *
123 * Range: 0 - 255 (%)
124 */
125 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3,
126
127 /*
128 * Defines antenna configuration (single/dual antenna)
129 *
130 * Range: 0 - single antenna, 1 - dual antenna
131 */
132 CONF_SG_ANTENNA_CONFIGURATION,
133
134 /*
135 * The threshold (percent) of max consequtive beacon misses before
136 * increasing priority of beacon reception.
137 *
138 * Range: 0 - 100 (%)
139 */
140 CONF_SG_BEACON_MISS_PERCENT,
141
142 /*
143 * The rate threshold below which receiving a data frame from the AP
144 * will increase the priority of the data frame above BT traffic.
145 *
146 * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54
147 */
148 CONF_SG_RATE_ADAPT_THRESH,
149
150 /*
151 * Not used currently.
152 *
153 * Range: 0
154 */
155 CONF_SG_RATE_ADAPT_SNR,
156
157 /*
158 * Configure the min and max time BT gains the antenna
159 * in WLAN PSM / BT master basic rate
160 *
161 * Range: 0 - 255 (ms)
162 */
163 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR,
164 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR,
165
166 /*
167 * The time after it expires no new WLAN trigger frame is trasmitted
168 * in WLAN PSM / BT master basic rate
169 *
170 * Range: 0 - 255 (ms)
171 */
172 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR,
173
174 /*
175 * Configure the min and max time BT gains the antenna
176 * in WLAN PSM / BT slave basic rate
177 *
178 * Range: 0 - 255 (ms)
79 */ 179 */
80 u32 per_threshold; 180 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR,
181 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR,
81 182
82 /* 183 /*
83 * This value is an absolute time in micro-seconds to limit the 184 * The time after it expires no new WLAN trigger frame is trasmitted
84 * maximum scan duration compensation while in SG 185 * in WLAN PSM / BT slave basic rate
186 *
187 * Range: 0 - 255 (ms)
85 */ 188 */
86 u32 max_scan_compensation_time; 189 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR,
87 190
88 /* Defines the PER threshold of the BT voice of which reaching this 191 /*
89 * value will trigger raising the priority of the BT voice until next 192 * Configure the min and max time BT gains the antenna
90 * NFS sample interval time as defined in sample_interval. 193 * in WLAN PSM / BT master EDR
91 * 194 *
92 * Unit: msec 195 * Range: 0 - 255 (ms)
93 * Range: 1-65000
94 */ 196 */
95 u16 nfs_sample_interval; 197 CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR,
198 CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR,
96 199
97 /* 200 /*
98 * Defines the load ratio for the BT. 201 * The time after it expires no new WLAN trigger frame is trasmitted
99 * The WLAN ratio is: 100 - load_ratio 202 * in WLAN PSM / BT master EDR
100 * 203 *
101 * Unit: Percent 204 * Range: 0 - 255 (ms)
102 * Range: 0-100
103 */ 205 */
104 u8 load_ratio; 206 CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR,
105 207
106 /* 208 /*
107 * true - Co-ex is allowed to enter/exit P.S automatically and 209 * Configure the min and max time BT gains the antenna
108 * transparently to the host 210 * in WLAN PSM / BT slave EDR
109 * 211 *
110 * false - Co-ex is disallowed to enter/exit P.S and will trigger an 212 * Range: 0 - 255 (ms)
111 * event to the host to notify for the need to enter/exit P.S 213 */
112 * due to BT change state 214 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR,
215 CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR,
216
217 /*
218 * The time after it expires no new WLAN trigger frame is trasmitted
219 * in WLAN PSM / BT slave EDR
113 * 220 *
221 * Range: 0 - 255 (ms)
114 */ 222 */
115 u8 auto_ps_mode; 223 CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR,
116 224
117 /* 225 /*
118 * This parameter defines the compensation percentage of num of probe 226 * RX guard time before the beginning of a new BT voice frame during
119 * requests in case scan is initiated during BT voice/BT ACL 227 * which no new WLAN trigger frame is transmitted.
120 * guaranteed link.
121 * 228 *
122 * Unit: Percent 229 * Range: 0 - 100000 (us)
123 * Range: 0-255 (0 - No compensation)
124 */ 230 */
125 u8 probe_req_compensation; 231 CONF_SG_RXT,
126 232
127 /* 233 /*
128 * This parameter defines the compensation percentage of scan window 234 * TX guard time before the beginning of a new BT voice frame during
129 * size in case scan is initiated during BT voice/BT ACL Guaranteed 235 * which no new WLAN frame is transmitted.
130 * link.
131 * 236 *
132 * Unit: Percent 237 * Range: 0 - 100000 (us)
133 * Range: 0-255 (0 - No compensation)
134 */ 238 */
135 u8 scan_window_compensation; 239
240 CONF_SG_TXT,
136 241
137 /* 242 /*
138 * Defines the antenna configuration. 243 * Enable adaptive RXT/TXT algorithm. If disabled, the host values
244 * will be utilized.
139 * 245 *
140 * Range: 0 - Single Antenna; 1 - Dual Antenna 246 * Range: 0 - disable, 1 - enable
141 */ 247 */
142 u8 antenna_config; 248 CONF_SG_ADAPTIVE_RXT_TXT,
143 249
144 /* 250 /*
145 * The percent out of the Max consecutive beacon miss roaming trigger 251 * The used WLAN legacy service period during active BT ACL link
146 * which is the threshold for raising the priority of beacon
147 * reception.
148 * 252 *
149 * Range: 1-100 253 * Range: 0 - 255 (ms)
150 * N = MaxConsecutiveBeaconMiss
151 * P = coexMaxConsecutiveBeaconMissPrecent
152 * Threshold = MIN( N-1, round(N * P / 100))
153 */ 254 */
154 u8 beacon_miss_threshold; 255 CONF_SG_PS_POLL_TIMEOUT,
155 256
156 /* 257 /*
157 * The RX rate threshold below which rate adaptation is assumed to be 258 * The used WLAN UPSD service period during active BT ACL link
158 * occurring at the AP which will raise priority for ACTIVE_RX and RX
159 * SP.
160 * 259 *
161 * Range: HW_BIT_RATE_* 260 * Range: 0 - 255 (ms)
162 */ 261 */
163 u32 rate_adaptation_threshold; 262 CONF_SG_UPSD_TIMEOUT,
164 263
165 /* 264 /*
166 * The SNR above which the RX rate threshold indicating AP rate 265 * Configure the min and max time BT gains the antenna
167 * adaptation is valid 266 * in WLAN Active / BT master EDR
168 * 267 *
169 * Range: -128 - 127 268 * Range: 0 - 255 (ms)
170 */ 269 */
171 s8 rate_adaptation_snr; 270 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR,
271 CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR,
272
273 /*
274 * The maximum time WLAN can gain the antenna for
275 * in WLAN Active / BT master EDR
276 *
277 * Range: 0 - 255 (ms)
278 */
279 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR,
280
281 /*
282 * Configure the min and max time BT gains the antenna
283 * in WLAN Active / BT slave EDR
284 *
285 * Range: 0 - 255 (ms)
286 */
287 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR,
288 CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR,
289
290 /*
291 * The maximum time WLAN can gain the antenna for
292 * in WLAN Active / BT slave EDR
293 *
294 * Range: 0 - 255 (ms)
295 */
296 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR,
297
298 /*
299 * Configure the min and max time BT gains the antenna
300 * in WLAN Active / BT basic rate
301 *
302 * Range: 0 - 255 (ms)
303 */
304 CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR,
305 CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR,
306
307 /*
308 * The maximum time WLAN can gain the antenna for
309 * in WLAN Active / BT basic rate
310 *
311 * Range: 0 - 255 (ms)
312 */
313 CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR,
314
315 /*
316 * Compensation percentage of WLAN passive scan window if initiated
317 * during BT voice
318 *
319 * Range: 0 - 1000 (%)
320 */
321 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3,
322
323 /*
324 * Compensation percentage of WLAN passive scan window if initiated
325 * during BT A2DP
326 *
327 * Range: 0 - 1000 (%)
328 */
329 CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP,
330
331 /*
332 * Fixed time ensured for BT traffic to gain the antenna during WLAN
333 * passive scan.
334 *
335 * Range: 0 - 1000 ms
336 */
337 CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME,
338
339 /*
340 * Fixed time ensured for WLAN traffic to gain the antenna during WLAN
341 * passive scan.
342 *
343 * Range: 0 - 1000 ms
344 */
345 CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME,
346
347 /*
348 * Number of consequent BT voice frames not interrupted by WLAN
349 *
350 * Range: 0 - 100
351 */
352 CONF_SG_HV3_MAX_SERVED,
353
354 /*
355 * Protection time of the DHCP procedure.
356 *
357 * Range: 0 - 100000 (ms)
358 */
359 CONF_SG_DHCP_TIME,
360
361 /*
362 * Compensation percentage of WLAN active scan window if initiated
363 * during BT A2DP
364 *
365 * Range: 0 - 1000 (%)
366 */
367 CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP,
368 CONF_SG_TEMP_PARAM_1,
369 CONF_SG_TEMP_PARAM_2,
370 CONF_SG_TEMP_PARAM_3,
371 CONF_SG_TEMP_PARAM_4,
372 CONF_SG_TEMP_PARAM_5,
373 CONF_SG_PARAMS_MAX,
374 CONF_SG_PARAMS_ALL = 0xff
375};
376
377struct conf_sg_settings {
378 __le32 params[CONF_SG_PARAMS_MAX];
379 u8 state;
172}; 380};
173 381
174enum conf_rx_queue_type { 382enum conf_rx_queue_type {
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
index 8d7588ca68fd..3c0f5b1ac272 100644
--- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c
+++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c
@@ -28,6 +28,7 @@
28#include "wl1271.h" 28#include "wl1271.h"
29#include "wl1271_acx.h" 29#include "wl1271_acx.h"
30#include "wl1271_ps.h" 30#include "wl1271_ps.h"
31#include "wl1271_io.h"
31 32
32/* ms */ 33/* ms */
33#define WL1271_DEBUGFS_STATS_LIFETIME 1000 34#define WL1271_DEBUGFS_STATS_LIFETIME 1000
@@ -276,13 +277,10 @@ static ssize_t gpio_power_write(struct file *file,
276 goto out; 277 goto out;
277 } 278 }
278 279
279 if (value) { 280 if (value)
280 wl->set_power(true); 281 wl1271_power_on(wl);
281 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 282 else
282 } else { 283 wl1271_power_off(wl);
283 wl->set_power(false);
284 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
285 }
286 284
287out: 285out:
288 mutex_unlock(&wl->mutex); 286 mutex_unlock(&wl->mutex);
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 5533519a1418..4d35af96c597 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -44,7 +44,9 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
44 * scanning as it checks that. 44 * scanning as it checks that.
45 */ 45 */
46 clear_bit(WL1271_FLAG_SCANNING, &wl->flags); 46 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
47 /* FIXME: ie missing! */
47 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, 48 wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len,
49 NULL, 0,
48 wl->scan.active, 50 wl->scan.active,
49 wl->scan.high_prio, 51 wl->scan.high_prio,
50 WL1271_SCAN_BAND_5_GHZ, 52 WL1271_SCAN_BAND_5_GHZ,
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index 86c30a86a456..d9335fc2a575 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -160,11 +160,11 @@ int wl1271_init_pta(struct wl1271 *wl)
160{ 160{
161 int ret; 161 int ret;
162 162
163 ret = wl1271_acx_sg_enable(wl); 163 ret = wl1271_acx_sg_cfg(wl);
164 if (ret < 0) 164 if (ret < 0)
165 return ret; 165 return ret;
166 166
167 ret = wl1271_acx_sg_cfg(wl); 167 ret = wl1271_acx_sg_enable(wl, wl->sg_enabled);
168 if (ret < 0) 168 if (ret < 0)
169 return ret; 169 return ret;
170 170
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h
index 95d2168f8af4..d8837ef0bb40 100644
--- a/drivers/net/wireless/wl12xx/wl1271_io.h
+++ b/drivers/net/wireless/wl12xx/wl1271_io.h
@@ -138,6 +138,18 @@ static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val)
138 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); 138 wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);
139} 139}
140 140
141static inline void wl1271_power_off(struct wl1271 *wl)
142{
143 wl->if_ops->power(wl, false);
144 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
145}
146
147static inline void wl1271_power_on(struct wl1271 *wl)
148{
149 wl->if_ops->power(wl, true);
150 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
151}
152
141 153
142/* Top Register IO */ 154/* Top Register IO */
143void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); 155void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);
@@ -149,6 +161,7 @@ int wl1271_set_partition(struct wl1271 *wl,
149/* Functions from wl1271_main.c */ 161/* Functions from wl1271_main.c */
150 162
151int wl1271_register_hw(struct wl1271 *wl); 163int wl1271_register_hw(struct wl1271 *wl);
164void wl1271_unregister_hw(struct wl1271 *wl);
152int wl1271_init_ieee80211(struct wl1271 *wl); 165int wl1271_init_ieee80211(struct wl1271 *wl);
153struct ieee80211_hw *wl1271_alloc_hw(void); 166struct ieee80211_hw *wl1271_alloc_hw(void);
154int wl1271_free_hw(struct wl1271 *wl); 167int wl1271_free_hw(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 0a4ff7b02f59..3daba6c0c77f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -29,6 +29,7 @@
29#include <linux/etherdevice.h> 29#include <linux/etherdevice.h>
30#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
31#include <linux/inetdevice.h> 31#include <linux/inetdevice.h>
32#include <linux/platform_device.h>
32 33
33#include "wl1271.h" 34#include "wl1271.h"
34#include "wl12xx_80211.h" 35#include "wl12xx_80211.h"
@@ -48,17 +49,57 @@
48 49
49static struct conf_drv_settings default_conf = { 50static struct conf_drv_settings default_conf = {
50 .sg = { 51 .sg = {
51 .per_threshold = 7500, 52 .params = {
52 .max_scan_compensation_time = 120000, 53 [CONF_SG_BT_PER_THRESHOLD] = 7500,
53 .nfs_sample_interval = 400, 54 [CONF_SG_HV3_MAX_OVERRIDE] = 0,
54 .load_ratio = 50, 55 [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400,
55 .auto_ps_mode = 0, 56 [CONF_SG_BT_LOAD_RATIO] = 50,
56 .probe_req_compensation = 170, 57 [CONF_SG_AUTO_PS_MODE] = 0,
57 .scan_window_compensation = 50, 58 [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170,
58 .antenna_config = 0, 59 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50,
59 .beacon_miss_threshold = 60, 60 [CONF_SG_ANTENNA_CONFIGURATION] = 0,
60 .rate_adaptation_threshold = CONF_HW_BIT_RATE_12MBPS, 61 [CONF_SG_BEACON_MISS_PERCENT] = 60,
61 .rate_adaptation_snr = 0 62 [CONF_SG_RATE_ADAPT_THRESH] = 12,
63 [CONF_SG_RATE_ADAPT_SNR] = 0,
64 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10,
65 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30,
66 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8,
67 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20,
68 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50,
69 /* Note: with UPSD, this should be 4 */
70 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8,
71 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7,
72 [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25,
73 [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20,
74 /* Note: with UPDS, this should be 15 */
75 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8,
76 /* Note: with UPDS, this should be 50 */
77 [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40,
78 /* Note: with UPDS, this should be 10 */
79 [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20,
80 [CONF_SG_RXT] = 1200,
81 [CONF_SG_TXT] = 1000,
82 [CONF_SG_ADAPTIVE_RXT_TXT] = 1,
83 [CONF_SG_PS_POLL_TIMEOUT] = 10,
84 [CONF_SG_UPSD_TIMEOUT] = 10,
85 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
86 [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
87 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
88 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8,
89 [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20,
90 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15,
91 [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20,
92 [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50,
93 [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10,
94 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200,
95 [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
96 [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75,
97 [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15,
98 [CONF_SG_HV3_MAX_SERVED] = 6,
99 [CONF_SG_DHCP_TIME] = 5000,
100 [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100,
101 },
102 .state = CONF_SG_PROTECTIVE,
62 }, 103 },
63 .rx = { 104 .rx = {
64 .rx_msdu_life_time = 512000, 105 .rx_msdu_life_time = 512000,
@@ -240,6 +281,21 @@ static struct conf_drv_settings default_conf = {
240 } 281 }
241}; 282};
242 283
284static void wl1271_device_release(struct device *dev)
285{
286
287}
288
289static struct platform_device wl1271_device = {
290 .name = "wl1271",
291 .id = -1,
292
293 /* device model insists to have a release function */
294 .dev = {
295 .release = wl1271_device_release,
296 },
297};
298
243static LIST_HEAD(wl_list); 299static LIST_HEAD(wl_list);
244 300
245static void wl1271_conf_init(struct wl1271 *wl) 301static void wl1271_conf_init(struct wl1271 *wl)
@@ -359,18 +415,6 @@ static int wl1271_plt_init(struct wl1271 *wl)
359 return ret; 415 return ret;
360} 416}
361 417
362static void wl1271_power_off(struct wl1271 *wl)
363{
364 wl->set_power(false);
365 clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
366}
367
368static void wl1271_power_on(struct wl1271 *wl)
369{
370 wl->set_power(true);
371 set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags);
372}
373
374static void wl1271_fw_status(struct wl1271 *wl, 418static void wl1271_fw_status(struct wl1271 *wl,
375 struct wl1271_fw_status *status) 419 struct wl1271_fw_status *status)
376{ 420{
@@ -526,40 +570,6 @@ out:
526 return ret; 570 return ret;
527} 571}
528 572
529static int wl1271_update_mac_addr(struct wl1271 *wl)
530{
531 int ret = 0;
532 u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
533
534 /* get mac address from the NVS */
535 wl->mac_addr[0] = nvs_ptr[11];
536 wl->mac_addr[1] = nvs_ptr[10];
537 wl->mac_addr[2] = nvs_ptr[6];
538 wl->mac_addr[3] = nvs_ptr[5];
539 wl->mac_addr[4] = nvs_ptr[4];
540 wl->mac_addr[5] = nvs_ptr[3];
541
542 /* FIXME: if it is a zero-address, we should bail out. Now, instead,
543 we randomize an address */
544 if (is_zero_ether_addr(wl->mac_addr)) {
545 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
546 memcpy(wl->mac_addr, nokia_oui, 3);
547 get_random_bytes(wl->mac_addr + 3, 3);
548
549 /* update this address to the NVS */
550 nvs_ptr[11] = wl->mac_addr[0];
551 nvs_ptr[10] = wl->mac_addr[1];
552 nvs_ptr[6] = wl->mac_addr[2];
553 nvs_ptr[5] = wl->mac_addr[3];
554 nvs_ptr[4] = wl->mac_addr[4];
555 nvs_ptr[3] = wl->mac_addr[5];
556 }
557
558 SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
559
560 return ret;
561}
562
563static int wl1271_fetch_nvs(struct wl1271 *wl) 573static int wl1271_fetch_nvs(struct wl1271 *wl)
564{ 574{
565 const struct firmware *fw; 575 const struct firmware *fw;
@@ -589,8 +599,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl)
589 599
590 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); 600 memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));
591 601
592 ret = wl1271_update_mac_addr(wl);
593
594out: 602out:
595 release_firmware(fw); 603 release_firmware(fw);
596 604
@@ -908,13 +916,58 @@ static struct notifier_block wl1271_dev_notifier = {
908 916
909static int wl1271_op_start(struct ieee80211_hw *hw) 917static int wl1271_op_start(struct ieee80211_hw *hw)
910{ 918{
919 wl1271_debug(DEBUG_MAC80211, "mac80211 start");
920
921 /*
922 * We have to delay the booting of the hardware because
923 * we need to know the local MAC address before downloading and
924 * initializing the firmware. The MAC address cannot be changed
925 * after boot, and without the proper MAC address, the firmware
926 * will not function properly.
927 *
928 * The MAC address is first known when the corresponding interface
929 * is added. That is where we will initialize the hardware.
930 */
931
932 return 0;
933}
934
935static void wl1271_op_stop(struct ieee80211_hw *hw)
936{
937 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
938}
939
940static int wl1271_op_add_interface(struct ieee80211_hw *hw,
941 struct ieee80211_vif *vif)
942{
911 struct wl1271 *wl = hw->priv; 943 struct wl1271 *wl = hw->priv;
912 int retries = WL1271_BOOT_RETRIES; 944 int retries = WL1271_BOOT_RETRIES;
913 int ret = 0; 945 int ret = 0;
914 946
915 wl1271_debug(DEBUG_MAC80211, "mac80211 start"); 947 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
948 vif->type, vif->addr);
916 949
917 mutex_lock(&wl->mutex); 950 mutex_lock(&wl->mutex);
951 if (wl->vif) {
952 ret = -EBUSY;
953 goto out;
954 }
955
956 wl->vif = vif;
957
958 switch (vif->type) {
959 case NL80211_IFTYPE_STATION:
960 wl->bss_type = BSS_TYPE_STA_BSS;
961 break;
962 case NL80211_IFTYPE_ADHOC:
963 wl->bss_type = BSS_TYPE_IBSS;
964 break;
965 default:
966 ret = -EOPNOTSUPP;
967 goto out;
968 }
969
970 memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
918 971
919 if (wl->state != WL1271_STATE_OFF) { 972 if (wl->state != WL1271_STATE_OFF) {
920 wl1271_error("cannot start because not in off state: %d", 973 wl1271_error("cannot start because not in off state: %d",
@@ -970,19 +1023,20 @@ out:
970 return ret; 1023 return ret;
971} 1024}
972 1025
973static void wl1271_op_stop(struct ieee80211_hw *hw) 1026static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1027 struct ieee80211_vif *vif)
974{ 1028{
975 struct wl1271 *wl = hw->priv; 1029 struct wl1271 *wl = hw->priv;
976 int i; 1030 int i;
977 1031
978 wl1271_info("down");
979
980 wl1271_debug(DEBUG_MAC80211, "mac80211 stop");
981
982 unregister_inetaddr_notifier(&wl1271_dev_notifier); 1032 unregister_inetaddr_notifier(&wl1271_dev_notifier);
983 list_del(&wl->list);
984 1033
985 mutex_lock(&wl->mutex); 1034 mutex_lock(&wl->mutex);
1035 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1036
1037 wl1271_info("down");
1038
1039 list_del(&wl->list);
986 1040
987 WARN_ON(wl->state != WL1271_STATE_ON); 1041 WARN_ON(wl->state != WL1271_STATE_ON);
988 1042
@@ -1026,6 +1080,8 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1026 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 1080 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1027 wl->sta_rate_set = 0; 1081 wl->sta_rate_set = 0;
1028 wl->flags = 0; 1082 wl->flags = 0;
1083 wl->vif = NULL;
1084 wl->filters = 0;
1029 1085
1030 for (i = 0; i < NUM_TX_QUEUES; i++) 1086 for (i = 0; i < NUM_TX_QUEUES; i++)
1031 wl->tx_blocks_freed[i] = 0; 1087 wl->tx_blocks_freed[i] = 0;
@@ -1034,119 +1090,39 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1034 mutex_unlock(&wl->mutex); 1090 mutex_unlock(&wl->mutex);
1035} 1091}
1036 1092
1037static int wl1271_op_add_interface(struct ieee80211_hw *hw, 1093static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
1038 struct ieee80211_vif *vif)
1039{ 1094{
1040 struct wl1271 *wl = hw->priv; 1095 wl->rx_config = WL1271_DEFAULT_RX_CONFIG;
1041 int ret = 0; 1096 wl->rx_filter = WL1271_DEFAULT_RX_FILTER;
1042 1097
1043 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", 1098 /* combine requested filters with current filter config */
1044 vif->type, vif->addr); 1099 filters = wl->filters | filters;
1045 1100
1046 mutex_lock(&wl->mutex); 1101 wl1271_debug(DEBUG_FILTERS, "RX filters set: ");
1047 if (wl->vif) {
1048 ret = -EBUSY;
1049 goto out;
1050 }
1051 1102
1052 wl->vif = vif; 1103 if (filters & FIF_PROMISC_IN_BSS) {
1053 1104 wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS");
1054 switch (vif->type) { 1105 wl->rx_config &= ~CFG_UNI_FILTER_EN;
1055 case NL80211_IFTYPE_STATION: 1106 wl->rx_config |= CFG_BSSID_FILTER_EN;
1056 wl->bss_type = BSS_TYPE_STA_BSS;
1057 break;
1058 case NL80211_IFTYPE_ADHOC:
1059 wl->bss_type = BSS_TYPE_IBSS;
1060 break;
1061 default:
1062 ret = -EOPNOTSUPP;
1063 goto out;
1064 } 1107 }
1065 1108 if (filters & FIF_BCN_PRBRESP_PROMISC) {
1066 /* FIXME: what if conf->mac_addr changes? */ 1109 wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC");
1067 1110 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1068out: 1111 wl->rx_config &= ~CFG_SSID_FILTER_EN;
1069 mutex_unlock(&wl->mutex);
1070 return ret;
1071}
1072
1073static void wl1271_op_remove_interface(struct ieee80211_hw *hw,
1074 struct ieee80211_vif *vif)
1075{
1076 struct wl1271 *wl = hw->priv;
1077
1078 mutex_lock(&wl->mutex);
1079 wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
1080 wl->vif = NULL;
1081 mutex_unlock(&wl->mutex);
1082}
1083
1084#if 0
1085static int wl1271_op_config_interface(struct ieee80211_hw *hw,
1086 struct ieee80211_vif *vif,
1087 struct ieee80211_if_conf *conf)
1088{
1089 struct wl1271 *wl = hw->priv;
1090 struct sk_buff *beacon;
1091 int ret;
1092
1093 wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM",
1094 conf->bssid);
1095 wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid,
1096 conf->ssid_len);
1097
1098 mutex_lock(&wl->mutex);
1099
1100 ret = wl1271_ps_elp_wakeup(wl, false);
1101 if (ret < 0)
1102 goto out;
1103
1104 if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) {
1105 wl1271_debug(DEBUG_MAC80211, "bssid changed");
1106
1107 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
1108
1109 ret = wl1271_cmd_join(wl, wl->bss_type);
1110 if (ret < 0)
1111 goto out_sleep;
1112
1113 ret = wl1271_cmd_build_null_data(wl);
1114 if (ret < 0)
1115 goto out_sleep;
1116 } 1112 }
1117 1113 if (filters & FIF_OTHER_BSS) {
1118 wl->ssid_len = conf->ssid_len; 1114 wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS");
1119 if (wl->ssid_len) 1115 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1120 memcpy(wl->ssid, conf->ssid, wl->ssid_len); 1116 }
1121 1117 if (filters & FIF_CONTROL) {
1122 if (conf->changed & IEEE80211_IFCC_BEACON) { 1118 wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL");
1123 beacon = ieee80211_beacon_get(hw, vif); 1119 wl->rx_filter |= CFG_RX_CTL_EN;
1124 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, 1120 }
1125 beacon->data, beacon->len); 1121 if (filters & FIF_FCSFAIL) {
1126 1122 wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL");
1127 if (ret < 0) { 1123 wl->rx_filter |= CFG_RX_FCS_ERROR;
1128 dev_kfree_skb(beacon);
1129 goto out_sleep;
1130 }
1131
1132 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE,
1133 beacon->data, beacon->len);
1134
1135 dev_kfree_skb(beacon);
1136
1137 if (ret < 0)
1138 goto out_sleep;
1139 } 1124 }
1140
1141out_sleep:
1142 wl1271_ps_elp_sleep(wl);
1143
1144out:
1145 mutex_unlock(&wl->mutex);
1146
1147 return ret;
1148} 1125}
1149#endif
1150 1126
1151static int wl1271_join_channel(struct wl1271 *wl, int channel) 1127static int wl1271_join_channel(struct wl1271 *wl, int channel)
1152{ 1128{
@@ -1155,12 +1131,12 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel)
1155 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, 1131 static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde,
1156 0xad, 0xbe, 0xef }; 1132 0xad, 0xbe, 0xef };
1157 1133
1158 /* disable mac filter, so we hear everything */
1159 wl->rx_config &= ~CFG_BSSID_FILTER_EN;
1160
1161 wl->channel = channel; 1134 wl->channel = channel;
1162 memcpy(wl->bssid, dummy_bssid, ETH_ALEN); 1135 memcpy(wl->bssid, dummy_bssid, ETH_ALEN);
1163 1136
1137 /* pass through frames from all BSS */
1138 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1139
1164 /* the dummy join is performed always with STATION BSS type to allow 1140 /* the dummy join is performed always with STATION BSS type to allow
1165 also ad-hoc mode to listen to the surroundings without sending any 1141 also ad-hoc mode to listen to the surroundings without sending any
1166 beacons yet. */ 1142 beacons yet. */
@@ -1186,7 +1162,9 @@ static int wl1271_unjoin_channel(struct wl1271 *wl)
1186 clear_bit(WL1271_FLAG_JOINED, &wl->flags); 1162 clear_bit(WL1271_FLAG_JOINED, &wl->flags);
1187 wl->channel = 0; 1163 wl->channel = 0;
1188 memset(wl->bssid, 0, ETH_ALEN); 1164 memset(wl->bssid, 0, ETH_ALEN);
1189 wl->rx_config = WL1271_DEFAULT_RX_CONFIG; 1165
1166 /* stop filterting packets based on bssid */
1167 wl1271_configure_filters(wl, FIF_OTHER_BSS);
1190 1168
1191out: 1169out:
1192 return ret; 1170 return ret;
@@ -1359,14 +1337,14 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
1359 if (ret < 0) 1337 if (ret < 0)
1360 goto out_sleep; 1338 goto out_sleep;
1361 1339
1362 kfree(fp);
1363
1364 /* FIXME: We still need to set our filters properly */
1365
1366 /* determine, whether supported filter values have changed */ 1340 /* determine, whether supported filter values have changed */
1367 if (changed == 0) 1341 if (changed == 0)
1368 goto out_sleep; 1342 goto out_sleep;
1369 1343
1344 /* configure filters */
1345 wl->filters = *total;
1346 wl1271_configure_filters(wl, 0);
1347
1370 /* apply configured filters */ 1348 /* apply configured filters */
1371 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); 1349 ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
1372 if (ret < 0) 1350 if (ret < 0)
@@ -1377,6 +1355,7 @@ out_sleep:
1377 1355
1378out: 1356out:
1379 mutex_unlock(&wl->mutex); 1357 mutex_unlock(&wl->mutex);
1358 kfree(fp);
1380} 1359}
1381 1360
1382static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 1361static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -1522,10 +1501,12 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
1522 goto out; 1501 goto out;
1523 1502
1524 if (wl1271_11a_enabled()) 1503 if (wl1271_11a_enabled())
1525 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1504 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1505 req->ie, req->ie_len, 1, 0,
1526 WL1271_SCAN_BAND_DUAL, 3); 1506 WL1271_SCAN_BAND_DUAL, 3);
1527 else 1507 else
1528 ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, 1508 ret = wl1271_cmd_scan(hw->priv, ssid, len,
1509 req->ie, req->ie_len, 1, 0,
1529 WL1271_SCAN_BAND_2_4_GHZ, 3); 1510 WL1271_SCAN_BAND_2_4_GHZ, 3);
1530 1511
1531 wl1271_ps_elp_sleep(wl); 1512 wl1271_ps_elp_sleep(wl);
@@ -1638,14 +1619,14 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1638 * and enable the BSSID filter 1619 * and enable the BSSID filter
1639 */ 1620 */
1640 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { 1621 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1641 wl->rx_config |= CFG_BSSID_FILTER_EN;
1642 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1622 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1623
1643 ret = wl1271_cmd_build_null_data(wl); 1624 ret = wl1271_cmd_build_null_data(wl);
1644 if (ret < 0) { 1625 if (ret < 0)
1645 wl1271_warning("cmd buld null data failed %d",
1646 ret);
1647 goto out_sleep; 1626 goto out_sleep;
1648 } 1627
1628 /* filter out all packets not from this BSSID */
1629 wl1271_configure_filters(wl, 0);
1649 1630
1650 /* Need to update the BSSID (for filtering etc) */ 1631 /* Need to update the BSSID (for filtering etc) */
1651 do_join = true; 1632 do_join = true;
@@ -1735,6 +1716,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1735 const struct ieee80211_tx_queue_params *params) 1716 const struct ieee80211_tx_queue_params *params)
1736{ 1717{
1737 struct wl1271 *wl = hw->priv; 1718 struct wl1271 *wl = hw->priv;
1719 u8 ps_scheme;
1738 int ret; 1720 int ret;
1739 1721
1740 mutex_lock(&wl->mutex); 1722 mutex_lock(&wl->mutex);
@@ -1745,17 +1727,22 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1745 if (ret < 0) 1727 if (ret < 0)
1746 goto out; 1728 goto out;
1747 1729
1730 /* the txop is confed in units of 32us by the mac80211, we need us */
1748 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), 1731 ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
1749 params->cw_min, params->cw_max, 1732 params->cw_min, params->cw_max,
1750 params->aifs, params->txop); 1733 params->aifs, params->txop << 5);
1751 if (ret < 0) 1734 if (ret < 0)
1752 goto out_sleep; 1735 goto out_sleep;
1753 1736
1737 if (params->uapsd)
1738 ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER;
1739 else
1740 ps_scheme = CONF_PS_SCHEME_LEGACY;
1741
1754 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), 1742 ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
1755 CONF_CHANNEL_TYPE_EDCF, 1743 CONF_CHANNEL_TYPE_EDCF,
1756 wl1271_tx_get_queue(queue), 1744 wl1271_tx_get_queue(queue),
1757 CONF_PS_SCHEME_LEGACY_PSPOLL, 1745 ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0);
1758 CONF_ACK_POLICY_LEGACY, 0, 0);
1759 if (ret < 0) 1746 if (ret < 0)
1760 goto out_sleep; 1747 goto out_sleep;
1761 1748
@@ -1925,7 +1912,6 @@ static const struct ieee80211_ops wl1271_ops = {
1925 .add_interface = wl1271_op_add_interface, 1912 .add_interface = wl1271_op_add_interface,
1926 .remove_interface = wl1271_op_remove_interface, 1913 .remove_interface = wl1271_op_remove_interface,
1927 .config = wl1271_op_config, 1914 .config = wl1271_op_config,
1928/* .config_interface = wl1271_op_config_interface, */
1929 .prepare_multicast = wl1271_op_prepare_multicast, 1915 .prepare_multicast = wl1271_op_prepare_multicast,
1930 .configure_filter = wl1271_op_configure_filter, 1916 .configure_filter = wl1271_op_configure_filter,
1931 .tx = wl1271_op_tx, 1917 .tx = wl1271_op_tx,
@@ -1937,6 +1923,68 @@ static const struct ieee80211_ops wl1271_ops = {
1937 CFG80211_TESTMODE_CMD(wl1271_tm_cmd) 1923 CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
1938}; 1924};
1939 1925
1926static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev,
1927 struct device_attribute *attr,
1928 char *buf)
1929{
1930 struct wl1271 *wl = dev_get_drvdata(dev);
1931 ssize_t len;
1932
1933 /* FIXME: what's the maximum length of buf? page size?*/
1934 len = 500;
1935
1936 mutex_lock(&wl->mutex);
1937 len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n",
1938 wl->sg_enabled);
1939 mutex_unlock(&wl->mutex);
1940
1941 return len;
1942
1943}
1944
1945static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
1946 struct device_attribute *attr,
1947 const char *buf, size_t count)
1948{
1949 struct wl1271 *wl = dev_get_drvdata(dev);
1950 unsigned long res;
1951 int ret;
1952
1953 ret = strict_strtoul(buf, 10, &res);
1954
1955 if (ret < 0) {
1956 wl1271_warning("incorrect value written to bt_coex_mode");
1957 return count;
1958 }
1959
1960 mutex_lock(&wl->mutex);
1961
1962 res = !!res;
1963
1964 if (res == wl->sg_enabled)
1965 goto out;
1966
1967 wl->sg_enabled = res;
1968
1969 if (wl->state == WL1271_STATE_OFF)
1970 goto out;
1971
1972 ret = wl1271_ps_elp_wakeup(wl, false);
1973 if (ret < 0)
1974 goto out;
1975
1976 wl1271_acx_sg_enable(wl, wl->sg_enabled);
1977 wl1271_ps_elp_sleep(wl);
1978
1979 out:
1980 mutex_unlock(&wl->mutex);
1981 return count;
1982}
1983
1984static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR,
1985 wl1271_sysfs_show_bt_coex_state,
1986 wl1271_sysfs_store_bt_coex_state);
1987
1940int wl1271_register_hw(struct wl1271 *wl) 1988int wl1271_register_hw(struct wl1271 *wl)
1941{ 1989{
1942 int ret; 1990 int ret;
@@ -1960,6 +2008,14 @@ int wl1271_register_hw(struct wl1271 *wl)
1960} 2008}
1961EXPORT_SYMBOL_GPL(wl1271_register_hw); 2009EXPORT_SYMBOL_GPL(wl1271_register_hw);
1962 2010
2011void wl1271_unregister_hw(struct wl1271 *wl)
2012{
2013 ieee80211_unregister_hw(wl->hw);
2014 wl->mac80211_registered = false;
2015
2016}
2017EXPORT_SYMBOL_GPL(wl1271_unregister_hw);
2018
1963int wl1271_init_ieee80211(struct wl1271 *wl) 2019int wl1271_init_ieee80211(struct wl1271 *wl)
1964{ 2020{
1965 /* The tx descriptor buffer and the TKIP space. */ 2021 /* The tx descriptor buffer and the TKIP space. */
@@ -1974,6 +2030,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
1974 IEEE80211_HW_NOISE_DBM | 2030 IEEE80211_HW_NOISE_DBM |
1975 IEEE80211_HW_BEACON_FILTER | 2031 IEEE80211_HW_BEACON_FILTER |
1976 IEEE80211_HW_SUPPORTS_PS | 2032 IEEE80211_HW_SUPPORTS_PS |
2033 IEEE80211_HW_SUPPORTS_UAPSD |
1977 IEEE80211_HW_HAS_RATE_CONTROL; 2034 IEEE80211_HW_HAS_RATE_CONTROL;
1978 2035
1979 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 2036 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
@@ -1984,6 +2041,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
1984 if (wl1271_11a_enabled()) 2041 if (wl1271_11a_enabled())
1985 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; 2042 wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz;
1986 2043
2044 wl->hw->queues = 4;
2045
1987 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); 2046 SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl));
1988 2047
1989 return 0; 2048 return 0;
@@ -1995,21 +2054,34 @@ EXPORT_SYMBOL_GPL(wl1271_init_ieee80211);
1995struct ieee80211_hw *wl1271_alloc_hw(void) 2054struct ieee80211_hw *wl1271_alloc_hw(void)
1996{ 2055{
1997 struct ieee80211_hw *hw; 2056 struct ieee80211_hw *hw;
2057 struct platform_device *plat_dev = NULL;
1998 struct wl1271 *wl; 2058 struct wl1271 *wl;
1999 int i; 2059 int i, ret;
2060 static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
2000 2061
2001 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); 2062 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);
2002 if (!hw) { 2063 if (!hw) {
2003 wl1271_error("could not alloc ieee80211_hw"); 2064 wl1271_error("could not alloc ieee80211_hw");
2004 return ERR_PTR(-ENOMEM); 2065 ret = -ENOMEM;
2066 goto err_hw_alloc;
2005 } 2067 }
2006 2068
2069 plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL);
2070 if (!plat_dev) {
2071 wl1271_error("could not allocate platform_device");
2072 ret = -ENOMEM;
2073 goto err_plat_alloc;
2074 }
2075
2076 memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device));
2077
2007 wl = hw->priv; 2078 wl = hw->priv;
2008 memset(wl, 0, sizeof(*wl)); 2079 memset(wl, 0, sizeof(*wl));
2009 2080
2010 INIT_LIST_HEAD(&wl->list); 2081 INIT_LIST_HEAD(&wl->list);
2011 2082
2012 wl->hw = hw; 2083 wl->hw = hw;
2084 wl->plat_dev = plat_dev;
2013 2085
2014 skb_queue_head_init(&wl->tx_queue); 2086 skb_queue_head_init(&wl->tx_queue);
2015 2087
@@ -2027,6 +2099,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2027 wl->band = IEEE80211_BAND_2GHZ; 2099 wl->band = IEEE80211_BAND_2GHZ;
2028 wl->vif = NULL; 2100 wl->vif = NULL;
2029 wl->flags = 0; 2101 wl->flags = 0;
2102 wl->sg_enabled = true;
2030 2103
2031 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 2104 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
2032 wl->tx_frames[i] = NULL; 2105 wl->tx_frames[i] = NULL;
@@ -2036,18 +2109,55 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
2036 wl->state = WL1271_STATE_OFF; 2109 wl->state = WL1271_STATE_OFF;
2037 mutex_init(&wl->mutex); 2110 mutex_init(&wl->mutex);
2038 2111
2112 /*
2113 * FIXME: we should use a zero MAC address here, but for now we
2114 * generate a random Nokia address.
2115 */
2116 memcpy(wl->mac_addr, nokia_oui, 3);
2117 get_random_bytes(wl->mac_addr + 3, 3);
2118
2039 /* Apply default driver configuration. */ 2119 /* Apply default driver configuration. */
2040 wl1271_conf_init(wl); 2120 wl1271_conf_init(wl);
2041 2121
2042 wl1271_debugfs_init(wl); 2122 wl1271_debugfs_init(wl);
2043 2123
2124 /* Register platform device */
2125 ret = platform_device_register(wl->plat_dev);
2126 if (ret) {
2127 wl1271_error("couldn't register platform device");
2128 goto err_hw;
2129 }
2130 dev_set_drvdata(&wl->plat_dev->dev, wl);
2131
2132 /* Create sysfs file to control bt coex state */
2133 ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state);
2134 if (ret < 0) {
2135 wl1271_error("failed to create sysfs file bt_coex_state");
2136 goto err_platform;
2137 }
2138
2044 return hw; 2139 return hw;
2140
2141err_platform:
2142 platform_device_unregister(wl->plat_dev);
2143
2144err_hw:
2145 wl1271_debugfs_exit(wl);
2146 kfree(plat_dev);
2147
2148err_plat_alloc:
2149 ieee80211_free_hw(hw);
2150
2151err_hw_alloc:
2152
2153 return ERR_PTR(ret);
2045} 2154}
2046EXPORT_SYMBOL_GPL(wl1271_alloc_hw); 2155EXPORT_SYMBOL_GPL(wl1271_alloc_hw);
2047 2156
2048int wl1271_free_hw(struct wl1271 *wl) 2157int wl1271_free_hw(struct wl1271 *wl)
2049{ 2158{
2050 ieee80211_unregister_hw(wl->hw); 2159 platform_device_unregister(wl->plat_dev);
2160 kfree(wl->plat_dev);
2051 2161
2052 wl1271_debugfs_exit(wl); 2162 wl1271_debugfs_exit(wl);
2053 2163
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c
index 1f204db30c27..3c03de74dbfc 100644
--- a/drivers/net/wireless/wl12xx/wl1271_sdio.c
+++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c
@@ -102,15 +102,14 @@ static void wl1271_sdio_init(struct wl1271 *wl)
102} 102}
103 103
104static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, 104static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
105 size_t len, bool fixed) 105 size_t len, bool fixed)
106{ 106{
107 int ret; 107 int ret;
108 struct sdio_func *func = wl_to_func(wl); 108 struct sdio_func *func = wl_to_func(wl);
109 109
110 sdio_claim_host(func);
111 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 110 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
112 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); 111 ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret);
113 wl1271_debug(DEBUG_SPI, "sdio read 52 addr 0x%x, byte 0x%02x", 112 wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x",
114 addr, ((u8 *)buf)[0]); 113 addr, ((u8 *)buf)[0]);
115 } else { 114 } else {
116 if (fixed) 115 if (fixed)
@@ -118,32 +117,30 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf,
118 else 117 else
119 ret = sdio_memcpy_fromio(func, buf, addr, len); 118 ret = sdio_memcpy_fromio(func, buf, addr, len);
120 119
121 wl1271_debug(DEBUG_SPI, "sdio read 53 addr 0x%x, %d bytes", 120 wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %d bytes",
122 addr, len); 121 addr, len);
123 wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); 122 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
124 } 123 }
125 124
126 if (ret) 125 if (ret)
127 wl1271_error("sdio read failed (%d)", ret); 126 wl1271_error("sdio read failed (%d)", ret);
128 127
129 sdio_release_host(func);
130} 128}
131 129
132static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, 130static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
133 size_t len, bool fixed) 131 size_t len, bool fixed)
134{ 132{
135 int ret; 133 int ret;
136 struct sdio_func *func = wl_to_func(wl); 134 struct sdio_func *func = wl_to_func(wl);
137 135
138 sdio_claim_host(func);
139 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { 136 if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) {
140 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); 137 sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret);
141 wl1271_debug(DEBUG_SPI, "sdio write 52 addr 0x%x, byte 0x%02x", 138 wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x",
142 addr, ((u8 *)buf)[0]); 139 addr, ((u8 *)buf)[0]);
143 } else { 140 } else {
144 wl1271_debug(DEBUG_SPI, "sdio write 53 addr 0x%x, %d bytes", 141 wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %d bytes",
145 addr, len); 142 addr, len);
146 wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); 143 wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len);
147 144
148 if (fixed) 145 if (fixed)
149 ret = sdio_writesb(func, addr, buf, len); 146 ret = sdio_writesb(func, addr, buf, len);
@@ -153,7 +150,23 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf,
153 if (ret) 150 if (ret)
154 wl1271_error("sdio write failed (%d)", ret); 151 wl1271_error("sdio write failed (%d)", ret);
155 152
156 sdio_release_host(func); 153}
154
155static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable)
156{
157 struct sdio_func *func = wl_to_func(wl);
158
159 /* Let the SDIO stack handle wlan_enable control, so we
160 * keep host claimed while wlan is in use to keep wl1271
161 * alive.
162 */
163 if (enable) {
164 sdio_claim_host(func);
165 sdio_enable_func(func);
166 } else {
167 sdio_disable_func(func);
168 sdio_release_host(func);
169 }
157} 170}
158 171
159static struct wl1271_if_operations sdio_ops = { 172static struct wl1271_if_operations sdio_ops = {
@@ -161,15 +174,12 @@ static struct wl1271_if_operations sdio_ops = {
161 .write = wl1271_sdio_raw_write, 174 .write = wl1271_sdio_raw_write,
162 .reset = wl1271_sdio_reset, 175 .reset = wl1271_sdio_reset,
163 .init = wl1271_sdio_init, 176 .init = wl1271_sdio_init,
177 .power = wl1271_sdio_set_power,
164 .dev = wl1271_sdio_wl_to_dev, 178 .dev = wl1271_sdio_wl_to_dev,
165 .enable_irq = wl1271_sdio_enable_interrupts, 179 .enable_irq = wl1271_sdio_enable_interrupts,
166 .disable_irq = wl1271_sdio_disable_interrupts 180 .disable_irq = wl1271_sdio_disable_interrupts
167}; 181};
168 182
169static void wl1271_sdio_set_power(bool enable)
170{
171}
172
173static int __devinit wl1271_probe(struct sdio_func *func, 183static int __devinit wl1271_probe(struct sdio_func *func,
174 const struct sdio_device_id *id) 184 const struct sdio_device_id *id)
175{ 185{
@@ -190,8 +200,6 @@ static int __devinit wl1271_probe(struct sdio_func *func,
190 wl->if_priv = func; 200 wl->if_priv = func;
191 wl->if_ops = &sdio_ops; 201 wl->if_ops = &sdio_ops;
192 202
193 wl->set_power = wl1271_sdio_set_power;
194
195 /* Grab access to FN0 for ELP reg. */ 203 /* Grab access to FN0 for ELP reg. */
196 func->card->quirks |= MMC_QUIRK_LENIENT_FN0; 204 func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
197 205
@@ -220,28 +228,18 @@ static int __devinit wl1271_probe(struct sdio_func *func,
220 if (ret) 228 if (ret)
221 goto out_irq; 229 goto out_irq;
222 230
223 sdio_claim_host(func);
224 sdio_set_drvdata(func, wl); 231 sdio_set_drvdata(func, wl);
225 232
226 ret = sdio_enable_func(func);
227 if (ret)
228 goto out_release;
229
230 sdio_release_host(func);
231
232 wl1271_notice("initialized"); 233 wl1271_notice("initialized");
233 234
234 return 0; 235 return 0;
235 236
236 out_release:
237 sdio_release_host(func);
238
239 out_irq: 237 out_irq:
240 free_irq(wl->irq, wl); 238 free_irq(wl->irq, wl);
241 239
242 240
243 out_free: 241 out_free:
244 ieee80211_free_hw(hw); 242 wl1271_free_hw(wl);
245 243
246 return ret; 244 return ret;
247} 245}
@@ -250,24 +248,10 @@ static void __devexit wl1271_remove(struct sdio_func *func)
250{ 248{
251 struct wl1271 *wl = sdio_get_drvdata(func); 249 struct wl1271 *wl = sdio_get_drvdata(func);
252 250
253 ieee80211_unregister_hw(wl->hw);
254
255 sdio_claim_host(func);
256 sdio_disable_func(func);
257 sdio_release_host(func);
258
259 free_irq(wl->irq, wl); 251 free_irq(wl->irq, wl);
260 252
261 kfree(wl->target_mem_map); 253 wl1271_unregister_hw(wl);
262 vfree(wl->fw); 254 wl1271_free_hw(wl);
263 wl->fw = NULL;
264 kfree(wl->nvs);
265 wl->nvs = NULL;
266
267 kfree(wl->fw_status);
268 kfree(wl->tx_res_if);
269
270 ieee80211_free_hw(wl->hw);
271} 255}
272 256
273static struct sdio_driver wl1271_sdio_driver = { 257static struct sdio_driver wl1271_sdio_driver = {
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index ed285fec2a08..f44b05a32b0d 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -23,7 +23,6 @@
23 23
24#include <linux/irq.h> 24#include <linux/irq.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/crc7.h> 26#include <linux/crc7.h>
28#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
29#include <linux/spi/wl12xx.h> 28#include <linux/spi/wl12xx.h>
@@ -332,26 +331,18 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
332 return IRQ_HANDLED; 331 return IRQ_HANDLED;
333} 332}
334 333
335static void wl1271_device_release(struct device *dev) 334static void wl1271_spi_set_power(struct wl1271 *wl, bool enable)
336{ 335{
337 336 if (wl->set_power)
337 wl->set_power(enable);
338} 338}
339 339
340static struct platform_device wl1271_device = {
341 .name = "wl1271",
342 .id = -1,
343
344 /* device model insists to have a release function */
345 .dev = {
346 .release = wl1271_device_release,
347 },
348};
349
350static struct wl1271_if_operations spi_ops = { 340static struct wl1271_if_operations spi_ops = {
351 .read = wl1271_spi_raw_read, 341 .read = wl1271_spi_raw_read,
352 .write = wl1271_spi_raw_write, 342 .write = wl1271_spi_raw_write,
353 .reset = wl1271_spi_reset, 343 .reset = wl1271_spi_reset,
354 .init = wl1271_spi_init, 344 .init = wl1271_spi_init,
345 .power = wl1271_spi_set_power,
355 .dev = wl1271_spi_wl_to_dev, 346 .dev = wl1271_spi_wl_to_dev,
356 .enable_irq = wl1271_spi_enable_interrupts, 347 .enable_irq = wl1271_spi_enable_interrupts,
357 .disable_irq = wl1271_spi_disable_interrupts 348 .disable_irq = wl1271_spi_disable_interrupts
@@ -415,33 +406,23 @@ static int __devinit wl1271_probe(struct spi_device *spi)
415 406
416 disable_irq(wl->irq); 407 disable_irq(wl->irq);
417 408
418 ret = platform_device_register(&wl1271_device);
419 if (ret) {
420 wl1271_error("couldn't register platform device");
421 goto out_irq;
422 }
423 dev_set_drvdata(&wl1271_device.dev, wl);
424
425 ret = wl1271_init_ieee80211(wl); 409 ret = wl1271_init_ieee80211(wl);
426 if (ret) 410 if (ret)
427 goto out_platform; 411 goto out_irq;
428 412
429 ret = wl1271_register_hw(wl); 413 ret = wl1271_register_hw(wl);
430 if (ret) 414 if (ret)
431 goto out_platform; 415 goto out_irq;
432 416
433 wl1271_notice("initialized"); 417 wl1271_notice("initialized");
434 418
435 return 0; 419 return 0;
436 420
437 out_platform:
438 platform_device_unregister(&wl1271_device);
439
440 out_irq: 421 out_irq:
441 free_irq(wl->irq, wl); 422 free_irq(wl->irq, wl);
442 423
443 out_free: 424 out_free:
444 ieee80211_free_hw(hw); 425 wl1271_free_hw(wl);
445 426
446 return ret; 427 return ret;
447} 428}
@@ -450,9 +431,9 @@ static int __devexit wl1271_remove(struct spi_device *spi)
450{ 431{
451 struct wl1271 *wl = dev_get_drvdata(&spi->dev); 432 struct wl1271 *wl = dev_get_drvdata(&spi->dev);
452 433
453 platform_device_unregister(&wl1271_device);
454 free_irq(wl->irq, wl); 434 free_irq(wl->irq, wl);
455 435
436 wl1271_unregister_hw(wl);
456 wl1271_free_hw(wl); 437 wl1271_free_hw(wl);
457 438
458 return 0; 439 return 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h
index 8b9f6b4f5652..5e6c27a57415 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.h
@@ -125,9 +125,6 @@ struct wl1271_tx_hw_res_if {
125 125
126static inline int wl1271_tx_get_queue(int queue) 126static inline int wl1271_tx_get_queue(int queue)
127{ 127{
128 /* FIXME: use best effort until WMM is enabled */
129 return CONF_TX_AC_BE;
130
131 switch (queue) { 128 switch (queue) {
132 case 0: 129 case 0:
133 return CONF_TX_AC_VO; 130 return CONF_TX_AC_VO;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 7b9621de239f..65dd502eab0d 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1834,32 +1834,32 @@ out:
1834} 1834}
1835 1835
1836static const iw_handler wl3501_handler[] = { 1836static const iw_handler wl3501_handler[] = {
1837 [SIOCGIWNAME - SIOCIWFIRST] = wl3501_get_name, 1837 IW_HANDLER(SIOCGIWNAME, wl3501_get_name),
1838 [SIOCSIWFREQ - SIOCIWFIRST] = wl3501_set_freq, 1838 IW_HANDLER(SIOCSIWFREQ, wl3501_set_freq),
1839 [SIOCGIWFREQ - SIOCIWFIRST] = wl3501_get_freq, 1839 IW_HANDLER(SIOCGIWFREQ, wl3501_get_freq),
1840 [SIOCSIWMODE - SIOCIWFIRST] = wl3501_set_mode, 1840 IW_HANDLER(SIOCSIWMODE, wl3501_set_mode),
1841 [SIOCGIWMODE - SIOCIWFIRST] = wl3501_get_mode, 1841 IW_HANDLER(SIOCGIWMODE, wl3501_get_mode),
1842 [SIOCGIWSENS - SIOCIWFIRST] = wl3501_get_sens, 1842 IW_HANDLER(SIOCGIWSENS, wl3501_get_sens),
1843 [SIOCGIWRANGE - SIOCIWFIRST] = wl3501_get_range, 1843 IW_HANDLER(SIOCGIWRANGE, wl3501_get_range),
1844 [SIOCSIWSPY - SIOCIWFIRST] = iw_handler_set_spy, 1844 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1845 [SIOCGIWSPY - SIOCIWFIRST] = iw_handler_get_spy, 1845 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1846 [SIOCSIWTHRSPY - SIOCIWFIRST] = iw_handler_set_thrspy, 1846 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1847 [SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy, 1847 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1848 [SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap, 1848 IW_HANDLER(SIOCSIWAP, wl3501_set_wap),
1849 [SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap, 1849 IW_HANDLER(SIOCGIWAP, wl3501_get_wap),
1850 [SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan, 1850 IW_HANDLER(SIOCSIWSCAN, wl3501_set_scan),
1851 [SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan, 1851 IW_HANDLER(SIOCGIWSCAN, wl3501_get_scan),
1852 [SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid, 1852 IW_HANDLER(SIOCSIWESSID, wl3501_set_essid),
1853 [SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid, 1853 IW_HANDLER(SIOCGIWESSID, wl3501_get_essid),
1854 [SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick, 1854 IW_HANDLER(SIOCSIWNICKN, wl3501_set_nick),
1855 [SIOCGIWNICKN - SIOCIWFIRST] = wl3501_get_nick, 1855 IW_HANDLER(SIOCGIWNICKN, wl3501_get_nick),
1856 [SIOCGIWRATE - SIOCIWFIRST] = wl3501_get_rate, 1856 IW_HANDLER(SIOCGIWRATE, wl3501_get_rate),
1857 [SIOCGIWRTS - SIOCIWFIRST] = wl3501_get_rts_threshold, 1857 IW_HANDLER(SIOCGIWRTS, wl3501_get_rts_threshold),
1858 [SIOCGIWFRAG - SIOCIWFIRST] = wl3501_get_frag_threshold, 1858 IW_HANDLER(SIOCGIWFRAG, wl3501_get_frag_threshold),
1859 [SIOCGIWTXPOW - SIOCIWFIRST] = wl3501_get_txpow, 1859 IW_HANDLER(SIOCGIWTXPOW, wl3501_get_txpow),
1860 [SIOCGIWRETRY - SIOCIWFIRST] = wl3501_get_retry, 1860 IW_HANDLER(SIOCGIWRETRY, wl3501_get_retry),
1861 [SIOCGIWENCODE - SIOCIWFIRST] = wl3501_get_encode, 1861 IW_HANDLER(SIOCGIWENCODE, wl3501_get_encode),
1862 [SIOCGIWPOWER - SIOCIWFIRST] = wl3501_get_power, 1862 IW_HANDLER(SIOCGIWPOWER, wl3501_get_power),
1863}; 1863};
1864 1864
1865static const struct iw_handler_def wl3501_handler_def = { 1865static const struct iw_handler_def wl3501_handler_def = {