aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/xmit.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-12-14 16:08:08 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-15 14:46:36 -0500
commitf94375431749d555a16659051d8033ba9a0fe83b (patch)
tree88c6c31f276a2cf974c9a0566554f7e970f22b4f /drivers/net/wireless/ath/ath9k/xmit.c
parent3ad2952998b08442044690fa9b4ec38c6c3fc4a9 (diff)
ath9k: avoid retransmitting aggregation frames that a BAR was sent for
The receiver will discard them anyway. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/xmit.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 8766796b48b8..23e80e63bca9 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -206,6 +206,8 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
206 while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) { 206 while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) {
207 INCR(tid->seq_start, IEEE80211_SEQ_MAX); 207 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
208 INCR(tid->baw_head, ATH_TID_MAX_BUFS); 208 INCR(tid->baw_head, ATH_TID_MAX_BUFS);
209 if (tid->bar_index >= 0)
210 tid->bar_index--;
209 } 211 }
210} 212}
211 213
@@ -263,6 +265,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
263 265
264 tid->seq_next = tid->seq_start; 266 tid->seq_next = tid->seq_start;
265 tid->baw_tail = tid->baw_head; 267 tid->baw_tail = tid->baw_head;
268 tid->bar_index = -1;
266} 269}
267 270
268static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, 271static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
@@ -551,8 +554,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
551 bf = bf_next; 554 bf = bf_next;
552 } 555 }
553 556
554 if (bar_index >= 0) 557 if (bar_index >= 0) {
558 u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index);
555 ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1)); 559 ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1));
560 if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq))
561 tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq);
562 }
556 563
557 /* prepend un-acked frames to the beginning of the pending frame queue */ 564 /* prepend un-acked frames to the beginning of the pending frame queue */
558 if (!skb_queue_empty(&bf_pending)) { 565 if (!skb_queue_empty(&bf_pending)) {
@@ -779,8 +786,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
779 786
780 bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; 787 bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
781 seqno = bf->bf_state.seqno; 788 seqno = bf->bf_state.seqno;
782 if (!bf_first)
783 bf_first = bf;
784 789
785 /* do not step over block-ack window */ 790 /* do not step over block-ack window */
786 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { 791 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
@@ -788,6 +793,21 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
788 break; 793 break;
789 } 794 }
790 795
796 if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
797 struct ath_tx_status ts = {};
798 struct list_head bf_head;
799
800 INIT_LIST_HEAD(&bf_head);
801 list_add(&bf->list, &bf_head);
802 __skb_unlink(skb, &tid->buf_q);
803 ath_tx_update_baw(sc, tid, seqno);
804 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
805 continue;
806 }
807
808 if (!bf_first)
809 bf_first = bf;
810
791 if (!rl) { 811 if (!rl) {
792 aggr_limit = ath_lookup_rate(sc, bf, tid); 812 aggr_limit = ath_lookup_rate(sc, bf, tid);
793 rl = 1; 813 rl = 1;
@@ -1130,6 +1150,7 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
1130 txtid->state |= AGGR_ADDBA_PROGRESS; 1150 txtid->state |= AGGR_ADDBA_PROGRESS;
1131 txtid->paused = true; 1151 txtid->paused = true;
1132 *ssn = txtid->seq_start = txtid->seq_next; 1152 *ssn = txtid->seq_start = txtid->seq_next;
1153 txtid->bar_index = -1;
1133 1154
1134 memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); 1155 memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf));
1135 txtid->baw_head = txtid->baw_tail = 0; 1156 txtid->baw_head = txtid->baw_tail = 0;