ea5d5b793d7f749c6a86ae4165bd1d51518fdc37
[openwrt.git] / package / mac80211 / patches / 570-ath9k_fix_max_aggr_duration.patch
1 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
2 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
3 @@ -298,6 +298,7 @@ struct ath_tx {
4         struct ath_descdma txdma;
5         struct ath_txq *txq_map[WME_NUM_AC];
6         u32 txq_max_pending[WME_NUM_AC];
7 +       u16 max_aggr_framelen[WME_NUM_AC][4][32];
8  };
9  
10  struct ath_rx_edma {
11 @@ -342,6 +343,7 @@ int ath_tx_init(struct ath_softc *sc, in
12  void ath_tx_cleanup(struct ath_softc *sc);
13  int ath_txq_update(struct ath_softc *sc, int qnum,
14                    struct ath9k_tx_queue_info *q);
15 +void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
16  int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
17                  struct ath_tx_control *txctl);
18  void ath_tx_tasklet(struct ath_softc *sc);
19 --- a/drivers/net/wireless/ath/ath9k/xmit.c
20 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
21 @@ -29,6 +29,8 @@
22  #define HT_LTF(_ns)             (4 * (_ns))
23  #define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
24  #define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
25 +#define TIME_SYMBOLS(t)         ((t) >> 2)
26 +#define TIME_SYMBOLS_HALFGI(t)  (((t) * 5 - 4) / 18)
27  #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
28  #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
29  
30 @@ -74,33 +76,6 @@ enum {
31         MCS_HT40_SGI,
32  };
33  
34 -static int ath_max_4ms_framelen[4][32] = {
35 -       [MCS_HT20] = {
36 -               3212,  6432,  9648,  12864,  19300,  25736,  28952,  32172,
37 -               6424,  12852, 19280, 25708,  38568,  51424,  57852,  64280,
38 -               9628,  19260, 28896, 38528,  57792,  65532,  65532,  65532,
39 -               12828, 25656, 38488, 51320,  65532,  65532,  65532,  65532,
40 -       },
41 -       [MCS_HT20_SGI] = {
42 -               3572,  7144,  10720,  14296,  21444,  28596,  32172,  35744,
43 -               7140,  14284, 21428,  28568,  42856,  57144,  64288,  65532,
44 -               10700, 21408, 32112,  42816,  64228,  65532,  65532,  65532,
45 -               14256, 28516, 42780,  57040,  65532,  65532,  65532,  65532,
46 -       },
47 -       [MCS_HT40] = {
48 -               6680,  13360,  20044,  26724,  40092,  53456,  60140,  65532,
49 -               13348, 26700,  40052,  53400,  65532,  65532,  65532,  65532,
50 -               20004, 40008,  60016,  65532,  65532,  65532,  65532,  65532,
51 -               26644, 53292,  65532,  65532,  65532,  65532,  65532,  65532,
52 -       },
53 -       [MCS_HT40_SGI] = {
54 -               7420,  14844,  22272,  29696,  44544,  59396,  65532,  65532,
55 -               14832, 29668,  44504,  59340,  65532,  65532,  65532,  65532,
56 -               22232, 44464,  65532,  65532,  65532,  65532,  65532,  65532,
57 -               29616, 59232,  65532,  65532,  65532,  65532,  65532,  65532,
58 -       }
59 -};
60 -
61  /*********************/
62  /* Aggregation logic */
63  /*********************/
64 @@ -648,6 +623,7 @@ static u32 ath_lookup_rate(struct ath_so
65         struct ieee80211_tx_rate *rates;
66         u32 max_4ms_framelen, frmlen;
67         u16 aggr_limit, bt_aggr_limit, legacy = 0;
68 +       int q = tid->ac->txq->mac80211_qnum;
69         int i;
70  
71         skb = bf->bf_mpdu;
72 @@ -680,7 +656,7 @@ static u32 ath_lookup_rate(struct ath_so
73                 if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
74                         modeidx++;
75  
76 -               frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx];
77 +               frmlen = sc->tx.max_aggr_framelen[q][modeidx][rates[i].idx];
78                 max_4ms_framelen = min(max_4ms_framelen, frmlen);
79         }
80  
81 @@ -927,6 +903,44 @@ static u32 ath_pkt_duration(struct ath_s
82         return duration;
83  }
84  
85 +static int ath_max_framelen(int usec, int mcs, bool ht40, bool sgi)
86 +{
87 +       int streams = HT_RC_2_STREAMS(mcs);
88 +       int symbols, bits;
89 +       int bytes = 0;
90 +
91 +       symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec);
92 +       bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams;
93 +       bits -= OFDM_PLCP_BITS;
94 +       bytes = bits / 8;
95 +       bytes -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
96 +       if (bytes > 65532)
97 +               bytes = 65532;
98 +
99 +       return bytes;
100 +}
101 +
102 +void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop)
103 +{
104 +       u16 *cur_ht20, *cur_ht20_sgi, *cur_ht40, *cur_ht40_sgi;
105 +       int mcs;
106 +
107 +       /* 4ms is the default (and maximum) duration */
108 +       if (!txop || txop > 4096)
109 +               txop = 4096;
110 +
111 +       cur_ht20 = sc->tx.max_aggr_framelen[queue][MCS_HT20];
112 +       cur_ht20_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT20_SGI];
113 +       cur_ht40 = sc->tx.max_aggr_framelen[queue][MCS_HT40];
114 +       cur_ht40_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT40_SGI];
115 +       for (mcs = 0; mcs < 32; mcs++) {
116 +               cur_ht20[mcs] = ath_max_framelen(txop, mcs, false, false);
117 +               cur_ht20_sgi[mcs] = ath_max_framelen(txop, mcs, false, true);
118 +               cur_ht40[mcs] = ath_max_framelen(txop, mcs, true, false);
119 +               cur_ht40_sgi[mcs] = ath_max_framelen(txop, mcs, true, true);
120 +       }
121 +}
122 +
123  static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
124                              struct ath_tx_info *info, int len)
125  {
126 --- a/drivers/net/wireless/ath/ath9k/main.c
127 +++ b/drivers/net/wireless/ath/ath9k/main.c
128 @@ -1366,6 +1366,7 @@ static int ath9k_conf_tx(struct ieee8021
129                 queue, txq->axq_qnum, params->aifs, params->cw_min,
130                 params->cw_max, params->txop);
131  
132 +       ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
133         ret = ath_txq_update(sc, txq->axq_qnum, &qi);
134         if (ret)
135                 ath_err(common, "TXQ Update failed\n");