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