diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2010-10-26 18:27:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-15 13:24:46 -0500 |
commit | 4bdd1e978ede034c1211957eb17eaf50de00d234 (patch) | |
tree | 156a3d3bd8b4c89e3a36103d14d9afe9cfce7bd0 | |
parent | 9d94674ab754be0e275120a183670ead435f9c0d (diff) |
ath9k: move the PCU lock to the sc structure
The PCU lock should be used to contend TX DMA as well,
this will be done next.
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.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 4 |
4 files changed, 25 insertions, 25 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index cb9194a5b561..61d450750acb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -309,7 +309,6 @@ struct ath_rx { | |||
309 | u8 rxotherant; | 309 | u8 rxotherant; |
310 | u32 *rxlink; | 310 | u32 *rxlink; |
311 | unsigned int rxfilter; | 311 | unsigned int rxfilter; |
312 | spinlock_t pcu_lock; | ||
313 | spinlock_t rxbuflock; | 312 | spinlock_t rxbuflock; |
314 | struct list_head rxbuf; | 313 | struct list_head rxbuf; |
315 | struct ath_descdma rxdma; | 314 | struct ath_descdma rxdma; |
@@ -601,6 +600,7 @@ struct ath_softc { | |||
601 | int irq; | 600 | int irq; |
602 | spinlock_t sc_serial_rw; | 601 | spinlock_t sc_serial_rw; |
603 | spinlock_t sc_pm_lock; | 602 | spinlock_t sc_pm_lock; |
603 | spinlock_t sc_pcu_lock; | ||
604 | struct mutex mutex; | 604 | struct mutex mutex; |
605 | struct work_struct paprd_work; | 605 | struct work_struct paprd_work; |
606 | struct work_struct hw_check_work; | 606 | struct work_struct hw_check_work; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 341d587b686b..463ac1229f53 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -242,7 +242,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
242 | ath9k_hw_disable_interrupts(ah); | 242 | ath9k_hw_disable_interrupts(ah); |
243 | ath_drain_all_txq(sc, false); | 243 | ath_drain_all_txq(sc, false); |
244 | 244 | ||
245 | spin_lock_bh(&sc->rx.pcu_lock); | 245 | spin_lock_bh(&sc->sc_pcu_lock); |
246 | 246 | ||
247 | stopped = ath_stoprecv(sc); | 247 | stopped = ath_stoprecv(sc); |
248 | 248 | ||
@@ -268,7 +268,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
268 | "Unable to reset channel (%u MHz), " | 268 | "Unable to reset channel (%u MHz), " |
269 | "reset status %d\n", | 269 | "reset status %d\n", |
270 | channel->center_freq, r); | 270 | channel->center_freq, r); |
271 | spin_unlock_bh(&sc->rx.pcu_lock); | 271 | spin_unlock_bh(&sc->sc_pcu_lock); |
272 | goto ps_restore; | 272 | goto ps_restore; |
273 | } | 273 | } |
274 | 274 | ||
@@ -276,11 +276,11 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
276 | ath_print(common, ATH_DBG_FATAL, | 276 | ath_print(common, ATH_DBG_FATAL, |
277 | "Unable to restart recv logic\n"); | 277 | "Unable to restart recv logic\n"); |
278 | r = -EIO; | 278 | r = -EIO; |
279 | spin_unlock_bh(&sc->rx.pcu_lock); | 279 | spin_unlock_bh(&sc->sc_pcu_lock); |
280 | goto ps_restore; | 280 | goto ps_restore; |
281 | } | 281 | } |
282 | 282 | ||
283 | spin_unlock_bh(&sc->rx.pcu_lock); | 283 | spin_unlock_bh(&sc->sc_pcu_lock); |
284 | 284 | ||
285 | ath_update_txpow(sc); | 285 | ath_update_txpow(sc); |
286 | ath9k_hw_set_interrupts(ah, ah->imask); | 286 | ath9k_hw_set_interrupts(ah, ah->imask); |
@@ -615,7 +615,7 @@ void ath9k_tasklet(unsigned long data) | |||
615 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | 615 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); |
616 | 616 | ||
617 | if (status & rxmask) { | 617 | if (status & rxmask) { |
618 | spin_lock_bh(&sc->rx.pcu_lock); | 618 | spin_lock_bh(&sc->sc_pcu_lock); |
619 | 619 | ||
620 | /* Check for high priority Rx first */ | 620 | /* Check for high priority Rx first */ |
621 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 621 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && |
@@ -623,7 +623,7 @@ void ath9k_tasklet(unsigned long data) | |||
623 | ath_rx_tasklet(sc, 0, true); | 623 | ath_rx_tasklet(sc, 0, true); |
624 | 624 | ||
625 | ath_rx_tasklet(sc, 0, false); | 625 | ath_rx_tasklet(sc, 0, false); |
626 | spin_unlock_bh(&sc->rx.pcu_lock); | 626 | spin_unlock_bh(&sc->sc_pcu_lock); |
627 | } | 627 | } |
628 | 628 | ||
629 | if (status & ATH9K_INT_TX) { | 629 | if (status & ATH9K_INT_TX) { |
@@ -881,7 +881,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
881 | if (!ah->curchan) | 881 | if (!ah->curchan) |
882 | ah->curchan = ath_get_curchannel(sc, sc->hw); | 882 | ah->curchan = ath_get_curchannel(sc, sc->hw); |
883 | 883 | ||
884 | spin_lock_bh(&sc->rx.pcu_lock); | 884 | spin_lock_bh(&sc->sc_pcu_lock); |
885 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); | 885 | r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); |
886 | if (r) { | 886 | if (r) { |
887 | ath_print(common, ATH_DBG_FATAL, | 887 | ath_print(common, ATH_DBG_FATAL, |
@@ -894,10 +894,10 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
894 | if (ath_startrecv(sc) != 0) { | 894 | if (ath_startrecv(sc) != 0) { |
895 | ath_print(common, ATH_DBG_FATAL, | 895 | ath_print(common, ATH_DBG_FATAL, |
896 | "Unable to restart recv logic\n"); | 896 | "Unable to restart recv logic\n"); |
897 | spin_unlock_bh(&sc->rx.pcu_lock); | 897 | spin_unlock_bh(&sc->sc_pcu_lock); |
898 | return; | 898 | return; |
899 | } | 899 | } |
900 | spin_unlock_bh(&sc->rx.pcu_lock); | 900 | spin_unlock_bh(&sc->sc_pcu_lock); |
901 | 901 | ||
902 | if (sc->sc_flags & SC_OP_BEACONS) | 902 | if (sc->sc_flags & SC_OP_BEACONS) |
903 | ath_beacon_config(sc, NULL); /* restart beacons */ | 903 | ath_beacon_config(sc, NULL); /* restart beacons */ |
@@ -937,7 +937,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
937 | 937 | ||
938 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ | 938 | ath_drain_all_txq(sc, false); /* clear pending tx frames */ |
939 | 939 | ||
940 | spin_lock_bh(&sc->rx.pcu_lock); | 940 | spin_lock_bh(&sc->sc_pcu_lock); |
941 | 941 | ||
942 | ath_stoprecv(sc); /* turn off frame recv */ | 942 | ath_stoprecv(sc); /* turn off frame recv */ |
943 | ath_flushrecv(sc); /* flush recv queue */ | 943 | ath_flushrecv(sc); /* flush recv queue */ |
@@ -955,7 +955,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
955 | 955 | ||
956 | ath9k_hw_phy_disable(ah); | 956 | ath9k_hw_phy_disable(ah); |
957 | 957 | ||
958 | spin_unlock_bh(&sc->rx.pcu_lock); | 958 | spin_unlock_bh(&sc->sc_pcu_lock); |
959 | 959 | ||
960 | ath9k_hw_configpcipowersave(ah, 1, 1); | 960 | ath9k_hw_configpcipowersave(ah, 1, 1); |
961 | ath9k_ps_restore(sc); | 961 | ath9k_ps_restore(sc); |
@@ -977,7 +977,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
977 | ath9k_hw_disable_interrupts(ah); | 977 | ath9k_hw_disable_interrupts(ah); |
978 | ath_drain_all_txq(sc, retry_tx); | 978 | ath_drain_all_txq(sc, retry_tx); |
979 | 979 | ||
980 | spin_lock_bh(&sc->rx.pcu_lock); | 980 | spin_lock_bh(&sc->sc_pcu_lock); |
981 | 981 | ||
982 | ath_stoprecv(sc); | 982 | ath_stoprecv(sc); |
983 | ath_flushrecv(sc); | 983 | ath_flushrecv(sc); |
@@ -991,7 +991,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
991 | ath_print(common, ATH_DBG_FATAL, | 991 | ath_print(common, ATH_DBG_FATAL, |
992 | "Unable to start recv logic\n"); | 992 | "Unable to start recv logic\n"); |
993 | 993 | ||
994 | spin_unlock_bh(&sc->rx.pcu_lock); | 994 | spin_unlock_bh(&sc->sc_pcu_lock); |
995 | 995 | ||
996 | /* | 996 | /* |
997 | * We may be doing a reset in response to a request | 997 | * We may be doing a reset in response to a request |
@@ -1155,14 +1155,14 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1155 | * be followed by initialization of the appropriate bits | 1155 | * be followed by initialization of the appropriate bits |
1156 | * and then setup of the interrupt mask. | 1156 | * and then setup of the interrupt mask. |
1157 | */ | 1157 | */ |
1158 | spin_lock_bh(&sc->rx.pcu_lock); | 1158 | spin_lock_bh(&sc->sc_pcu_lock); |
1159 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); | 1159 | r = ath9k_hw_reset(ah, init_channel, ah->caldata, false); |
1160 | if (r) { | 1160 | if (r) { |
1161 | ath_print(common, ATH_DBG_FATAL, | 1161 | ath_print(common, ATH_DBG_FATAL, |
1162 | "Unable to reset hardware; reset status %d " | 1162 | "Unable to reset hardware; reset status %d " |
1163 | "(freq %u MHz)\n", r, | 1163 | "(freq %u MHz)\n", r, |
1164 | curchan->center_freq); | 1164 | curchan->center_freq); |
1165 | spin_unlock_bh(&sc->rx.pcu_lock); | 1165 | spin_unlock_bh(&sc->sc_pcu_lock); |
1166 | goto mutex_unlock; | 1166 | goto mutex_unlock; |
1167 | } | 1167 | } |
1168 | 1168 | ||
@@ -1183,10 +1183,10 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1183 | ath_print(common, ATH_DBG_FATAL, | 1183 | ath_print(common, ATH_DBG_FATAL, |
1184 | "Unable to start recv logic\n"); | 1184 | "Unable to start recv logic\n"); |
1185 | r = -EIO; | 1185 | r = -EIO; |
1186 | spin_unlock_bh(&sc->rx.pcu_lock); | 1186 | spin_unlock_bh(&sc->sc_pcu_lock); |
1187 | goto mutex_unlock; | 1187 | goto mutex_unlock; |
1188 | } | 1188 | } |
1189 | spin_unlock_bh(&sc->rx.pcu_lock); | 1189 | spin_unlock_bh(&sc->sc_pcu_lock); |
1190 | 1190 | ||
1191 | /* Setup our intr mask. */ | 1191 | /* Setup our intr mask. */ |
1192 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | | 1192 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
@@ -1387,14 +1387,14 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1387 | 1387 | ||
1388 | if (!(sc->sc_flags & SC_OP_INVALID)) { | 1388 | if (!(sc->sc_flags & SC_OP_INVALID)) { |
1389 | ath_drain_all_txq(sc, false); | 1389 | ath_drain_all_txq(sc, false); |
1390 | spin_lock_bh(&sc->rx.pcu_lock); | 1390 | spin_lock_bh(&sc->sc_pcu_lock); |
1391 | ath_stoprecv(sc); | 1391 | ath_stoprecv(sc); |
1392 | ath9k_hw_phy_disable(ah); | 1392 | ath9k_hw_phy_disable(ah); |
1393 | spin_unlock_bh(&sc->rx.pcu_lock); | 1393 | spin_unlock_bh(&sc->sc_pcu_lock); |
1394 | } else { | 1394 | } else { |
1395 | spin_lock_bh(&sc->rx.pcu_lock); | 1395 | spin_lock_bh(&sc->sc_pcu_lock); |
1396 | sc->rx.rxlink = NULL; | 1396 | sc->rx.rxlink = NULL; |
1397 | spin_unlock_bh(&sc->rx.pcu_lock); | 1397 | spin_unlock_bh(&sc->sc_pcu_lock); |
1398 | } | 1398 | } |
1399 | 1399 | ||
1400 | /* disable HAL and put h/w to sleep */ | 1400 | /* disable HAL and put h/w to sleep */ |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 87fabf84e6fb..60300b225b6d 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -317,7 +317,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) | |||
317 | struct ath_buf *bf; | 317 | struct ath_buf *bf; |
318 | int error = 0; | 318 | int error = 0; |
319 | 319 | ||
320 | spin_lock_init(&sc->rx.pcu_lock); | 320 | spin_lock_init(&sc->sc_pcu_lock); |
321 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 321 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
322 | spin_lock_init(&sc->rx.rxbuflock); | 322 | spin_lock_init(&sc->rx.rxbuflock); |
323 | 323 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index e662ecade398..d97b7a336b5b 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->rx.pcu_lock); | 1151 | spin_lock_bh(&sc->sc_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->rx.pcu_lock); | 1157 | spin_unlock_bh(&sc->sc_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++) { |