aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-01-05 16:06:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-01-05 16:06:25 -0500
commitc96e96354a6c9456cdf1f150eca504e2ea35301e (patch)
tree751bec601fb8152116b8e31e0f1f83d687a37d6f /drivers/net/wireless/ath/ath9k
parentdbbe68bb12b34f3e450da7a73c20e6fa1f85d63a (diff)
parent33af88138b859f515b365a074e0a014d7cdbf846 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: net/bluetooth/Makefile
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c11
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h31
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c327
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c460
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c16
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h3
24 files changed, 623 insertions, 420 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index fdb5a835fdcf..f8a7771faee2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -22,7 +22,7 @@
22 22
23int modparam_force_new_ani; 23int modparam_force_new_ani;
24module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); 24module_param_named(force_new_ani, modparam_force_new_ani, int, 0444);
25MODULE_PARM_DESC(nohwcrypt, "Force new ANI for AR5008, AR9001, AR9002"); 25MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002");
26 26
27/* General hardware code for the A5008/AR9001/AR9002 hadware families */ 27/* General hardware code for the A5008/AR9001/AR9002 hadware families */
28 28
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 7ae66a889f5a..7d68d61e406b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -203,13 +203,14 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
203 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 203 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
204 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); 204 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
205 205
206 if (AR_NO_SPUR == cur_bb_spur)
207 break;
208
206 if (is2GHz) 209 if (is2GHz)
207 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; 210 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
208 else 211 else
209 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; 212 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
210 213
211 if (AR_NO_SPUR == cur_bb_spur)
212 break;
213 cur_bb_spur = cur_bb_spur - freq; 214 cur_bb_spur = cur_bb_spur - freq;
214 215
215 if (IS_CHAN_HT40(chan)) { 216 if (IS_CHAN_HT40(chan)) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 466d2bf02eab..4819747fa4c3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -59,6 +59,8 @@
59 59
60#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) 60#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
61 61
62#define EEPROM_DATA_LEN_9485 1088
63
62static int ar9003_hw_power_interpolate(int32_t x, 64static int ar9003_hw_power_interpolate(int32_t x,
63 int32_t *px, int32_t *py, u_int16_t np); 65 int32_t *px, int32_t *py, u_int16_t np);
64 66
@@ -3368,7 +3370,7 @@ found:
3368 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n", 3370 "Found block at %x: code=%d ref=%d length=%d major=%d minor=%d\n",
3369 cptr, code, reference, length, major, minor); 3371 cptr, code, reference, length, major, minor);
3370 if ((!AR_SREV_9485(ah) && length >= 1024) || 3372 if ((!AR_SREV_9485(ah) && length >= 1024) ||
3371 (AR_SREV_9485(ah) && length >= (4 * 1024))) { 3373 (AR_SREV_9485(ah) && length > EEPROM_DATA_LEN_9485)) {
3372 ath_dbg(common, ATH_DBG_EEPROM, 3374 ath_dbg(common, ATH_DBG_EEPROM,
3373 "Skipping bad header\n"); 3375 "Skipping bad header\n");
3374 cptr -= COMP_HDR_LEN; 3376 cptr -= COMP_HDR_LEN;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index b6e4ee48ef78..4ceddbbdfcee 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -613,9 +613,9 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
613 * possibly be reviewing the last subframe. AR_CRCErr 613 * possibly be reviewing the last subframe. AR_CRCErr
614 * is the CRC of the actual data. 614 * is the CRC of the actual data.
615 */ 615 */
616 if (rxsp->status11 & AR_CRCErr) { 616 if (rxsp->status11 & AR_CRCErr)
617 rxs->rs_status |= ATH9K_RXERR_CRC; 617 rxs->rs_status |= ATH9K_RXERR_CRC;
618 } else if (rxsp->status11 & AR_PHYErr) { 618 if (rxsp->status11 & AR_PHYErr) {
619 phyerr = MS(rxsp->status11, AR_PHYErrCode); 619 phyerr = MS(rxsp->status11, AR_PHYErrCode);
620 /* 620 /*
621 * If we reach a point here where AR_PostDelimCRCErr is 621 * If we reach a point here where AR_PostDelimCRCErr is
@@ -638,11 +638,12 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
638 rxs->rs_phyerr = phyerr; 638 rxs->rs_phyerr = phyerr;
639 } 639 }
640 640
641 } else if (rxsp->status11 & AR_DecryptCRCErr) { 641 }
642 if (rxsp->status11 & AR_DecryptCRCErr)
642 rxs->rs_status |= ATH9K_RXERR_DECRYPT; 643 rxs->rs_status |= ATH9K_RXERR_DECRYPT;
643 } else if (rxsp->status11 & AR_MichaelErr) { 644 if (rxsp->status11 & AR_MichaelErr)
644 rxs->rs_status |= ATH9K_RXERR_MIC; 645 rxs->rs_status |= ATH9K_RXERR_MIC;
645 } else if (rxsp->status11 & AR_KeyMiss) 646 if (rxsp->status11 & AR_KeyMiss)
646 rxs->rs_status |= ATH9K_RXERR_DECRYPT; 647 rxs->rs_status |= ATH9K_RXERR_DECRYPT;
647 } 648 }
648 649
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2c31f5142eda..3681caf54282 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -664,11 +664,13 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
664} 664}
665 665
666extern struct ieee80211_ops ath9k_ops; 666extern struct ieee80211_ops ath9k_ops;
667extern int modparam_nohwcrypt; 667extern int ath9k_modparam_nohwcrypt;
668extern int led_blink; 668extern int led_blink;
669extern int ath9k_pm_qos_value; 669extern int ath9k_pm_qos_value;
670extern bool is_ath9k_unloaded;
670 671
671irqreturn_t ath_isr(int irq, void *dev); 672irqreturn_t ath_isr(int irq, void *dev);
673void ath9k_init_crypto(struct ath_softc *sc);
672int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, 674int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
673 const struct ath_bus_ops *bus_ops); 675 const struct ath_bus_ops *bus_ops);
674void ath9k_deinit_device(struct ath_softc *sc); 676void ath9k_deinit_device(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 5e108c086904..385ba03134ba 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -566,8 +566,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
566 * last beacon we received (which may be none). 566 * last beacon we received (which may be none).
567 */ 567 */
568 dtimperiod = conf->dtim_period; 568 dtimperiod = conf->dtim_period;
569 if (dtimperiod <= 0) /* NB: 0 if not known */
570 dtimperiod = 1;
571 dtimcount = conf->dtim_count; 569 dtimcount = conf->dtim_count;
572 if (dtimcount >= dtimperiod) /* NB: sanity check */ 570 if (dtimcount >= dtimperiod) /* NB: sanity check */
573 dtimcount = 0; 571 dtimcount = 0;
@@ -575,8 +573,6 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
575 cfpcount = 0; 573 cfpcount = 0;
576 574
577 sleepduration = conf->listen_interval * intval; 575 sleepduration = conf->listen_interval * intval;
578 if (sleepduration <= 0)
579 sleepduration = intval;
580 576
581 /* 577 /*
582 * Pull nexttbtt forward to reflect the current 578 * Pull nexttbtt forward to reflect the current
@@ -662,8 +658,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
662} 658}
663 659
664static void ath_beacon_config_adhoc(struct ath_softc *sc, 660static void ath_beacon_config_adhoc(struct ath_softc *sc,
665 struct ath_beacon_config *conf, 661 struct ath_beacon_config *conf)
666 struct ieee80211_vif *vif)
667{ 662{
668 struct ath_hw *ah = sc->sc_ah; 663 struct ath_hw *ah = sc->sc_ah;
669 struct ath_common *common = ath9k_hw_common(ah); 664 struct ath_common *common = ath9k_hw_common(ah);
@@ -718,18 +713,17 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
718 /* Setup the beacon configuration parameters */ 713 /* Setup the beacon configuration parameters */
719 if (vif) { 714 if (vif) {
720 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 715 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
721
722 iftype = vif->type; 716 iftype = vif->type;
723
724 cur_conf->beacon_interval = bss_conf->beacon_int; 717 cur_conf->beacon_interval = bss_conf->beacon_int;
725 cur_conf->dtim_period = bss_conf->dtim_period; 718 cur_conf->dtim_period = bss_conf->dtim_period;
719 } else {
720 iftype = sc->sc_ah->opmode;
721 }
722
726 cur_conf->listen_interval = 1; 723 cur_conf->listen_interval = 1;
727 cur_conf->dtim_count = 1; 724 cur_conf->dtim_count = 1;
728 cur_conf->bmiss_timeout = 725 cur_conf->bmiss_timeout =
729 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; 726 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
730 } else {
731 iftype = sc->sc_ah->opmode;
732 }
733 727
734 /* 728 /*
735 * It looks like mac80211 may end up using beacon interval of zero in 729 * It looks like mac80211 may end up using beacon interval of zero in
@@ -740,13 +734,20 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
740 if (cur_conf->beacon_interval == 0) 734 if (cur_conf->beacon_interval == 0)
741 cur_conf->beacon_interval = 100; 735 cur_conf->beacon_interval = 100;
742 736
737 /*
738 * Some times we dont parse dtim period from mac80211, in that case
739 * use a default value
740 */
741 if (cur_conf->dtim_period == 0)
742 cur_conf->dtim_period = 1;
743
743 switch (iftype) { 744 switch (iftype) {
744 case NL80211_IFTYPE_AP: 745 case NL80211_IFTYPE_AP:
745 ath_beacon_config_ap(sc, cur_conf); 746 ath_beacon_config_ap(sc, cur_conf);
746 break; 747 break;
747 case NL80211_IFTYPE_ADHOC: 748 case NL80211_IFTYPE_ADHOC:
748 case NL80211_IFTYPE_MESH_POINT: 749 case NL80211_IFTYPE_MESH_POINT:
749 ath_beacon_config_adhoc(sc, cur_conf, vif); 750 ath_beacon_config_adhoc(sc, cur_conf);
750 break; 751 break;
751 case NL80211_IFTYPE_STATION: 752 case NL80211_IFTYPE_STATION:
752 ath_beacon_config_sta(sc, cur_conf); 753 ath_beacon_config_sta(sc, cur_conf);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index f6f09d1378f4..58e2ddc927a9 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -23,8 +23,6 @@
23#include <net/cfg80211.h> 23#include <net/cfg80211.h>
24#include "ar9003_eeprom.h" 24#include "ar9003_eeprom.h"
25 25
26#define AH_USE_EEPROM 0x1
27
28#ifdef __BIG_ENDIAN 26#ifdef __BIG_ENDIAN
29#define AR5416_EEPROM_MAGIC 0x5aa5 27#define AR5416_EEPROM_MAGIC 0x5aa5
30#else 28#else
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 22b68b3c8566..5ab3084eb9cb 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -153,16 +153,36 @@ static void hif_usb_tx_cb(struct urb *urb)
153 case -ENODEV: 153 case -ENODEV:
154 case -ESHUTDOWN: 154 case -ESHUTDOWN:
155 /* 155 /*
156 * The URB has been killed, free the SKBs 156 * The URB has been killed, free the SKBs.
157 * and return.
158 */ 157 */
159 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); 158 ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
160 return; 159
160 /*
161 * If the URBs are being flushed, no need to add this
162 * URB to the free list.
163 */
164 spin_lock(&hif_dev->tx.tx_lock);
165 if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
166 spin_unlock(&hif_dev->tx.tx_lock);
167 return;
168 }
169 spin_unlock(&hif_dev->tx.tx_lock);
170
171 /*
172 * In the stop() case, this URB has to be added to
173 * the free list.
174 */
175 goto add_free;
161 default: 176 default:
162 break; 177 break;
163 } 178 }
164 179
165 /* Check if TX has been stopped */ 180 /*
181 * Check if TX has been stopped, this is needed because
182 * this CB could have been invoked just after the TX lock
183 * was released in hif_stop() and kill_urb() hasn't been
184 * called yet.
185 */
166 spin_lock(&hif_dev->tx.tx_lock); 186 spin_lock(&hif_dev->tx.tx_lock);
167 if (hif_dev->tx.flags & HIF_USB_TX_STOP) { 187 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
168 spin_unlock(&hif_dev->tx.tx_lock); 188 spin_unlock(&hif_dev->tx.tx_lock);
@@ -314,6 +334,7 @@ static void hif_usb_start(void *hif_handle, u8 pipe_id)
314static void hif_usb_stop(void *hif_handle, u8 pipe_id) 334static void hif_usb_stop(void *hif_handle, u8 pipe_id)
315{ 335{
316 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; 336 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
337 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
317 unsigned long flags; 338 unsigned long flags;
318 339
319 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); 340 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
@@ -321,6 +342,12 @@ static void hif_usb_stop(void *hif_handle, u8 pipe_id)
321 hif_dev->tx.tx_skb_cnt = 0; 342 hif_dev->tx.tx_skb_cnt = 0;
322 hif_dev->tx.flags |= HIF_USB_TX_STOP; 343 hif_dev->tx.flags |= HIF_USB_TX_STOP;
323 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); 344 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
345
346 /* The pending URBs have to be canceled. */
347 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
348 &hif_dev->tx.tx_pending, list) {
349 usb_kill_urb(tx_buf->urb);
350 }
324} 351}
325 352
326static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, 353static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
@@ -587,6 +614,7 @@ free:
587static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) 614static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
588{ 615{
589 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; 616 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
617 unsigned long flags;
590 618
591 list_for_each_entry_safe(tx_buf, tx_buf_tmp, 619 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
592 &hif_dev->tx.tx_buf, list) { 620 &hif_dev->tx.tx_buf, list) {
@@ -597,6 +625,10 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
597 kfree(tx_buf); 625 kfree(tx_buf);
598 } 626 }
599 627
628 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
629 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
630 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
631
600 list_for_each_entry_safe(tx_buf, tx_buf_tmp, 632 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
601 &hif_dev->tx.tx_pending, list) { 633 &hif_dev->tx.tx_pending, list) {
602 usb_kill_urb(tx_buf->urb); 634 usb_kill_urb(tx_buf->urb);
@@ -993,16 +1025,16 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
993{ 1025{
994 struct usb_device *udev = interface_to_usbdev(interface); 1026 struct usb_device *udev = interface_to_usbdev(interface);
995 struct hif_device_usb *hif_dev = usb_get_intfdata(interface); 1027 struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1028 bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false;
996 1029
997 if (hif_dev) { 1030 if (hif_dev) {
998 ath9k_htc_hw_deinit(hif_dev->htc_handle, 1031 ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
999 (udev->state == USB_STATE_NOTATTACHED) ? true : false);
1000 ath9k_htc_hw_free(hif_dev->htc_handle); 1032 ath9k_htc_hw_free(hif_dev->htc_handle);
1001 ath9k_hif_usb_dev_deinit(hif_dev); 1033 ath9k_hif_usb_dev_deinit(hif_dev);
1002 usb_set_intfdata(interface, NULL); 1034 usb_set_intfdata(interface, NULL);
1003 } 1035 }
1004 1036
1005 if (hif_dev->flags & HIF_USB_START) 1037 if (!unplugged && (hif_dev->flags & HIF_USB_START))
1006 ath9k_hif_usb_reboot(udev); 1038 ath9k_hif_usb_reboot(udev);
1007 1039
1008 kfree(hif_dev); 1040 kfree(hif_dev);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index e4a5e2e79541..7b9d863d4035 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -64,6 +64,7 @@ struct tx_buf {
64}; 64};
65 65
66#define HIF_USB_TX_STOP BIT(0) 66#define HIF_USB_TX_STOP BIT(0)
67#define HIF_USB_TX_FLUSH BIT(1)
67 68
68struct hif_usb_tx { 69struct hif_usb_tx {
69 u8 flags; 70 u8 flags;
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index fdf9d5fe8cc0..a099b3e87ed3 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -331,17 +331,15 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
331 331
332#define OP_INVALID BIT(0) 332#define OP_INVALID BIT(0)
333#define OP_SCANNING BIT(1) 333#define OP_SCANNING BIT(1)
334#define OP_FULL_RESET BIT(2) 334#define OP_LED_ASSOCIATED BIT(2)
335#define OP_LED_ASSOCIATED BIT(3) 335#define OP_LED_ON BIT(3)
336#define OP_LED_ON BIT(4) 336#define OP_PREAMBLE_SHORT BIT(4)
337#define OP_PREAMBLE_SHORT BIT(5) 337#define OP_PROTECT_ENABLE BIT(5)
338#define OP_PROTECT_ENABLE BIT(6) 338#define OP_ASSOCIATED BIT(6)
339#define OP_ASSOCIATED BIT(7) 339#define OP_ENABLE_BEACON BIT(7)
340#define OP_ENABLE_BEACON BIT(8) 340#define OP_LED_DEINIT BIT(8)
341#define OP_LED_DEINIT BIT(9) 341#define OP_BT_PRIORITY_DETECTED BIT(9)
342#define OP_UNPLUGGED BIT(10) 342#define OP_BT_SCAN BIT(10)
343#define OP_BT_PRIORITY_DETECTED BIT(11)
344#define OP_BT_SCAN BIT(12)
345 343
346struct ath9k_htc_priv { 344struct ath9k_htc_priv {
347 struct device *dev; 345 struct device *dev;
@@ -378,7 +376,7 @@ struct ath9k_htc_priv {
378 struct ieee80211_vif *vif; 376 struct ieee80211_vif *vif;
379 struct htc_beacon_config cur_beacon_conf; 377 struct htc_beacon_config cur_beacon_conf;
380 unsigned int rxfilter; 378 unsigned int rxfilter;
381 struct tasklet_struct wmi_tasklet; 379 struct tasklet_struct swba_tasklet;
382 struct tasklet_struct rx_tasklet; 380 struct tasklet_struct rx_tasklet;
383 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 381 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
384 struct ath9k_htc_rx rx; 382 struct ath9k_htc_rx rx;
@@ -386,6 +384,7 @@ struct ath9k_htc_priv {
386 struct sk_buff_head tx_queue; 384 struct sk_buff_head tx_queue;
387 struct delayed_work ath9k_ani_work; 385 struct delayed_work ath9k_ani_work;
388 struct work_struct ps_work; 386 struct work_struct ps_work;
387 struct work_struct fatal_work;
389 388
390 struct mutex htc_pm_lock; 389 struct mutex htc_pm_lock;
391 unsigned long ps_usecount; 390 unsigned long ps_usecount;
@@ -420,6 +419,8 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
420 common->bus_ops->read_cachesize(common, csz); 419 common->bus_ops->read_cachesize(common, csz);
421} 420}
422 421
422void ath9k_htc_reset(struct ath9k_htc_priv *priv);
423
423void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv); 424void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
424void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, 425void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
425 struct ieee80211_vif *vif); 426 struct ieee80211_vif *vif);
@@ -435,6 +436,7 @@ void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
435void ath9k_htc_station_work(struct work_struct *work); 436void ath9k_htc_station_work(struct work_struct *work);
436void ath9k_htc_aggr_work(struct work_struct *work); 437void ath9k_htc_aggr_work(struct work_struct *work);
437void ath9k_ani_work(struct work_struct *work);; 438void ath9k_ani_work(struct work_struct *work);;
439void ath_start_ani(struct ath9k_htc_priv *priv);
438 440
439int ath9k_tx_init(struct ath9k_htc_priv *priv); 441int ath9k_tx_init(struct ath9k_htc_priv *priv);
440void ath9k_tx_tasklet(unsigned long data); 442void ath9k_tx_tasklet(unsigned long data);
@@ -457,8 +459,13 @@ void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv);
457void ath9k_ps_work(struct work_struct *work); 459void ath9k_ps_work(struct work_struct *work);
458bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, 460bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
459 enum ath9k_power_mode mode); 461 enum ath9k_power_mode mode);
462void ath_update_txpow(struct ath9k_htc_priv *priv);
460 463
461void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); 464void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
465void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
466void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
467void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
468void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
462void ath9k_init_leds(struct ath9k_htc_priv *priv); 469void ath9k_init_leds(struct ath9k_htc_priv *priv);
463void ath9k_deinit_leds(struct ath9k_htc_priv *priv); 470void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
464 471
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index 283ff97ed446..fe70f67aa088 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -1,3 +1,19 @@
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
1#include "htc.h" 17#include "htc.h"
2 18
3/******************/ 19/******************/
@@ -131,3 +147,314 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
131 cancel_delayed_work_sync(&priv->coex_period_work); 147 cancel_delayed_work_sync(&priv->coex_period_work);
132 cancel_delayed_work_sync(&priv->duty_cycle_work); 148 cancel_delayed_work_sync(&priv->duty_cycle_work);
133} 149}
150
151/*******/
152/* LED */
153/*******/
154
155static void ath9k_led_blink_work(struct work_struct *work)
156{
157 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
158 ath9k_led_blink_work.work);
159
160 if (!(priv->op_flags & OP_LED_ASSOCIATED))
161 return;
162
163 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
164 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
165 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
166 else
167 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
168 (priv->op_flags & OP_LED_ON) ? 1 : 0);
169
170 ieee80211_queue_delayed_work(priv->hw,
171 &priv->ath9k_led_blink_work,
172 (priv->op_flags & OP_LED_ON) ?
173 msecs_to_jiffies(priv->led_off_duration) :
174 msecs_to_jiffies(priv->led_on_duration));
175
176 priv->led_on_duration = priv->led_on_cnt ?
177 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
178 ATH_LED_ON_DURATION_IDLE;
179 priv->led_off_duration = priv->led_off_cnt ?
180 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
181 ATH_LED_OFF_DURATION_IDLE;
182 priv->led_on_cnt = priv->led_off_cnt = 0;
183
184 if (priv->op_flags & OP_LED_ON)
185 priv->op_flags &= ~OP_LED_ON;
186 else
187 priv->op_flags |= OP_LED_ON;
188}
189
190static void ath9k_led_brightness_work(struct work_struct *work)
191{
192 struct ath_led *led = container_of(work, struct ath_led,
193 brightness_work.work);
194 struct ath9k_htc_priv *priv = led->priv;
195
196 switch (led->brightness) {
197 case LED_OFF:
198 if (led->led_type == ATH_LED_ASSOC ||
199 led->led_type == ATH_LED_RADIO) {
200 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
201 (led->led_type == ATH_LED_RADIO));
202 priv->op_flags &= ~OP_LED_ASSOCIATED;
203 if (led->led_type == ATH_LED_RADIO)
204 priv->op_flags &= ~OP_LED_ON;
205 } else {
206 priv->led_off_cnt++;
207 }
208 break;
209 case LED_FULL:
210 if (led->led_type == ATH_LED_ASSOC) {
211 priv->op_flags |= OP_LED_ASSOCIATED;
212 ieee80211_queue_delayed_work(priv->hw,
213 &priv->ath9k_led_blink_work, 0);
214 } else if (led->led_type == ATH_LED_RADIO) {
215 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
216 priv->op_flags |= OP_LED_ON;
217 } else {
218 priv->led_on_cnt++;
219 }
220 break;
221 default:
222 break;
223 }
224}
225
226static void ath9k_led_brightness(struct led_classdev *led_cdev,
227 enum led_brightness brightness)
228{
229 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
230 struct ath9k_htc_priv *priv = led->priv;
231
232 led->brightness = brightness;
233 if (!(priv->op_flags & OP_LED_DEINIT))
234 ieee80211_queue_delayed_work(priv->hw,
235 &led->brightness_work, 0);
236}
237
238void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
239{
240 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
241 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
242 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
243 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
244}
245
246static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
247 char *trigger)
248{
249 int ret;
250
251 led->priv = priv;
252 led->led_cdev.name = led->name;
253 led->led_cdev.default_trigger = trigger;
254 led->led_cdev.brightness_set = ath9k_led_brightness;
255
256 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
257 if (ret)
258 ath_err(ath9k_hw_common(priv->ah),
259 "Failed to register led:%s", led->name);
260 else
261 led->registered = 1;
262
263 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
264
265 return ret;
266}
267
268static void ath9k_unregister_led(struct ath_led *led)
269{
270 if (led->registered) {
271 led_classdev_unregister(&led->led_cdev);
272 led->registered = 0;
273 }
274}
275
276void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
277{
278 priv->op_flags |= OP_LED_DEINIT;
279 ath9k_unregister_led(&priv->assoc_led);
280 priv->op_flags &= ~OP_LED_ASSOCIATED;
281 ath9k_unregister_led(&priv->tx_led);
282 ath9k_unregister_led(&priv->rx_led);
283 ath9k_unregister_led(&priv->radio_led);
284}
285
286void ath9k_init_leds(struct ath9k_htc_priv *priv)
287{
288 char *trigger;
289 int ret;
290
291 if (AR_SREV_9287(priv->ah))
292 priv->ah->led_pin = ATH_LED_PIN_9287;
293 else if (AR_SREV_9271(priv->ah))
294 priv->ah->led_pin = ATH_LED_PIN_9271;
295 else if (AR_DEVID_7010(priv->ah))
296 priv->ah->led_pin = ATH_LED_PIN_7010;
297 else
298 priv->ah->led_pin = ATH_LED_PIN_DEF;
299
300 /* Configure gpio 1 for output */
301 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
302 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
303 /* LED off, active low */
304 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
305
306 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
307
308 trigger = ieee80211_get_radio_led_name(priv->hw);
309 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
310 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
311 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
312 priv->radio_led.led_type = ATH_LED_RADIO;
313 if (ret)
314 goto fail;
315
316 trigger = ieee80211_get_assoc_led_name(priv->hw);
317 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
318 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
319 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
320 priv->assoc_led.led_type = ATH_LED_ASSOC;
321 if (ret)
322 goto fail;
323
324 trigger = ieee80211_get_tx_led_name(priv->hw);
325 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
326 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
327 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
328 priv->tx_led.led_type = ATH_LED_TX;
329 if (ret)
330 goto fail;
331
332 trigger = ieee80211_get_rx_led_name(priv->hw);
333 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
334 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
335 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
336 priv->rx_led.led_type = ATH_LED_RX;
337 if (ret)
338 goto fail;
339
340 priv->op_flags &= ~OP_LED_DEINIT;
341
342 return;
343
344fail:
345 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
346 ath9k_deinit_leds(priv);
347}
348
349/*******************/
350/* Rfkill */
351/*******************/
352
353static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
354{
355 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
356 priv->ah->rfkill_polarity;
357}
358
359void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
360{
361 struct ath9k_htc_priv *priv = hw->priv;
362 bool blocked = !!ath_is_rfkill_set(priv);
363
364 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
365}
366
367void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
368{
369 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
370 wiphy_rfkill_start_polling(priv->hw->wiphy);
371}
372
373void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
374{
375 struct ath9k_htc_priv *priv = hw->priv;
376 struct ath_hw *ah = priv->ah;
377 struct ath_common *common = ath9k_hw_common(ah);
378 int ret;
379 u8 cmd_rsp;
380
381 if (!ah->curchan)
382 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
383
384 /* Reset the HW */
385 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
386 if (ret) {
387 ath_err(common,
388 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
389 ret, ah->curchan->channel);
390 }
391
392 ath_update_txpow(priv);
393
394 /* Start RX */
395 WMI_CMD(WMI_START_RECV_CMDID);
396 ath9k_host_rx_init(priv);
397
398 /* Start TX */
399 htc_start(priv->htc);
400 spin_lock_bh(&priv->tx_lock);
401 priv->tx_queues_stop = false;
402 spin_unlock_bh(&priv->tx_lock);
403 ieee80211_wake_queues(hw);
404
405 WMI_CMD(WMI_ENABLE_INTR_CMDID);
406
407 /* Enable LED */
408 ath9k_hw_cfg_output(ah, ah->led_pin,
409 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
410 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
411}
412
413void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
414{
415 struct ath9k_htc_priv *priv = hw->priv;
416 struct ath_hw *ah = priv->ah;
417 struct ath_common *common = ath9k_hw_common(ah);
418 int ret;
419 u8 cmd_rsp;
420
421 ath9k_htc_ps_wakeup(priv);
422
423 /* Disable LED */
424 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
425 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
426
427 WMI_CMD(WMI_DISABLE_INTR_CMDID);
428
429 /* Stop TX */
430 ieee80211_stop_queues(hw);
431 htc_stop(priv->htc);
432 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
433 skb_queue_purge(&priv->tx_queue);
434
435 /* Stop RX */
436 WMI_CMD(WMI_STOP_RECV_CMDID);
437
438 /*
439 * The MIB counters have to be disabled here,
440 * since the target doesn't do it.
441 */
442 ath9k_hw_disable_mib_counters(ah);
443
444 if (!ah->curchan)
445 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
446
447 /* Reset the HW */
448 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
449 if (ret) {
450 ath_err(common,
451 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
452 ret, ah->curchan->channel);
453 }
454
455 /* Disable the PHY */
456 ath9k_hw_phy_disable(ah);
457
458 ath9k_htc_ps_restore(priv);
459 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
460}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 0f6be350fd3c..38433f9bfe59 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -142,7 +142,7 @@ static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
142{ 142{
143 ath9k_htc_exit_debug(priv->ah); 143 ath9k_htc_exit_debug(priv->ah);
144 ath9k_hw_deinit(priv->ah); 144 ath9k_hw_deinit(priv->ah);
145 tasklet_kill(&priv->wmi_tasklet); 145 tasklet_kill(&priv->swba_tasklet);
146 tasklet_kill(&priv->rx_tasklet); 146 tasklet_kill(&priv->rx_tasklet);
147 tasklet_kill(&priv->tx_tasklet); 147 tasklet_kill(&priv->tx_tasklet);
148 kfree(priv->ah); 148 kfree(priv->ah);
@@ -647,13 +647,15 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
647 spin_lock_init(&priv->tx_lock); 647 spin_lock_init(&priv->tx_lock);
648 mutex_init(&priv->mutex); 648 mutex_init(&priv->mutex);
649 mutex_init(&priv->htc_pm_lock); 649 mutex_init(&priv->htc_pm_lock);
650 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet, 650 tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet,
651 (unsigned long)priv); 651 (unsigned long)priv);
652 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, 652 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
653 (unsigned long)priv); 653 (unsigned long)priv);
654 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); 654 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
655 (unsigned long)priv);
655 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); 656 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
656 INIT_WORK(&priv->ps_work, ath9k_ps_work); 657 INIT_WORK(&priv->ps_work, ath9k_ps_work);
658 INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
657 659
658 /* 660 /*
659 * Cache line size is used to size and align various 661 * Cache line size is used to size and align various
@@ -714,8 +716,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
714 IEEE80211_HW_HAS_RATE_CONTROL | 716 IEEE80211_HW_HAS_RATE_CONTROL |
715 IEEE80211_HW_RX_INCLUDES_FCS | 717 IEEE80211_HW_RX_INCLUDES_FCS |
716 IEEE80211_HW_SUPPORTS_PS | 718 IEEE80211_HW_SUPPORTS_PS |
717 IEEE80211_HW_PS_NULLFUNC_STACK | 719 IEEE80211_HW_PS_NULLFUNC_STACK;
718 IEEE80211_HW_NEED_DTIM_PERIOD;
719 720
720 hw->wiphy->interface_modes = 721 hw->wiphy->interface_modes =
721 BIT(NL80211_IFTYPE_STATION) | 722 BIT(NL80211_IFTYPE_STATION) |
@@ -851,9 +852,6 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
851 if (ret) 852 if (ret)
852 goto err_init; 853 goto err_init;
853 854
854 /* The device may have been unplugged earlier. */
855 priv->op_flags &= ~OP_UNPLUGGED;
856
857 ret = ath9k_init_device(priv, devid, product, drv_info); 855 ret = ath9k_init_device(priv, devid, product, drv_info);
858 if (ret) 856 if (ret)
859 goto err_init; 857 goto err_init;
@@ -873,7 +871,7 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
873 871
874 /* Check if the device has been yanked out. */ 872 /* Check if the device has been yanked out. */
875 if (hotunplug) 873 if (hotunplug)
876 htc_handle->drv_priv->op_flags |= OP_UNPLUGGED; 874 htc_handle->drv_priv->ah->ah_flags |= AH_UNPLUGGED;
877 875
878 ath9k_deinit_device(htc_handle->drv_priv); 876 ath9k_deinit_device(htc_handle->drv_priv);
879 ath9k_deinit_wmi(htc_handle->drv_priv); 877 ath9k_deinit_wmi(htc_handle->drv_priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index dd17909bd903..845b4c938d16 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -24,7 +24,7 @@ static struct dentry *ath9k_debugfs_root;
24/* Utilities */ 24/* Utilities */
25/*************/ 25/*************/
26 26
27static void ath_update_txpow(struct ath9k_htc_priv *priv) 27void ath_update_txpow(struct ath9k_htc_priv *priv)
28{ 28{
29 struct ath_hw *ah = priv->ah; 29 struct ath_hw *ah = priv->ah;
30 30
@@ -116,6 +116,60 @@ void ath9k_ps_work(struct work_struct *work)
116 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); 116 ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP);
117} 117}
118 118
119void ath9k_htc_reset(struct ath9k_htc_priv *priv)
120{
121 struct ath_hw *ah = priv->ah;
122 struct ath_common *common = ath9k_hw_common(ah);
123 struct ieee80211_channel *channel = priv->hw->conf.channel;
124 struct ath9k_hw_cal_data *caldata;
125 enum htc_phymode mode;
126 __be16 htc_mode;
127 u8 cmd_rsp;
128 int ret;
129
130 mutex_lock(&priv->mutex);
131 ath9k_htc_ps_wakeup(priv);
132
133 if (priv->op_flags & OP_ASSOCIATED)
134 cancel_delayed_work_sync(&priv->ath9k_ani_work);
135
136 ieee80211_stop_queues(priv->hw);
137 htc_stop(priv->htc);
138 WMI_CMD(WMI_DISABLE_INTR_CMDID);
139 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
140 WMI_CMD(WMI_STOP_RECV_CMDID);
141
142 caldata = &priv->caldata[channel->hw_value];
143 ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
144 if (ret) {
145 ath_err(common,
146 "Unable to reset device (%u Mhz) reset status %d\n",
147 channel->center_freq, ret);
148 }
149
150 ath_update_txpow(priv);
151
152 WMI_CMD(WMI_START_RECV_CMDID);
153 ath9k_host_rx_init(priv);
154
155 mode = ath9k_htc_get_curmode(priv, ah->curchan);
156 htc_mode = cpu_to_be16(mode);
157 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
158
159 WMI_CMD(WMI_ENABLE_INTR_CMDID);
160 htc_start(priv->htc);
161
162 if (priv->op_flags & OP_ASSOCIATED) {
163 ath9k_htc_beacon_config(priv, priv->vif);
164 ath_start_ani(priv);
165 }
166
167 ieee80211_wake_queues(priv->hw);
168
169 ath9k_htc_ps_restore(priv);
170 mutex_unlock(&priv->mutex);
171}
172
119static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, 173static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
120 struct ieee80211_hw *hw, 174 struct ieee80211_hw *hw,
121 struct ath9k_channel *hchan) 175 struct ath9k_channel *hchan)
@@ -123,7 +177,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
123 struct ath_hw *ah = priv->ah; 177 struct ath_hw *ah = priv->ah;
124 struct ath_common *common = ath9k_hw_common(ah); 178 struct ath_common *common = ath9k_hw_common(ah);
125 struct ieee80211_conf *conf = &common->hw->conf; 179 struct ieee80211_conf *conf = &common->hw->conf;
126 bool fastcc = true; 180 bool fastcc;
127 struct ieee80211_channel *channel = hw->conf.channel; 181 struct ieee80211_channel *channel = hw->conf.channel;
128 struct ath9k_hw_cal_data *caldata; 182 struct ath9k_hw_cal_data *caldata;
129 enum htc_phymode mode; 183 enum htc_phymode mode;
@@ -134,8 +188,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
134 if (priv->op_flags & OP_INVALID) 188 if (priv->op_flags & OP_INVALID)
135 return -EIO; 189 return -EIO;
136 190
137 if (priv->op_flags & OP_FULL_RESET) 191 fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
138 fastcc = false;
139 192
140 ath9k_htc_ps_wakeup(priv); 193 ath9k_htc_ps_wakeup(priv);
141 htc_stop(priv->htc); 194 htc_stop(priv->htc);
@@ -177,23 +230,43 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
177 goto err; 230 goto err;
178 231
179 htc_start(priv->htc); 232 htc_start(priv->htc);
180
181 priv->op_flags &= ~OP_FULL_RESET;
182err: 233err:
183 ath9k_htc_ps_restore(priv); 234 ath9k_htc_ps_restore(priv);
184 return ret; 235 return ret;
185} 236}
186 237
238static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
239{
240 struct ath_common *common = ath9k_hw_common(priv->ah);
241 struct ath9k_htc_target_vif hvif;
242 int ret = 0;
243 u8 cmd_rsp;
244
245 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
246 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
247 hvif.index = 0; /* Should do for now */
248 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
249 priv->nvifs--;
250}
251
187static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) 252static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
188{ 253{
189 struct ath_common *common = ath9k_hw_common(priv->ah); 254 struct ath_common *common = ath9k_hw_common(priv->ah);
190 struct ath9k_htc_target_vif hvif; 255 struct ath9k_htc_target_vif hvif;
256 struct ath9k_htc_target_sta tsta;
191 int ret = 0; 257 int ret = 0;
192 u8 cmd_rsp; 258 u8 cmd_rsp;
193 259
194 if (priv->nvifs > 0) 260 if (priv->nvifs > 0)
195 return -ENOBUFS; 261 return -ENOBUFS;
196 262
263 if (priv->nstations >= ATH9K_HTC_MAX_STA)
264 return -ENOBUFS;
265
266 /*
267 * Add an interface.
268 */
269
197 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 270 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
198 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); 271 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
199 272
@@ -206,23 +279,57 @@ static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
206 return ret; 279 return ret;
207 280
208 priv->nvifs++; 281 priv->nvifs++;
282
283 /*
284 * Associate a station with the interface for packet injection.
285 */
286
287 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
288
289 memcpy(&tsta.macaddr, common->macaddr, ETH_ALEN);
290
291 tsta.is_vif_sta = 1;
292 tsta.sta_index = priv->nstations;
293 tsta.vif_index = hvif.index;
294 tsta.maxampdu = 0xffff;
295
296 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
297 if (ret) {
298 ath_err(common, "Unable to add station entry for monitor mode\n");
299 goto err_vif;
300 }
301
302 priv->nstations++;
303
209 return 0; 304 return 0;
305
306err_vif:
307 /*
308 * Remove the interface from the target.
309 */
310 __ath9k_htc_remove_monitor_interface(priv);
311 return ret;
210} 312}
211 313
212static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) 314static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
213{ 315{
214 struct ath_common *common = ath9k_hw_common(priv->ah); 316 struct ath_common *common = ath9k_hw_common(priv->ah);
215 struct ath9k_htc_target_vif hvif;
216 int ret = 0; 317 int ret = 0;
217 u8 cmd_rsp; 318 u8 cmd_rsp, sta_idx;
218 319
219 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); 320 __ath9k_htc_remove_monitor_interface(priv);
220 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
221 hvif.index = 0; /* Should do for now */
222 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
223 priv->nvifs--;
224 321
225 return ret; 322 sta_idx = 0; /* Only single interface, for now */
323
324 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
325 if (ret) {
326 ath_err(common, "Unable to remove station entry for monitor mode\n");
327 return ret;
328 }
329
330 priv->nstations--;
331
332 return 0;
226} 333}
227 334
228static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, 335static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
@@ -690,7 +797,7 @@ void ath9k_htc_debug_remove_root(void)
690/* ANI */ 797/* ANI */
691/*******/ 798/*******/
692 799
693static void ath_start_ani(struct ath9k_htc_priv *priv) 800void ath_start_ani(struct ath9k_htc_priv *priv)
694{ 801{
695 struct ath_common *common = ath9k_hw_common(priv->ah); 802 struct ath_common *common = ath9k_hw_common(priv->ah);
696 unsigned long timestamp = jiffies_to_msecs(jiffies); 803 unsigned long timestamp = jiffies_to_msecs(jiffies);
@@ -789,317 +896,6 @@ set_timer:
789 msecs_to_jiffies(cal_interval)); 896 msecs_to_jiffies(cal_interval));
790} 897}
791 898
792/*******/
793/* LED */
794/*******/
795
796static void ath9k_led_blink_work(struct work_struct *work)
797{
798 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
799 ath9k_led_blink_work.work);
800
801 if (!(priv->op_flags & OP_LED_ASSOCIATED))
802 return;
803
804 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
805 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
806 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
807 else
808 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
809 (priv->op_flags & OP_LED_ON) ? 1 : 0);
810
811 ieee80211_queue_delayed_work(priv->hw,
812 &priv->ath9k_led_blink_work,
813 (priv->op_flags & OP_LED_ON) ?
814 msecs_to_jiffies(priv->led_off_duration) :
815 msecs_to_jiffies(priv->led_on_duration));
816
817 priv->led_on_duration = priv->led_on_cnt ?
818 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
819 ATH_LED_ON_DURATION_IDLE;
820 priv->led_off_duration = priv->led_off_cnt ?
821 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
822 ATH_LED_OFF_DURATION_IDLE;
823 priv->led_on_cnt = priv->led_off_cnt = 0;
824
825 if (priv->op_flags & OP_LED_ON)
826 priv->op_flags &= ~OP_LED_ON;
827 else
828 priv->op_flags |= OP_LED_ON;
829}
830
831static void ath9k_led_brightness_work(struct work_struct *work)
832{
833 struct ath_led *led = container_of(work, struct ath_led,
834 brightness_work.work);
835 struct ath9k_htc_priv *priv = led->priv;
836
837 switch (led->brightness) {
838 case LED_OFF:
839 if (led->led_type == ATH_LED_ASSOC ||
840 led->led_type == ATH_LED_RADIO) {
841 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
842 (led->led_type == ATH_LED_RADIO));
843 priv->op_flags &= ~OP_LED_ASSOCIATED;
844 if (led->led_type == ATH_LED_RADIO)
845 priv->op_flags &= ~OP_LED_ON;
846 } else {
847 priv->led_off_cnt++;
848 }
849 break;
850 case LED_FULL:
851 if (led->led_type == ATH_LED_ASSOC) {
852 priv->op_flags |= OP_LED_ASSOCIATED;
853 ieee80211_queue_delayed_work(priv->hw,
854 &priv->ath9k_led_blink_work, 0);
855 } else if (led->led_type == ATH_LED_RADIO) {
856 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
857 priv->op_flags |= OP_LED_ON;
858 } else {
859 priv->led_on_cnt++;
860 }
861 break;
862 default:
863 break;
864 }
865}
866
867static void ath9k_led_brightness(struct led_classdev *led_cdev,
868 enum led_brightness brightness)
869{
870 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
871 struct ath9k_htc_priv *priv = led->priv;
872
873 led->brightness = brightness;
874 if (!(priv->op_flags & OP_LED_DEINIT))
875 ieee80211_queue_delayed_work(priv->hw,
876 &led->brightness_work, 0);
877}
878
879static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
880{
881 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
882 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
883 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
884 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
885}
886
887static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
888 char *trigger)
889{
890 int ret;
891
892 led->priv = priv;
893 led->led_cdev.name = led->name;
894 led->led_cdev.default_trigger = trigger;
895 led->led_cdev.brightness_set = ath9k_led_brightness;
896
897 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
898 if (ret)
899 ath_err(ath9k_hw_common(priv->ah),
900 "Failed to register led:%s", led->name);
901 else
902 led->registered = 1;
903
904 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
905
906 return ret;
907}
908
909static void ath9k_unregister_led(struct ath_led *led)
910{
911 if (led->registered) {
912 led_classdev_unregister(&led->led_cdev);
913 led->registered = 0;
914 }
915}
916
917void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
918{
919 priv->op_flags |= OP_LED_DEINIT;
920 ath9k_unregister_led(&priv->assoc_led);
921 priv->op_flags &= ~OP_LED_ASSOCIATED;
922 ath9k_unregister_led(&priv->tx_led);
923 ath9k_unregister_led(&priv->rx_led);
924 ath9k_unregister_led(&priv->radio_led);
925}
926
927void ath9k_init_leds(struct ath9k_htc_priv *priv)
928{
929 char *trigger;
930 int ret;
931
932 if (AR_SREV_9287(priv->ah))
933 priv->ah->led_pin = ATH_LED_PIN_9287;
934 else if (AR_SREV_9271(priv->ah))
935 priv->ah->led_pin = ATH_LED_PIN_9271;
936 else if (AR_DEVID_7010(priv->ah))
937 priv->ah->led_pin = ATH_LED_PIN_7010;
938 else
939 priv->ah->led_pin = ATH_LED_PIN_DEF;
940
941 /* Configure gpio 1 for output */
942 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
943 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
944 /* LED off, active low */
945 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
946
947 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
948
949 trigger = ieee80211_get_radio_led_name(priv->hw);
950 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
951 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
952 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
953 priv->radio_led.led_type = ATH_LED_RADIO;
954 if (ret)
955 goto fail;
956
957 trigger = ieee80211_get_assoc_led_name(priv->hw);
958 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
959 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
960 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
961 priv->assoc_led.led_type = ATH_LED_ASSOC;
962 if (ret)
963 goto fail;
964
965 trigger = ieee80211_get_tx_led_name(priv->hw);
966 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
967 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
968 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
969 priv->tx_led.led_type = ATH_LED_TX;
970 if (ret)
971 goto fail;
972
973 trigger = ieee80211_get_rx_led_name(priv->hw);
974 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
975 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
976 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
977 priv->rx_led.led_type = ATH_LED_RX;
978 if (ret)
979 goto fail;
980
981 priv->op_flags &= ~OP_LED_DEINIT;
982
983 return;
984
985fail:
986 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
987 ath9k_deinit_leds(priv);
988}
989
990/*******************/
991/* Rfkill */
992/*******************/
993
994static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
995{
996 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
997 priv->ah->rfkill_polarity;
998}
999
1000static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
1001{
1002 struct ath9k_htc_priv *priv = hw->priv;
1003 bool blocked = !!ath_is_rfkill_set(priv);
1004
1005 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1006}
1007
1008void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
1009{
1010 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1011 wiphy_rfkill_start_polling(priv->hw->wiphy);
1012}
1013
1014static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
1015{
1016 struct ath9k_htc_priv *priv = hw->priv;
1017 struct ath_hw *ah = priv->ah;
1018 struct ath_common *common = ath9k_hw_common(ah);
1019 int ret;
1020 u8 cmd_rsp;
1021
1022 if (!ah->curchan)
1023 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1024
1025 /* Reset the HW */
1026 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
1027 if (ret) {
1028 ath_err(common,
1029 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
1030 ret, ah->curchan->channel);
1031 }
1032
1033 ath_update_txpow(priv);
1034
1035 /* Start RX */
1036 WMI_CMD(WMI_START_RECV_CMDID);
1037 ath9k_host_rx_init(priv);
1038
1039 /* Start TX */
1040 htc_start(priv->htc);
1041 spin_lock_bh(&priv->tx_lock);
1042 priv->tx_queues_stop = false;
1043 spin_unlock_bh(&priv->tx_lock);
1044 ieee80211_wake_queues(hw);
1045
1046 WMI_CMD(WMI_ENABLE_INTR_CMDID);
1047
1048 /* Enable LED */
1049 ath9k_hw_cfg_output(ah, ah->led_pin,
1050 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1051 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1052}
1053
1054static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
1055{
1056 struct ath9k_htc_priv *priv = hw->priv;
1057 struct ath_hw *ah = priv->ah;
1058 struct ath_common *common = ath9k_hw_common(ah);
1059 int ret;
1060 u8 cmd_rsp;
1061
1062 ath9k_htc_ps_wakeup(priv);
1063
1064 /* Disable LED */
1065 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1066 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1067
1068 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1069
1070 /* Stop TX */
1071 ieee80211_stop_queues(hw);
1072 htc_stop(priv->htc);
1073 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1074 skb_queue_purge(&priv->tx_queue);
1075
1076 /* Stop RX */
1077 WMI_CMD(WMI_STOP_RECV_CMDID);
1078
1079 /*
1080 * The MIB counters have to be disabled here,
1081 * since the target doesn't do it.
1082 */
1083 ath9k_hw_disable_mib_counters(ah);
1084
1085 if (!ah->curchan)
1086 ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
1087
1088 /* Reset the HW */
1089 ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
1090 if (ret) {
1091 ath_err(common,
1092 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
1093 ret, ah->curchan->channel);
1094 }
1095
1096 /* Disable the PHY */
1097 ath9k_hw_phy_disable(ah);
1098
1099 ath9k_htc_ps_restore(priv);
1100 ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP);
1101}
1102
1103/**********************/ 899/**********************/
1104/* mac80211 Callbacks */ 900/* mac80211 Callbacks */
1105/**********************/ 901/**********************/
@@ -1218,6 +1014,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1218 int ret = 0; 1014 int ret = 0;
1219 u8 cmd_rsp; 1015 u8 cmd_rsp;
1220 1016
1017 /* Cancel all the running timers/work .. */
1018 cancel_work_sync(&priv->fatal_work);
1019 cancel_work_sync(&priv->ps_work);
1020 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1021 ath9k_led_stop_brightness(priv);
1022
1221 mutex_lock(&priv->mutex); 1023 mutex_lock(&priv->mutex);
1222 1024
1223 if (priv->op_flags & OP_INVALID) { 1025 if (priv->op_flags & OP_INVALID) {
@@ -1226,11 +1028,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
1226 return; 1028 return;
1227 } 1029 }
1228 1030
1229 /* Cancel all the running timers/work .. */
1230 cancel_work_sync(&priv->ps_work);
1231 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1232 ath9k_led_stop_brightness(priv);
1233
1234 ath9k_htc_ps_wakeup(priv); 1031 ath9k_htc_ps_wakeup(priv);
1235 htc_stop(priv->htc); 1032 htc_stop(priv->htc);
1236 WMI_CMD(WMI_DISABLE_INTR_CMDID); 1033 WMI_CMD(WMI_DISABLE_INTR_CMDID);
@@ -1792,7 +1589,6 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1792 spin_lock_bh(&priv->beacon_lock); 1589 spin_lock_bh(&priv->beacon_lock);
1793 priv->op_flags &= ~OP_SCANNING; 1590 priv->op_flags &= ~OP_SCANNING;
1794 spin_unlock_bh(&priv->beacon_lock); 1591 spin_unlock_bh(&priv->beacon_lock);
1795 priv->op_flags |= OP_FULL_RESET;
1796 if (priv->op_flags & OP_ASSOCIATED) { 1592 if (priv->op_flags & OP_ASSOCIATED) {
1797 ath9k_htc_beacon_config(priv, priv->vif); 1593 ath9k_htc_beacon_config(priv, priv->vif);
1798 ath_start_ani(priv); 1594 ath_start_ani(priv);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 4b51ed47fe69..fde978665e07 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1615,7 +1615,9 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
1615 * simply keep the ATH_DBG_WARN_ON_ONCE() but make 1615 * simply keep the ATH_DBG_WARN_ON_ONCE() but make
1616 * ath9k_hw_setpower() return type void. 1616 * ath9k_hw_setpower() return type void.
1617 */ 1617 */
1618 ATH_DBG_WARN_ON_ONCE(!status); 1618
1619 if (!(ah->ah_flags & AH_UNPLUGGED))
1620 ATH_DBG_WARN_ON_ONCE(!status);
1619 1621
1620 return status; 1622 return status;
1621} 1623}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b8ffaa5dc650..5a3dfec45e96 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -646,6 +646,10 @@ struct ath_nf_limits {
646 s16 nominal; 646 s16 nominal;
647}; 647};
648 648
649/* ah_flags */
650#define AH_USE_EEPROM 0x1
651#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
652
649struct ath_hw { 653struct ath_hw {
650 struct ieee80211_hw *hw; 654 struct ieee80211_hw *hw;
651 struct ath_common common; 655 struct ath_common common;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b0e5e716b167..767d8b86f1e1 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -29,8 +29,8 @@ static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
29module_param_named(debug, ath9k_debug, uint, 0); 29module_param_named(debug, ath9k_debug, uint, 0);
30MODULE_PARM_DESC(debug, "Debugging mask"); 30MODULE_PARM_DESC(debug, "Debugging mask");
31 31
32int modparam_nohwcrypt; 32int ath9k_modparam_nohwcrypt;
33module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 33module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
34MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); 34MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
35 35
36int led_blink; 36int led_blink;
@@ -45,6 +45,7 @@ int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE;
45module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); 45module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH);
46MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); 46MODULE_PARM_DESC(pmqos, "User specified PM-QOS value");
47 47
48bool is_ath9k_unloaded;
48/* We use the hw_value as an index into our private channel structure */ 49/* We use the hw_value as an index into our private channel structure */
49 50
50#define CHAN2G(_freq, _idx) { \ 51#define CHAN2G(_freq, _idx) { \
@@ -372,7 +373,7 @@ fail:
372#undef DS2PHYS 373#undef DS2PHYS
373} 374}
374 375
375static void ath9k_init_crypto(struct ath_softc *sc) 376void ath9k_init_crypto(struct ath_softc *sc)
376{ 377{
377 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 378 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
378 int i = 0; 379 int i = 0;
@@ -647,13 +648,12 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
647 IEEE80211_HW_SUPPORTS_PS | 648 IEEE80211_HW_SUPPORTS_PS |
648 IEEE80211_HW_PS_NULLFUNC_STACK | 649 IEEE80211_HW_PS_NULLFUNC_STACK |
649 IEEE80211_HW_SPECTRUM_MGMT | 650 IEEE80211_HW_SPECTRUM_MGMT |
650 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 651 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
651 IEEE80211_HW_NEED_DTIM_PERIOD;
652 652
653 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) 653 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
654 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 654 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
655 655
656 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt) 656 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
657 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 657 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
658 658
659 hw->wiphy->interface_modes = 659 hw->wiphy->interface_modes =
@@ -899,6 +899,7 @@ module_init(ath9k_init);
899 899
900static void __exit ath9k_exit(void) 900static void __exit ath9k_exit(void)
901{ 901{
902 is_ath9k_unloaded = true;
902 ath_ahb_exit(); 903 ath_ahb_exit();
903 ath_pci_exit(); 904 ath_pci_exit();
904 ath_rate_control_unregister(); 905 ath_rate_control_unregister();
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index e3d2ebf00e2e..180170d3ce25 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -692,15 +692,16 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
692 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { 692 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
693 if (ads.ds_rxstatus8 & AR_CRCErr) 693 if (ads.ds_rxstatus8 & AR_CRCErr)
694 rs->rs_status |= ATH9K_RXERR_CRC; 694 rs->rs_status |= ATH9K_RXERR_CRC;
695 else if (ads.ds_rxstatus8 & AR_PHYErr) { 695 if (ads.ds_rxstatus8 & AR_PHYErr) {
696 rs->rs_status |= ATH9K_RXERR_PHY; 696 rs->rs_status |= ATH9K_RXERR_PHY;
697 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); 697 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
698 rs->rs_phyerr = phyerr; 698 rs->rs_phyerr = phyerr;
699 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) 699 }
700 if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
700 rs->rs_status |= ATH9K_RXERR_DECRYPT; 701 rs->rs_status |= ATH9K_RXERR_DECRYPT;
701 else if (ads.ds_rxstatus8 & AR_MichaelErr) 702 if (ads.ds_rxstatus8 & AR_MichaelErr)
702 rs->rs_status |= ATH9K_RXERR_MIC; 703 rs->rs_status |= ATH9K_RXERR_MIC;
703 else if (ads.ds_rxstatus8 & AR_KeyMiss) 704 if (ads.ds_rxstatus8 & AR_KeyMiss)
704 rs->rs_status |= ATH9K_RXERR_DECRYPT; 705 rs->rs_status |= ATH9K_RXERR_DECRYPT;
705 } 706 }
706 707
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 8a1691db166d..f90a6ca94a76 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -285,7 +285,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
285 ath9k_hw_set_interrupts(ah, ah->imask); 285 ath9k_hw_set_interrupts(ah, ah->imask);
286 286
287 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 287 if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
288 ath_beacon_config(sc, NULL); 288 if (sc->sc_flags & SC_OP_BEACONS)
289 ath_beacon_config(sc, NULL);
289 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 290 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
290 ath_start_ani(common); 291 ath_start_ani(common);
291 } 292 }
@@ -599,7 +600,7 @@ void ath9k_tasklet(unsigned long data)
599 return; 600 return;
600 } 601 }
601 602
602 spin_lock_bh(&sc->sc_pcu_lock); 603 spin_lock(&sc->sc_pcu_lock);
603 604
604 if (!ath9k_hw_check_alive(ah)) 605 if (!ath9k_hw_check_alive(ah))
605 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 606 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
@@ -643,7 +644,7 @@ void ath9k_tasklet(unsigned long data)
643 /* re-enable hardware interrupt */ 644 /* re-enable hardware interrupt */
644 ath9k_hw_enable_interrupts(ah); 645 ath9k_hw_enable_interrupts(ah);
645 646
646 spin_unlock_bh(&sc->sc_pcu_lock); 647 spin_unlock(&sc->sc_pcu_lock);
647 ath9k_ps_restore(sc); 648 ath9k_ps_restore(sc);
648} 649}
649 650
@@ -1328,6 +1329,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1328 ath9k_ps_restore(sc); 1329 ath9k_ps_restore(sc);
1329 1330
1330 sc->ps_idle = true; 1331 sc->ps_idle = true;
1332 ath9k_set_wiphy_idle(aphy, true);
1331 ath_radio_disable(sc, hw); 1333 ath_radio_disable(sc, hw);
1332 1334
1333 sc->sc_flags |= SC_OP_INVALID; 1335 sc->sc_flags |= SC_OP_INVALID;
@@ -1455,6 +1457,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1455 struct ath_wiphy *aphy = hw->priv; 1457 struct ath_wiphy *aphy = hw->priv;
1456 struct ath_softc *sc = aphy->sc; 1458 struct ath_softc *sc = aphy->sc;
1457 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1459 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1460 int ret = 0;
1458 1461
1459 ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); 1462 ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
1460 mutex_lock(&sc->mutex); 1463 mutex_lock(&sc->mutex);
@@ -1464,7 +1467,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1464 case NL80211_IFTYPE_ADHOC: 1467 case NL80211_IFTYPE_ADHOC:
1465 if (sc->nbcnvifs >= ATH_BCBUF) { 1468 if (sc->nbcnvifs >= ATH_BCBUF) {
1466 ath_err(common, "No beacon slot available\n"); 1469 ath_err(common, "No beacon slot available\n");
1467 return -ENOBUFS; 1470 ret = -ENOBUFS;
1471 goto out;
1468 } 1472 }
1469 break; 1473 break;
1470 case NL80211_IFTYPE_STATION: 1474 case NL80211_IFTYPE_STATION:
@@ -1478,14 +1482,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1478 default: 1482 default:
1479 ath_err(common, "Interface type %d not yet supported\n", 1483 ath_err(common, "Interface type %d not yet supported\n",
1480 vif->type); 1484 vif->type);
1481 mutex_unlock(&sc->mutex); 1485 ret = -ENOTSUPP;
1482 return -ENOTSUPP; 1486 goto out;
1483 } 1487 }
1484 vif->type = new_type; 1488 vif->type = new_type;
1485 vif->p2p = p2p; 1489 vif->p2p = p2p;
1486 1490
1491out:
1487 mutex_unlock(&sc->mutex); 1492 mutex_unlock(&sc->mutex);
1488 return 0; 1493 return ret;
1489} 1494}
1490 1495
1491static void ath9k_remove_interface(struct ieee80211_hw *hw, 1496static void ath9k_remove_interface(struct ieee80211_hw *hw,
@@ -1824,7 +1829,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1824 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1829 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1825 int ret = 0; 1830 int ret = 0;
1826 1831
1827 if (modparam_nohwcrypt) 1832 if (ath9k_modparam_nohwcrypt)
1828 return -ENOSPC; 1833 return -ENOSPC;
1829 1834
1830 mutex_lock(&sc->mutex); 1835 mutex_lock(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 7ca8499249ec..78ef1f13386f 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -96,7 +96,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
96 struct pci_dev *pdev = to_pci_dev(sc->dev); 96 struct pci_dev *pdev = to_pci_dev(sc->dev);
97 u8 aspm; 97 u8 aspm;
98 98
99 if (!pdev->is_pcie) 99 if (!pci_is_pcie(pdev))
100 return; 100 return;
101 101
102 pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm); 102 pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
@@ -264,6 +264,8 @@ static void ath_pci_remove(struct pci_dev *pdev)
264 struct ath_softc *sc = aphy->sc; 264 struct ath_softc *sc = aphy->sc;
265 void __iomem *mem = sc->mem; 265 void __iomem *mem = sc->mem;
266 266
267 if (!is_ath9k_unloaded)
268 sc->sc_ah->ah_flags |= AH_UNPLUGGED;
267 ath9k_deinit_device(sc); 269 ath9k_deinit_device(sc);
268 free_irq(sc->irq, sc); 270 free_irq(sc->irq, sc);
269 ieee80211_free_hw(sc->hw); 271 ieee80211_free_hw(sc->hw);
@@ -309,7 +311,16 @@ static int ath_pci_resume(struct device *device)
309 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 311 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
310 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); 312 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
311 313
314 /*
315 * Reset key cache to sane defaults (all entries cleared) instead of
316 * semi-random values after suspend/resume.
317 */
318 ath9k_ps_wakeup(sc);
319 ath9k_init_crypto(sc);
320 ath9k_ps_restore(sc);
321
312 sc->ps_idle = true; 322 sc->ps_idle = true;
323 ath9k_set_wiphy_idle(aphy, true);
313 ath_radio_disable(sc, hw); 324 ath_radio_disable(sc, hw);
314 325
315 return 0; 326 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 896d12986b1e..e45147820eae 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -400,7 +400,7 @@ static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
400 } 400 }
401} 401}
402 402
403static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv) 403static void ath_rc_init_valid_rate_idx(struct ath_rate_priv *ath_rc_priv)
404{ 404{
405 u8 i; 405 u8 i;
406 406
@@ -408,7 +408,7 @@ static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
408 ath_rc_priv->valid_rate_index[i] = 0; 408 ath_rc_priv->valid_rate_index[i] = 0;
409} 409}
410 410
411static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv, 411static inline void ath_rc_set_valid_rate_idx(struct ath_rate_priv *ath_rc_priv,
412 u8 index, int valid_tx_rate) 412 u8 index, int valid_tx_rate)
413{ 413{
414 BUG_ON(index > ath_rc_priv->rate_table_size); 414 BUG_ON(index > ath_rc_priv->rate_table_size);
@@ -489,7 +489,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
489 489
490 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i; 490 ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
491 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 491 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
492 ath_rc_set_valid_txmask(ath_rc_priv, i, 1); 492 ath_rc_set_valid_rate_idx(ath_rc_priv, i, 1);
493 hi = i; 493 hi = i;
494 } 494 }
495 } 495 }
@@ -532,7 +532,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
532 ath_rc_priv->valid_phy_rateidx[phy] 532 ath_rc_priv->valid_phy_rateidx[phy]
533 [valid_rate_count] = j; 533 [valid_rate_count] = j;
534 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 534 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
535 ath_rc_set_valid_txmask(ath_rc_priv, j, 1); 535 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
536 hi = A_MAX(hi, j); 536 hi = A_MAX(hi, j);
537 } 537 }
538 } 538 }
@@ -568,7 +568,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
568 ath_rc_priv->valid_phy_rateidx[phy] 568 ath_rc_priv->valid_phy_rateidx[phy]
569 [ath_rc_priv->valid_phy_ratecnt[phy]] = j; 569 [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
570 ath_rc_priv->valid_phy_ratecnt[phy] += 1; 570 ath_rc_priv->valid_phy_ratecnt[phy] += 1;
571 ath_rc_set_valid_txmask(ath_rc_priv, j, 1); 571 ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
572 hi = A_MAX(hi, j); 572 hi = A_MAX(hi, j);
573 } 573 }
574 } 574 }
@@ -1210,7 +1210,7 @@ static void ath_rc_init(struct ath_softc *sc,
1210 } 1210 }
1211 1211
1212 /* Determine the valid rates */ 1212 /* Determine the valid rates */
1213 ath_rc_init_valid_txmask(ath_rc_priv); 1213 ath_rc_init_valid_rate_idx(ath_rc_priv);
1214 1214
1215 for (i = 0; i < WLAN_RC_PHY_MAX; i++) { 1215 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1216 for (j = 0; j < MAX_TX_RATE_PHY; j++) 1216 for (j = 0; j < MAX_TX_RATE_PHY; j++)
@@ -1321,7 +1321,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1321 struct ath_rate_priv *ath_rc_priv = priv_sta; 1321 struct ath_rate_priv *ath_rc_priv = priv_sta;
1322 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 1322 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1323 struct ieee80211_hdr *hdr; 1323 struct ieee80211_hdr *hdr;
1324 int final_ts_idx = 0, tx_status = 0, is_underrun = 0; 1324 int final_ts_idx = 0, tx_status = 0;
1325 int long_retry = 0; 1325 int long_retry = 0;
1326 __le16 fc; 1326 __le16 fc;
1327 int i; 1327 int i;
@@ -1358,7 +1358,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1358 tx_status = 1; 1358 tx_status = 1;
1359 1359
1360 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, 1360 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1361 (is_underrun) ? sc->hw->max_rate_tries : long_retry); 1361 long_retry);
1362 1362
1363 /* Check if aggregation has to be enabled for this tid */ 1363 /* Check if aggregation has to be enabled for this tid */
1364 if (conf_is_ht(&sc->hw->conf) && 1364 if (conf_is_ht(&sc->hw->conf) &&
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 31a004cb60ac..5d984b8acdb1 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -195,7 +195,6 @@ struct ath_rc_stats {
195 * @rate_max_phy: phy index for the max rate 195 * @rate_max_phy: phy index for the max rate
196 * @per: PER for every valid rate in % 196 * @per: PER for every valid rate in %
197 * @probe_interval: interval for ratectrl to probe for other rates 197 * @probe_interval: interval for ratectrl to probe for other rates
198 * @prev_data_rix: rate idx of last data frame
199 * @ht_cap: HT capabilities 198 * @ht_cap: HT capabilities
200 * @neg_rates: Negotatied rates 199 * @neg_rates: Negotatied rates
201 * @neg_ht_rates: Negotiated HT rates 200 * @neg_ht_rates: Negotiated HT rates
@@ -214,10 +213,8 @@ struct ath_rate_priv {
214 u32 probe_time; 213 u32 probe_time;
215 u32 per_down_time; 214 u32 per_down_time;
216 u32 probe_interval; 215 u32 probe_interval;
217 u32 prev_data_rix;
218 struct ath_rateset neg_rates; 216 struct ath_rateset neg_rates;
219 struct ath_rateset neg_ht_rates; 217 struct ath_rateset neg_ht_rates;
220 struct ath_rate_softc *asc;
221 const struct ath_rate_table *rate_table; 218 const struct ath_rate_table *rate_table;
222 219
223 struct dentry *debugfs_rcstats; 220 struct dentry *debugfs_rcstats;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 00ebed3f9158..b2497b8601e5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -528,7 +528,8 @@ bool ath_stoprecv(struct ath_softc *sc)
528 sc->rx.rxlink = NULL; 528 sc->rx.rxlink = NULL;
529 spin_unlock_bh(&sc->rx.rxbuflock); 529 spin_unlock_bh(&sc->rx.rxbuflock);
530 530
531 if (unlikely(!stopped)) { 531 if (!(ah->ah_flags & AH_UNPLUGGED) &&
532 unlikely(!stopped)) {
532 ath_err(ath9k_hw_common(sc->sc_ah), 533 ath_err(ath9k_hw_common(sc->sc_ah),
533 "Could not stop RX, we could be " 534 "Could not stop RX, we could be "
534 "confusing the DMA engine when we start RX up\n"); 535 "confusing the DMA engine when we start RX up\n");
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 8f42ea78198c..dc862f5e1162 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -120,7 +120,7 @@ void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
120 kfree(priv->wmi); 120 kfree(priv->wmi);
121} 121}
122 122
123void ath9k_wmi_tasklet(unsigned long data) 123void ath9k_swba_tasklet(unsigned long data)
124{ 124{
125 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; 125 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
126 struct ath_common *common = ath9k_hw_common(priv->ah); 126 struct ath_common *common = ath9k_hw_common(priv->ah);
@@ -131,6 +131,16 @@ void ath9k_wmi_tasklet(unsigned long data)
131 131
132} 132}
133 133
134void ath9k_fatal_work(struct work_struct *work)
135{
136 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
137 fatal_work);
138 struct ath_common *common = ath9k_hw_common(priv->ah);
139
140 ath_dbg(common, ATH_DBG_FATAL, "FATAL Event received, resetting device\n");
141 ath9k_htc_reset(priv);
142}
143
134static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb) 144static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
135{ 145{
136 skb_pull(skb, sizeof(struct wmi_cmd_hdr)); 146 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
@@ -163,7 +173,11 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
163 switch (cmd_id) { 173 switch (cmd_id) {
164 case WMI_SWBA_EVENTID: 174 case WMI_SWBA_EVENTID:
165 wmi->beacon_pending = *(u8 *)wmi_event; 175 wmi->beacon_pending = *(u8 *)wmi_event;
166 tasklet_schedule(&wmi->drv_priv->wmi_tasklet); 176 tasklet_schedule(&wmi->drv_priv->swba_tasklet);
177 break;
178 case WMI_FATAL_EVENTID:
179 ieee80211_queue_work(wmi->drv_priv->hw,
180 &wmi->drv_priv->fatal_work);
167 break; 181 break;
168 case WMI_TXRATE_EVENTID: 182 case WMI_TXRATE_EVENTID:
169#ifdef CONFIG_ATH9K_HTC_DEBUGFS 183#ifdef CONFIG_ATH9K_HTC_DEBUGFS
@@ -250,7 +264,7 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
250 int time_left, ret = 0; 264 int time_left, ret = 0;
251 unsigned long flags; 265 unsigned long flags;
252 266
253 if (wmi->drv_priv->op_flags & OP_UNPLUGGED) 267 if (ah->ah_flags & AH_UNPLUGGED)
254 return 0; 268 return 0;
255 269
256 skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); 270 skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC);
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index ac61074af8ac..42084277522d 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -117,7 +117,8 @@ int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
117 u8 *cmd_buf, u32 cmd_len, 117 u8 *cmd_buf, u32 cmd_len,
118 u8 *rsp_buf, u32 rsp_len, 118 u8 *rsp_buf, u32 rsp_len,
119 u32 timeout); 119 u32 timeout);
120void ath9k_wmi_tasklet(unsigned long data); 120void ath9k_swba_tasklet(unsigned long data);
121void ath9k_fatal_work(struct work_struct *work);
121 122
122#define WMI_CMD(_wmi_cmd) \ 123#define WMI_CMD(_wmi_cmd) \
123 do { \ 124 do { \