aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-10-26 18:27:23 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:24:44 -0500
commit9d94674ab754be0e275120a183670ead435f9c0d (patch)
treefea71c005c3af1e76c47405afeda262f49df9463
parent5d4c428254f73bae272be9d296724b1ee09d76ec (diff)
ath9k: simplify hw reset locking
The new PCU lock is better placed so we can just contend against that when trying to reset hardware. This is part of a series of patches which fix stopping TX DMA completley when requested on the driver. For more details about this issue refer to this thread: http://marc.info/?l=linux-wireless&m=128629803703756&w=2 Tested-by: Ben Greear <greearb@candelatech.com> Cc: Kyungwan Nam <kyungwan.nam@atheros.com> Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
4 files changed, 8 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 81fed83add7a..cb9194a5b561 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -599,7 +599,6 @@ struct ath_softc {
599 struct ath_hw *sc_ah; 599 struct ath_hw *sc_ah;
600 void __iomem *mem; 600 void __iomem *mem;
601 int irq; 601 int irq;
602 spinlock_t sc_resetlock;
603 spinlock_t sc_serial_rw; 602 spinlock_t sc_serial_rw;
604 spinlock_t sc_pm_lock; 603 spinlock_t sc_pm_lock;
605 struct mutex mutex; 604 struct mutex mutex;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 1b72720b36e2..adff0da01f4c 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -580,7 +580,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
580 spin_lock_init(&common->cc_lock); 580 spin_lock_init(&common->cc_lock);
581 581
582 spin_lock_init(&sc->wiphy_lock); 582 spin_lock_init(&sc->wiphy_lock);
583 spin_lock_init(&sc->sc_resetlock);
584 spin_lock_init(&sc->sc_serial_rw); 583 spin_lock_init(&sc->sc_serial_rw);
585 spin_lock_init(&sc->sc_pm_lock); 584 spin_lock_init(&sc->sc_pm_lock);
586 mutex_init(&sc->mutex); 585 mutex_init(&sc->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 92ed5bb71196..341d587b686b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -262,19 +262,15 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
262 channel->center_freq, conf_is_ht40(conf), 262 channel->center_freq, conf_is_ht40(conf),
263 fastcc); 263 fastcc);
264 264
265 spin_lock_bh(&sc->sc_resetlock);
266
267 r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 265 r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
268 if (r) { 266 if (r) {
269 ath_print(common, ATH_DBG_FATAL, 267 ath_print(common, ATH_DBG_FATAL,
270 "Unable to reset channel (%u MHz), " 268 "Unable to reset channel (%u MHz), "
271 "reset status %d\n", 269 "reset status %d\n",
272 channel->center_freq, r); 270 channel->center_freq, r);
273 spin_unlock_bh(&sc->sc_resetlock);
274 spin_unlock_bh(&sc->rx.pcu_lock); 271 spin_unlock_bh(&sc->rx.pcu_lock);
275 goto ps_restore; 272 goto ps_restore;
276 } 273 }
277 spin_unlock_bh(&sc->sc_resetlock);
278 274
279 if (ath_startrecv(sc) != 0) { 275 if (ath_startrecv(sc) != 0) {
280 ath_print(common, ATH_DBG_FATAL, 276 ath_print(common, ATH_DBG_FATAL,
@@ -886,7 +882,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
886 ah->curchan = ath_get_curchannel(sc, sc->hw); 882 ah->curchan = ath_get_curchannel(sc, sc->hw);
887 883
888 spin_lock_bh(&sc->rx.pcu_lock); 884 spin_lock_bh(&sc->rx.pcu_lock);
889 spin_lock_bh(&sc->sc_resetlock);
890 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 885 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
891 if (r) { 886 if (r) {
892 ath_print(common, ATH_DBG_FATAL, 887 ath_print(common, ATH_DBG_FATAL,
@@ -894,7 +889,6 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
894 "reset status %d\n", 889 "reset status %d\n",
895 channel->center_freq, r); 890 channel->center_freq, r);
896 } 891 }
897 spin_unlock_bh(&sc->sc_resetlock);
898 892
899 ath_update_txpow(sc); 893 ath_update_txpow(sc);
900 if (ath_startrecv(sc) != 0) { 894 if (ath_startrecv(sc) != 0) {
@@ -951,7 +945,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
951 if (!ah->curchan) 945 if (!ah->curchan)
952 ah->curchan = ath_get_curchannel(sc, hw); 946 ah->curchan = ath_get_curchannel(sc, hw);
953 947
954 spin_lock_bh(&sc->sc_resetlock);
955 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); 948 r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
956 if (r) { 949 if (r) {
957 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, 950 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
@@ -959,7 +952,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
959 "reset status %d\n", 952 "reset status %d\n",
960 channel->center_freq, r); 953 channel->center_freq, r);
961 } 954 }
962 spin_unlock_bh(&sc->sc_resetlock);
963 955
964 ath9k_hw_phy_disable(ah); 956 ath9k_hw_phy_disable(ah);
965 957
@@ -990,12 +982,10 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
990 ath_stoprecv(sc); 982 ath_stoprecv(sc);
991 ath_flushrecv(sc); 983 ath_flushrecv(sc);
992 984
993 spin_lock_bh(&sc->sc_resetlock);
994 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 985 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
995 if (r) 986 if (r)
996 ath_print(common, ATH_DBG_FATAL, 987 ath_print(common, ATH_DBG_FATAL,
997 "Unable to reset hardware; reset status %d\n", r); 988 "Unable to reset hardware; reset status %d\n", r);
998 spin_unlock_bh(&sc->sc_resetlock);
999 989
1000 if (ath_startrecv(sc) != 0) 990 if (ath_startrecv(sc) != 0)
1001 ath_print(common, ATH_DBG_FATAL, 991 ath_print(common, ATH_DBG_FATAL,
@@ -1166,18 +1156,15 @@ static int ath9k_start(struct ieee80211_hw *hw)
1166 * and then setup of the interrupt mask. 1156 * and then setup of the interrupt mask.
1167 */ 1157 */
1168 spin_lock_bh(&sc->rx.pcu_lock); 1158 spin_lock_bh(&sc->rx.pcu_lock);
1169 spin_lock_bh(&sc->sc_resetlock);
1170 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); 1159 r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
1171 if (r) { 1160 if (r) {
1172 ath_print(common, ATH_DBG_FATAL, 1161 ath_print(common, ATH_DBG_FATAL,
1173 "Unable to reset hardware; reset status %d " 1162 "Unable to reset hardware; reset status %d "
1174 "(freq %u MHz)\n", r, 1163 "(freq %u MHz)\n", r,
1175 curchan->center_freq); 1164 curchan->center_freq);
1176 spin_unlock_bh(&sc->sc_resetlock);
1177 spin_unlock_bh(&sc->rx.pcu_lock); 1165 spin_unlock_bh(&sc->rx.pcu_lock);
1178 goto mutex_unlock; 1166 goto mutex_unlock;
1179 } 1167 }
1180 spin_unlock_bh(&sc->sc_resetlock);
1181 1168
1182 /* 1169 /*
1183 * This is needed only to setup initial state 1170 * This is needed only to setup initial state
@@ -1398,14 +1385,17 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1398 * before setting the invalid flag. */ 1385 * before setting the invalid flag. */
1399 ath9k_hw_disable_interrupts(ah); 1386 ath9k_hw_disable_interrupts(ah);
1400 1387
1401 spin_lock_bh(&sc->rx.pcu_lock);
1402 if (!(sc->sc_flags & SC_OP_INVALID)) { 1388 if (!(sc->sc_flags & SC_OP_INVALID)) {
1403 ath_drain_all_txq(sc, false); 1389 ath_drain_all_txq(sc, false);
1390 spin_lock_bh(&sc->rx.pcu_lock);
1404 ath_stoprecv(sc); 1391 ath_stoprecv(sc);
1405 ath9k_hw_phy_disable(ah); 1392 ath9k_hw_phy_disable(ah);
1406 } else 1393 spin_unlock_bh(&sc->rx.pcu_lock);
1394 } else {
1395 spin_lock_bh(&sc->rx.pcu_lock);
1407 sc->rx.rxlink = NULL; 1396 sc->rx.rxlink = NULL;
1408 spin_unlock_bh(&sc->rx.pcu_lock); 1397 spin_unlock_bh(&sc->rx.pcu_lock);
1398 }
1409 1399
1410 /* disable HAL and put h/w to sleep */ 1400 /* disable HAL and put h/w to sleep */
1411 ath9k_hw_disable(ah); 1401 ath9k_hw_disable(ah);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index f2ade2402ce2..e662ecade398 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1148,13 +1148,13 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1148 ath_print(common, ATH_DBG_FATAL, 1148 ath_print(common, ATH_DBG_FATAL,
1149 "Failed to stop TX DMA. Resetting hardware!\n"); 1149 "Failed to stop TX DMA. Resetting hardware!\n");
1150 1150
1151 spin_lock_bh(&sc->sc_resetlock); 1151 spin_lock_bh(&sc->rx.pcu_lock);
1152 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 1152 r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
1153 if (r) 1153 if (r)
1154 ath_print(common, ATH_DBG_FATAL, 1154 ath_print(common, ATH_DBG_FATAL,
1155 "Unable to reset hardware; reset status %d\n", 1155 "Unable to reset hardware; reset status %d\n",
1156 r); 1156 r);
1157 spin_unlock_bh(&sc->sc_resetlock); 1157 spin_unlock_bh(&sc->rx.pcu_lock);
1158 } 1158 }
1159 1159
1160 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { 1160 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {