0b4a490a03970a8128cc296796ee7258293111a9
[platform/kernel/linux-rpi.git] / drivers / net / wireless / brcm80211 / brcmsmac / ampdu.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
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
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 #include <net/mac80211.h>
17
18 #include "rate.h"
19 #include "scb.h"
20 #include "phy/phy_hal.h"
21 #include "antsel.h"
22 #include "main.h"
23 #include "ampdu.h"
24
25 /* max number of mpdus in an ampdu */
26 #define AMPDU_MAX_MPDU                  32
27 /* max number of mpdus in an ampdu to a legacy */
28 #define AMPDU_NUM_MPDU_LEGACY           16
29 /* max Tx ba window size (in pdu) */
30 #define AMPDU_TX_BA_MAX_WSIZE           64
31 /* default Tx ba window size (in pdu) */
32 #define AMPDU_TX_BA_DEF_WSIZE           64
33 /* default Rx ba window size (in pdu) */
34 #define AMPDU_RX_BA_DEF_WSIZE           64
35 /* max Rx ba window size (in pdu) */
36 #define AMPDU_RX_BA_MAX_WSIZE           64
37 /* max dur of tx ampdu (in msec) */
38 #define AMPDU_MAX_DUR                   5
39 /* default tx retry limit */
40 #define AMPDU_DEF_RETRY_LIMIT           5
41 /* default tx retry limit at reg rate */
42 #define AMPDU_DEF_RR_RETRY_LIMIT        2
43 /* default ffpld reserved bytes */
44 #define AMPDU_DEF_FFPLD_RSVD            2048
45 /* # of inis to be freed on detach */
46 #define AMPDU_INI_FREE                  10
47 /* max # of mpdus released at a time */
48 #define AMPDU_SCB_MAX_RELEASE           20
49
50 #define NUM_FFPLD_FIFO 4        /* number of fifo concerned by pre-loading */
51 #define FFPLD_TX_MAX_UNFL   200 /* default value of the average number of ampdu
52                                  * without underflows
53                                  */
54 #define FFPLD_MPDU_SIZE 1800    /* estimate of maximum mpdu size */
55 #define FFPLD_MAX_MCS 23        /* we don't deal with mcs 32 */
56 #define FFPLD_PLD_INCR 1000     /* increments in bytes */
57 #define FFPLD_MAX_AMPDU_CNT 5000        /* maximum number of ampdu we
58                                          * accumulate between resets.
59                                          */
60
61 #define AMPDU_DELIMITER_LEN     4
62
63 /* max allowed number of mpdus in an ampdu (2 streams) */
64 #define AMPDU_NUM_MPDU          16
65
66 #define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
67
68 /* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
69 #define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
70         AMPDU_DELIMITER_LEN + 3\
71         + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
72
73 /* modulo add/sub, bound = 2^k */
74 #define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
75 #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
76
77 /* structure to hold tx fifo information and pre-loading state
78  * counters specific to tx underflows of ampdus
79  * some counters might be redundant with the ones in wlc or ampdu structures.
80  * This allows to maintain a specific state independently of
81  * how often and/or when the wlc counters are updated.
82  *
83  * ampdu_pld_size: number of bytes to be pre-loaded
84  * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
85  * prev_txfunfl: num of underflows last read from the HW macstats counter
86  * accum_txfunfl: num of underflows since we modified pld params
87  * accum_txampdu: num of tx ampdu since we modified pld params
88  * prev_txampdu: previous reading of tx ampdu
89  * dmaxferrate: estimated dma avg xfer rate in kbits/sec
90  */
91 struct brcms_fifo_info {
92         u16 ampdu_pld_size;
93         u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
94         u16 prev_txfunfl;
95         u32 accum_txfunfl;
96         u32 accum_txampdu;
97         u32 prev_txampdu;
98         u32 dmaxferrate;
99 };
100
101 /* AMPDU module specific state
102  *
103  * wlc: pointer to main wlc structure
104  * scb_handle: scb cubby handle to retrieve data from scb
105  * ini_enable: per-tid initiator enable/disable of ampdu
106  * ba_tx_wsize: Tx ba window size (in pdu)
107  * ba_rx_wsize: Rx ba window size (in pdu)
108  * retry_limit: mpdu transmit retry limit
109  * rr_retry_limit: mpdu transmit retry limit at regular rate
110  * retry_limit_tid: per-tid mpdu transmit retry limit
111  * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
112  * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
113  * max_pdu: max pdus allowed in ampdu
114  * dur: max duration of an ampdu (in msec)
115  * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
116  * ffpld_rsvd: number of bytes to reserve for preload
117  * max_txlen: max size of ampdu per mcs, bw and sgi
118  * mfbr: enable multiple fallback rate
119  * tx_max_funl: underflows should be kept such that
120  *              (tx_max_funfl*underflows) < tx frames
121  * fifo_tb: table of fifo infos
122  */
123 struct ampdu_info {
124         struct brcms_c_info *wlc;
125         int scb_handle;
126         u8 ini_enable[AMPDU_MAX_SCB_TID];
127         u8 ba_tx_wsize;
128         u8 ba_rx_wsize;
129         u8 retry_limit;
130         u8 rr_retry_limit;
131         u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
132         u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
133         u8 mpdu_density;
134         s8 max_pdu;
135         u8 dur;
136         u8 rx_factor;
137         u32 ffpld_rsvd;
138         u32 max_txlen[MCS_TABLE_SIZE][2][2];
139         bool mfbr;
140         u32 tx_max_funl;
141         struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
142 };
143
144 /* used for flushing ampdu packets */
145 struct cb_del_ampdu_pars {
146         struct ieee80211_sta *sta;
147         u16 tid;
148 };
149
150 static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
151 {
152         u32 rate, mcs;
153
154         for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
155                 /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
156                 /* 20MHz, No SGI */
157                 rate = mcs_2_rate(mcs, false, false);
158                 ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
159                 /* 40 MHz, No SGI */
160                 rate = mcs_2_rate(mcs, true, false);
161                 ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
162                 /* 20MHz, SGI */
163                 rate = mcs_2_rate(mcs, false, true);
164                 ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
165                 /* 40 MHz, SGI */
166                 rate = mcs_2_rate(mcs, true, true);
167                 ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
168         }
169 }
170
171 static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
172 {
173         if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
174                 return true;
175         else
176                 return false;
177 }
178
179 static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
180 {
181         struct brcms_c_info *wlc = ampdu->wlc;
182
183         wlc->pub->_ampdu = false;
184
185         if (on) {
186                 if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
187                         wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
188                                 "nmode enabled\n", wlc->pub->unit);
189                         return -ENOTSUPP;
190                 }
191                 if (!brcms_c_ampdu_cap(ampdu)) {
192                         wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
193                                 "ampdu capable\n", wlc->pub->unit);
194                         return -ENOTSUPP;
195                 }
196                 wlc->pub->_ampdu = on;
197         }
198
199         return 0;
200 }
201
202 static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
203 {
204         int i, j;
205         struct brcms_fifo_info *fifo;
206
207         for (j = 0; j < NUM_FFPLD_FIFO; j++) {
208                 fifo = (ampdu->fifo_tb + j);
209                 fifo->ampdu_pld_size = 0;
210                 for (i = 0; i <= FFPLD_MAX_MCS; i++)
211                         fifo->mcs2ampdu_table[i] = 255;
212                 fifo->dmaxferrate = 0;
213                 fifo->accum_txampdu = 0;
214                 fifo->prev_txfunfl = 0;
215                 fifo->accum_txfunfl = 0;
216
217         }
218 }
219
220 struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
221 {
222         struct ampdu_info *ampdu;
223         int i;
224
225         ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
226         if (!ampdu)
227                 return NULL;
228
229         ampdu->wlc = wlc;
230
231         for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
232                 ampdu->ini_enable[i] = true;
233         /* Disable ampdu for VO by default */
234         ampdu->ini_enable[PRIO_8021D_VO] = false;
235         ampdu->ini_enable[PRIO_8021D_NC] = false;
236
237         /* Disable ampdu for BK by default since not enough fifo space */
238         ampdu->ini_enable[PRIO_8021D_NONE] = false;
239         ampdu->ini_enable[PRIO_8021D_BK] = false;
240
241         ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
242         ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
243         ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
244         ampdu->max_pdu = AUTO;
245         ampdu->dur = AMPDU_MAX_DUR;
246
247         ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
248         /*
249          * bump max ampdu rcv size to 64k for all 11n
250          * devices except 4321A0 and 4321A1
251          */
252         if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
253                 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
254         else
255                 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
256         ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
257         ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
258
259         for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
260                 ampdu->retry_limit_tid[i] = ampdu->retry_limit;
261                 ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
262         }
263
264         brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
265         ampdu->mfbr = false;
266         /* try to set ampdu to the default value */
267         brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
268
269         ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
270         brcms_c_ffpld_init(ampdu);
271
272         return ampdu;
273 }
274
275 void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
276 {
277         kfree(ampdu);
278 }
279
280 static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
281                                             struct scb *scb)
282 {
283         struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
284         int i;
285
286         scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
287
288         /* go back to legacy size if some preloading is occurring */
289         for (i = 0; i < NUM_FFPLD_FIFO; i++) {
290                 if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
291                         scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
292         }
293
294         /* apply user override */
295         if (ampdu->max_pdu != AUTO)
296                 scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
297
298         scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
299                                    AMPDU_SCB_MAX_RELEASE);
300
301         if (scb_ampdu->max_rx_ampdu_bytes)
302                 scb_ampdu->release = min_t(u8, scb_ampdu->release,
303                         scb_ampdu->max_rx_ampdu_bytes / 1600);
304
305         scb_ampdu->release = min(scb_ampdu->release,
306                                  ampdu->fifo_tb[TX_AC_BE_FIFO].
307                                  mcs2ampdu_table[FFPLD_MAX_MCS]);
308 }
309
310 static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
311 {
312         brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
313 }
314
315 static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
316 {
317         int i;
318         u32 phy_rate, dma_rate, tmp;
319         u8 max_mpdu;
320         struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
321
322         /* recompute the dma rate */
323         /* note : we divide/multiply by 100 to avoid integer overflows */
324         max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
325                          AMPDU_NUM_MPDU_LEGACY);
326         phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
327         dma_rate =
328             (((phy_rate / 100) *
329               (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
330              / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
331         fifo->dmaxferrate = dma_rate;
332
333         /* fill up the mcs2ampdu table; do not recalc the last mcs */
334         dma_rate = dma_rate >> 7;
335         for (i = 0; i < FFPLD_MAX_MCS; i++) {
336                 /* shifting to keep it within integer range */
337                 phy_rate = mcs_2_rate(i, true, false) >> 7;
338                 if (phy_rate > dma_rate) {
339                         tmp = ((fifo->ampdu_pld_size * phy_rate) /
340                                ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
341                         tmp = min_t(u32, tmp, 255);
342                         fifo->mcs2ampdu_table[i] = (u8) tmp;
343                 }
344         }
345 }
346
347 /* evaluate the dma transfer rate using the tx underflows as feedback.
348  * If necessary, increase tx fifo preloading. If not enough,
349  * decrease maximum ampdu size for each mcs till underflows stop
350  * Return 1 if pre-loading not active, -1 if not an underflow event,
351  * 0 if pre-loading module took care of the event.
352  */
353 static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
354 {
355         struct ampdu_info *ampdu = wlc->ampdu;
356         u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
357         u32 txunfl_ratio;
358         u8 max_mpdu;
359         u32 current_ampdu_cnt = 0;
360         u16 max_pld_size;
361         u32 new_txunfl;
362         struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
363         uint xmtfifo_sz;
364         u16 cur_txunfl;
365
366         /* return if we got here for a different reason than underflows */
367         cur_txunfl = brcms_b_read_shm(wlc->hw,
368                                       M_UCODE_MACSTAT +
369                                       offsetof(struct macstat, txfunfl[fid]));
370         new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
371         if (new_txunfl == 0) {
372                 BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
373                 return -1;
374         }
375         fifo->prev_txfunfl = cur_txunfl;
376
377         if (!ampdu->tx_max_funl)
378                 return 1;
379
380         /* check if fifo is big enough */
381         if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
382                 return -1;
383
384         if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
385                 return 1;
386
387         max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
388         fifo->accum_txfunfl += new_txunfl;
389
390         /* we need to wait for at least 10 underflows */
391         if (fifo->accum_txfunfl < 10)
392                 return 0;
393
394         BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
395                 current_ampdu_cnt, fifo->accum_txfunfl);
396
397         /*
398            compute the current ratio of tx unfl per ampdu.
399            When the current ampdu count becomes too
400            big while the ratio remains small, we reset
401            the current count in order to not
402            introduce too big of a latency in detecting a
403            large amount of tx underflows later.
404          */
405
406         txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
407
408         if (txunfl_ratio > ampdu->tx_max_funl) {
409                 if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
410                         fifo->accum_txfunfl = 0;
411
412                 return 0;
413         }
414         max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
415                          AMPDU_NUM_MPDU_LEGACY);
416
417         /* In case max value max_pdu is already lower than
418            the fifo depth, there is nothing more we can do.
419          */
420
421         if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
422                 fifo->accum_txfunfl = 0;
423                 return 0;
424         }
425
426         if (fifo->ampdu_pld_size < max_pld_size) {
427
428                 /* increment by TX_FIFO_PLD_INC bytes */
429                 fifo->ampdu_pld_size += FFPLD_PLD_INCR;
430                 if (fifo->ampdu_pld_size > max_pld_size)
431                         fifo->ampdu_pld_size = max_pld_size;
432
433                 /* update scb release size */
434                 brcms_c_scb_ampdu_update_config_all(ampdu);
435
436                 /*
437                  * compute a new dma xfer rate for max_mpdu @ max mcs.
438                  * This is the minimum dma rate that can achieve no
439                  * underflow condition for the current mpdu size.
440                  *
441                  * note : we divide/multiply by 100 to avoid integer overflows
442                  */
443                 fifo->dmaxferrate =
444                     (((phy_rate / 100) *
445                       (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
446                      / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
447
448                 BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
449                         "pre-load size %d\n",
450                         fifo->dmaxferrate, fifo->ampdu_pld_size);
451         } else {
452
453                 /* decrease ampdu size */
454                 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
455                         if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
456                                 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
457                                     AMPDU_NUM_MPDU_LEGACY - 1;
458                         else
459                                 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
460
461                         /* recompute the table */
462                         brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
463
464                         /* update scb release size */
465                         brcms_c_scb_ampdu_update_config_all(ampdu);
466                 }
467         }
468         fifo->accum_txfunfl = 0;
469         return 0;
470 }
471
472 void
473 brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
474         u8 ba_wsize,            /* negotiated ba window size (in pdu) */
475         uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
476 {
477         struct scb_ampdu *scb_ampdu;
478         struct scb_ampdu_tid_ini *ini;
479         struct ampdu_info *ampdu = wlc->ampdu;
480         struct scb *scb = &wlc->pri_scb;
481         scb_ampdu = &scb->scb_ampdu;
482
483         if (!ampdu->ini_enable[tid]) {
484                 wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
485                           __func__, tid);
486                 return;
487         }
488
489         ini = &scb_ampdu->ini[tid];
490         ini->tid = tid;
491         ini->scb = scb_ampdu->scb;
492         ini->ba_wsize = ba_wsize;
493         scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
494 }
495
496 void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
497                                  struct brcms_c_info *wlc)
498 {
499         session->wlc = wlc;
500         skb_queue_head_init(&session->skb_list);
501         session->max_ampdu_len = 0;    /* determined from first MPDU */
502         session->max_ampdu_frames = 0; /* determined from first MPDU */
503         session->ampdu_len = 0;
504         session->dma_len = 0;
505 }
506
507 /*
508  * Preps the given packet for AMPDU based on the session data. If the
509  * frame cannot be accomodated in the current session, -ENOSPC is
510  * returned.
511  */
512 int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
513                             struct sk_buff *p)
514 {
515         struct brcms_c_info *wlc = session->wlc;
516         struct ampdu_info *ampdu = wlc->ampdu;
517         struct scb *scb = &wlc->pri_scb;
518         struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
519         struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
520         struct ieee80211_tx_rate *txrate = tx_info->status.rates;
521         struct d11txh *txh = (struct d11txh *)p->data;
522         unsigned ampdu_frames;
523         u8 ndelim, tid;
524         u8 *plcp;
525         uint len;
526         u16 mcl;
527         bool fbr_iscck;
528         bool rr;
529
530         ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
531         plcp = (u8 *)(txh + 1);
532         fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
533         len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
534                           BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
535         len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN;
536
537         ampdu_frames = skb_queue_len(&session->skb_list);
538         if (ampdu_frames != 0) {
539                 struct sk_buff *first;
540
541                 if (ampdu_frames + 1 > session->max_ampdu_frames ||
542                     session->ampdu_len + len > session->max_ampdu_len)
543                         return -ENOSPC;
544
545                 /*
546                  * We aren't really out of space if the new frame is of
547                  * a different priority, but we want the same behaviour
548                  * so return -ENOSPC anyway.
549                  *
550                  * XXX: The old AMPDU code did this, but is it really
551                  * necessary?
552                  */
553                 first = skb_peek(&session->skb_list);
554                 if (p->priority != first->priority)
555                         return -ENOSPC;
556         }
557
558         /*
559          * Now that we're sure this frame can be accomodated, update the
560          * session information.
561          */
562         session->ampdu_len += len;
563         session->dma_len += p->len;
564
565         tid = (u8)p->priority;
566
567         /* Handle retry limits */
568         if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) {
569                 txrate[0].count++;
570                 rr = true;
571         } else {
572                 txrate[1].count++;
573                 rr = false;
574         }
575
576         if (ampdu_frames == 0) {
577                 u8 plcp0, plcp3, is40, sgi, mcs;
578                 uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
579                 struct brcms_fifo_info *f = &ampdu->fifo_tb[fifo];
580
581                 if (rr) {
582                         plcp0 = plcp[0];
583                         plcp3 = plcp[3];
584                 } else {
585                         plcp0 = txh->FragPLCPFallback[0];
586                         plcp3 = txh->FragPLCPFallback[3];
587
588                 }
589
590                 /* Limit AMPDU size based on MCS */
591                 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
592                 sgi = plcp3_issgi(plcp3) ? 1 : 0;
593                 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
594                 session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes,
595                                              ampdu->max_txlen[mcs][is40][sgi]);
596
597                 session->max_ampdu_frames = scb_ampdu->max_pdu;
598                 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
599                         session->max_ampdu_frames =
600                                 min_t(u16, f->mcs2ampdu_table[mcs],
601                                       session->max_ampdu_frames);
602                 }
603         }
604
605         /*
606          * Treat all frames as "middle" frames of AMPDU here. First and
607          * last frames must be fixed up after all MPDUs have been prepped.
608          */
609         mcl = le16_to_cpu(txh->MacTxControlLow);
610         mcl &= ~TXC_AMPDU_MASK;
611         mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
612         mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
613         txh->MacTxControlLow = cpu_to_le16(mcl);
614         txh->PreloadSize = 0;   /* always default to 0 */
615
616         skb_queue_tail(&session->skb_list, p);
617
618         return 0;
619 }
620
621 void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
622 {
623         struct brcms_c_info *wlc = session->wlc;
624         struct ampdu_info *ampdu = wlc->ampdu;
625         struct sk_buff *first, *last;
626         struct d11txh *txh;
627         struct ieee80211_tx_info *tx_info;
628         struct ieee80211_tx_rate *txrate;
629         u8 ndelim;
630         u8 *plcp;
631         uint len;
632         uint fifo;
633         struct brcms_fifo_info *f;
634         u16 mcl;
635         bool fbr;
636         bool fbr_iscck;
637         struct ieee80211_rts *rts;
638         bool use_rts = false, use_cts = false;
639         u16 dma_len = session->dma_len;
640         u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
641         u32 rspec = 0, rspec_fallback = 0;
642         u32 rts_rspec = 0, rts_rspec_fallback = 0;
643         u8 plcp0, plcp3, is40, sgi, mcs;
644         u16 mch;
645         u8 preamble_type = BRCMS_GF_PREAMBLE;
646         u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
647         u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
648         u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
649
650         if (skb_queue_empty(&session->skb_list))
651                 return;
652
653         first = skb_peek(&session->skb_list);
654         last = skb_peek_tail(&session->skb_list);
655
656         /* Need to fix up last MPDU first to adjust AMPDU length */
657         txh = (struct d11txh *)last->data;
658         fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
659         f = &ampdu->fifo_tb[fifo];
660
661         mcl = le16_to_cpu(txh->MacTxControlLow);
662         mcl &= ~TXC_AMPDU_MASK;
663         mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
664         txh->MacTxControlLow = cpu_to_le16(mcl);
665
666         /* remove the null delimiter after last mpdu */
667         ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
668         txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
669         session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
670
671         /* remove the pad len from last mpdu */
672         fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
673         len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
674                           BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
675         session->ampdu_len -= roundup(len, 4) - len;
676
677         /* Now fix up the first MPDU */
678         tx_info = IEEE80211_SKB_CB(first);
679         txrate = tx_info->status.rates;
680         txh = (struct d11txh *)first->data;
681         plcp = (u8 *)(txh + 1);
682         rts = (struct ieee80211_rts *)&txh->rts_frame;
683
684         mcl = le16_to_cpu(txh->MacTxControlLow);
685         /* If only one MPDU leave it marked as last */
686         if (first != last) {
687                 mcl &= ~TXC_AMPDU_MASK;
688                 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
689         }
690         mcl |= TXC_STARTMSDU;
691         if (ieee80211_is_rts(rts->frame_control)) {
692                 mcl |= TXC_SENDRTS;
693                 use_rts = true;
694         }
695         if (ieee80211_is_cts(rts->frame_control)) {
696                 mcl |= TXC_SENDCTS;
697                 use_cts = true;
698         }
699         txh->MacTxControlLow = cpu_to_le16(mcl);
700
701         fbr = txrate[1].count > 0;
702         if (!fbr) {
703                 plcp0 = plcp[0];
704                 plcp3 = plcp[3];
705         } else {
706                 plcp0 = txh->FragPLCPFallback[0];
707                 plcp3 = txh->FragPLCPFallback[3];
708         }
709         is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
710         sgi = plcp3_issgi(plcp3) ? 1 : 0;
711         mcs = plcp0 & ~MIMO_PLCP_40MHZ;
712
713         if (is40) {
714                 if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi)))
715                         mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP;
716                 else
717                         mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
718         }
719
720         /* rebuild the rspec and rspec_fallback */
721         rspec = RSPEC_MIMORATE;
722         rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
723         if (plcp[0] & MIMO_PLCP_40MHZ)
724                 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
725
726         fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
727         if (fbr_iscck) {
728                 rspec_fallback =
729                         cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0]));
730         } else {
731                 rspec_fallback = RSPEC_MIMORATE;
732                 rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
733                 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
734                         rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT;
735         }
736
737         if (use_rts || use_cts) {
738                 rts_rspec =
739                         brcms_c_rspec_to_rts_rspec(wlc, rspec,
740                                                    false, mimo_ctlchbw);
741                 rts_rspec_fallback =
742                         brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback,
743                                                    false, mimo_ctlchbw);
744         }
745
746         BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len);
747         /* mark plcp to indicate ampdu */
748         BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
749
750         /* reset the mixed mode header durations */
751         if (txh->MModeLen) {
752                 u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec,
753                                                      session->ampdu_len);
754                 txh->MModeLen = cpu_to_le16(mmodelen);
755                 preamble_type = BRCMS_MM_PREAMBLE;
756         }
757         if (txh->MModeFbrLen) {
758                 u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback,
759                                                      session->ampdu_len);
760                 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
761                 fbr_preamble_type = BRCMS_MM_PREAMBLE;
762         }
763
764         /* set the preload length */
765         if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
766                 dma_len = min(dma_len, f->ampdu_pld_size);
767                 txh->PreloadSize = cpu_to_le16(dma_len);
768         } else {
769                 txh->PreloadSize = 0;
770         }
771
772         mch = le16_to_cpu(txh->MacTxControlHigh);
773
774         /* update RTS dur fields */
775         if (use_rts || use_cts) {
776                 u16 durid;
777                 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
778                     TXC_PREAMBLE_RTS_MAIN_SHORT)
779                         rts_preamble_type = BRCMS_SHORT_PREAMBLE;
780
781                 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
782                      TXC_PREAMBLE_RTS_FB_SHORT)
783                         rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
784
785                 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
786                                                    rspec, rts_preamble_type,
787                                                    preamble_type,
788                                                    session->ampdu_len, true);
789                 rts->duration = cpu_to_le16(durid);
790                 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
791                                                    rts_rspec_fallback,
792                                                    rspec_fallback,
793                                                    rts_fbr_preamble_type,
794                                                    fbr_preamble_type,
795                                                    session->ampdu_len, true);
796                 txh->RTSDurFallback = cpu_to_le16(durid);
797                 /* set TxFesTimeNormal */
798                 txh->TxFesTimeNormal = rts->duration;
799                 /* set fallback rate version of TxFesTimeNormal */
800                 txh->TxFesTimeFallback = txh->RTSDurFallback;
801         }
802
803         /* set flag and plcp for fallback rate */
804         if (fbr) {
805                 mch |= TXC_AMPDU_FBR;
806                 txh->MacTxControlHigh = cpu_to_le16(mch);
807                 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
808                 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
809         }
810
811         BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
812                 wlc->pub->unit, skb_queue_len(&session->skb_list),
813                 session->ampdu_len);
814 }
815
816 int
817 brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
818               struct sk_buff **pdu, int prec)
819 {
820         struct brcms_c_info *wlc;
821         struct sk_buff *p;
822         struct brcms_ampdu_session session;
823         int err = 0;
824         u8 tid;
825
826         uint count, fifo, seg_cnt = 0;
827         struct scb *scb;
828         struct scb_ampdu *scb_ampdu;
829         struct scb_ampdu_tid_ini *ini;
830         struct ieee80211_tx_info *tx_info;
831         u16 qlen;
832         struct wiphy *wiphy;
833
834         wlc = ampdu->wlc;
835         wiphy = wlc->wiphy;
836         p = *pdu;
837
838         tid = (u8) (p->priority);
839
840         scb = &wlc->pri_scb;
841         scb_ampdu = &scb->scb_ampdu;
842         ini = &scb_ampdu->ini[tid];
843
844         /* Let pressure continue to build ... */
845         qlen = pktq_plen(&qi->q, prec);
846         if (ini->tx_in_transit > 0 &&
847             qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
848                 /* Collect multiple MPDU's to be sent in the next AMPDU */
849                 return -EBUSY;
850
851         /* at this point we intend to transmit an AMPDU */
852         brcms_c_ampdu_reset_session(&session, wlc);
853
854         while (p) {
855                 struct ieee80211_tx_rate *txrate;
856
857                 tx_info = IEEE80211_SKB_CB(p);
858                 txrate = tx_info->status.rates;
859
860                 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
861                         err = brcms_c_prep_pdu(wlc, p, &fifo);
862                 } else {
863                         wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
864                         *pdu = NULL;
865                         err = 0;
866                         break;
867                 }
868
869                 if (err) {
870                         if (err == -EBUSY) {
871                                 wiphy_err(wiphy, "wl%d: sendampdu: "
872                                           "prep_xdu retry\n", wlc->pub->unit);
873                                 *pdu = p;
874                                 break;
875                         }
876
877                         /* error in the packet; reject it */
878                         wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
879                                   "rejected\n", wlc->pub->unit);
880                         *pdu = NULL;
881                         break;
882                 }
883
884                 err = brcms_c_ampdu_add_frame(&session, p);
885                 if (err == -ENOSPC) {
886                         /*
887                          * No space for this packet in the AMPDU.
888                          * Requeue packet and proceed;
889                          */
890                         *pdu = p;
891                         break;
892                 } else if (err) {
893                         /* Unexpected error; reject packet */
894                         wiphy_err(wiphy, "wl%d: sendampdu: add_frame rejected",
895                                   wlc->pub->unit);
896                         *pdu = NULL;
897                         break;
898                 }
899
900                 seg_cnt += 1;
901
902                 /*
903                  * check to see if the next pkt is
904                  * a candidate for aggregation
905                  */
906                 p = pktq_ppeek(&qi->q, prec);
907                 if (p) {
908                         tx_info = IEEE80211_SKB_CB(p);
909                         if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
910                                 /*
911                                  * check if there are enough
912                                  * descriptors available
913                                  */
914                                 if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
915                                         wiphy_err(wiphy, "%s: No fifo space "
916                                                   "!!\n", __func__);
917                                         p = NULL;
918                                         continue;
919                                 }
920                                 /* next packet fit for aggregation so dequeue */
921                                 p = brcmu_pktq_pdeq(&qi->q, prec);
922                         } else {
923                                 p = NULL;
924                         }
925                 }
926         }                       /* end while(p) */
927
928         count = skb_queue_len(&session.skb_list);
929         ini->tx_in_transit += count;
930
931         if (count) {
932                 /* patch up first and last txh's */
933                 brcms_c_ampdu_finalize(&session);
934
935                 while ((p = skb_dequeue(&session.skb_list)) != NULL)
936                         brcms_c_txfifo(wlc, fifo, p,
937                                        skb_queue_empty(&session.skb_list));
938         }
939         /* endif (count) */
940         return err;
941 }
942
943 static void
944 brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
945                           struct ieee80211_tx_info *tx_info,
946                           struct tx_status *txs, u8 mcs)
947 {
948         struct ieee80211_tx_rate *txrate = tx_info->status.rates;
949         int i;
950
951         /* clear the rest of the rates */
952         for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
953                 txrate[i].idx = -1;
954                 txrate[i].count = 0;
955         }
956 }
957
958 static void
959 brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
960                               struct sk_buff *p, struct tx_status *txs,
961                               u32 s1, u32 s2)
962 {
963         struct scb_ampdu *scb_ampdu;
964         struct brcms_c_info *wlc = ampdu->wlc;
965         struct scb_ampdu_tid_ini *ini;
966         u8 bitmap[8], queue, tid;
967         struct d11txh *txh;
968         u8 *plcp;
969         struct ieee80211_hdr *h;
970         u16 seq, start_seq = 0, bindex, index, mcl;
971         u8 mcs = 0;
972         bool ba_recd = false, ack_recd = false;
973         u8 suc_mpdu = 0, tot_mpdu = 0;
974         uint supr_status;
975         bool update_rate = true, retry = true, tx_error = false;
976         u16 mimoantsel = 0;
977         u8 antselid = 0;
978         u8 retry_limit, rr_retry_limit;
979         struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
980         struct wiphy *wiphy = wlc->wiphy;
981
982 #ifdef DEBUG
983         u8 hole[AMPDU_MAX_MPDU];
984         memset(hole, 0, sizeof(hole));
985 #endif
986
987         scb_ampdu = &scb->scb_ampdu;
988         tid = (u8) (p->priority);
989
990         ini = &scb_ampdu->ini[tid];
991         retry_limit = ampdu->retry_limit_tid[tid];
992         rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
993         memset(bitmap, 0, sizeof(bitmap));
994         queue = txs->frameid & TXFID_QUEUE_MASK;
995         supr_status = txs->status & TX_STATUS_SUPR_MASK;
996
997         if (txs->status & TX_STATUS_ACK_RCV) {
998                 if (TX_STATUS_SUPR_UF == supr_status)
999                         update_rate = false;
1000
1001                 WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
1002                 start_seq = txs->sequence >> SEQNUM_SHIFT;
1003                 bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
1004                     TX_STATUS_BA_BMAP03_SHIFT;
1005
1006                 WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
1007                 WARN_ON(!(s1 & TX_STATUS_AMPDU));
1008
1009                 bitmap[0] |=
1010                     (s1 & TX_STATUS_BA_BMAP47_MASK) <<
1011                     TX_STATUS_BA_BMAP47_SHIFT;
1012                 bitmap[1] = (s1 >> 8) & 0xff;
1013                 bitmap[2] = (s1 >> 16) & 0xff;
1014                 bitmap[3] = (s1 >> 24) & 0xff;
1015
1016                 bitmap[4] = s2 & 0xff;
1017                 bitmap[5] = (s2 >> 8) & 0xff;
1018                 bitmap[6] = (s2 >> 16) & 0xff;
1019                 bitmap[7] = (s2 >> 24) & 0xff;
1020
1021                 ba_recd = true;
1022         } else {
1023                 if (supr_status) {
1024                         update_rate = false;
1025                         if (supr_status == TX_STATUS_SUPR_BADCH) {
1026                                 wiphy_err(wiphy,
1027                                           "%s: Pkt tx suppressed, illegal channel possibly %d\n",
1028                                           __func__, CHSPEC_CHANNEL(
1029                                           wlc->default_bss->chanspec));
1030                         } else {
1031                                 if (supr_status != TX_STATUS_SUPR_FRAG)
1032                                         wiphy_err(wiphy, "%s: supr_status 0x%x\n",
1033                                                   __func__, supr_status);
1034                         }
1035                         /* no need to retry for badch; will fail again */
1036                         if (supr_status == TX_STATUS_SUPR_BADCH ||
1037                             supr_status == TX_STATUS_SUPR_EXPTIME) {
1038                                 retry = false;
1039                         } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
1040                                 /* TX underflow:
1041                                  *   try tuning pre-loading or ampdu size
1042                                  */
1043                         } else if (supr_status == TX_STATUS_SUPR_FRAG) {
1044                                 /*
1045                                  * if there were underflows, but pre-loading
1046                                  * is not active, notify rate adaptation.
1047                                  */
1048                                 if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0)
1049                                         tx_error = true;
1050                         }
1051                 } else if (txs->phyerr) {
1052                         update_rate = false;
1053                         wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
1054                                   __func__, txs->phyerr);
1055
1056                         if (brcm_msg_level & LOG_ERROR_VAL) {
1057                                 brcmu_prpkt("txpkt (AMPDU)", p);
1058                                 brcms_c_print_txdesc((struct d11txh *) p->data);
1059                         }
1060                         brcms_c_print_txstatus(txs);
1061                 }
1062         }
1063
1064         /* loop through all pkts and retry if not acked */
1065         while (p) {
1066                 tx_info = IEEE80211_SKB_CB(p);
1067                 txh = (struct d11txh *) p->data;
1068                 mcl = le16_to_cpu(txh->MacTxControlLow);
1069                 plcp = (u8 *) (txh + 1);
1070                 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1071                 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1072
1073                 if (tot_mpdu == 0) {
1074                         mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1075                         mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
1076                 }
1077
1078                 index = TX_SEQ_TO_INDEX(seq);
1079                 ack_recd = false;
1080                 if (ba_recd) {
1081                         bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1082                         BCMMSG(wiphy,
1083                                "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
1084                                tid, seq, start_seq, bindex,
1085                                isset(bitmap, bindex), index);
1086                         /* if acked then clear bit and free packet */
1087                         if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1088                             && isset(bitmap, bindex)) {
1089                                 ini->tx_in_transit--;
1090                                 ini->txretry[index] = 0;
1091
1092                                 /*
1093                                  * ampdu_ack_len:
1094                                  *   number of acked aggregated frames
1095                                  */
1096                                 /* ampdu_len: number of aggregated frames */
1097                                 brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1098                                                           mcs);
1099                                 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1100                                 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1101                                 tx_info->status.ampdu_ack_len =
1102                                         tx_info->status.ampdu_len = 1;
1103
1104                                 skb_pull(p, D11_PHY_HDR_LEN);
1105                                 skb_pull(p, D11_TXH_LEN);
1106
1107                                 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1108                                                             p);
1109                                 ack_recd = true;
1110                                 suc_mpdu++;
1111                         }
1112                 }
1113                 /* either retransmit or send bar if ack not recd */
1114                 if (!ack_recd) {
1115                         if (retry && (ini->txretry[index] < (int)retry_limit)) {
1116                                 ini->txretry[index]++;
1117                                 ini->tx_in_transit--;
1118                                 brcms_c_txq_enq(wlc, scb, p);
1119                         } else {
1120                                 /* Retry timeout */
1121                                 ini->tx_in_transit--;
1122                                 ieee80211_tx_info_clear_status(tx_info);
1123                                 tx_info->status.ampdu_ack_len = 0;
1124                                 tx_info->status.ampdu_len = 1;
1125                                 tx_info->flags |=
1126                                     IEEE80211_TX_STAT_AMPDU_NO_BACK;
1127                                 skb_pull(p, D11_PHY_HDR_LEN);
1128                                 skb_pull(p, D11_TXH_LEN);
1129                                 BCMMSG(wiphy,
1130                                        "BA Timeout, seq %d, in_transit %d\n",
1131                                        seq, ini->tx_in_transit);
1132                                 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1133                                                             p);
1134                         }
1135                 }
1136                 tot_mpdu++;
1137
1138                 /* break out if last packet of ampdu */
1139                 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1140                     TXC_AMPDU_LAST)
1141                         break;
1142
1143                 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
1144         }
1145         brcms_c_send_q(wlc);
1146
1147         /* update rate state */
1148         antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1149
1150         brcms_c_txfifo_complete(wlc, queue);
1151 }
1152
1153 void
1154 brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1155                      struct sk_buff *p, struct tx_status *txs)
1156 {
1157         struct scb_ampdu *scb_ampdu;
1158         struct brcms_c_info *wlc = ampdu->wlc;
1159         struct scb_ampdu_tid_ini *ini;
1160         u32 s1 = 0, s2 = 0;
1161         struct ieee80211_tx_info *tx_info;
1162
1163         tx_info = IEEE80211_SKB_CB(p);
1164
1165         /* BMAC_NOTE: For the split driver, second level txstatus comes later
1166          * So if the ACK was received then wait for the second level else just
1167          * call the first one
1168          */
1169         if (txs->status & TX_STATUS_ACK_RCV) {
1170                 u8 status_delay = 0;
1171
1172                 /* wait till the next 8 bytes of txstatus is available */
1173                 s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
1174                 while ((s1 & TXS_V) == 0) {
1175                         udelay(1);
1176                         status_delay++;
1177                         if (status_delay > 10)
1178                                 return; /* error condition */
1179                         s1 = bcma_read32(wlc->hw->d11core,
1180                                          D11REGOFFS(frmtxstatus));
1181                 }
1182
1183                 s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
1184         }
1185
1186         if (scb) {
1187                 scb_ampdu = &scb->scb_ampdu;
1188                 ini = &scb_ampdu->ini[p->priority];
1189                 brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
1190         } else {
1191                 /* loop through all pkts and free */
1192                 u8 queue = txs->frameid & TXFID_QUEUE_MASK;
1193                 struct d11txh *txh;
1194                 u16 mcl;
1195                 while (p) {
1196                         tx_info = IEEE80211_SKB_CB(p);
1197                         txh = (struct d11txh *) p->data;
1198                         mcl = le16_to_cpu(txh->MacTxControlLow);
1199                         brcmu_pkt_buf_free_skb(p);
1200                         /* break out if last packet of ampdu */
1201                         if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1202                             TXC_AMPDU_LAST)
1203                                 break;
1204                         p = dma_getnexttxp(wlc->hw->di[queue],
1205                                            DMA_RANGE_TRANSMITTED);
1206                 }
1207                 brcms_c_txfifo_complete(wlc, queue);
1208         }
1209 }
1210
1211 void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
1212 {
1213         char template[T_RAM_ACCESS_SZ * 2];
1214
1215         /* driver needs to write the ta in the template; ta is at offset 16 */
1216         memset(template, 0, sizeof(template));
1217         memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
1218         brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
1219                                   (T_RAM_ACCESS_SZ * 2),
1220                                   template);
1221 }
1222
1223 bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
1224 {
1225         return wlc->ampdu->ini_enable[tid];
1226 }
1227
1228 void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1229 {
1230         struct brcms_c_info *wlc = ampdu->wlc;
1231
1232         /*
1233          * Extend ucode internal watchdog timer to
1234          * match larger received frames
1235          */
1236         if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
1237             IEEE80211_HT_MAX_AMPDU_64K) {
1238                 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
1239                 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
1240         } else {
1241                 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
1242                 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
1243         }
1244 }
1245
1246 /*
1247  * callback function that helps flushing ampdu packets from a priority queue
1248  */
1249 static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1250 {
1251         struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1252         struct cb_del_ampdu_pars *ampdu_pars =
1253                                  (struct cb_del_ampdu_pars *)arg_a;
1254         bool rc;
1255
1256         rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1257         rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL ||
1258                     tx_info->rate_driver_data[0] == ampdu_pars->sta);
1259         rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1260         return rc;
1261 }
1262
1263 /*
1264  * callback function that helps invalidating ampdu packets in a DMA queue
1265  */
1266 static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1267 {
1268         struct ieee80211_sta *sta = arg_a;
1269         struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
1270
1271         if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1272             (tx_info->rate_driver_data[0] == sta || sta == NULL))
1273                 tx_info->rate_driver_data[0] = NULL;
1274 }
1275
1276 /*
1277  * When a remote party is no longer available for ampdu communication, any
1278  * pending tx ampdu packets in the driver have to be flushed.
1279  */
1280 void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1281                      struct ieee80211_sta *sta, u16 tid)
1282 {
1283         struct brcms_txq_info *qi = wlc->pkt_queue;
1284         struct pktq *pq = &qi->q;
1285         int prec;
1286         struct cb_del_ampdu_pars ampdu_pars;
1287
1288         ampdu_pars.sta = sta;
1289         ampdu_pars.tid = tid;
1290         for (prec = 0; prec < pq->num_prec; prec++)
1291                 brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1292                             (void *)&ampdu_pars);
1293         brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
1294 }