123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- From: Felix Fietkau <nbd@nbd.name>
- Date: Tue, 30 Aug 2016 12:44:08 +0200
- Subject: [PATCH] ath9k: fix block-ack window tracking issues
- Ensure that a buffer gets tracked as part of the block-ack window as
- soon as it's dequeued from the tid for the first time. Ensure that
- double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause
- any issues.
- Signed-off-by: Felix Fietkau <nbd@nbd.name>
- ---
- --- a/drivers/net/wireless/ath/ath9k/xmit.c
- +++ b/drivers/net/wireless/ath/ath9k/xmit.c
- @@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_
- struct ath_tx_status *ts, int nframes, int nbad,
- int txok);
- static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
- - int seqno);
- + struct ath_buf *bf);
- static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
- struct ath_txq *txq,
- struct ath_atx_tid *tid,
- @@ -300,7 +300,7 @@ static void ath_tx_flush_tid(struct ath_
- }
-
- if (fi->baw_tracked) {
- - ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
- + ath_tx_update_baw(sc, tid, bf);
- sendbar = true;
- }
-
- @@ -316,10 +316,15 @@ static void ath_tx_flush_tid(struct ath_
- }
-
- static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
- - int seqno)
- + struct ath_buf *bf)
- {
- + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu);
- + u16 seqno = bf->bf_state.seqno;
- int index, cindex;
-
- + if (!fi->baw_tracked)
- + return;
- +
- index = ATH_BA_INDEX(tid->seq_start, seqno);
- cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
- @@ -340,6 +345,9 @@ static void ath_tx_addto_baw(struct ath_
- u16 seqno = bf->bf_state.seqno;
- int index, cindex;
-
- + if (fi->baw_tracked)
- + return;
- +
- index = ATH_BA_INDEX(tid->seq_start, seqno);
- cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
- __set_bit(cindex, tid->tx_buf);
- @@ -616,7 +624,7 @@ static void ath_tx_complete_aggr(struct
- * complete the acked-ones/xretried ones; update
- * block-ack window
- */
- - ath_tx_update_baw(sc, tid, seqno);
- + ath_tx_update_baw(sc, tid, bf);
-
- if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
- memcpy(tx_info->control.rates, rates, sizeof(rates));
- @@ -646,7 +654,7 @@ static void ath_tx_complete_aggr(struct
- * run out of tx buf.
- */
- if (!tbf) {
- - ath_tx_update_baw(sc, tid, seqno);
- + ath_tx_update_baw(sc, tid, bf);
-
- ath_tx_complete_buf(sc, bf, txq,
- &bf_head, NULL, ts,
- @@ -987,11 +995,14 @@ ath_tx_get_tid_subframe(struct ath_softc
-
- INIT_LIST_HEAD(&bf_head);
- list_add(&bf->list, &bf_head);
- - ath_tx_update_baw(sc, tid, seqno);
- + ath_tx_update_baw(sc, tid, bf);
- ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0);
- continue;
- }
-
- + if (bf_isampdu(bf))
- + ath_tx_addto_baw(sc, tid, bf);
- +
- return bf;
- }
-
- @@ -1049,8 +1060,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s
- bf->bf_next = NULL;
-
- /* link buffers of this frame to the aggregate */
- - if (!fi->baw_tracked)
- - ath_tx_addto_baw(sc, tid, bf);
- bf->bf_state.ndelim = ndelim;
-
- list_add_tail(&bf->list, bf_q);
- @@ -1686,10 +1695,8 @@ void ath9k_release_buffered_frames(struc
- ath9k_set_moredata(sc, bf, true);
- list_add_tail(&bf->list, &bf_q);
- ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
- - if (bf_isampdu(bf)) {
- - ath_tx_addto_baw(sc, tid, bf);
- + if (bf_isampdu(bf))
- bf->bf_state.bf_type &= ~BUF_AGGR;
- - }
- if (bf_tail)
- bf_tail->bf_next = bf;
-
|