aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2009-01-16 11:08:47 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:00:40 -0500
commit043a040503b0d0c21bf3fba971813eba3322267d (patch)
tree4aae2852af5581da07c3de609b7ac0308499ceb8
parent55f5e4a9800ae6e6e052380a8b3c9c4996d5cd05 (diff)
ath9k: Merge queue draining functions
The TX queue draining routines have confusing names, rename them approprately and merge ath_drain_txdataq() with ath_drain_all_txq(). Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath9k/core.h4
-rw-r--r--drivers/net/wireless/ath9k/main.c8
-rw-r--r--drivers/net/wireless/ath9k/xmit.c98
4 files changed, 55 insertions, 57 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index be1d84a5dafb..61d37be9717e 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -220,7 +220,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
220 * acquires txq lock inside. 220 * acquires txq lock inside.
221 */ 221 */
222 if (sc->sc_nvaps > 1) { 222 if (sc->sc_nvaps > 1) {
223 ath_tx_draintxq(sc, cabq, false); 223 ath_draintxq(sc, cabq, false);
224 DPRINTF(sc, ATH_DBG_BEACON, 224 DPRINTF(sc, ATH_DBG_BEACON,
225 "flush previous cabq traffic\n"); 225 "flush previous cabq traffic\n");
226 } 226 }
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 4eb21a7f0d80..04bc6fd611d8 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -485,8 +485,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush);
485struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); 485struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
486void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); 486void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
487int ath_tx_setup(struct ath_softc *sc, int haltype); 487int ath_tx_setup(struct ath_softc *sc, int haltype);
488void ath_draintxq(struct ath_softc *sc, bool retry_tx); 488void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
489void ath_tx_draintxq(struct ath_softc *sc, 489void ath_draintxq(struct ath_softc *sc,
490 struct ath_txq *txq, bool retry_tx); 490 struct ath_txq *txq, bool retry_tx);
491void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); 491void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
492void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an); 492void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 7f4d1bbaf6c8..8ad927a8870c 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -247,7 +247,7 @@ static int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
247 * the relevant bits of the h/w. 247 * the relevant bits of the h/w.
248 */ 248 */
249 ath9k_hw_set_interrupts(ah, 0); 249 ath9k_hw_set_interrupts(ah, 0);
250 ath_draintxq(sc, false); 250 ath_drain_all_txq(sc, false);
251 stopped = ath_stoprecv(sc); 251 stopped = ath_stoprecv(sc);
252 252
253 /* XXX: do not flush receive queue here. We don't want 253 /* XXX: do not flush receive queue here. We don't want
@@ -1092,7 +1092,7 @@ static void ath_radio_disable(struct ath_softc *sc)
1092 /* Disable interrupts */ 1092 /* Disable interrupts */
1093 ath9k_hw_set_interrupts(ah, 0); 1093 ath9k_hw_set_interrupts(ah, 0);
1094 1094
1095 ath_draintxq(sc, false); /* clear pending tx frames */ 1095 ath_drain_all_txq(sc, false); /* clear pending tx frames */
1096 ath_stoprecv(sc); /* turn off frame recv */ 1096 ath_stoprecv(sc); /* turn off frame recv */
1097 ath_flushrecv(sc); /* flush recv queue */ 1097 ath_flushrecv(sc); /* flush recv queue */
1098 1098
@@ -1592,7 +1592,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1592 int r; 1592 int r;
1593 1593
1594 ath9k_hw_set_interrupts(ah, 0); 1594 ath9k_hw_set_interrupts(ah, 0);
1595 ath_draintxq(sc, retry_tx); 1595 ath_drain_all_txq(sc, retry_tx);
1596 ath_stoprecv(sc); 1596 ath_stoprecv(sc);
1597 ath_flushrecv(sc); 1597 ath_flushrecv(sc);
1598 1598
@@ -1988,7 +1988,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
1988 ath9k_hw_set_interrupts(sc->sc_ah, 0); 1988 ath9k_hw_set_interrupts(sc->sc_ah, 0);
1989 1989
1990 if (!(sc->sc_flags & SC_OP_INVALID)) { 1990 if (!(sc->sc_flags & SC_OP_INVALID)) {
1991 ath_draintxq(sc, false); 1991 ath_drain_all_txq(sc, false);
1992 ath_stoprecv(sc); 1992 ath_stoprecv(sc);
1993 ath9k_hw_phy_disable(sc->sc_ah); 1993 ath9k_hw_phy_disable(sc->sc_ah);
1994 } else 1994 } else
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index c9ead1ba88da..a29b998fac63 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -890,43 +890,6 @@ static void ath_get_beaconconfig(struct ath_softc *sc, int if_id,
890 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval; 890 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
891} 891}
892 892
893static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
894{
895 struct ath_hal *ah = sc->sc_ah;
896 struct ath_txq *txq;
897 int i, npend = 0;
898
899 if (sc->sc_flags & SC_OP_INVALID)
900 return;
901
902 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
903 if (ATH_TXQ_SETUP(sc, i)) {
904 txq = &sc->tx.txq[i];
905 ath9k_hw_stoptxdma(ah, txq->axq_qnum);
906 npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
907 }
908 }
909
910 if (npend) {
911 int r;
912
913 DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
914
915 spin_lock_bh(&sc->sc_resetlock);
916 r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true);
917 if (r)
918 DPRINTF(sc, ATH_DBG_FATAL,
919 "Unable to reset hardware; reset status %u\n",
920 r);
921 spin_unlock_bh(&sc->sc_resetlock);
922 }
923
924 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
925 if (ATH_TXQ_SETUP(sc, i))
926 ath_tx_draintxq(sc, &sc->tx.txq[i], retry_tx);
927 }
928}
929
930static void ath_txq_drain_pending_buffers(struct ath_softc *sc, 893static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
931 struct ath_txq *txq) 894 struct ath_txq *txq)
932{ 895{
@@ -1120,17 +1083,19 @@ int ath_cabq_update(struct ath_softc *sc)
1120 return 0; 1083 return 0;
1121} 1084}
1122 1085
1123void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) 1086/*
1087 * Drain a given TX queue (could be Beacon or Data)
1088 *
1089 * This assumes output has been stopped and
1090 * we do not need to block ath_tx_tasklet.
1091 */
1092void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1124{ 1093{
1125 struct ath_buf *bf, *lastbf; 1094 struct ath_buf *bf, *lastbf;
1126 struct list_head bf_head; 1095 struct list_head bf_head;
1127 1096
1128 INIT_LIST_HEAD(&bf_head); 1097 INIT_LIST_HEAD(&bf_head);
1129 1098
1130 /*
1131 * NB: this assumes output has been stopped and
1132 * we do not need to block ath_tx_tasklet
1133 */
1134 for (;;) { 1099 for (;;) {
1135 spin_lock_bh(&txq->axq_lock); 1100 spin_lock_bh(&txq->axq_lock);
1136 1101
@@ -1180,18 +1145,51 @@ void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1180 } 1145 }
1181} 1146}
1182 1147
1183void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) 1148void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
1184{ 1149{
1185 ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum); 1150 struct ath_hal *ah = sc->sc_ah;
1186 sc->tx.txqsetup &= ~(1<<txq->axq_qnum); 1151 struct ath_txq *txq;
1152 int i, npend = 0;
1153
1154 if (sc->sc_flags & SC_OP_INVALID)
1155 return;
1156
1157 /* Stop beacon queue */
1158 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
1159
1160 /* Stop data queues */
1161 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1162 if (ATH_TXQ_SETUP(sc, i)) {
1163 txq = &sc->tx.txq[i];
1164 ath9k_hw_stoptxdma(ah, txq->axq_qnum);
1165 npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
1166 }
1167 }
1168
1169 if (npend) {
1170 int r;
1171
1172 DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
1173
1174 spin_lock_bh(&sc->sc_resetlock);
1175 r = ath9k_hw_reset(ah, sc->sc_ah->ah_curchan, true);
1176 if (r)
1177 DPRINTF(sc, ATH_DBG_FATAL,
1178 "Unable to reset hardware; reset status %u\n",
1179 r);
1180 spin_unlock_bh(&sc->sc_resetlock);
1181 }
1182
1183 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1184 if (ATH_TXQ_SETUP(sc, i))
1185 ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
1186 }
1187} 1187}
1188 1188
1189void ath_draintxq(struct ath_softc *sc, bool retry_tx) 1189void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
1190{ 1190{
1191 if (!(sc->sc_flags & SC_OP_INVALID)) 1191 ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
1192 (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1192 sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
1193
1194 ath_drain_txdataq(sc, retry_tx);
1195} 1193}
1196 1194
1197void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) 1195void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)