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