OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 * Copyright (c) 2008-2009 Atheros Communications Inc. |
3 * | 3 * |
4 * Permission to use, copy, modify, and/or distribute this software for any | 4 * Permission to use, copy, modify, and/or distribute this software for any |
5 * purpose with or without fee is hereby granted, provided that the above | 5 * purpose with or without fee is hereby granted, provided that the above |
6 * copyright notice and this permission notice appear in all copies. | 6 * copyright notice and this permission notice appear in all copies. |
7 * | 7 * |
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 117 |
118 if (ac->sched) | 118 if (ac->sched) |
119 return; | 119 return; |
120 | 120 |
121 ac->sched = true; | 121 ac->sched = true; |
122 list_add_tail(&ac->list, &txq->axq_acq); | 122 list_add_tail(&ac->list, &txq->axq_acq); |
123 } | 123 } |
124 | 124 |
125 static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 125 static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
126 { | 126 { |
127 » struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 127 » struct ath_txq *txq = tid->ac->txq; |
128 | 128 |
129 WARN_ON(!tid->paused); | 129 WARN_ON(!tid->paused); |
130 | 130 |
131 spin_lock_bh(&txq->axq_lock); | 131 spin_lock_bh(&txq->axq_lock); |
132 tid->paused = false; | 132 tid->paused = false; |
133 | 133 |
134 if (list_empty(&tid->buf_q)) | 134 if (list_empty(&tid->buf_q)) |
135 goto unlock; | 135 goto unlock; |
136 | 136 |
137 ath_tx_queue_tid(txq, tid); | 137 ath_tx_queue_tid(txq, tid); |
138 ath_txq_schedule(sc, txq); | 138 ath_txq_schedule(sc, txq); |
139 unlock: | 139 unlock: |
140 spin_unlock_bh(&txq->axq_lock); | 140 spin_unlock_bh(&txq->axq_lock); |
141 } | 141 } |
142 | 142 |
143 static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) | 143 static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) |
144 { | 144 { |
145 » struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; | 145 » struct ath_txq *txq = tid->ac->txq; |
146 struct ath_buf *bf; | 146 struct ath_buf *bf; |
147 struct list_head bf_head; | 147 struct list_head bf_head; |
148 struct ath_tx_status ts; | 148 struct ath_tx_status ts; |
149 | 149 |
150 INIT_LIST_HEAD(&bf_head); | 150 INIT_LIST_HEAD(&bf_head); |
151 | 151 |
152 memset(&ts, 0, sizeof(ts)); | 152 memset(&ts, 0, sizeof(ts)); |
153 spin_lock_bh(&txq->axq_lock); | 153 spin_lock_bh(&txq->axq_lock); |
154 | 154 |
155 while (!list_empty(&tid->buf_q)) { | 155 while (!list_empty(&tid->buf_q)) { |
(...skipping 12 matching lines...) Expand all Loading... |
168 } | 168 } |
169 | 169 |
170 static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 170 static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
171 int seqno) | 171 int seqno) |
172 { | 172 { |
173 int index, cindex; | 173 int index, cindex; |
174 | 174 |
175 index = ATH_BA_INDEX(tid->seq_start, seqno); | 175 index = ATH_BA_INDEX(tid->seq_start, seqno); |
176 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | 176 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); |
177 | 177 |
178 » __clear_bit(cindex, tid->tx_buf); | 178 » tid->tx_buf[cindex] = NULL; |
179 | 179 |
180 » while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->t
x_buf)) { | 180 » while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) { |
181 INCR(tid->seq_start, IEEE80211_SEQ_MAX); | 181 INCR(tid->seq_start, IEEE80211_SEQ_MAX); |
182 INCR(tid->baw_head, ATH_TID_MAX_BUFS); | 182 INCR(tid->baw_head, ATH_TID_MAX_BUFS); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, | 186 static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, |
187 struct ath_buf *bf) | 187 struct ath_buf *bf) |
188 { | 188 { |
189 int index, cindex; | 189 int index, cindex; |
190 | 190 |
191 if (bf_isretried(bf)) | 191 if (bf_isretried(bf)) |
192 return; | 192 return; |
193 | 193 |
194 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); | 194 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); |
195 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); | 195 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); |
196 » __set_bit(cindex, tid->tx_buf); | 196 |
| 197 » BUG_ON(tid->tx_buf[cindex] != NULL); |
| 198 » tid->tx_buf[cindex] = bf; |
197 | 199 |
198 if (index >= ((tid->baw_tail - tid->baw_head) & | 200 if (index >= ((tid->baw_tail - tid->baw_head) & |
199 (ATH_TID_MAX_BUFS - 1))) { | 201 (ATH_TID_MAX_BUFS - 1))) { |
200 tid->baw_tail = cindex; | 202 tid->baw_tail = cindex; |
201 INCR(tid->baw_tail, ATH_TID_MAX_BUFS); | 203 INCR(tid->baw_tail, ATH_TID_MAX_BUFS); |
202 } | 204 } |
203 } | 205 } |
204 | 206 |
205 /* | 207 /* |
206 * TODO: For frame(s) that are in the retry state, we will reuse the | 208 * TODO: For frame(s) that are in the retry state, we will reuse the |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
310 struct ieee80211_hdr *hdr; | 312 struct ieee80211_hdr *hdr; |
311 struct ieee80211_tx_info *tx_info; | 313 struct ieee80211_tx_info *tx_info; |
312 struct ath_atx_tid *tid = NULL; | 314 struct ath_atx_tid *tid = NULL; |
313 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 315 struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
314 struct list_head bf_head, bf_pending; | 316 struct list_head bf_head, bf_pending; |
315 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; | 317 u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; |
316 u32 ba[WME_BA_BMP_SIZE >> 5]; | 318 u32 ba[WME_BA_BMP_SIZE >> 5]; |
317 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; | 319 int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; |
318 bool rc_update = true; | 320 bool rc_update = true; |
319 struct ieee80211_tx_rate rates[4]; | 321 struct ieee80211_tx_rate rates[4]; |
| 322 int nframes; |
320 | 323 |
321 skb = bf->bf_mpdu; | 324 skb = bf->bf_mpdu; |
322 hdr = (struct ieee80211_hdr *)skb->data; | 325 hdr = (struct ieee80211_hdr *)skb->data; |
323 | 326 |
324 tx_info = IEEE80211_SKB_CB(skb); | 327 tx_info = IEEE80211_SKB_CB(skb); |
325 hw = bf->aphy->hw; | 328 hw = bf->aphy->hw; |
326 | 329 |
327 memcpy(rates, tx_info->control.rates, sizeof(rates)); | 330 memcpy(rates, tx_info->control.rates, sizeof(rates)); |
| 331 nframes = bf->bf_nframes; |
328 | 332 |
329 rcu_read_lock(); | 333 rcu_read_lock(); |
330 | 334 |
331 /* XXX: use ieee80211_find_sta! */ | 335 /* XXX: use ieee80211_find_sta! */ |
332 sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); | 336 sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); |
333 if (!sta) { | 337 if (!sta) { |
334 rcu_read_unlock(); | 338 rcu_read_unlock(); |
335 | 339 |
336 INIT_LIST_HEAD(&bf_head); | 340 INIT_LIST_HEAD(&bf_head); |
337 while (bf) { | 341 while (bf) { |
338 bf_next = bf->bf_next; | 342 bf_next = bf->bf_next; |
339 | 343 |
340 bf->bf_state.bf_type |= BUF_XRETRY; | 344 bf->bf_state.bf_type |= BUF_XRETRY; |
341 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || | 345 if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || |
342 !bf->bf_stale || bf_next != NULL) | 346 !bf->bf_stale || bf_next != NULL) |
343 list_move_tail(&bf->list, &bf_head); | 347 list_move_tail(&bf->list, &bf_head); |
344 | 348 |
345 » » » ath_tx_rc_status(bf, ts, 0, 0, false); | 349 » » » ath_tx_rc_status(bf, ts, 1, 0, false); |
346 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 350 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
347 0, 0); | 351 0, 0); |
348 | 352 |
349 bf = bf_next; | 353 bf = bf_next; |
350 } | 354 } |
351 return; | 355 return; |
352 } | 356 } |
353 | 357 |
354 an = (struct ath_node *)sta->drv_priv; | 358 an = (struct ath_node *)sta->drv_priv; |
355 tid = ATH_AN_2_TID(an, bf->bf_tidno); | 359 tid = ATH_AN_2_TID(an, bf->bf_tidno); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 /* | 444 /* |
441 * complete the acked-ones/xretried ones; update | 445 * complete the acked-ones/xretried ones; update |
442 * block-ack window | 446 * block-ack window |
443 */ | 447 */ |
444 spin_lock_bh(&txq->axq_lock); | 448 spin_lock_bh(&txq->axq_lock); |
445 ath_tx_update_baw(sc, tid, bf->bf_seqno); | 449 ath_tx_update_baw(sc, tid, bf->bf_seqno); |
446 spin_unlock_bh(&txq->axq_lock); | 450 spin_unlock_bh(&txq->axq_lock); |
447 | 451 |
448 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 452 if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
449 memcpy(tx_info->control.rates, rates, sizeof(rat
es)); | 453 memcpy(tx_info->control.rates, rates, sizeof(rat
es)); |
| 454 bf->bf_nframes = nframes; |
450 ath_tx_rc_status(bf, ts, nbad, txok, true); | 455 ath_tx_rc_status(bf, ts, nbad, txok, true); |
451 rc_update = false; | 456 rc_update = false; |
452 } else { | 457 } else { |
453 ath_tx_rc_status(bf, ts, nbad, txok, false); | 458 ath_tx_rc_status(bf, ts, nbad, txok, false); |
454 } | 459 } |
455 | 460 |
456 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 461 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
457 !txfail, sendbar); | 462 !txfail, sendbar); |
458 } else { | 463 } else { |
459 /* retry the un-acked ones */ | 464 /* retry the un-acked ones */ |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 txtid->paused = true; | 808 txtid->paused = true; |
804 *ssn = txtid->seq_start; | 809 *ssn = txtid->seq_start; |
805 | 810 |
806 return 0; | 811 return 0; |
807 } | 812 } |
808 | 813 |
809 void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 814 void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) |
810 { | 815 { |
811 struct ath_node *an = (struct ath_node *)sta->drv_priv; | 816 struct ath_node *an = (struct ath_node *)sta->drv_priv; |
812 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 817 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
813 » struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; | 818 » struct ath_txq *txq = txtid->ac->txq; |
814 | 819 |
815 if (txtid->state & AGGR_CLEANUP) | 820 if (txtid->state & AGGR_CLEANUP) |
816 return; | 821 return; |
817 | 822 |
818 if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 823 if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
819 txtid->state &= ~AGGR_ADDBA_PROGRESS; | 824 txtid->state &= ~AGGR_ADDBA_PROGRESS; |
820 return; | 825 return; |
821 } | 826 } |
822 | 827 |
823 spin_lock_bh(&txq->axq_lock); | 828 spin_lock_bh(&txq->axq_lock); |
(...skipping 24 matching lines...) Expand all Loading... |
848 if (sc->sc_flags & SC_OP_TXAGGR) { | 853 if (sc->sc_flags & SC_OP_TXAGGR) { |
849 txtid = ATH_AN_2_TID(an, tid); | 854 txtid = ATH_AN_2_TID(an, tid); |
850 txtid->baw_size = | 855 txtid->baw_size = |
851 IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | 856 IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; |
852 txtid->state |= AGGR_ADDBA_COMPLETE; | 857 txtid->state |= AGGR_ADDBA_COMPLETE; |
853 txtid->state &= ~AGGR_ADDBA_PROGRESS; | 858 txtid->state &= ~AGGR_ADDBA_PROGRESS; |
854 ath_tx_resume_tid(sc, txtid); | 859 ath_tx_resume_tid(sc, txtid); |
855 } | 860 } |
856 } | 861 } |
857 | 862 |
| 863 bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) |
| 864 { |
| 865 struct ath_atx_tid *txtid; |
| 866 |
| 867 if (!(sc->sc_flags & SC_OP_TXAGGR)) |
| 868 return false; |
| 869 |
| 870 txtid = ATH_AN_2_TID(an, tidno); |
| 871 |
| 872 if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) |
| 873 return true; |
| 874 return false; |
| 875 } |
| 876 |
858 /********************/ | 877 /********************/ |
859 /* Queue Management */ | 878 /* Queue Management */ |
860 /********************/ | 879 /********************/ |
861 | 880 |
862 static void ath_txq_drain_pending_buffers(struct ath_softc *sc, | 881 static void ath_txq_drain_pending_buffers(struct ath_softc *sc, |
863 struct ath_txq *txq) | 882 struct ath_txq *txq) |
864 { | 883 { |
865 struct ath_atx_ac *ac, *ac_tmp; | 884 struct ath_atx_ac *ac, *ac_tmp; |
866 struct ath_atx_tid *tid, *tid_tmp; | 885 struct ath_atx_tid *tid, *tid_tmp; |
867 | 886 |
868 list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { | 887 list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) { |
869 list_del(&ac->list); | 888 list_del(&ac->list); |
870 ac->sched = false; | 889 ac->sched = false; |
871 list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { | 890 list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) { |
872 list_del(&tid->list); | 891 list_del(&tid->list); |
873 tid->sched = false; | 892 tid->sched = false; |
874 ath_tid_drain(sc, txq, tid); | 893 ath_tid_drain(sc, txq, tid); |
875 } | 894 } |
876 } | 895 } |
877 } | 896 } |
878 | 897 |
879 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | 898 struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) |
880 { | 899 { |
881 struct ath_hw *ah = sc->sc_ah; | 900 struct ath_hw *ah = sc->sc_ah; |
882 struct ath_common *common = ath9k_hw_common(ah); | 901 struct ath_common *common = ath9k_hw_common(ah); |
883 struct ath9k_tx_queue_info qi; | 902 struct ath9k_tx_queue_info qi; |
| 903 static const int subtype_txq_to_hwq[] = { |
| 904 [WME_AC_BE] = ATH_TXQ_AC_BE, |
| 905 [WME_AC_BK] = ATH_TXQ_AC_BK, |
| 906 [WME_AC_VI] = ATH_TXQ_AC_VI, |
| 907 [WME_AC_VO] = ATH_TXQ_AC_VO, |
| 908 }; |
884 int qnum, i; | 909 int qnum, i; |
885 | 910 |
886 memset(&qi, 0, sizeof(qi)); | 911 memset(&qi, 0, sizeof(qi)); |
887 » qi.tqi_subtype = subtype; | 912 » qi.tqi_subtype = subtype_txq_to_hwq[subtype]; |
888 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; | 913 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; |
889 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; | 914 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; |
890 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; | 915 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; |
891 qi.tqi_physCompBuf = 0; | 916 qi.tqi_physCompBuf = 0; |
892 | 917 |
893 /* | 918 /* |
894 * Enable interrupts only for EOL and DESC conditions. | 919 * Enable interrupts only for EOL and DESC conditions. |
895 * We mark tx descriptors to receive a DESC interrupt | 920 * We mark tx descriptors to receive a DESC interrupt |
896 * when a tx queue gets deep; otherwise waiting for the | 921 * when a tx queue gets deep; otherwise waiting for the |
897 * EOL to reap descriptors. Note that this is done to | 922 * EOL to reap descriptors. Note that this is done to |
(...skipping 28 matching lines...) Expand all Loading... |
926 if (qnum >= ARRAY_SIZE(sc->tx.txq)) { | 951 if (qnum >= ARRAY_SIZE(sc->tx.txq)) { |
927 ath_print(common, ATH_DBG_FATAL, | 952 ath_print(common, ATH_DBG_FATAL, |
928 "qnum %u out of range, max %u!\n", | 953 "qnum %u out of range, max %u!\n", |
929 qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq)); | 954 qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq)); |
930 ath9k_hw_releasetxqueue(ah, qnum); | 955 ath9k_hw_releasetxqueue(ah, qnum); |
931 return NULL; | 956 return NULL; |
932 } | 957 } |
933 if (!ATH_TXQ_SETUP(sc, qnum)) { | 958 if (!ATH_TXQ_SETUP(sc, qnum)) { |
934 struct ath_txq *txq = &sc->tx.txq[qnum]; | 959 struct ath_txq *txq = &sc->tx.txq[qnum]; |
935 | 960 |
936 txq->axq_class = subtype; | |
937 txq->axq_qnum = qnum; | 961 txq->axq_qnum = qnum; |
938 txq->axq_link = NULL; | 962 txq->axq_link = NULL; |
939 INIT_LIST_HEAD(&txq->axq_q); | 963 INIT_LIST_HEAD(&txq->axq_q); |
940 INIT_LIST_HEAD(&txq->axq_acq); | 964 INIT_LIST_HEAD(&txq->axq_acq); |
941 spin_lock_init(&txq->axq_lock); | 965 spin_lock_init(&txq->axq_lock); |
942 txq->axq_depth = 0; | 966 txq->axq_depth = 0; |
943 txq->axq_tx_inprogress = false; | 967 txq->axq_tx_inprogress = false; |
944 sc->tx.txqsetup |= 1<<qnum; | 968 sc->tx.txqsetup |= 1<<qnum; |
945 | 969 |
946 txq->txq_headidx = txq->txq_tailidx = 0; | 970 txq->txq_headidx = txq->txq_tailidx = 0; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 if (bf_isampdu(bf)) | 1099 if (bf_isampdu(bf)) |
1076 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0); | 1100 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0); |
1077 else | 1101 else |
1078 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 1102 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
1079 } | 1103 } |
1080 | 1104 |
1081 spin_lock_bh(&txq->axq_lock); | 1105 spin_lock_bh(&txq->axq_lock); |
1082 txq->axq_tx_inprogress = false; | 1106 txq->axq_tx_inprogress = false; |
1083 spin_unlock_bh(&txq->axq_lock); | 1107 spin_unlock_bh(&txq->axq_lock); |
1084 | 1108 |
1085 /* flush any pending frames if aggregation is enabled */ | |
1086 if (sc->sc_flags & SC_OP_TXAGGR) { | |
1087 if (!retry_tx) { | |
1088 spin_lock_bh(&txq->axq_lock); | |
1089 ath_txq_drain_pending_buffers(sc, txq); | |
1090 spin_unlock_bh(&txq->axq_lock); | |
1091 } | |
1092 } | |
1093 | |
1094 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1109 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1095 spin_lock_bh(&txq->axq_lock); | 1110 spin_lock_bh(&txq->axq_lock); |
1096 while (!list_empty(&txq->txq_fifo_pending)) { | 1111 while (!list_empty(&txq->txq_fifo_pending)) { |
1097 bf = list_first_entry(&txq->txq_fifo_pending, | 1112 bf = list_first_entry(&txq->txq_fifo_pending, |
1098 struct ath_buf, list); | 1113 struct ath_buf, list); |
1099 list_cut_position(&bf_head, | 1114 list_cut_position(&bf_head, |
1100 &txq->txq_fifo_pending, | 1115 &txq->txq_fifo_pending, |
1101 &bf->bf_lastbf->list); | 1116 &bf->bf_lastbf->list); |
1102 spin_unlock_bh(&txq->axq_lock); | 1117 spin_unlock_bh(&txq->axq_lock); |
1103 | 1118 |
1104 if (bf_isampdu(bf)) | 1119 if (bf_isampdu(bf)) |
1105 ath_tx_complete_aggr(sc, txq, bf, &bf_head, | 1120 ath_tx_complete_aggr(sc, txq, bf, &bf_head, |
1106 &ts, 0); | 1121 &ts, 0); |
1107 else | 1122 else |
1108 ath_tx_complete_buf(sc, bf, txq, &bf_head, | 1123 ath_tx_complete_buf(sc, bf, txq, &bf_head, |
1109 &ts, 0, 0); | 1124 &ts, 0, 0); |
1110 spin_lock_bh(&txq->axq_lock); | 1125 spin_lock_bh(&txq->axq_lock); |
1111 } | 1126 } |
1112 spin_unlock_bh(&txq->axq_lock); | 1127 spin_unlock_bh(&txq->axq_lock); |
1113 } | 1128 } |
| 1129 |
| 1130 /* flush any pending frames if aggregation is enabled */ |
| 1131 if (sc->sc_flags & SC_OP_TXAGGR) { |
| 1132 if (!retry_tx) { |
| 1133 spin_lock_bh(&txq->axq_lock); |
| 1134 ath_txq_drain_pending_buffers(sc, txq); |
| 1135 spin_unlock_bh(&txq->axq_lock); |
| 1136 } |
| 1137 } |
1114 } | 1138 } |
1115 | 1139 |
1116 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1140 void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
1117 { | 1141 { |
1118 struct ath_hw *ah = sc->sc_ah; | 1142 struct ath_hw *ah = sc->sc_ah; |
1119 struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1143 struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1120 struct ath_txq *txq; | 1144 struct ath_txq *txq; |
1121 int i, npend = 0; | 1145 int i, npend = 0; |
1122 | 1146 |
1123 if (sc->sc_flags & SC_OP_INVALID) | 1147 if (sc->sc_flags & SC_OP_INVALID) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 } while (!list_empty(&ac->tid_q)); | 1220 } while (!list_empty(&ac->tid_q)); |
1197 | 1221 |
1198 if (!list_empty(&ac->tid_q)) { | 1222 if (!list_empty(&ac->tid_q)) { |
1199 if (!ac->sched) { | 1223 if (!ac->sched) { |
1200 ac->sched = true; | 1224 ac->sched = true; |
1201 list_add_tail(&ac->list, &txq->axq_acq); | 1225 list_add_tail(&ac->list, &txq->axq_acq); |
1202 } | 1226 } |
1203 } | 1227 } |
1204 } | 1228 } |
1205 | 1229 |
1206 int ath_tx_setup(struct ath_softc *sc, int haltype) | |
1207 { | |
1208 struct ath_txq *txq; | |
1209 | |
1210 if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { | |
1211 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, | |
1212 "HAL AC %u out of range, max %zu!\n", | |
1213 haltype, ARRAY_SIZE(sc->tx.hwq_map)); | |
1214 return 0; | |
1215 } | |
1216 txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype); | |
1217 if (txq != NULL) { | |
1218 sc->tx.hwq_map[haltype] = txq->axq_qnum; | |
1219 return 1; | |
1220 } else | |
1221 return 0; | |
1222 } | |
1223 | |
1224 /***********/ | 1230 /***********/ |
1225 /* TX, DMA */ | 1231 /* TX, DMA */ |
1226 /***********/ | 1232 /***********/ |
1227 | 1233 |
1228 /* | 1234 /* |
1229 * Insert a chain of ath_buf (descriptors) on a txq and | 1235 * Insert a chain of ath_buf (descriptors) on a txq and |
1230 * assume the descriptors are already chained together by caller. | 1236 * assume the descriptors are already chained together by caller. |
1231 */ | 1237 */ |
1232 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 1238 static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
1233 struct list_head *head) | 1239 struct list_head *head) |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1718 if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && | 1724 if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && |
1719 tx_info->control.sta) { | 1725 tx_info->control.sta) { |
1720 an = (struct ath_node *)tx_info->control.sta->drv_priv; | 1726 an = (struct ath_node *)tx_info->control.sta->drv_priv; |
1721 tid = ATH_AN_2_TID(an, bf->bf_tidno); | 1727 tid = ATH_AN_2_TID(an, bf->bf_tidno); |
1722 | 1728 |
1723 if (!ieee80211_is_data_qos(fc)) { | 1729 if (!ieee80211_is_data_qos(fc)) { |
1724 ath_tx_send_normal(sc, txctl->txq, &bf_head); | 1730 ath_tx_send_normal(sc, txctl->txq, &bf_head); |
1725 goto tx_done; | 1731 goto tx_done; |
1726 } | 1732 } |
1727 | 1733 |
| 1734 WARN_ON(tid->ac->txq != txctl->txq); |
1728 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 1735 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
1729 /* | 1736 /* |
1730 * Try aggregation if it's a unicast data frame | 1737 * Try aggregation if it's a unicast data frame |
1731 * and the destination is HT capable. | 1738 * and the destination is HT capable. |
1732 */ | 1739 */ |
1733 ath_tx_send_ampdu(sc, tid, &bf_head, txctl); | 1740 ath_tx_send_ampdu(sc, tid, &bf_head, txctl); |
1734 } else { | 1741 } else { |
1735 /* | 1742 /* |
1736 * Send this frame as regular when ADDBA | 1743 * Send this frame as regular when ADDBA |
1737 * exchange is neither complete nor pending. | 1744 * exchange is neither complete nor pending. |
(...skipping 19 matching lines...) Expand all Loading... |
1757 struct ath_txq *txq = txctl->txq; | 1764 struct ath_txq *txq = txctl->txq; |
1758 struct ath_buf *bf; | 1765 struct ath_buf *bf; |
1759 int q, r; | 1766 int q, r; |
1760 | 1767 |
1761 bf = ath_tx_get_buffer(sc); | 1768 bf = ath_tx_get_buffer(sc); |
1762 if (!bf) { | 1769 if (!bf) { |
1763 ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); | 1770 ath_print(common, ATH_DBG_XMIT, "TX buffers are full\n"); |
1764 return -1; | 1771 return -1; |
1765 } | 1772 } |
1766 | 1773 |
| 1774 q = skb_get_queue_mapping(skb); |
1767 r = ath_tx_setup_buffer(hw, bf, skb, txctl); | 1775 r = ath_tx_setup_buffer(hw, bf, skb, txctl); |
1768 if (unlikely(r)) { | 1776 if (unlikely(r)) { |
1769 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); | 1777 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); |
1770 | 1778 |
1771 /* upon ath_tx_processq() this TX queue will be resumed, we | 1779 /* upon ath_tx_processq() this TX queue will be resumed, we |
1772 * guarantee this will happen by knowing beforehand that | 1780 * guarantee this will happen by knowing beforehand that |
1773 * we will at least have to run TX completionon one buffer | 1781 * we will at least have to run TX completionon one buffer |
1774 * on the queue */ | 1782 * on the queue */ |
1775 spin_lock_bh(&txq->axq_lock); | 1783 spin_lock_bh(&txq->axq_lock); |
1776 » » if (!txq->stopped && txq->axq_depth > 1) { | 1784 » » if (txq == sc->tx.txq_map[q] && !txq->stopped && |
1777 » » » ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); | 1785 » » txq->axq_depth > 1) { |
| 1786 » » » ath_mac80211_stop_queue(sc, q); |
1778 txq->stopped = 1; | 1787 txq->stopped = 1; |
1779 } | 1788 } |
1780 spin_unlock_bh(&txq->axq_lock); | 1789 spin_unlock_bh(&txq->axq_lock); |
1781 | 1790 |
1782 ath_tx_return_buffer(sc, bf); | 1791 ath_tx_return_buffer(sc, bf); |
1783 | 1792 |
1784 return r; | 1793 return r; |
1785 } | 1794 } |
1786 | 1795 |
1787 q = skb_get_queue_mapping(skb); | |
1788 if (q >= 4) | |
1789 q = 0; | |
1790 | |
1791 spin_lock_bh(&txq->axq_lock); | 1796 spin_lock_bh(&txq->axq_lock); |
1792 » if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { | 1797 » if (txq == sc->tx.txq_map[q] && |
1793 » » ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); | 1798 » ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { |
| 1799 » » ath_mac80211_stop_queue(sc, q); |
1794 txq->stopped = 1; | 1800 txq->stopped = 1; |
1795 } | 1801 } |
1796 spin_unlock_bh(&txq->axq_lock); | 1802 spin_unlock_bh(&txq->axq_lock); |
1797 | 1803 |
1798 ath_tx_start_dma(sc, bf, txctl); | 1804 ath_tx_start_dma(sc, bf, txctl); |
1799 | 1805 |
1800 return 0; | 1806 return 0; |
1801 } | 1807 } |
1802 | 1808 |
1803 void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | 1809 void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1851 return; | 1857 return; |
1852 exit: | 1858 exit: |
1853 dev_kfree_skb_any(skb); | 1859 dev_kfree_skb_any(skb); |
1854 } | 1860 } |
1855 | 1861 |
1856 /*****************/ | 1862 /*****************/ |
1857 /* TX Completion */ | 1863 /* TX Completion */ |
1858 /*****************/ | 1864 /*****************/ |
1859 | 1865 |
1860 static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | 1866 static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, |
1861 » » » struct ath_wiphy *aphy, int tx_flags) | 1867 » » » struct ath_wiphy *aphy, int tx_flags, |
| 1868 » » » struct ath_txq *txq) |
1862 { | 1869 { |
1863 struct ieee80211_hw *hw = sc->hw; | 1870 struct ieee80211_hw *hw = sc->hw; |
1864 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1871 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1865 struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1872 struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1866 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | 1873 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; |
1867 int q, padpos, padsize; | 1874 int q, padpos, padsize; |
1868 | 1875 |
1869 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); | 1876 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); |
1870 | 1877 |
1871 if (aphy) | 1878 if (aphy) |
(...skipping 26 matching lines...) Expand all Loading... |
1898 sc->ps_flags & (PS_WAIT_FOR_BEACON | | 1905 sc->ps_flags & (PS_WAIT_FOR_BEACON | |
1899 PS_WAIT_FOR_CAB | | 1906 PS_WAIT_FOR_CAB | |
1900 PS_WAIT_FOR_PSPOLL_DATA | | 1907 PS_WAIT_FOR_PSPOLL_DATA | |
1901 PS_WAIT_FOR_TX_ACK)); | 1908 PS_WAIT_FOR_TX_ACK)); |
1902 } | 1909 } |
1903 | 1910 |
1904 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) | 1911 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) |
1905 ath9k_tx_status(hw, skb); | 1912 ath9k_tx_status(hw, skb); |
1906 else { | 1913 else { |
1907 q = skb_get_queue_mapping(skb); | 1914 q = skb_get_queue_mapping(skb); |
1908 » » if (q >= 4) | 1915 » » if (txq == sc->tx.txq_map[q]) { |
1909 » » » q = 0; | 1916 » » » spin_lock_bh(&txq->axq_lock); |
1910 | 1917 » » » if (WARN_ON(--txq->pending_frames < 0)) |
1911 » » if (--sc->tx.pending_frames[q] < 0) | 1918 » » » » txq->pending_frames = 0; |
1912 » » » sc->tx.pending_frames[q] = 0; | 1919 » » » spin_unlock_bh(&txq->axq_lock); |
| 1920 » » } |
1913 | 1921 |
1914 ieee80211_tx_status(hw, skb); | 1922 ieee80211_tx_status(hw, skb); |
1915 } | 1923 } |
1916 } | 1924 } |
1917 | 1925 |
1918 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1926 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
1919 struct ath_txq *txq, struct list_head *bf_q, | 1927 struct ath_txq *txq, struct list_head *bf_q, |
1920 struct ath_tx_status *ts, int txok, int sendbar) | 1928 struct ath_tx_status *ts, int txok, int sendbar) |
1921 { | 1929 { |
1922 struct sk_buff *skb = bf->bf_mpdu; | 1930 struct sk_buff *skb = bf->bf_mpdu; |
(...skipping 13 matching lines...) Expand all Loading... |
1936 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1944 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1937 | 1945 |
1938 if (bf->bf_state.bfs_paprd) { | 1946 if (bf->bf_state.bfs_paprd) { |
1939 if (time_after(jiffies, | 1947 if (time_after(jiffies, |
1940 bf->bf_state.bfs_paprd_timestamp + | 1948 bf->bf_state.bfs_paprd_timestamp + |
1941 msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) | 1949 msecs_to_jiffies(ATH_PAPRD_TIMEOUT))) |
1942 dev_kfree_skb_any(skb); | 1950 dev_kfree_skb_any(skb); |
1943 else | 1951 else |
1944 complete(&sc->paprd_complete); | 1952 complete(&sc->paprd_complete); |
1945 } else { | 1953 } else { |
1946 » » ath_tx_complete(sc, skb, bf->aphy, tx_flags); | 1954 » » ath_debug_stat_tx(sc, bf, ts); |
1947 » » ath_debug_stat_tx(sc, txq, bf, ts); | 1955 » » ath_tx_complete(sc, skb, bf->aphy, tx_flags, txq); |
| 1956 |
1948 } | 1957 } |
1949 | 1958 |
1950 /* | 1959 /* |
1951 * Return the list of ath_buf of this mpdu to free queue | 1960 * Return the list of ath_buf of this mpdu to free queue |
1952 */ | 1961 */ |
1953 spin_lock_irqsave(&sc->tx.txbuflock, flags); | 1962 spin_lock_irqsave(&sc->tx.txbuflock, flags); |
1954 list_splice_tail_init(bf_q, &sc->tx.txbuf); | 1963 list_splice_tail_init(bf_q, &sc->tx.txbuf); |
1955 spin_unlock_irqrestore(&sc->tx.txbuflock, flags); | 1964 spin_unlock_irqrestore(&sc->tx.txbuflock, flags); |
1956 } | 1965 } |
1957 | 1966 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1994 u8 i, tx_rateindex; | 2003 u8 i, tx_rateindex; |
1995 | 2004 |
1996 if (txok) | 2005 if (txok) |
1997 tx_info->status.ack_signal = ts->ts_rssi; | 2006 tx_info->status.ack_signal = ts->ts_rssi; |
1998 | 2007 |
1999 tx_rateindex = ts->ts_rateindex; | 2008 tx_rateindex = ts->ts_rateindex; |
2000 WARN_ON(tx_rateindex >= hw->max_rates); | 2009 WARN_ON(tx_rateindex >= hw->max_rates); |
2001 | 2010 |
2002 if (ts->ts_status & ATH9K_TXERR_FILT) | 2011 if (ts->ts_status & ATH9K_TXERR_FILT) |
2003 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 2012 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
2004 » if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) | 2013 » if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { |
2005 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | 2014 tx_info->flags |= IEEE80211_TX_STAT_AMPDU; |
2006 | 2015 |
| 2016 BUG_ON(nbad > bf->bf_nframes); |
| 2017 |
| 2018 tx_info->status.ampdu_len = bf->bf_nframes; |
| 2019 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; |
| 2020 } |
| 2021 |
2007 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && | 2022 if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && |
2008 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 2023 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
2009 if (ieee80211_is_data(hdr->frame_control)) { | 2024 if (ieee80211_is_data(hdr->frame_control)) { |
2010 if (ts->ts_flags & | 2025 if (ts->ts_flags & |
2011 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) | 2026 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
2012 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; | 2027 tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
2013 if ((ts->ts_status & ATH9K_TXERR_XRETRY) || | 2028 if ((ts->ts_status & ATH9K_TXERR_XRETRY) || |
2014 (ts->ts_status & ATH9K_TXERR_FIFO)) | 2029 (ts->ts_status & ATH9K_TXERR_FIFO)) |
2015 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | 2030 tx_info->pad[0] |= ATH_TX_INFO_XRETRY; |
2016 tx_info->status.ampdu_len = bf->bf_nframes; | |
2017 tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | |
2018 } | 2031 } |
2019 } | 2032 } |
2020 | 2033 |
2021 for (i = tx_rateindex + 1; i < hw->max_rates; i++) { | 2034 for (i = tx_rateindex + 1; i < hw->max_rates; i++) { |
2022 tx_info->status.rates[i].count = 0; | 2035 tx_info->status.rates[i].count = 0; |
2023 tx_info->status.rates[i].idx = -1; | 2036 tx_info->status.rates[i].idx = -1; |
2024 } | 2037 } |
2025 | 2038 |
2026 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; | 2039 tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
2027 } | 2040 } |
2028 | 2041 |
2029 static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) | 2042 static void ath_wake_mac80211_queue(struct ath_softc *sc, int qnum) |
2030 { | 2043 { |
2031 » int qnum; | 2044 » struct ath_txq *txq; |
2032 | 2045 |
2033 » qnum = ath_get_mac80211_qnum(txq->axq_class, sc); | 2046 » txq = sc->tx.txq_map[qnum]; |
2034 » if (qnum == -1) | |
2035 » » return; | |
2036 | |
2037 spin_lock_bh(&txq->axq_lock); | 2047 spin_lock_bh(&txq->axq_lock); |
2038 » if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { | 2048 » if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { |
2039 if (ath_mac80211_start_queue(sc, qnum)) | 2049 if (ath_mac80211_start_queue(sc, qnum)) |
2040 txq->stopped = 0; | 2050 txq->stopped = 0; |
2041 } | 2051 } |
2042 spin_unlock_bh(&txq->axq_lock); | 2052 spin_unlock_bh(&txq->axq_lock); |
2043 } | 2053 } |
2044 | 2054 |
2045 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | 2055 static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
2046 { | 2056 { |
2047 struct ath_hw *ah = sc->sc_ah; | 2057 struct ath_hw *ah = sc->sc_ah; |
2048 struct ath_common *common = ath9k_hw_common(ah); | 2058 struct ath_common *common = ath9k_hw_common(ah); |
2049 struct ath_buf *bf, *lastbf, *bf_held = NULL; | 2059 struct ath_buf *bf, *lastbf, *bf_held = NULL; |
2050 struct list_head bf_head; | 2060 struct list_head bf_head; |
2051 struct ath_desc *ds; | 2061 struct ath_desc *ds; |
2052 struct ath_tx_status ts; | 2062 struct ath_tx_status ts; |
2053 int txok; | 2063 int txok; |
2054 int status; | 2064 int status; |
| 2065 int qnum; |
2055 | 2066 |
2056 ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | 2067 ath_print(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", |
2057 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 2068 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
2058 txq->axq_link); | 2069 txq->axq_link); |
2059 | 2070 |
2060 for (;;) { | 2071 for (;;) { |
2061 spin_lock_bh(&txq->axq_lock); | 2072 spin_lock_bh(&txq->axq_lock); |
2062 if (list_empty(&txq->axq_q)) { | 2073 if (list_empty(&txq->axq_q)) { |
2063 txq->axq_link = NULL; | 2074 txq->axq_link = NULL; |
2064 spin_unlock_bh(&txq->axq_lock); | 2075 spin_unlock_bh(&txq->axq_lock); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2129 if (bf_held) | 2140 if (bf_held) |
2130 ath_tx_return_buffer(sc, bf_held); | 2141 ath_tx_return_buffer(sc, bf_held); |
2131 | 2142 |
2132 if (!bf_isampdu(bf)) { | 2143 if (!bf_isampdu(bf)) { |
2133 /* | 2144 /* |
2134 * This frame is sent out as a single frame. | 2145 * This frame is sent out as a single frame. |
2135 * Use hardware retry status for this frame. | 2146 * Use hardware retry status for this frame. |
2136 */ | 2147 */ |
2137 if (ts.ts_status & ATH9K_TXERR_XRETRY) | 2148 if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2138 bf->bf_state.bf_type |= BUF_XRETRY; | 2149 bf->bf_state.bf_type |= BUF_XRETRY; |
2139 » » » ath_tx_rc_status(bf, &ts, 0, txok, true); | 2150 » » » ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); |
2140 } | 2151 } |
2141 | 2152 |
| 2153 qnum = skb_get_queue_mapping(bf->bf_mpdu); |
| 2154 |
2142 if (bf_isampdu(bf)) | 2155 if (bf_isampdu(bf)) |
2143 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); | 2156 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); |
2144 else | 2157 else |
2145 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0)
; | 2158 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0)
; |
2146 | 2159 |
2147 » » ath_wake_mac80211_queue(sc, txq); | 2160 » » if (txq == sc->tx.txq_map[qnum]) |
| 2161 » » » ath_wake_mac80211_queue(sc, qnum); |
2148 | 2162 |
2149 spin_lock_bh(&txq->axq_lock); | 2163 spin_lock_bh(&txq->axq_lock); |
2150 if (sc->sc_flags & SC_OP_TXAGGR) | 2164 if (sc->sc_flags & SC_OP_TXAGGR) |
2151 ath_txq_schedule(sc, txq); | 2165 ath_txq_schedule(sc, txq); |
2152 spin_unlock_bh(&txq->axq_lock); | 2166 spin_unlock_bh(&txq->axq_lock); |
2153 } | 2167 } |
2154 } | 2168 } |
2155 | 2169 |
2156 static void ath_tx_complete_poll_work(struct work_struct *work) | 2170 static void ath_tx_complete_poll_work(struct work_struct *work) |
2157 { | 2171 { |
(...skipping 16 matching lines...) Expand all Loading... |
2174 txq->axq_tx_inprogress = true; | 2188 txq->axq_tx_inprogress = true; |
2175 } | 2189 } |
2176 } | 2190 } |
2177 spin_unlock_bh(&txq->axq_lock); | 2191 spin_unlock_bh(&txq->axq_lock); |
2178 } | 2192 } |
2179 | 2193 |
2180 if (needreset) { | 2194 if (needreset) { |
2181 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, | 2195 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET, |
2182 "tx hung, resetting the chip\n"); | 2196 "tx hung, resetting the chip\n"); |
2183 ath9k_ps_wakeup(sc); | 2197 ath9k_ps_wakeup(sc); |
2184 » » ath_reset(sc, false); | 2198 » » ath_reset(sc, true); |
2185 ath9k_ps_restore(sc); | 2199 ath9k_ps_restore(sc); |
2186 } | 2200 } |
2187 | 2201 |
2188 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, | 2202 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, |
2189 msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); | 2203 msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); |
2190 } | 2204 } |
2191 | 2205 |
2192 | 2206 |
2193 | 2207 |
2194 void ath_tx_tasklet(struct ath_softc *sc) | 2208 void ath_tx_tasklet(struct ath_softc *sc) |
(...skipping 12 matching lines...) Expand all Loading... |
2207 void ath_tx_edma_tasklet(struct ath_softc *sc) | 2221 void ath_tx_edma_tasklet(struct ath_softc *sc) |
2208 { | 2222 { |
2209 struct ath_tx_status txs; | 2223 struct ath_tx_status txs; |
2210 struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2224 struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
2211 struct ath_hw *ah = sc->sc_ah; | 2225 struct ath_hw *ah = sc->sc_ah; |
2212 struct ath_txq *txq; | 2226 struct ath_txq *txq; |
2213 struct ath_buf *bf, *lastbf; | 2227 struct ath_buf *bf, *lastbf; |
2214 struct list_head bf_head; | 2228 struct list_head bf_head; |
2215 int status; | 2229 int status; |
2216 int txok; | 2230 int txok; |
| 2231 int qnum; |
2217 | 2232 |
2218 for (;;) { | 2233 for (;;) { |
2219 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | 2234 status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); |
2220 if (status == -EINPROGRESS) | 2235 if (status == -EINPROGRESS) |
2221 break; | 2236 break; |
2222 if (status == -EIO) { | 2237 if (status == -EIO) { |
2223 ath_print(common, ATH_DBG_XMIT, | 2238 ath_print(common, ATH_DBG_XMIT, |
2224 "Error processing tx status\n"); | 2239 "Error processing tx status\n"); |
2225 break; | 2240 break; |
2226 } | 2241 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2258 if (bf->bf_isnullfunc && txok) { | 2273 if (bf->bf_isnullfunc && txok) { |
2259 if ((sc->ps_flags & PS_ENABLED)) | 2274 if ((sc->ps_flags & PS_ENABLED)) |
2260 ath9k_enable_ps(sc); | 2275 ath9k_enable_ps(sc); |
2261 else | 2276 else |
2262 sc->ps_flags |= PS_NULLFUNC_COMPLETED; | 2277 sc->ps_flags |= PS_NULLFUNC_COMPLETED; |
2263 } | 2278 } |
2264 | 2279 |
2265 if (!bf_isampdu(bf)) { | 2280 if (!bf_isampdu(bf)) { |
2266 if (txs.ts_status & ATH9K_TXERR_XRETRY) | 2281 if (txs.ts_status & ATH9K_TXERR_XRETRY) |
2267 bf->bf_state.bf_type |= BUF_XRETRY; | 2282 bf->bf_state.bf_type |= BUF_XRETRY; |
2268 » » » ath_tx_rc_status(bf, &txs, 0, txok, true); | 2283 » » » ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); |
2269 } | 2284 } |
2270 | 2285 |
| 2286 qnum = skb_get_queue_mapping(bf->bf_mpdu); |
| 2287 |
2271 if (bf_isampdu(bf)) | 2288 if (bf_isampdu(bf)) |
2272 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); | 2289 ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); |
2273 else | 2290 else |
2274 ath_tx_complete_buf(sc, bf, txq, &bf_head, | 2291 ath_tx_complete_buf(sc, bf, txq, &bf_head, |
2275 &txs, txok, 0); | 2292 &txs, txok, 0); |
2276 | 2293 |
2277 » » ath_wake_mac80211_queue(sc, txq); | 2294 » » if (txq == sc->tx.txq_map[qnum]) |
| 2295 » » » ath_wake_mac80211_queue(sc, qnum); |
2278 | 2296 |
2279 spin_lock_bh(&txq->axq_lock); | 2297 spin_lock_bh(&txq->axq_lock); |
2280 if (!list_empty(&txq->txq_fifo_pending)) { | 2298 if (!list_empty(&txq->txq_fifo_pending)) { |
2281 INIT_LIST_HEAD(&bf_head); | 2299 INIT_LIST_HEAD(&bf_head); |
2282 bf = list_first_entry(&txq->txq_fifo_pending, | 2300 bf = list_first_entry(&txq->txq_fifo_pending, |
2283 struct ath_buf, list); | 2301 struct ath_buf, list); |
2284 list_cut_position(&bf_head, &txq->txq_fifo_pending, | 2302 list_cut_position(&bf_head, &txq->txq_fifo_pending, |
2285 &bf->bf_lastbf->list); | 2303 &bf->bf_lastbf->list); |
2286 ath_tx_txqaddbuf(sc, txq, &bf_head); | 2304 ath_tx_txqaddbuf(sc, txq, &bf_head); |
2287 } else if (sc->sc_flags & SC_OP_TXAGGR) | 2305 } else if (sc->sc_flags & SC_OP_TXAGGR) |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2399 INIT_LIST_HEAD(&tid->buf_q); | 2417 INIT_LIST_HEAD(&tid->buf_q); |
2400 acno = TID_TO_WME_AC(tidno); | 2418 acno = TID_TO_WME_AC(tidno); |
2401 tid->ac = &an->ac[acno]; | 2419 tid->ac = &an->ac[acno]; |
2402 tid->state &= ~AGGR_ADDBA_COMPLETE; | 2420 tid->state &= ~AGGR_ADDBA_COMPLETE; |
2403 tid->state &= ~AGGR_ADDBA_PROGRESS; | 2421 tid->state &= ~AGGR_ADDBA_PROGRESS; |
2404 } | 2422 } |
2405 | 2423 |
2406 for (acno = 0, ac = &an->ac[acno]; | 2424 for (acno = 0, ac = &an->ac[acno]; |
2407 acno < WME_NUM_AC; acno++, ac++) { | 2425 acno < WME_NUM_AC; acno++, ac++) { |
2408 ac->sched = false; | 2426 ac->sched = false; |
2409 » » ac->qnum = sc->tx.hwq_map[acno]; | 2427 » » ac->txq = sc->tx.txq_map[acno]; |
2410 INIT_LIST_HEAD(&ac->tid_q); | 2428 INIT_LIST_HEAD(&ac->tid_q); |
2411 } | 2429 } |
2412 } | 2430 } |
2413 | 2431 |
2414 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) | 2432 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) |
2415 { | 2433 { |
2416 struct ath_atx_ac *ac; | 2434 struct ath_atx_ac *ac; |
2417 struct ath_atx_tid *tid; | 2435 struct ath_atx_tid *tid; |
2418 struct ath_txq *txq; | 2436 struct ath_txq *txq; |
2419 » int i, tidno; | 2437 » int tidno; |
2420 | 2438 |
2421 for (tidno = 0, tid = &an->tid[tidno]; | 2439 for (tidno = 0, tid = &an->tid[tidno]; |
2422 tidno < WME_NUM_TID; tidno++, tid++) { | 2440 tidno < WME_NUM_TID; tidno++, tid++) { |
2423 i = tid->ac->qnum; | |
2424 | 2441 |
2425 if (!ATH_TXQ_SETUP(sc, i)) | |
2426 continue; | |
2427 | |
2428 txq = &sc->tx.txq[i]; | |
2429 ac = tid->ac; | 2442 ac = tid->ac; |
| 2443 txq = ac->txq; |
2430 | 2444 |
2431 spin_lock_bh(&txq->axq_lock); | 2445 spin_lock_bh(&txq->axq_lock); |
2432 | 2446 |
2433 if (tid->sched) { | 2447 if (tid->sched) { |
2434 list_del(&tid->list); | 2448 list_del(&tid->list); |
2435 tid->sched = false; | 2449 tid->sched = false; |
2436 } | 2450 } |
2437 | 2451 |
2438 if (ac->sched) { | 2452 if (ac->sched) { |
2439 list_del(&ac->list); | 2453 list_del(&ac->list); |
2440 tid->ac->sched = false; | 2454 tid->ac->sched = false; |
2441 } | 2455 } |
2442 | 2456 |
2443 ath_tid_drain(sc, txq, tid); | 2457 ath_tid_drain(sc, txq, tid); |
2444 tid->state &= ~AGGR_ADDBA_COMPLETE; | 2458 tid->state &= ~AGGR_ADDBA_COMPLETE; |
2445 tid->state &= ~AGGR_CLEANUP; | 2459 tid->state &= ~AGGR_CLEANUP; |
2446 | 2460 |
2447 spin_unlock_bh(&txq->axq_lock); | 2461 spin_unlock_bh(&txq->axq_lock); |
2448 } | 2462 } |
2449 } | 2463 } |
OLD | NEW |