kernel: add a recent upstream commit (post-3.3) to the ssb update patch, required...
[openwrt.git] / package / mac80211 / patches / 564-ath9k_track_last_bar.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -242,6 +242,7 @@ struct ath_atx_tid {
4         struct ath_atx_ac *ac;
5         unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
6         int buf_pending;
7 +       int bar_index;
8         u16 seq_start;
9         u16 seq_next;
10         u16 baw_size;
11 --- a/drivers/net/wireless/ath/ath9k/xmit.c
12 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
13 @@ -206,6 +206,8 @@ static void ath_tx_update_baw(struct ath
14         while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) {
15                 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
16                 INCR(tid->baw_head, ATH_TID_MAX_BUFS);
17 +               if (tid->bar_index >= 0)
18 +                       tid->bar_index--;
19         }
20  }
21  
22 @@ -263,6 +265,7 @@ static void ath_tid_drain(struct ath_sof
23  
24         tid->seq_next = tid->seq_start;
25         tid->baw_tail = tid->baw_head;
26 +       tid->bar_index = -1;
27  }
28  
29  static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
30 @@ -561,8 +564,12 @@ static void ath_tx_complete_aggr(struct 
31                 bf = bf_next;
32         }
33  
34 -       if (bar_index >= 0)
35 +       if (bar_index >= 0) {
36 +               u16 bar_seq = ATH_BA_INDEX2SEQ(seq_first, bar_index);
37                 ath_send_bar(tid, ATH_BA_INDEX2SEQ(seq_first, bar_index + 1));
38 +               if (BAW_WITHIN(tid->seq_start, tid->baw_size, bar_seq))
39 +                       tid->bar_index = ATH_BA_INDEX(tid->seq_start, bar_seq);
40 +       }
41  
42         /* prepend un-acked frames to the beginning of the pending frame queue */
43         if (!skb_queue_empty(&bf_pending)) {
44 @@ -789,8 +796,6 @@ static enum ATH_AGGR_STATUS ath_tx_form_
45  
46                 bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
47                 seqno = bf->bf_state.seqno;
48 -               if (!bf_first)
49 -                       bf_first = bf;
50  
51                 /* do not step over block-ack window */
52                 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) {
53 @@ -798,6 +803,21 @@ static enum ATH_AGGR_STATUS ath_tx_form_
54                         break;
55                 }
56  
57 +               if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) {
58 +                       struct ath_tx_status ts = {};
59 +                       struct list_head bf_head;
60 +
61 +                       INIT_LIST_HEAD(&bf_head);
62 +                       list_add(&bf->list, &bf_head);
63 +                       __skb_unlink(skb, &tid->buf_q);
64 +                       ath_tx_update_baw(sc, tid, seqno);
65 +                       ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
66 +                       continue;
67 +               }
68 +
69 +               if (!bf_first)
70 +                       bf_first = bf;
71 +
72                 if (!rl) {
73                         aggr_limit = ath_lookup_rate(sc, bf, tid);
74                         rl = 1;
75 @@ -1141,6 +1161,7 @@ int ath_tx_aggr_start(struct ath_softc *
76         txtid->state |= AGGR_ADDBA_PROGRESS;
77         txtid->paused = true;
78         *ssn = txtid->seq_start = txtid->seq_next;
79 +       txtid->bar_index = -1;
80  
81         memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf));
82         txtid->baw_head = txtid->baw_tail = 0;