aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/xmit.c
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 /drivers/net/wireless/ath9k/xmit.c
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>
Diffstat (limited to 'drivers/net/wireless/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath9k/xmit.c98
1 files changed, 48 insertions, 50 deletions
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)