1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -429,6 +429,7 @@ void ath9k_set_beaconing_status(struct a
5 #define ATH_PAPRD_TIMEOUT 100 /* msecs */
7 +void ath_reset_work(struct work_struct *work);
8 void ath_hw_check(struct work_struct *work);
9 void ath_hw_pll_work(struct work_struct *work);
10 void ath_paprd_calibrate(struct work_struct *work);
11 @@ -559,6 +560,7 @@ struct ath_ant_comb {
12 #define SC_OP_RXFLUSH BIT(7)
13 #define SC_OP_LED_ASSOCIATED BIT(8)
14 #define SC_OP_LED_ON BIT(9)
15 +#define SC_OP_HW_RESET BIT(10)
16 #define SC_OP_TSF_RESET BIT(11)
17 #define SC_OP_BT_PRIORITY_DETECTED BIT(12)
18 #define SC_OP_BT_SCAN BIT(13)
19 @@ -609,6 +611,7 @@ struct ath_softc {
21 struct work_struct paprd_work;
22 struct work_struct hw_check_work;
23 + struct work_struct hw_reset_work;
24 struct completion paprd_complete;
26 unsigned int hw_busy_count;
27 @@ -655,7 +658,6 @@ struct ath_softc {
30 void ath9k_tasklet(unsigned long data);
31 -int ath_reset(struct ath_softc *sc, bool retry_tx);
32 int ath_cabq_update(struct ath_softc *);
34 static inline void ath_read_cachesize(struct ath_common *common, int *csz)
35 --- a/drivers/net/wireless/ath/ath9k/beacon.c
36 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
37 @@ -386,9 +386,7 @@ void ath_beacon_tasklet(unsigned long da
38 ath_dbg(common, ATH_DBG_BSTUCK,
39 "beacon is officially stuck\n");
40 sc->sc_flags |= SC_OP_TSF_RESET;
41 - spin_lock(&sc->sc_pcu_lock);
42 - ath_reset(sc, true);
43 - spin_unlock(&sc->sc_pcu_lock);
44 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
48 --- a/drivers/net/wireless/ath/ath9k/init.c
49 +++ b/drivers/net/wireless/ath/ath9k/init.c
50 @@ -776,6 +776,7 @@ int ath9k_init_device(u16 devid, struct
54 + INIT_WORK(&sc->hw_reset_work, ath_reset_work);
55 INIT_WORK(&sc->hw_check_work, ath_hw_check);
56 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
57 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
58 --- a/drivers/net/wireless/ath/ath9k/main.c
59 +++ b/drivers/net/wireless/ath/ath9k/main.c
60 @@ -595,74 +595,6 @@ static void ath_node_detach(struct ath_s
61 ath_tx_node_cleanup(sc, an);
64 -void ath_hw_check(struct work_struct *work)
66 - struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
67 - struct ath_common *common = ath9k_hw_common(sc->sc_ah);
68 - unsigned long flags;
71 - ath9k_ps_wakeup(sc);
72 - if (ath9k_hw_check_alive(sc->sc_ah))
75 - spin_lock_irqsave(&common->cc_lock, flags);
76 - busy = ath_update_survey_stats(sc);
77 - spin_unlock_irqrestore(&common->cc_lock, flags);
79 - ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
80 - "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
82 - if (++sc->hw_busy_count >= 3) {
83 - spin_lock_bh(&sc->sc_pcu_lock);
84 - ath_reset(sc, true);
85 - spin_unlock_bh(&sc->sc_pcu_lock);
87 - } else if (busy >= 0)
88 - sc->hw_busy_count = 0;
91 - ath9k_ps_restore(sc);
94 -static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
97 - struct ath_common *common = ath9k_hw_common(sc->sc_ah);
99 - if (pll_sqsum >= 0x40000) {
102 - /* Rx is hung for more than 500ms. Reset it */
103 - ath_dbg(common, ATH_DBG_RESET,
104 - "Possible RX hang, resetting");
105 - spin_lock_bh(&sc->sc_pcu_lock);
106 - ath_reset(sc, true);
107 - spin_unlock_bh(&sc->sc_pcu_lock);
114 -void ath_hw_pll_work(struct work_struct *work)
116 - struct ath_softc *sc = container_of(work, struct ath_softc,
120 - if (AR_SREV_9485(sc->sc_ah)) {
122 - ath9k_ps_wakeup(sc);
123 - pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
124 - ath9k_ps_restore(sc);
126 - ath_hw_pll_rx_hang_check(sc, pll_sqsum);
128 - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
133 void ath9k_tasklet(unsigned long data)
135 @@ -675,9 +607,7 @@ void ath9k_tasklet(unsigned long data)
137 if ((status & ATH9K_INT_FATAL) ||
138 (status & ATH9K_INT_BB_WATCHDOG)) {
139 - spin_lock(&sc->sc_pcu_lock);
140 - ath_reset(sc, true);
141 - spin_unlock(&sc->sc_pcu_lock);
142 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
146 @@ -968,13 +898,14 @@ void ath_radio_disable(struct ath_softc
147 ath9k_ps_restore(sc);
150 -int ath_reset(struct ath_softc *sc, bool retry_tx)
151 +static int ath_reset(struct ath_softc *sc, bool retry_tx)
153 struct ath_hw *ah = sc->sc_ah;
154 struct ath_common *common = ath9k_hw_common(ah);
155 struct ieee80211_hw *hw = sc->hw;
158 + sc->sc_flags &= ~SC_OP_HW_RESET;
159 sc->hw_busy_count = 0;
162 @@ -1035,6 +966,84 @@ int ath_reset(struct ath_softc *sc, bool
166 +void ath_reset_work(struct work_struct *work)
168 + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
170 + spin_lock_bh(&sc->sc_pcu_lock);
171 + ath_reset(sc, true);
172 + spin_unlock_bh(&sc->sc_pcu_lock);
175 +void ath_hw_check(struct work_struct *work)
177 + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
178 + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
179 + unsigned long flags;
182 + ath9k_ps_wakeup(sc);
183 + if (ath9k_hw_check_alive(sc->sc_ah))
186 + spin_lock_irqsave(&common->cc_lock, flags);
187 + busy = ath_update_survey_stats(sc);
188 + spin_unlock_irqrestore(&common->cc_lock, flags);
190 + ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
191 + "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
193 + if (++sc->hw_busy_count >= 3) {
194 + spin_lock_bh(&sc->sc_pcu_lock);
195 + ath_reset(sc, true);
196 + spin_unlock_bh(&sc->sc_pcu_lock);
199 + } else if (busy >= 0)
200 + sc->hw_busy_count = 0;
203 + ath9k_ps_restore(sc);
206 +static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
209 + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
211 + if (pll_sqsum >= 0x40000) {
214 + /* Rx is hung for more than 500ms. Reset it */
215 + ath_dbg(common, ATH_DBG_RESET,
216 + "Possible RX hang, resetting");
217 + spin_lock_bh(&sc->sc_pcu_lock);
218 + ath_reset(sc, true);
219 + spin_unlock_bh(&sc->sc_pcu_lock);
226 +void ath_hw_pll_work(struct work_struct *work)
228 + struct ath_softc *sc = container_of(work, struct ath_softc,
232 + if (AR_SREV_9485(sc->sc_ah)) {
234 + ath9k_ps_wakeup(sc);
235 + pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
236 + ath9k_ps_restore(sc);
238 + ath_hw_pll_rx_hang_check(sc, pll_sqsum);
240 + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
244 /**********************/
245 /* mac80211 callbacks */
246 /**********************/
247 --- a/drivers/net/wireless/ath/ath9k/xmit.c
248 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
249 @@ -600,8 +600,10 @@ static void ath_tx_complete_aggr(struct
254 - ath_reset(sc, false);
256 + sc->sc_flags |= SC_OP_HW_RESET;
257 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
261 static bool ath_lookup_legacy(struct ath_buf *bf)
262 @@ -2181,6 +2183,9 @@ static void ath_tx_processq(struct ath_s
264 spin_lock_bh(&txq->axq_lock);
266 + if (sc->sc_flags & SC_OP_HW_RESET)
269 if (list_empty(&txq->axq_q)) {
270 txq->axq_link = NULL;
271 if (sc->sc_flags & SC_OP_TXAGGR)
272 @@ -2268,9 +2273,7 @@ static void ath_tx_complete_poll_work(st
274 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
275 "tx hung, resetting the chip\n");
276 - spin_lock_bh(&sc->sc_pcu_lock);
277 - ath_reset(sc, true);
278 - spin_unlock_bh(&sc->sc_pcu_lock);
279 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
282 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
283 @@ -2303,6 +2306,9 @@ void ath_tx_edma_tasklet(struct ath_soft
287 + if (sc->sc_flags & SC_OP_HW_RESET)
290 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
291 if (status == -EINPROGRESS)