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 @@ -609,6 +610,7 @@ struct ath_softc {
13 struct work_struct paprd_work;
14 struct work_struct hw_check_work;
15 + struct work_struct hw_reset_work;
16 struct completion paprd_complete;
18 unsigned int hw_busy_count;
19 @@ -655,7 +657,6 @@ struct ath_softc {
22 void ath9k_tasklet(unsigned long data);
23 -int ath_reset(struct ath_softc *sc, bool retry_tx);
24 int ath_cabq_update(struct ath_softc *);
26 static inline void ath_read_cachesize(struct ath_common *common, int *csz)
27 --- a/drivers/net/wireless/ath/ath9k/init.c
28 +++ b/drivers/net/wireless/ath/ath9k/init.c
29 @@ -776,6 +776,7 @@ int ath9k_init_device(u16 devid, struct
33 + INIT_WORK(&sc->hw_reset_work, ath_reset_work);
34 INIT_WORK(&sc->hw_check_work, ath_hw_check);
35 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
36 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
37 --- a/drivers/net/wireless/ath/ath9k/main.c
38 +++ b/drivers/net/wireless/ath/ath9k/main.c
39 @@ -595,74 +595,6 @@ static void ath_node_detach(struct ath_s
40 ath_tx_node_cleanup(sc, an);
43 -void ath_hw_check(struct work_struct *work)
45 - struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
46 - struct ath_common *common = ath9k_hw_common(sc->sc_ah);
47 - unsigned long flags;
50 - ath9k_ps_wakeup(sc);
51 - if (ath9k_hw_check_alive(sc->sc_ah))
54 - spin_lock_irqsave(&common->cc_lock, flags);
55 - busy = ath_update_survey_stats(sc);
56 - spin_unlock_irqrestore(&common->cc_lock, flags);
58 - ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
59 - "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
61 - if (++sc->hw_busy_count >= 3) {
62 - spin_lock_bh(&sc->sc_pcu_lock);
63 - ath_reset(sc, true);
64 - spin_unlock_bh(&sc->sc_pcu_lock);
66 - } else if (busy >= 0)
67 - sc->hw_busy_count = 0;
70 - ath9k_ps_restore(sc);
73 -static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
76 - struct ath_common *common = ath9k_hw_common(sc->sc_ah);
78 - if (pll_sqsum >= 0x40000) {
81 - /* Rx is hung for more than 500ms. Reset it */
82 - ath_dbg(common, ATH_DBG_RESET,
83 - "Possible RX hang, resetting");
84 - spin_lock_bh(&sc->sc_pcu_lock);
85 - ath_reset(sc, true);
86 - spin_unlock_bh(&sc->sc_pcu_lock);
93 -void ath_hw_pll_work(struct work_struct *work)
95 - struct ath_softc *sc = container_of(work, struct ath_softc,
99 - if (AR_SREV_9485(sc->sc_ah)) {
101 - ath9k_ps_wakeup(sc);
102 - pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
103 - ath9k_ps_restore(sc);
105 - ath_hw_pll_rx_hang_check(sc, pll_sqsum);
107 - ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
112 void ath9k_tasklet(unsigned long data)
114 @@ -675,9 +607,7 @@ void ath9k_tasklet(unsigned long data)
116 if ((status & ATH9K_INT_FATAL) ||
117 (status & ATH9K_INT_BB_WATCHDOG)) {
118 - spin_lock(&sc->sc_pcu_lock);
119 - ath_reset(sc, true);
120 - spin_unlock(&sc->sc_pcu_lock);
121 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
125 @@ -968,7 +898,7 @@ void ath_radio_disable(struct ath_softc
126 ath9k_ps_restore(sc);
129 -int ath_reset(struct ath_softc *sc, bool retry_tx)
130 +static int ath_reset(struct ath_softc *sc, bool retry_tx)
132 struct ath_hw *ah = sc->sc_ah;
133 struct ath_common *common = ath9k_hw_common(ah);
134 @@ -1035,6 +965,84 @@ int ath_reset(struct ath_softc *sc, bool
138 +void ath_reset_work(struct work_struct *work)
140 + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
142 + spin_lock_bh(&sc->sc_pcu_lock);
143 + ath_reset(sc, true);
144 + spin_unlock_bh(&sc->sc_pcu_lock);
147 +void ath_hw_check(struct work_struct *work)
149 + struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
150 + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
151 + unsigned long flags;
154 + ath9k_ps_wakeup(sc);
155 + if (ath9k_hw_check_alive(sc->sc_ah))
158 + spin_lock_irqsave(&common->cc_lock, flags);
159 + busy = ath_update_survey_stats(sc);
160 + spin_unlock_irqrestore(&common->cc_lock, flags);
162 + ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
163 + "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
165 + if (++sc->hw_busy_count >= 3) {
166 + spin_lock_bh(&sc->sc_pcu_lock);
167 + ath_reset(sc, true);
168 + spin_unlock_bh(&sc->sc_pcu_lock);
171 + } else if (busy >= 0)
172 + sc->hw_busy_count = 0;
175 + ath9k_ps_restore(sc);
178 +static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
181 + struct ath_common *common = ath9k_hw_common(sc->sc_ah);
183 + if (pll_sqsum >= 0x40000) {
186 + /* Rx is hung for more than 500ms. Reset it */
187 + ath_dbg(common, ATH_DBG_RESET,
188 + "Possible RX hang, resetting");
189 + spin_lock_bh(&sc->sc_pcu_lock);
190 + ath_reset(sc, true);
191 + spin_unlock_bh(&sc->sc_pcu_lock);
198 +void ath_hw_pll_work(struct work_struct *work)
200 + struct ath_softc *sc = container_of(work, struct ath_softc,
204 + if (AR_SREV_9485(sc->sc_ah)) {
206 + ath9k_ps_wakeup(sc);
207 + pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
208 + ath9k_ps_restore(sc);
210 + ath_hw_pll_rx_hang_check(sc, pll_sqsum);
212 + ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
216 /**********************/
217 /* mac80211 callbacks */
218 /**********************/
219 --- a/drivers/net/wireless/ath/ath9k/xmit.c
220 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
221 @@ -601,7 +601,7 @@ static void ath_tx_complete_aggr(struct
225 - ath_reset(sc, false);
226 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
229 static bool ath_lookup_legacy(struct ath_buf *bf)
230 @@ -2268,9 +2268,7 @@ static void ath_tx_complete_poll_work(st
232 ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
233 "tx hung, resetting the chip\n");
234 - spin_lock_bh(&sc->sc_pcu_lock);
235 - ath_reset(sc, true);
236 - spin_unlock_bh(&sc->sc_pcu_lock);
237 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
240 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
241 --- a/drivers/net/wireless/ath/ath9k/beacon.c
242 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
243 @@ -386,9 +386,7 @@ void ath_beacon_tasklet(unsigned long da
244 ath_dbg(common, ATH_DBG_BSTUCK,
245 "beacon is officially stuck\n");
246 sc->sc_flags |= SC_OP_TSF_RESET;
247 - spin_lock(&sc->sc_pcu_lock);
248 - ath_reset(sc, true);
249 - spin_unlock(&sc->sc_pcu_lock);
250 + ieee80211_queue_work(sc->hw, &sc->hw_reset_work);