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 weight of ampdu in txfifo */
44#define AMPDU_DEF_TXPKT_WEIGHT		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 */
93struct 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 * txpkt_weight: weight of ampdu in txfifo; reduces rate lag
118 * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
119 * ffpld_rsvd: number of bytes to reserve for preload
120 * max_txlen: max size of ampdu per mcs, bw and sgi
121 * mfbr: enable multiple fallback rate
122 * tx_max_funl: underflows should be kept such that
123 *		(tx_max_funfl*underflows) < tx frames
124 * fifo_tb: table of fifo infos
125 */
126struct ampdu_info {
127	struct brcms_c_info *wlc;
128	int scb_handle;
129	u8 ini_enable[AMPDU_MAX_SCB_TID];
130	u8 ba_tx_wsize;
131	u8 ba_rx_wsize;
132	u8 retry_limit;
133	u8 rr_retry_limit;
134	u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
135	u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
136	u8 mpdu_density;
137	s8 max_pdu;
138	u8 dur;
139	u8 txpkt_weight;
140	u8 rx_factor;
141	u32 ffpld_rsvd;
142	u32 max_txlen[MCS_TABLE_SIZE][2][2];
143	bool mfbr;
144	u32 tx_max_funl;
145	struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
146};
147
148/* used for flushing ampdu packets */
149struct cb_del_ampdu_pars {
150	struct ieee80211_sta *sta;
151	u16 tid;
152};
153
154static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
155{
156	u32 rate, mcs;
157
158	for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
159		/* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
160		/* 20MHz, No SGI */
161		rate = mcs_2_rate(mcs, false, false);
162		ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
163		/* 40 MHz, No SGI */
164		rate = mcs_2_rate(mcs, true, false);
165		ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
166		/* 20MHz, SGI */
167		rate = mcs_2_rate(mcs, false, true);
168		ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
169		/* 40 MHz, SGI */
170		rate = mcs_2_rate(mcs, true, true);
171		ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
172	}
173}
174
175static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
176{
177	if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
178		return true;
179	else
180		return false;
181}
182
183static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
184{
185	struct brcms_c_info *wlc = ampdu->wlc;
186
187	wlc->pub->_ampdu = false;
188
189	if (on) {
190		if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
191			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
192				"nmode enabled\n", wlc->pub->unit);
193			return -ENOTSUPP;
194		}
195		if (!brcms_c_ampdu_cap(ampdu)) {
196			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
197				"ampdu capable\n", wlc->pub->unit);
198			return -ENOTSUPP;
199		}
200		wlc->pub->_ampdu = on;
201	}
202
203	return 0;
204}
205
206static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
207{
208	int i, j;
209	struct brcms_fifo_info *fifo;
210
211	for (j = 0; j < NUM_FFPLD_FIFO; j++) {
212		fifo = (ampdu->fifo_tb + j);
213		fifo->ampdu_pld_size = 0;
214		for (i = 0; i <= FFPLD_MAX_MCS; i++)
215			fifo->mcs2ampdu_table[i] = 255;
216		fifo->dmaxferrate = 0;
217		fifo->accum_txampdu = 0;
218		fifo->prev_txfunfl = 0;
219		fifo->accum_txfunfl = 0;
220
221	}
222}
223
224struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
225{
226	struct ampdu_info *ampdu;
227	int i;
228
229	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
230	if (!ampdu)
231		return NULL;
232
233	ampdu->wlc = wlc;
234
235	for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
236		ampdu->ini_enable[i] = true;
237	/* Disable ampdu for VO by default */
238	ampdu->ini_enable[PRIO_8021D_VO] = false;
239	ampdu->ini_enable[PRIO_8021D_NC] = false;
240
241	/* Disable ampdu for BK by default since not enough fifo space */
242	ampdu->ini_enable[PRIO_8021D_NONE] = false;
243	ampdu->ini_enable[PRIO_8021D_BK] = false;
244
245	ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
246	ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
247	ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
248	ampdu->max_pdu = AUTO;
249	ampdu->dur = AMPDU_MAX_DUR;
250	ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT;
251
252	ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
253	/*
254	 * bump max ampdu rcv size to 64k for all 11n
255	 * devices except 4321A0 and 4321A1
256	 */
257	if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
258		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
259	else
260		ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
261	ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
262	ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
263
264	for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
265		ampdu->retry_limit_tid[i] = ampdu->retry_limit;
266		ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
267	}
268
269	brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
270	ampdu->mfbr = false;
271	/* try to set ampdu to the default value */
272	brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
273
274	ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
275	brcms_c_ffpld_init(ampdu);
276
277	return ampdu;
278}
279
280void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
281{
282	kfree(ampdu);
283}
284
285static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
286					    struct scb *scb)
287{
288	struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
289	int i;
290
291	scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
292
293	/* go back to legacy size if some preloading is occurring */
294	for (i = 0; i < NUM_FFPLD_FIFO; i++) {
295		if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
296			scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
297	}
298
299	/* apply user override */
300	if (ampdu->max_pdu != AUTO)
301		scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
302
303	scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
304				   AMPDU_SCB_MAX_RELEASE);
305
306	if (scb_ampdu->max_rx_ampdu_bytes)
307		scb_ampdu->release = min_t(u8, scb_ampdu->release,
308			scb_ampdu->max_rx_ampdu_bytes / 1600);
309
310	scb_ampdu->release = min(scb_ampdu->release,
311				 ampdu->fifo_tb[TX_AC_BE_FIFO].
312				 mcs2ampdu_table[FFPLD_MAX_MCS]);
313}
314
315static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
316{
317	brcms_c_scb_ampdu_update_config(ampdu, &ampdu->wlc->pri_scb);
318}
319
320static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
321{
322	int i;
323	u32 phy_rate, dma_rate, tmp;
324	u8 max_mpdu;
325	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
326
327	/* recompute the dma rate */
328	/* note : we divide/multiply by 100 to avoid integer overflows */
329	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
330			 AMPDU_NUM_MPDU_LEGACY);
331	phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
332	dma_rate =
333	    (((phy_rate / 100) *
334	      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
335	     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
336	fifo->dmaxferrate = dma_rate;
337
338	/* fill up the mcs2ampdu table; do not recalc the last mcs */
339	dma_rate = dma_rate >> 7;
340	for (i = 0; i < FFPLD_MAX_MCS; i++) {
341		/* shifting to keep it within integer range */
342		phy_rate = mcs_2_rate(i, true, false) >> 7;
343		if (phy_rate > dma_rate) {
344			tmp = ((fifo->ampdu_pld_size * phy_rate) /
345			       ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
346			tmp = min_t(u32, tmp, 255);
347			fifo->mcs2ampdu_table[i] = (u8) tmp;
348		}
349	}
350}
351
352/* evaluate the dma transfer rate using the tx underflows as feedback.
353 * If necessary, increase tx fifo preloading. If not enough,
354 * decrease maximum ampdu size for each mcs till underflows stop
355 * Return 1 if pre-loading not active, -1 if not an underflow event,
356 * 0 if pre-loading module took care of the event.
357 */
358static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
359{
360	struct ampdu_info *ampdu = wlc->ampdu;
361	u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
362	u32 txunfl_ratio;
363	u8 max_mpdu;
364	u32 current_ampdu_cnt = 0;
365	u16 max_pld_size;
366	u32 new_txunfl;
367	struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
368	uint xmtfifo_sz;
369	u16 cur_txunfl;
370
371	/* return if we got here for a different reason than underflows */
372	cur_txunfl = brcms_b_read_shm(wlc->hw,
373				      M_UCODE_MACSTAT +
374				      offsetof(struct macstat, txfunfl[fid]));
375	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
376	if (new_txunfl == 0) {
377		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
378		return -1;
379	}
380	fifo->prev_txfunfl = cur_txunfl;
381
382	if (!ampdu->tx_max_funl)
383		return 1;
384
385	/* check if fifo is big enough */
386	if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
387		return -1;
388
389	if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
390		return 1;
391
392	max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
393	fifo->accum_txfunfl += new_txunfl;
394
395	/* we need to wait for at least 10 underflows */
396	if (fifo->accum_txfunfl < 10)
397		return 0;
398
399	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
400		current_ampdu_cnt, fifo->accum_txfunfl);
401
402	/*
403	   compute the current ratio of tx unfl per ampdu.
404	   When the current ampdu count becomes too
405	   big while the ratio remains small, we reset
406	   the current count in order to not
407	   introduce too big of a latency in detecting a
408	   large amount of tx underflows later.
409	 */
410
411	txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
412
413	if (txunfl_ratio > ampdu->tx_max_funl) {
414		if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
415			fifo->accum_txfunfl = 0;
416
417		return 0;
418	}
419	max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
420			 AMPDU_NUM_MPDU_LEGACY);
421
422	/* In case max value max_pdu is already lower than
423	   the fifo depth, there is nothing more we can do.
424	 */
425
426	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
427		fifo->accum_txfunfl = 0;
428		return 0;
429	}
430
431	if (fifo->ampdu_pld_size < max_pld_size) {
432
433		/* increment by TX_FIFO_PLD_INC bytes */
434		fifo->ampdu_pld_size += FFPLD_PLD_INCR;
435		if (fifo->ampdu_pld_size > max_pld_size)
436			fifo->ampdu_pld_size = max_pld_size;
437
438		/* update scb release size */
439		brcms_c_scb_ampdu_update_config_all(ampdu);
440
441		/*
442		 * compute a new dma xfer rate for max_mpdu @ max mcs.
443		 * This is the minimum dma rate that can achieve no
444		 * underflow condition for the current mpdu size.
445		 *
446		 * note : we divide/multiply by 100 to avoid integer overflows
447		 */
448		fifo->dmaxferrate =
449		    (((phy_rate / 100) *
450		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
451		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
452
453		BCMMSG(wlc->wiphy, "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
477void
478brcms_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		wiphy_err(ampdu->wlc->wiphy, "%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
501int
502brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
503	      struct sk_buff **pdu, int prec)
504{
505	struct brcms_c_info *wlc;
506	struct sk_buff *p, *pkt[AMPDU_MAX_MPDU];
507	u8 tid, ndelim;
508	int err = 0;
509	u8 preamble_type = BRCMS_GF_PREAMBLE;
510	u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
511	u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
512	u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
513
514	bool rr = true, fbr = false;
515	uint i, count = 0, fifo, seg_cnt = 0;
516	u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0;
517	u32 ampdu_len, max_ampdu_bytes = 0;
518	struct d11txh *txh = NULL;
519	u8 *plcp;
520	struct ieee80211_hdr *h;
521	struct scb *scb;
522	struct scb_ampdu *scb_ampdu;
523	struct scb_ampdu_tid_ini *ini;
524	u8 mcs = 0;
525	bool use_rts = false, use_cts = false;
526	u32 rspec = 0, rspec_fallback = 0;
527	u32 rts_rspec = 0, rts_rspec_fallback = 0;
528	u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
529	struct ieee80211_rts *rts;
530	u8 rr_retry_limit;
531	struct brcms_fifo_info *f;
532	bool fbr_iscck;
533	struct ieee80211_tx_info *tx_info;
534	u16 qlen;
535	struct wiphy *wiphy;
536
537	wlc = ampdu->wlc;
538	wiphy = wlc->wiphy;
539	p = *pdu;
540
541	tid = (u8) (p->priority);
542
543	f = ampdu->fifo_tb + prio2fifo[tid];
544
545	scb = &wlc->pri_scb;
546	scb_ampdu = &scb->scb_ampdu;
547	ini = &scb_ampdu->ini[tid];
548
549	/* Let pressure continue to build ... */
550	qlen = pktq_plen(&qi->q, prec);
551	if (ini->tx_in_transit > 0 &&
552	    qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
553		/* Collect multiple MPDU's to be sent in the next AMPDU */
554		return -EBUSY;
555
556	/* at this point we intend to transmit an AMPDU */
557	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
558	ampdu_len = 0;
559	dma_len = 0;
560	while (p) {
561		struct ieee80211_tx_rate *txrate;
562
563		tx_info = IEEE80211_SKB_CB(p);
564		txrate = tx_info->status.rates;
565
566		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
567			err = brcms_c_prep_pdu(wlc, p, &fifo);
568		} else {
569			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
570			*pdu = NULL;
571			err = 0;
572			break;
573		}
574
575		if (err) {
576			if (err == -EBUSY) {
577				wiphy_err(wiphy, "wl%d: sendampdu: "
578					  "prep_xdu retry; seq 0x%x\n",
579					  wlc->pub->unit, seq);
580				*pdu = p;
581				break;
582			}
583
584			/* error in the packet; reject it */
585			wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
586				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
587			*pdu = NULL;
588			break;
589		}
590
591		/* pkt is good to be aggregated */
592		txh = (struct d11txh *) p->data;
593		plcp = (u8 *) (txh + 1);
594		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
595		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
596		index = TX_SEQ_TO_INDEX(seq);
597
598		/* check mcl fields and test whether it can be agg'd */
599		mcl = le16_to_cpu(txh->MacTxControlLow);
600		mcl &= ~TXC_AMPDU_MASK;
601		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
602		txh->PreloadSize = 0;	/* always default to 0 */
603
604		/*  Handle retry limits */
605		if (txrate[0].count <= rr_retry_limit) {
606			txrate[0].count++;
607			rr = true;
608			fbr = false;
609		} else {
610			fbr = true;
611			rr = false;
612			txrate[1].count++;
613		}
614
615		/* extract the length info */
616		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
617		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
618
619		/* retrieve null delimiter count */
620		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
621		seg_cnt += 1;
622
623		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
624			wlc->pub->unit, count, len);
625
626		/*
627		 * aggregateable mpdu. For ucode/hw agg,
628		 * test whether need to break or change the epoch
629		 */
630		if (count == 0) {
631			mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
632			/* refill the bits since might be a retx mpdu */
633			mcl |= TXC_STARTMSDU;
634			rts = (struct ieee80211_rts *)&txh->rts_frame;
635
636			if (ieee80211_is_rts(rts->frame_control)) {
637				mcl |= TXC_SENDRTS;
638				use_rts = true;
639			}
640			if (ieee80211_is_cts(rts->frame_control)) {
641				mcl |= TXC_SENDCTS;
642				use_cts = true;
643			}
644		} else {
645			mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
646			mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
647		}
648
649		len = roundup(len, 4);
650		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
651
652		dma_len += (u16) p->len;
653
654		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
655			" seg_cnt %d null delim %d\n",
656			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
657
658		txh->MacTxControlLow = cpu_to_le16(mcl);
659
660		/* this packet is added */
661		pkt[count++] = p;
662
663		/* patch the first MPDU */
664		if (count == 1) {
665			u8 plcp0, plcp3, is40, sgi;
666			struct ieee80211_sta *sta;
667
668			sta = tx_info->control.sta;
669
670			if (rr) {
671				plcp0 = plcp[0];
672				plcp3 = plcp[3];
673			} else {
674				plcp0 = txh->FragPLCPFallback[0];
675				plcp3 = txh->FragPLCPFallback[3];
676
677			}
678			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
679			sgi = plcp3_issgi(plcp3) ? 1 : 0;
680			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
681			max_ampdu_bytes =
682			    min(scb_ampdu->max_rx_ampdu_bytes,
683				ampdu->max_txlen[mcs][is40][sgi]);
684
685			if (is40)
686				mimo_ctlchbw =
687				   CHSPEC_SB_UPPER(wlc_phy_chanspec_get(
688								 wlc->band->pi))
689				   ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ;
690
691			/* rebuild the rspec and rspec_fallback */
692			rspec = RSPEC_MIMORATE;
693			rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
694			if (plcp[0] & MIMO_PLCP_40MHZ)
695				rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
696
697			if (fbr_iscck)	/* CCK */
698				rspec_fallback = cck_rspec(cck_phy2mac_rate
699						    (txh->FragPLCPFallback[0]));
700			else {	/* MIMO */
701				rspec_fallback = RSPEC_MIMORATE;
702				rspec_fallback |=
703				    txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
704				if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
705					rspec_fallback |=
706					    (PHY_TXC1_BW_40MHZ <<
707					     RSPEC_BW_SHIFT);
708			}
709
710			if (use_rts || use_cts) {
711				rts_rspec =
712				    brcms_c_rspec_to_rts_rspec(wlc,
713					rspec, false, mimo_ctlchbw);
714				rts_rspec_fallback =
715				    brcms_c_rspec_to_rts_rspec(wlc,
716					rspec_fallback, false, mimo_ctlchbw);
717			}
718		}
719
720		/* if (first mpdu for host agg) */
721		/* test whether to add more */
722		if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) &&
723		    (count == f->mcs2ampdu_table[mcs])) {
724			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
725				" ampdu at %d for mcs %d\n",
726				wlc->pub->unit, count, mcs);
727			break;
728		}
729
730		if (count == scb_ampdu->max_pdu)
731			break;
732
733		/*
734		 * check to see if the next pkt is
735		 * a candidate for aggregation
736		 */
737		p = pktq_ppeek(&qi->q, prec);
738		/* tx_info must be checked with current p */
739		tx_info = IEEE80211_SKB_CB(p);
740
741		if (p) {
742			if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
743			    ((u8) (p->priority) == tid)) {
744				plen = p->len + AMPDU_MAX_MPDU_OVERHEAD;
745				plen = max(scb_ampdu->min_len, plen);
746
747				if ((plen + ampdu_len) > max_ampdu_bytes) {
748					p = NULL;
749					continue;
750				}
751
752				/*
753				 * check if there are enough
754				 * descriptors available
755				 */
756				if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
757					wiphy_err(wiphy, "%s: No fifo space  "
758						  "!!\n", __func__);
759					p = NULL;
760					continue;
761				}
762				p = brcmu_pktq_pdeq(&qi->q, prec);
763			} else {
764				p = NULL;
765			}
766		}
767	}			/* end while(p) */
768
769	ini->tx_in_transit += count;
770
771	if (count) {
772		/* patch up the last txh */
773		txh = (struct d11txh *) pkt[count - 1]->data;
774		mcl = le16_to_cpu(txh->MacTxControlLow);
775		mcl &= ~TXC_AMPDU_MASK;
776		mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
777		txh->MacTxControlLow = cpu_to_le16(mcl);
778
779		/* remove the null delimiter after last mpdu */
780		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
781		txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
782		ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
783
784		/* remove the pad len from last mpdu */
785		fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
786		len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback)
787		    : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
788		ampdu_len -= roundup(len, 4) - len;
789
790		/* patch up the first txh & plcp */
791		txh = (struct d11txh *) pkt[0]->data;
792		plcp = (u8 *) (txh + 1);
793
794		BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len);
795		/* mark plcp to indicate ampdu */
796		BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
797
798		/* reset the mixed mode header durations */
799		if (txh->MModeLen) {
800			u16 mmodelen =
801			    brcms_c_calc_lsig_len(wlc, rspec, ampdu_len);
802			txh->MModeLen = cpu_to_le16(mmodelen);
803			preamble_type = BRCMS_MM_PREAMBLE;
804		}
805		if (txh->MModeFbrLen) {
806			u16 mmfbrlen =
807			    brcms_c_calc_lsig_len(wlc, rspec_fallback,
808						  ampdu_len);
809			txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
810			fbr_preamble_type = BRCMS_MM_PREAMBLE;
811		}
812
813		/* set the preload length */
814		if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
815			dma_len = min(dma_len, f->ampdu_pld_size);
816			txh->PreloadSize = cpu_to_le16(dma_len);
817		} else
818			txh->PreloadSize = 0;
819
820		mch = le16_to_cpu(txh->MacTxControlHigh);
821
822		/* update RTS dur fields */
823		if (use_rts || use_cts) {
824			u16 durid;
825			rts = (struct ieee80211_rts *)&txh->rts_frame;
826			if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
827			    TXC_PREAMBLE_RTS_MAIN_SHORT)
828				rts_preamble_type = BRCMS_SHORT_PREAMBLE;
829
830			if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
831			    TXC_PREAMBLE_RTS_FB_SHORT)
832				rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
833
834			durid =
835			    brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
836						   rspec, rts_preamble_type,
837						   preamble_type, ampdu_len,
838						   true);
839			rts->duration = cpu_to_le16(durid);
840			durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
841						       rts_rspec_fallback,
842						       rspec_fallback,
843						       rts_fbr_preamble_type,
844						       fbr_preamble_type,
845						       ampdu_len, true);
846			txh->RTSDurFallback = cpu_to_le16(durid);
847			/* set TxFesTimeNormal */
848			txh->TxFesTimeNormal = rts->duration;
849			/* set fallback rate version of TxFesTimeNormal */
850			txh->TxFesTimeFallback = txh->RTSDurFallback;
851		}
852
853		/* set flag and plcp for fallback rate */
854		if (fbr) {
855			mch |= TXC_AMPDU_FBR;
856			txh->MacTxControlHigh = cpu_to_le16(mch);
857			BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
858			BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
859		}
860
861		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
862			wlc->pub->unit, count, ampdu_len);
863
864		/* inform rate_sel if it this is a rate probe pkt */
865		frameid = le16_to_cpu(txh->TxFrameID);
866		if (frameid & TXFID_RATE_PROBE_MASK)
867			wiphy_err(wiphy, "%s: XXX what to do with "
868				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
869
870		for (i = 0; i < count; i++)
871			brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1),
872				   ampdu->txpkt_weight);
873
874	}
875	/* endif (count) */
876	return err;
877}
878
879static void
880brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
881			  struct ieee80211_tx_info *tx_info,
882			  struct tx_status *txs, u8 mcs)
883{
884	struct ieee80211_tx_rate *txrate = tx_info->status.rates;
885	int i;
886
887	/* clear the rest of the rates */
888	for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
889		txrate[i].idx = -1;
890		txrate[i].count = 0;
891	}
892}
893
894static void
895brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
896			      struct sk_buff *p, struct tx_status *txs,
897			      u32 s1, u32 s2)
898{
899	struct scb_ampdu *scb_ampdu;
900	struct brcms_c_info *wlc = ampdu->wlc;
901	struct scb_ampdu_tid_ini *ini;
902	u8 bitmap[8], queue, tid;
903	struct d11txh *txh;
904	u8 *plcp;
905	struct ieee80211_hdr *h;
906	u16 seq, start_seq = 0, bindex, index, mcl;
907	u8 mcs = 0;
908	bool ba_recd = false, ack_recd = false;
909	u8 suc_mpdu = 0, tot_mpdu = 0;
910	uint supr_status;
911	bool update_rate = true, retry = true, tx_error = false;
912	u16 mimoantsel = 0;
913	u8 antselid = 0;
914	u8 retry_limit, rr_retry_limit;
915	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
916	struct wiphy *wiphy = wlc->wiphy;
917
918#ifdef DEBUG
919	u8 hole[AMPDU_MAX_MPDU];
920	memset(hole, 0, sizeof(hole));
921#endif
922
923	scb_ampdu = &scb->scb_ampdu;
924	tid = (u8) (p->priority);
925
926	ini = &scb_ampdu->ini[tid];
927	retry_limit = ampdu->retry_limit_tid[tid];
928	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
929	memset(bitmap, 0, sizeof(bitmap));
930	queue = txs->frameid & TXFID_QUEUE_MASK;
931	supr_status = txs->status & TX_STATUS_SUPR_MASK;
932
933	if (txs->status & TX_STATUS_ACK_RCV) {
934		if (TX_STATUS_SUPR_UF == supr_status)
935			update_rate = false;
936
937		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
938		start_seq = txs->sequence >> SEQNUM_SHIFT;
939		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
940		    TX_STATUS_BA_BMAP03_SHIFT;
941
942		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
943		WARN_ON(!(s1 & TX_STATUS_AMPDU));
944
945		bitmap[0] |=
946		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
947		    TX_STATUS_BA_BMAP47_SHIFT;
948		bitmap[1] = (s1 >> 8) & 0xff;
949		bitmap[2] = (s1 >> 16) & 0xff;
950		bitmap[3] = (s1 >> 24) & 0xff;
951
952		bitmap[4] = s2 & 0xff;
953		bitmap[5] = (s2 >> 8) & 0xff;
954		bitmap[6] = (s2 >> 16) & 0xff;
955		bitmap[7] = (s2 >> 24) & 0xff;
956
957		ba_recd = true;
958	} else {
959		if (supr_status) {
960			update_rate = false;
961			if (supr_status == TX_STATUS_SUPR_BADCH) {
962				wiphy_err(wiphy,
963					  "%s: Pkt tx suppressed, illegal channel possibly %d\n",
964					  __func__, CHSPEC_CHANNEL(
965					  wlc->default_bss->chanspec));
966			} else {
967				if (supr_status != TX_STATUS_SUPR_FRAG)
968					wiphy_err(wiphy, "%s: supr_status 0x%x\n",
969						  __func__, supr_status);
970			}
971			/* no need to retry for badch; will fail again */
972			if (supr_status == TX_STATUS_SUPR_BADCH ||
973			    supr_status == TX_STATUS_SUPR_EXPTIME) {
974				retry = false;
975			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
976				/* TX underflow:
977				 *   try tuning pre-loading or ampdu size
978				 */
979			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
980				/*
981				 * if there were underflows, but pre-loading
982				 * is not active, notify rate adaptation.
983				 */
984				if (brcms_c_ffpld_check_txfunfl(wlc,
985					prio2fifo[tid]) > 0)
986					tx_error = true;
987			}
988		} else if (txs->phyerr) {
989			update_rate = false;
990			wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
991				  __func__, txs->phyerr);
992
993			if (brcm_msg_level & LOG_ERROR_VAL) {
994				brcmu_prpkt("txpkt (AMPDU)", p);
995				brcms_c_print_txdesc((struct d11txh *) p->data);
996			}
997			brcms_c_print_txstatus(txs);
998		}
999	}
1000
1001	/* loop through all pkts and retry if not acked */
1002	while (p) {
1003		tx_info = IEEE80211_SKB_CB(p);
1004		txh = (struct d11txh *) p->data;
1005		mcl = le16_to_cpu(txh->MacTxControlLow);
1006		plcp = (u8 *) (txh + 1);
1007		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1008		seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1009
1010		if (tot_mpdu == 0) {
1011			mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1012			mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
1013		}
1014
1015		index = TX_SEQ_TO_INDEX(seq);
1016		ack_recd = false;
1017		if (ba_recd) {
1018			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1019			BCMMSG(wiphy,
1020			       "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
1021			       tid, seq, start_seq, bindex,
1022			       isset(bitmap, bindex), index);
1023			/* if acked then clear bit and free packet */
1024			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1025			    && isset(bitmap, bindex)) {
1026				ini->tx_in_transit--;
1027				ini->txretry[index] = 0;
1028
1029				/*
1030				 * ampdu_ack_len:
1031				 *   number of acked aggregated frames
1032				 */
1033				/* ampdu_len: number of aggregated frames */
1034				brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1035							  mcs);
1036				tx_info->flags |= IEEE80211_TX_STAT_ACK;
1037				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1038				tx_info->status.ampdu_ack_len =
1039					tx_info->status.ampdu_len = 1;
1040
1041				skb_pull(p, D11_PHY_HDR_LEN);
1042				skb_pull(p, D11_TXH_LEN);
1043
1044				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1045							    p);
1046				ack_recd = true;
1047				suc_mpdu++;
1048			}
1049		}
1050		/* either retransmit or send bar if ack not recd */
1051		if (!ack_recd) {
1052			if (retry && (ini->txretry[index] < (int)retry_limit)) {
1053				ini->txretry[index]++;
1054				ini->tx_in_transit--;
1055				/*
1056				 * Use high prededence for retransmit to
1057				 * give some punch
1058				 */
1059				brcms_c_txq_enq(wlc, scb, p,
1060						BRCMS_PRIO_TO_HI_PREC(tid));
1061			} else {
1062				/* Retry timeout */
1063				ini->tx_in_transit--;
1064				ieee80211_tx_info_clear_status(tx_info);
1065				tx_info->status.ampdu_ack_len = 0;
1066				tx_info->status.ampdu_len = 1;
1067				tx_info->flags |=
1068				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
1069				skb_pull(p, D11_PHY_HDR_LEN);
1070				skb_pull(p, D11_TXH_LEN);
1071				BCMMSG(wiphy,
1072				       "BA Timeout, seq %d, in_transit %d\n",
1073				       seq, ini->tx_in_transit);
1074				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1075							    p);
1076			}
1077		}
1078		tot_mpdu++;
1079
1080		/* break out if last packet of ampdu */
1081		if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1082		    TXC_AMPDU_LAST)
1083			break;
1084
1085		p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
1086	}
1087	brcms_c_send_q(wlc);
1088
1089	/* update rate state */
1090	antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1091
1092	brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1093}
1094
1095void
1096brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1097		     struct sk_buff *p, struct tx_status *txs)
1098{
1099	struct scb_ampdu *scb_ampdu;
1100	struct brcms_c_info *wlc = ampdu->wlc;
1101	struct scb_ampdu_tid_ini *ini;
1102	u32 s1 = 0, s2 = 0;
1103	struct ieee80211_tx_info *tx_info;
1104
1105	tx_info = IEEE80211_SKB_CB(p);
1106
1107	/* BMAC_NOTE: For the split driver, second level txstatus comes later
1108	 * So if the ACK was received then wait for the second level else just
1109	 * call the first one
1110	 */
1111	if (txs->status & TX_STATUS_ACK_RCV) {
1112		u8 status_delay = 0;
1113
1114		/* wait till the next 8 bytes of txstatus is available */
1115		s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
1116		while ((s1 & TXS_V) == 0) {
1117			udelay(1);
1118			status_delay++;
1119			if (status_delay > 10)
1120				return; /* error condition */
1121			s1 = bcma_read32(wlc->hw->d11core,
1122					 D11REGOFFS(frmtxstatus));
1123		}
1124
1125		s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
1126	}
1127
1128	if (scb) {
1129		scb_ampdu = &scb->scb_ampdu;
1130		ini = &scb_ampdu->ini[p->priority];
1131		brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
1132	} else {
1133		/* loop through all pkts and free */
1134		u8 queue = txs->frameid & TXFID_QUEUE_MASK;
1135		struct d11txh *txh;
1136		u16 mcl;
1137		while (p) {
1138			tx_info = IEEE80211_SKB_CB(p);
1139			txh = (struct d11txh *) p->data;
1140			mcl = le16_to_cpu(txh->MacTxControlLow);
1141			brcmu_pkt_buf_free_skb(p);
1142			/* break out if last packet of ampdu */
1143			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1144			    TXC_AMPDU_LAST)
1145				break;
1146			p = dma_getnexttxp(wlc->hw->di[queue],
1147					   DMA_RANGE_TRANSMITTED);
1148		}
1149		brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
1150	}
1151}
1152
1153void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
1154{
1155	char template[T_RAM_ACCESS_SZ * 2];
1156
1157	/* driver needs to write the ta in the template; ta is at offset 16 */
1158	memset(template, 0, sizeof(template));
1159	memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
1160	brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
1161				  (T_RAM_ACCESS_SZ * 2),
1162				  template);
1163}
1164
1165bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
1166{
1167	return wlc->ampdu->ini_enable[tid];
1168}
1169
1170void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1171{
1172	struct brcms_c_info *wlc = ampdu->wlc;
1173
1174	/*
1175	 * Extend ucode internal watchdog timer to
1176	 * match larger received frames
1177	 */
1178	if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
1179	    IEEE80211_HT_MAX_AMPDU_64K) {
1180		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
1181		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
1182	} else {
1183		brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
1184		brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
1185	}
1186}
1187
1188/*
1189 * callback function that helps flushing ampdu packets from a priority queue
1190 */
1191static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1192{
1193	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1194	struct cb_del_ampdu_pars *ampdu_pars =
1195				 (struct cb_del_ampdu_pars *)arg_a;
1196	bool rc;
1197
1198	rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1199	rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL ||
1200		    tx_info->control.sta == ampdu_pars->sta);
1201	rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1202	return rc;
1203}
1204
1205/*
1206 * callback function that helps invalidating ampdu packets in a DMA queue
1207 */
1208static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1209{
1210	struct ieee80211_sta *sta = arg_a;
1211	struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
1212
1213	if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1214	    (tx_info->control.sta == sta || sta == NULL))
1215		tx_info->control.sta = NULL;
1216}
1217
1218/*
1219 * When a remote party is no longer available for ampdu communication, any
1220 * pending tx ampdu packets in the driver have to be flushed.
1221 */
1222void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1223		     struct ieee80211_sta *sta, u16 tid)
1224{
1225	struct brcms_txq_info *qi = wlc->pkt_queue;
1226	struct pktq *pq = &qi->q;
1227	int prec;
1228	struct cb_del_ampdu_pars ampdu_pars;
1229
1230	ampdu_pars.sta = sta;
1231	ampdu_pars.tid = tid;
1232	for (prec = 0; prec < pq->num_prec; prec++)
1233		brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1234			    (void *)&ampdu_pars);
1235	brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
1236}
1237