1218159Sadrian/*-
2218159Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
3218159Sadrian * All rights reserved.
4218159Sadrian *
5218159Sadrian * Redistribution and use in source and binary forms, with or without
6218159Sadrian * modification, are permitted provided that the following conditions
7218159Sadrian * are met:
8218159Sadrian * 1. Redistributions of source code must retain the above copyright
9218159Sadrian *    notice, this list of conditions and the following disclaimer,
10218159Sadrian *    without modification.
11218159Sadrian * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12218159Sadrian *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13218159Sadrian *    redistribution must be conditioned upon including a substantially
14218159Sadrian *    similar Disclaimer requirement for further binary redistribution.
15218159Sadrian *
16218159Sadrian * NO WARRANTY
17218159Sadrian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18218159Sadrian * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19218159Sadrian * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20218159Sadrian * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21218159Sadrian * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22218159Sadrian * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23218159Sadrian * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24218159Sadrian * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25218159Sadrian * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26218159Sadrian * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27218159Sadrian * THE POSSIBILITY OF SUCH DAMAGES.
28218159Sadrian */
29218159Sadrian
30218159Sadrian#include <sys/cdefs.h>
31218159Sadrian__FBSDID("$FreeBSD$");
32218159Sadrian
33218159Sadrian#include "opt_inet.h"
34218159Sadrian#include "opt_ath.h"
35218159Sadrian#include "opt_wlan.h"
36218159Sadrian
37218159Sadrian#include <sys/param.h>
38218159Sadrian#include <sys/systm.h>
39218159Sadrian#include <sys/sysctl.h>
40218159Sadrian#include <sys/mbuf.h>
41218159Sadrian#include <sys/malloc.h>
42218159Sadrian#include <sys/lock.h>
43218159Sadrian#include <sys/mutex.h>
44218159Sadrian#include <sys/kernel.h>
45218159Sadrian#include <sys/socket.h>
46218159Sadrian#include <sys/sockio.h>
47218159Sadrian#include <sys/errno.h>
48218159Sadrian#include <sys/callout.h>
49218159Sadrian#include <sys/bus.h>
50218159Sadrian#include <sys/endian.h>
51218159Sadrian#include <sys/kthread.h>
52218159Sadrian#include <sys/taskqueue.h>
53218159Sadrian#include <sys/priv.h>
54218159Sadrian
55218159Sadrian#include <machine/bus.h>
56218159Sadrian
57218159Sadrian#include <net/if.h>
58218159Sadrian#include <net/if_dl.h>
59218159Sadrian#include <net/if_media.h>
60218159Sadrian#include <net/if_types.h>
61218159Sadrian#include <net/if_arp.h>
62218159Sadrian#include <net/ethernet.h>
63218159Sadrian#include <net/if_llc.h>
64218159Sadrian
65218159Sadrian#include <net80211/ieee80211_var.h>
66218159Sadrian#include <net80211/ieee80211_regdomain.h>
67218159Sadrian#ifdef IEEE80211_SUPPORT_SUPERG
68218159Sadrian#include <net80211/ieee80211_superg.h>
69218159Sadrian#endif
70218159Sadrian#ifdef IEEE80211_SUPPORT_TDMA
71218159Sadrian#include <net80211/ieee80211_tdma.h>
72218159Sadrian#endif
73218159Sadrian
74218159Sadrian#include <net/bpf.h>
75218159Sadrian
76218159Sadrian#ifdef INET
77218159Sadrian#include <netinet/in.h>
78218159Sadrian#include <netinet/if_ether.h>
79218159Sadrian#endif
80218159Sadrian
81218159Sadrian#include <dev/ath/if_athvar.h>
82218159Sadrian#include <dev/ath/ath_hal/ah_devid.h>		/* XXX for softled */
83218159Sadrian#include <dev/ath/ath_hal/ah_diagcodes.h>
84218159Sadrian
85218159Sadrian#ifdef ATH_TX99_DIAG
86218159Sadrian#include <dev/ath/ath_tx99/ath_tx99.h>
87218159Sadrian#endif
88218159Sadrian
89227364Sadrian#include <dev/ath/if_ath_tx.h>		/* XXX for some support functions */
90218159Sadrian#include <dev/ath/if_ath_tx_ht.h>
91227364Sadrian#include <dev/ath/if_athrate.h>
92227364Sadrian#include <dev/ath/if_ath_debug.h>
93218159Sadrian
94218159Sadrian/*
95227364Sadrian * XXX net80211?
96227364Sadrian */
97227364Sadrian#define	IEEE80211_AMPDU_SUBFRAME_DEFAULT		32
98227364Sadrian
99237171Sadrian#define	ATH_AGGR_DELIM_SZ	4	/* delimiter size */
100227364Sadrian#define	ATH_AGGR_MINPLEN	256	/* in bytes, minimum packet length */
101237171Sadrian/* number of delimiters for encryption padding */
102237171Sadrian#define	ATH_AGGR_ENCRYPTDELIM	10
103227364Sadrian
104227364Sadrian/*
105227364Sadrian * returns delimiter padding required given the packet length
106227364Sadrian */
107227364Sadrian#define	ATH_AGGR_GET_NDELIM(_len)					\
108227364Sadrian	    (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?	\
109227364Sadrian	    (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
110227364Sadrian
111227364Sadrian#define	PADBYTES(_len)		((4 - ((_len) % 4)) % 4)
112227364Sadrian
113227364Sadrianint ath_max_4ms_framelen[4][32] = {
114227364Sadrian	[MCS_HT20] = {
115227364Sadrian		3212,  6432,  9648,  12864,  19300,  25736,  28952,  32172,
116227364Sadrian		6424,  12852, 19280, 25708,  38568,  51424,  57852,  64280,
117227364Sadrian		9628,  19260, 28896, 38528,  57792,  65532,  65532,  65532,
118227364Sadrian		12828, 25656, 38488, 51320,  65532,  65532,  65532,  65532,
119227364Sadrian	},
120227364Sadrian	[MCS_HT20_SGI] = {
121227364Sadrian		3572,  7144,  10720,  14296,  21444,  28596,  32172,  35744,
122227364Sadrian		7140,  14284, 21428,  28568,  42856,  57144,  64288,  65532,
123227364Sadrian		10700, 21408, 32112,  42816,  64228,  65532,  65532,  65532,
124227364Sadrian		14256, 28516, 42780,  57040,  65532,  65532,  65532,  65532,
125227364Sadrian	},
126227364Sadrian	[MCS_HT40] = {
127227364Sadrian		6680,  13360,  20044,  26724,  40092,  53456,  60140,  65532,
128227364Sadrian		13348, 26700,  40052,  53400,  65532,  65532,  65532,  65532,
129227364Sadrian		20004, 40008,  60016,  65532,  65532,  65532,  65532,  65532,
130227364Sadrian		26644, 53292,  65532,  65532,  65532,  65532,  65532,  65532,
131227364Sadrian	},
132227364Sadrian	[MCS_HT40_SGI] = {
133227364Sadrian		7420,  14844,  22272,  29696,  44544,  59396,  65532,  65532,
134227364Sadrian		14832, 29668,  44504,  59340,  65532,  65532,  65532,  65532,
135227364Sadrian		22232, 44464,  65532,  65532,  65532,  65532,  65532,  65532,
136227364Sadrian		29616, 59232,  65532,  65532,  65532,  65532,  65532,  65532,
137227364Sadrian	}
138227364Sadrian};
139227364Sadrian
140227364Sadrian/*
141227364Sadrian * XXX should be in net80211
142227364Sadrian */
143227364Sadrianstatic int ieee80211_mpdudensity_map[] = {
144227364Sadrian	0,		/* IEEE80211_HTCAP_MPDUDENSITY_NA */
145227364Sadrian	25,		/* IEEE80211_HTCAP_MPDUDENSITY_025 */
146227364Sadrian	50,		/* IEEE80211_HTCAP_MPDUDENSITY_05 */
147227364Sadrian	100,		/* IEEE80211_HTCAP_MPDUDENSITY_1 */
148227364Sadrian	200,		/* IEEE80211_HTCAP_MPDUDENSITY_2 */
149227364Sadrian	400,		/* IEEE80211_HTCAP_MPDUDENSITY_4 */
150227364Sadrian	800,		/* IEEE80211_HTCAP_MPDUDENSITY_8 */
151227364Sadrian	1600,		/* IEEE80211_HTCAP_MPDUDENSITY_16 */
152227364Sadrian};
153227364Sadrian
154227364Sadrian/*
155227364Sadrian * XXX should be in the HAL/net80211 ?
156227364Sadrian */
157227364Sadrian#define	BITS_PER_BYTE		8
158227364Sadrian#define	OFDM_PLCP_BITS		22
159227364Sadrian#define	HT_RC_2_MCS(_rc)	((_rc) & 0x7f)
160227364Sadrian#define	HT_RC_2_STREAMS(_rc)	((((_rc) & 0x78) >> 3) + 1)
161227364Sadrian#define	L_STF			8
162227364Sadrian#define	L_LTF			8
163227364Sadrian#define	L_SIG			4
164227364Sadrian#define	HT_SIG			8
165227364Sadrian#define	HT_STF			4
166227364Sadrian#define	HT_LTF(_ns)		(4 * (_ns))
167227364Sadrian#define	SYMBOL_TIME(_ns)	((_ns) << 2)		// ns * 4 us
168227364Sadrian#define	SYMBOL_TIME_HALFGI(_ns)	(((_ns) * 18 + 4) / 5)	// ns * 3.6 us
169227364Sadrian#define	NUM_SYMBOLS_PER_USEC(_usec)	(_usec >> 2)
170227364Sadrian#define	NUM_SYMBOLS_PER_USEC_HALFGI(_usec)	(((_usec*5)-4)/18)
171227364Sadrian#define	IS_HT_RATE(_rate)	((_rate) & 0x80)
172227364Sadrian
173227364Sadrianconst uint32_t bits_per_symbol[][2] = {
174227364Sadrian    /* 20MHz 40MHz */
175227364Sadrian    {    26,   54 },     //  0: BPSK
176227364Sadrian    {    52,  108 },     //  1: QPSK 1/2
177227364Sadrian    {    78,  162 },     //  2: QPSK 3/4
178227364Sadrian    {   104,  216 },     //  3: 16-QAM 1/2
179227364Sadrian    {   156,  324 },     //  4: 16-QAM 3/4
180227364Sadrian    {   208,  432 },     //  5: 64-QAM 2/3
181227364Sadrian    {   234,  486 },     //  6: 64-QAM 3/4
182227364Sadrian    {   260,  540 },     //  7: 64-QAM 5/6
183227364Sadrian    {    52,  108 },     //  8: BPSK
184227364Sadrian    {   104,  216 },     //  9: QPSK 1/2
185227364Sadrian    {   156,  324 },     // 10: QPSK 3/4
186227364Sadrian    {   208,  432 },     // 11: 16-QAM 1/2
187227364Sadrian    {   312,  648 },     // 12: 16-QAM 3/4
188227364Sadrian    {   416,  864 },     // 13: 64-QAM 2/3
189227364Sadrian    {   468,  972 },     // 14: 64-QAM 3/4
190227364Sadrian    {   520, 1080 },     // 15: 64-QAM 5/6
191227364Sadrian    {    78,  162 },     // 16: BPSK
192227364Sadrian    {   156,  324 },     // 17: QPSK 1/2
193227364Sadrian    {   234,  486 },     // 18: QPSK 3/4
194227364Sadrian    {   312,  648 },     // 19: 16-QAM 1/2
195227364Sadrian    {   468,  972 },     // 20: 16-QAM 3/4
196227364Sadrian    {   624, 1296 },     // 21: 64-QAM 2/3
197227364Sadrian    {   702, 1458 },     // 22: 64-QAM 3/4
198227364Sadrian    {   780, 1620 },     // 23: 64-QAM 5/6
199227364Sadrian    {   104,  216 },     // 24: BPSK
200227364Sadrian    {   208,  432 },     // 25: QPSK 1/2
201227364Sadrian    {   312,  648 },     // 26: QPSK 3/4
202227364Sadrian    {   416,  864 },     // 27: 16-QAM 1/2
203227364Sadrian    {   624, 1296 },     // 28: 16-QAM 3/4
204227364Sadrian    {   832, 1728 },     // 29: 64-QAM 2/3
205227364Sadrian    {   936, 1944 },     // 30: 64-QAM 3/4
206227364Sadrian    {  1040, 2160 },     // 31: 64-QAM 5/6
207227364Sadrian};
208227364Sadrian
209227364Sadrian/*
210227364Sadrian * Fill in the rate array information based on the current
211227364Sadrian * node configuration and the choices made by the rate
212227364Sadrian * selection code and ath_buf setup code.
213227364Sadrian *
214227364Sadrian * Later on, this may end up also being made by the
215227364Sadrian * rate control code, but for now it can live here.
216227364Sadrian *
217227364Sadrian * This needs to be called just before the packet is
218227364Sadrian * queued to the software queue or hardware queue,
219227364Sadrian * so all of the needed fields in bf_state are setup.
220227364Sadrian */
221227364Sadrianvoid
222227364Sadrianath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
223227364Sadrian{
224227364Sadrian	struct ieee80211_node *ni = bf->bf_node;
225227364Sadrian	struct ieee80211com *ic = ni->ni_ic;
226227364Sadrian	const HAL_RATE_TABLE *rt = sc->sc_currates;
227227364Sadrian	struct ath_rc_series *rc = bf->bf_state.bfs_rc;
228227364Sadrian	uint8_t rate;
229227364Sadrian	int i;
230227364Sadrian
231227364Sadrian	for (i = 0; i < ATH_RC_NUM; i++) {
232227364Sadrian		rc[i].flags = 0;
233227364Sadrian		if (rc[i].tries == 0)
234227364Sadrian			continue;
235227364Sadrian
236227364Sadrian		rate = rt->info[rc[i].rix].rateCode;
237227364Sadrian
238227364Sadrian		/*
239247506Sadrian		 * Only enable short preamble for legacy rates
240227364Sadrian		 */
241247507Sadrian		if ((! IS_HT_RATE(rate)) && bf->bf_state.bfs_shpream)
242227364Sadrian			rate |= rt->info[rc[i].rix].shortPreamble;
243227364Sadrian
244227364Sadrian		/*
245227364Sadrian		 * Save this, used by the TX and completion code
246227364Sadrian		 */
247227364Sadrian		rc[i].ratecode = rate;
248227364Sadrian
249233966Sadrian		if (bf->bf_state.bfs_txflags &
250227364Sadrian		    (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA))
251227364Sadrian			rc[i].flags |= ATH_RC_RTSCTS_FLAG;
252227364Sadrian
253227364Sadrian		/* Only enable shortgi, 2040, dual-stream if HT is set */
254227364Sadrian		if (IS_HT_RATE(rate)) {
255227364Sadrian			rc[i].flags |= ATH_RC_HT_FLAG;
256227364Sadrian
257227364Sadrian			if (ni->ni_chw == 40)
258227364Sadrian				rc[i].flags |= ATH_RC_CW40_FLAG;
259227364Sadrian
260227364Sadrian			if (ni->ni_chw == 40 &&
261227364Sadrian			    ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40 &&
262227364Sadrian			    ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40)
263227364Sadrian				rc[i].flags |= ATH_RC_SGI_FLAG;
264227364Sadrian
265227364Sadrian			if (ni->ni_chw == 20 &&
266227364Sadrian			    ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20 &&
267227364Sadrian			    ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
268227364Sadrian				rc[i].flags |= ATH_RC_SGI_FLAG;
269227364Sadrian
270247506Sadrian			/*
271247506Sadrian			 * If we have STBC TX enabled and the receiver
272247506Sadrian			 * can receive (at least) 1 stream STBC, AND it's
273247506Sadrian			 * MCS 0-7, AND we have at least two chains enabled,
274247506Sadrian			 * enable STBC.
275247506Sadrian			 */
276247506Sadrian			if (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC &&
277247506Sadrian			    ni->ni_htcap & IEEE80211_HTCAP_RXSTBC_1STREAM &&
278247506Sadrian			    (sc->sc_cur_txchainmask > 1) &&
279247506Sadrian			    HT_RC_2_STREAMS(rate) == 1) {
280247506Sadrian				rc[i].flags |= ATH_RC_STBC_FLAG;
281247506Sadrian			}
282247506Sadrian
283249578Sadrian			/*
284249578Sadrian			 * XXX TODO: LDPC
285249578Sadrian			 */
286249578Sadrian
287249578Sadrian			/*
288249578Sadrian			 * Dual / Triple stream rate?
289249578Sadrian			 */
290249578Sadrian			if (HT_RC_2_STREAMS(rate) == 2)
291249578Sadrian				rc[i].flags |= ATH_RC_DS_FLAG;
292249578Sadrian			else if (HT_RC_2_STREAMS(rate) == 3)
293249578Sadrian				rc[i].flags |= ATH_RC_TS_FLAG;
294227364Sadrian		}
295227364Sadrian
296227364Sadrian		/*
297249578Sadrian		 * Calculate the maximum TX power cap for the current
298249578Sadrian		 * node.
299249578Sadrian		 */
300249578Sadrian		rc[i].tx_power_cap = ieee80211_get_node_txpower(ni);
301249578Sadrian
302249578Sadrian		/*
303227364Sadrian		 * Calculate the maximum 4ms frame length based
304227364Sadrian		 * on the MCS rate, SGI and channel width flags.
305227364Sadrian		 */
306227364Sadrian		if ((rc[i].flags & ATH_RC_HT_FLAG) &&
307227364Sadrian		    (HT_RC_2_MCS(rate) < 32)) {
308227364Sadrian			int j;
309227364Sadrian			if (rc[i].flags & ATH_RC_CW40_FLAG) {
310227364Sadrian				if (rc[i].flags & ATH_RC_SGI_FLAG)
311227364Sadrian					j = MCS_HT40_SGI;
312227364Sadrian				else
313227364Sadrian					j = MCS_HT40;
314227364Sadrian			} else {
315227364Sadrian				if (rc[i].flags & ATH_RC_SGI_FLAG)
316227364Sadrian					j = MCS_HT20_SGI;
317227364Sadrian				else
318227364Sadrian					j = MCS_HT20;
319227364Sadrian			}
320227364Sadrian			rc[i].max4msframelen =
321227364Sadrian			    ath_max_4ms_framelen[j][HT_RC_2_MCS(rate)];
322227364Sadrian		} else
323227364Sadrian			rc[i].max4msframelen = 0;
324227364Sadrian		DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
325227364Sadrian		    "%s: i=%d, rate=0x%x, flags=0x%x, max4ms=%d\n",
326227364Sadrian		    __func__, i, rate, rc[i].flags, rc[i].max4msframelen);
327227364Sadrian	}
328227364Sadrian}
329227364Sadrian
330227364Sadrian/*
331227364Sadrian * Return the number of delimiters to be added to
332227364Sadrian * meet the minimum required mpdudensity.
333227364Sadrian *
334227364Sadrian * Caller should make sure that the rate is HT.
335227364Sadrian *
336227364Sadrian * TODO: is this delimiter calculation supposed to be the
337227364Sadrian * total frame length, the hdr length, the data length (including
338227364Sadrian * delimiters, padding, CRC, etc) or ?
339227364Sadrian *
340227364Sadrian * TODO: this should ensure that the rate control information
341227364Sadrian * HAS been setup for the first rate.
342227364Sadrian *
343227364Sadrian * TODO: ensure this is only called for MCS rates.
344227364Sadrian *
345227364Sadrian * TODO: enforce MCS < 31
346227364Sadrian */
347227364Sadrianstatic int
348227364Sadrianath_compute_num_delims(struct ath_softc *sc, struct ath_buf *first_bf,
349227364Sadrian    uint16_t pktlen)
350227364Sadrian{
351227364Sadrian	const HAL_RATE_TABLE *rt = sc->sc_currates;
352227364Sadrian	struct ieee80211_node *ni = first_bf->bf_node;
353227364Sadrian	struct ieee80211vap *vap = ni->ni_vap;
354227364Sadrian	int ndelim, mindelim = 0;
355227364Sadrian	int mpdudensity;	 /* in 1/100'th of a microsecond */
356227364Sadrian	uint8_t rc, rix, flags;
357227364Sadrian	int width, half_gi;
358227364Sadrian	uint32_t nsymbits, nsymbols;
359227364Sadrian	uint16_t minlen;
360227364Sadrian
361227364Sadrian	/*
362227364Sadrian	 * vap->iv_ampdu_density is a value, rather than the actual
363227364Sadrian	 * density.
364227364Sadrian	 */
365227364Sadrian	if (vap->iv_ampdu_density > IEEE80211_HTCAP_MPDUDENSITY_16)
366227364Sadrian		mpdudensity = 1600;		/* maximum density */
367227364Sadrian	else
368227364Sadrian		mpdudensity = ieee80211_mpdudensity_map[vap->iv_ampdu_density];
369227364Sadrian
370227364Sadrian	/* Select standard number of delimiters based on frame length */
371227364Sadrian	ndelim = ATH_AGGR_GET_NDELIM(pktlen);
372227364Sadrian
373227364Sadrian	/*
374227364Sadrian	 * If encryption is enabled, add extra delimiters to let the
375227364Sadrian	 * crypto hardware catch up. This could be tuned per-MAC and
376227364Sadrian	 * per-rate, but for now we'll simply assume encryption is
377227364Sadrian	 * always enabled.
378247085Sadrian	 *
379247085Sadrian	 * Also note that the Atheros reference driver inserts two
380247085Sadrian	 * delimiters by default for pre-AR9380 peers.  This will
381247085Sadrian	 * include "that" required delimiter.
382227364Sadrian	 */
383227364Sadrian	ndelim += ATH_AGGR_ENCRYPTDELIM;
384227364Sadrian
385242528Sadrian	/*
386242528Sadrian	 * For AR9380, there's a minimum number of delimeters
387242528Sadrian	 * required when doing RTS.
388247085Sadrian	 *
389247085Sadrian	 * XXX TODO: this is only needed if (a) RTS/CTS is enabled, and
390247085Sadrian	 * XXX (b) this is the first sub-frame in the aggregate.
391242528Sadrian	 */
392242528Sadrian	if (sc->sc_use_ent && (sc->sc_ent_cfg & AH_ENT_RTSCTS_DELIM_WAR)
393242528Sadrian	    && ndelim < AH_FIRST_DESC_NDELIMS)
394242528Sadrian		ndelim = AH_FIRST_DESC_NDELIMS;
395242528Sadrian
396247087Sadrian	/*
397247087Sadrian	 * If sc_delim_min_pad is non-zero, enforce it as the minimum
398247087Sadrian	 * pad delimiter count.
399247087Sadrian	 */
400247087Sadrian	if (sc->sc_delim_min_pad != 0)
401247087Sadrian		ndelim = MAX(ndelim, sc->sc_delim_min_pad);
402247087Sadrian
403227364Sadrian	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
404227364Sadrian	    "%s: pktlen=%d, ndelim=%d, mpdudensity=%d\n",
405227364Sadrian	    __func__, pktlen, ndelim, mpdudensity);
406227364Sadrian
407227364Sadrian	/*
408227364Sadrian	 * If the MPDU density is 0, we can return here.
409227364Sadrian	 * Otherwise, we need to convert the desired mpdudensity
410227364Sadrian	 * into a byte length, based on the rate in the subframe.
411227364Sadrian	 */
412227364Sadrian	if (mpdudensity == 0)
413227364Sadrian		return ndelim;
414227364Sadrian
415227364Sadrian	/*
416227364Sadrian	 * Convert desired mpdu density from microeconds to bytes based
417227364Sadrian	 * on highest rate in rate series (i.e. first rate) to determine
418227364Sadrian	 * required minimum length for subframe. Take into account
419227364Sadrian	 * whether high rate is 20 or 40Mhz and half or full GI.
420227364Sadrian	 */
421227364Sadrian	rix = first_bf->bf_state.bfs_rc[0].rix;
422227364Sadrian	rc = rt->info[rix].rateCode;
423227364Sadrian	flags = first_bf->bf_state.bfs_rc[0].flags;
424227364Sadrian	width = !! (flags & ATH_RC_CW40_FLAG);
425227364Sadrian	half_gi = !! (flags & ATH_RC_SGI_FLAG);
426227364Sadrian
427227364Sadrian	/*
428227364Sadrian	 * mpdudensity is in 1/100th of a usec, so divide by 100
429227364Sadrian	 */
430227364Sadrian	if (half_gi)
431227364Sadrian		nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
432227364Sadrian	else
433227364Sadrian		nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
434227364Sadrian	nsymbols /= 100;
435227364Sadrian
436227364Sadrian	if (nsymbols == 0)
437227364Sadrian		nsymbols = 1;
438227364Sadrian
439227364Sadrian	nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
440227364Sadrian	minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
441227364Sadrian
442227364Sadrian	/*
443227364Sadrian	 * Min length is the minimum frame length for the
444227364Sadrian	 * required MPDU density.
445227364Sadrian	 */
446227364Sadrian	if (pktlen < minlen) {
447227364Sadrian		mindelim = (minlen - pktlen) / ATH_AGGR_DELIM_SZ;
448227364Sadrian		ndelim = MAX(mindelim, ndelim);
449227364Sadrian	}
450227364Sadrian
451227364Sadrian	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR,
452227364Sadrian	    "%s: pktlen=%d, minlen=%d, rix=%x, rc=%x, width=%d, hgi=%d, ndelim=%d\n",
453227364Sadrian	    __func__, pktlen, minlen, rix, rc, width, half_gi, ndelim);
454227364Sadrian
455227364Sadrian	return ndelim;
456227364Sadrian}
457227364Sadrian
458227364Sadrian/*
459227364Sadrian * Fetch the aggregation limit.
460227364Sadrian *
461227364Sadrian * It's the lowest of the four rate series 4ms frame length.
462227364Sadrian */
463227364Sadrianstatic int
464227364Sadrianath_get_aggr_limit(struct ath_softc *sc, struct ath_buf *bf)
465227364Sadrian{
466247085Sadrian	int amin = ATH_AGGR_MAXSIZE;
467227364Sadrian	int i;
468227364Sadrian
469247085Sadrian	if (sc->sc_aggr_limit > 0 && sc->sc_aggr_limit < ATH_AGGR_MAXSIZE)
470247085Sadrian		amin = sc->sc_aggr_limit;
471247085Sadrian
472237171Sadrian	for (i = 0; i < ATH_RC_NUM; i++) {
473227364Sadrian		if (bf->bf_state.bfs_rc[i].tries == 0)
474227364Sadrian			continue;
475227364Sadrian		amin = MIN(amin, bf->bf_state.bfs_rc[i].max4msframelen);
476227364Sadrian	}
477227364Sadrian
478227364Sadrian	DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: max frame len= %d\n",
479227364Sadrian	    __func__, amin);
480227364Sadrian
481227364Sadrian	return amin;
482227364Sadrian}
483227364Sadrian
484227364Sadrian/*
485218159Sadrian * Setup a 11n rate series structure
486218159Sadrian *
487218159Sadrian * This should be called for both legacy and MCS rates.
488227364Sadrian *
489249578Sadrian * This uses the rate series stuf from ath_tx_rate_fill_rcflags().
490249578Sadrian *
491227364Sadrian * It, along with ath_buf_set_rate, must be called -after- a burst
492227364Sadrian * or aggregate is setup.
493218159Sadrian */
494218159Sadrianstatic void
495218159Sadrianath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni,
496227364Sadrian    struct ath_buf *bf, HAL_11N_RATE_SERIES *series)
497218159Sadrian{
498218159Sadrian	struct ieee80211com *ic = ni->ni_ic;
499218159Sadrian	struct ath_hal *ah = sc->sc_ah;
500218159Sadrian	HAL_BOOL shortPreamble = AH_FALSE;
501218159Sadrian	const HAL_RATE_TABLE *rt = sc->sc_currates;
502218159Sadrian	int i;
503227364Sadrian	int pktlen;
504227364Sadrian	struct ath_rc_series *rc = bf->bf_state.bfs_rc;
505218159Sadrian
506218159Sadrian	if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
507218159Sadrian	    (ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_PREAMBLE))
508218159Sadrian		shortPreamble = AH_TRUE;
509218159Sadrian
510227364Sadrian	/*
511227364Sadrian	 * If this is the first frame in an aggregate series,
512227364Sadrian	 * use the aggregate length.
513227364Sadrian	 */
514227364Sadrian	if (bf->bf_state.bfs_aggr)
515227364Sadrian		pktlen = bf->bf_state.bfs_al;
516227364Sadrian	else
517227364Sadrian		pktlen = bf->bf_state.bfs_pktlen;
518227364Sadrian
519227364Sadrian	/*
520227364Sadrian	 * XXX TODO: modify this routine to use the bfs_rc[x].flags
521227364Sadrian	 * XXX fields.
522227364Sadrian	 */
523218159Sadrian	memset(series, 0, sizeof(HAL_11N_RATE_SERIES) * 4);
524237171Sadrian	for (i = 0; i < ATH_RC_NUM;  i++) {
525218931Sadrian		/* Only set flags for actual TX attempts */
526227364Sadrian		if (rc[i].tries == 0)
527218931Sadrian			continue;
528218931Sadrian
529227364Sadrian		series[i].Tries = rc[i].tries;
530218931Sadrian
531218931Sadrian		/*
532247085Sadrian		 * XXX TODO: When the NIC is capable of three stream TX,
533247085Sadrian		 * transmit 1/2 stream rates on two streams.
534247085Sadrian		 *
535247085Sadrian		 * This reduces the power consumption of the NIC and
536247085Sadrian		 * keeps it within the PCIe slot power limits.
537247085Sadrian		 */
538247287Sadrian		series[i].ChSel = sc->sc_cur_txchainmask;
539218931Sadrian
540219985Sadrian		/*
541247368Sadrian		 * Setup rate and TX power cap for this series.
542247287Sadrian		 */
543247368Sadrian		series[i].Rate = rt->info[rc[i].rix].rateCode;
544247368Sadrian		series[i].RateIndex = rc[i].rix;
545249578Sadrian		series[i].tx_power_cap = rc[i].tx_power_cap;
546247287Sadrian
547247287Sadrian		/*
548247506Sadrian		 * Enable RTS/CTS as appropriate.
549247368Sadrian		 */
550249578Sadrian		if (rc[i].flags & ATH_RC_RTSCTS_FLAG)
551247506Sadrian			series[i].RateFlags |= HAL_RATESERIES_RTS_CTS;
552247506Sadrian
553249578Sadrian		/*
554249578Sadrian		 * 11n rate? Update 11n flags.
555249578Sadrian		 */
556249578Sadrian		if (rc[i].flags & ATH_RC_HT_FLAG) {
557249578Sadrian			if (rc[i].flags & ATH_RC_CW40_FLAG)
558247506Sadrian				series[i].RateFlags |= HAL_RATESERIES_2040;
559247506Sadrian
560249578Sadrian			if (rc[i].flags & ATH_RC_SGI_FLAG)
561247506Sadrian				series[i].RateFlags |= HAL_RATESERIES_HALFGI;
562247506Sadrian
563249578Sadrian			if (rc[i].flags & ATH_RC_STBC_FLAG)
564247506Sadrian				series[i].RateFlags |= HAL_RATESERIES_STBC;
565247368Sadrian		}
566247368Sadrian
567247368Sadrian		/*
568237171Sadrian		 * PktDuration doesn't include slot, ACK, RTS, etc timing -
569237171Sadrian		 * it's just the packet duration
570237171Sadrian		 */
571249578Sadrian		if (rc[i].flags & ATH_RC_HT_FLAG) {
572218159Sadrian			series[i].PktDuration =
573218159Sadrian			    ath_computedur_ht(pktlen
574218907Sadrian				, series[i].Rate
575219588Sadrian				, HT_RC_2_STREAMS(series[i].Rate)
576219588Sadrian				, series[i].RateFlags & HAL_RATESERIES_2040
577218566Sadrian				, series[i].RateFlags & HAL_RATESERIES_HALFGI);
578218159Sadrian		} else {
579219870Sadrian			if (shortPreamble)
580227364Sadrian				series[i].Rate |=
581227364Sadrian				    rt->info[rc[i].rix].shortPreamble;
582218159Sadrian			series[i].PktDuration = ath_hal_computetxtime(ah,
583227364Sadrian			    rt, pktlen, rc[i].rix, shortPreamble);
584218159Sadrian		}
585218159Sadrian	}
586218159Sadrian}
587218159Sadrian
588218159Sadrian#if 0
589218159Sadrianstatic void
590237171Sadrianath_rateseries_print(struct ath_softc *sc, HAL_11N_RATE_SERIES *series)
591218159Sadrian{
592218159Sadrian	int i;
593237171Sadrian	for (i = 0; i < ATH_RC_NUM; i++) {
594237171Sadrian		device_printf(sc->sc_dev ,"series %d: rate %x; tries %d; "
595242528Sadrian		    "pktDuration %d; chSel %d; txpowcap %d, rateFlags %x\n",
596218159Sadrian		    i,
597218159Sadrian		    series[i].Rate,
598218159Sadrian		    series[i].Tries,
599218159Sadrian		    series[i].PktDuration,
600218159Sadrian		    series[i].ChSel,
601242528Sadrian		    series[i].tx_power_cap,
602218159Sadrian		    series[i].RateFlags);
603218159Sadrian	}
604218159Sadrian}
605218159Sadrian#endif
606218159Sadrian
607218159Sadrian/*
608218159Sadrian * Setup the 11n rate scenario and burst duration for the given TX descriptor
609218159Sadrian * list.
610218159Sadrian *
611218159Sadrian * This isn't useful for sending beacon frames, which has different needs
612218159Sadrian * wrt what's passed into the rate scenario function.
613218159Sadrian */
614218159Sadrianvoid
615227364Sadrianath_buf_set_rate(struct ath_softc *sc, struct ieee80211_node *ni,
616227364Sadrian    struct ath_buf *bf)
617218159Sadrian{
618218159Sadrian	HAL_11N_RATE_SERIES series[4];
619218159Sadrian	struct ath_desc *ds = bf->bf_desc;
620218159Sadrian	struct ath_hal *ah = sc->sc_ah;
621227364Sadrian	int is_pspoll = (bf->bf_state.bfs_atype == HAL_PKT_TYPE_PSPOLL);
622227364Sadrian	int ctsrate = bf->bf_state.bfs_ctsrate;
623233966Sadrian	int flags = bf->bf_state.bfs_txflags;
624218159Sadrian
625218159Sadrian	/* Setup rate scenario */
626218159Sadrian	memset(&series, 0, sizeof(series));
627218159Sadrian
628227364Sadrian	ath_rateseries_setup(sc, ni, bf, series);
629218159Sadrian
630218935Sadrian#if 0
631237171Sadrian	ath_rateseries_print(sc, series);
632218935Sadrian#endif
633218935Sadrian
634218159Sadrian	/* Set rate scenario */
635237171Sadrian	/*
636237171Sadrian	 * Note: Don't allow hardware to override the duration on
637237171Sadrian	 * ps-poll packets.
638237171Sadrian	 */
639218159Sadrian	ath_hal_set11nratescenario(ah, ds,
640218593Sadrian	    !is_pspoll,	/* whether to override the duration or not */
641218159Sadrian	    ctsrate,	/* rts/cts rate */
642218159Sadrian	    series,	/* 11n rate series */
643218159Sadrian	    4,		/* number of series */
644218159Sadrian	    flags);
645218159Sadrian
646218159Sadrian	/* Set burst duration */
647227364Sadrian	/*
648227364Sadrian	 * This is only required when doing 11n burst, not aggregation
649227364Sadrian	 * ie, if there's a second frame in a RIFS or A-MPDU burst
650227364Sadrian	 * w/ >1 A-MPDU frame bursting back to back.
651227364Sadrian	 * Normal A-MPDU doesn't do bursting -between- aggregates.
652227364Sadrian	 *
653227364Sadrian	 * .. and it's highly likely this won't ever be implemented
654227364Sadrian	 */
655218159Sadrian	//ath_hal_set11nburstduration(ah, ds, 8192);
656218159Sadrian}
657227364Sadrian
658227364Sadrian/*
659227364Sadrian * Form an aggregate packet list.
660227364Sadrian *
661227364Sadrian * This function enforces the aggregate restrictions/requirements.
662227364Sadrian *
663227364Sadrian * These are:
664227364Sadrian *
665227364Sadrian * + The aggregate size maximum (64k for AR9160 and later, 8K for
666227364Sadrian *   AR5416 when doing RTS frame protection.)
667227364Sadrian * + Maximum number of sub-frames for an aggregate
668227364Sadrian * + The aggregate delimiter size, giving MACs time to do whatever is
669227364Sadrian *   needed before each frame
670227364Sadrian * + Enforce the BAW limit
671227364Sadrian *
672227364Sadrian * Each descriptor queued should have the DMA setup.
673227364Sadrian * The rate series, descriptor setup, linking, etc is all done
674227364Sadrian * externally. This routine simply chains them together.
675227364Sadrian * ath_tx_setds_11n() will take care of configuring the per-
676227364Sadrian * descriptor setup, and ath_buf_set_rate() will configure the
677227364Sadrian * rate control.
678227364Sadrian *
679237171Sadrian * The TID lock is required for the entirety of this function.
680237171Sadrian *
681237171Sadrian * If some code in another thread adds to the head of this
682227364Sadrian * list, very strange behaviour will occur. Since retransmission is the
683227364Sadrian * only reason this will occur, and this routine is designed to be called
684227364Sadrian * from within the scheduler task, it won't ever clash with the completion
685227364Sadrian * task.
686227364Sadrian *
687227364Sadrian * So if you want to call this from an upper layer context (eg, to direct-
688227364Sadrian * dispatch aggregate frames to the hardware), please keep this in mind.
689227364Sadrian */
690227364SadrianATH_AGGR_STATUS
691237171Sadrianath_tx_form_aggr(struct ath_softc *sc, struct ath_node *an,
692237171Sadrian    struct ath_tid *tid, ath_bufhead *bf_q)
693227364Sadrian{
694236872Sadrian	//struct ieee80211_node *ni = &an->an_node;
695227364Sadrian	struct ath_buf *bf, *bf_first = NULL, *bf_prev = NULL;
696227364Sadrian	int nframes = 0;
697227364Sadrian	uint16_t aggr_limit = 0, al = 0, bpad = 0, al_delta, h_baw;
698227364Sadrian	struct ieee80211_tx_ampdu *tap;
699227364Sadrian	int status = ATH_AGGR_DONE;
700227364Sadrian	int prev_frames = 0;	/* XXX for AR5416 burst, not done here */
701227364Sadrian	int prev_al = 0;	/* XXX also for AR5416 burst */
702227364Sadrian
703243786Sadrian	ATH_TX_LOCK_ASSERT(sc);
704227364Sadrian
705227364Sadrian	tap = ath_tx_get_tx_tid(an, tid->tid);
706227364Sadrian	if (tap == NULL) {
707227364Sadrian		status = ATH_AGGR_ERROR;
708227364Sadrian		goto finish;
709227364Sadrian	}
710227364Sadrian
711227364Sadrian	h_baw = tap->txa_wnd / 2;
712227364Sadrian
713227364Sadrian	for (;;) {
714241336Sadrian		bf = ATH_TID_FIRST(tid);
715227364Sadrian		if (bf_first == NULL)
716227364Sadrian			bf_first = bf;
717227364Sadrian		if (bf == NULL) {
718227364Sadrian			status = ATH_AGGR_DONE;
719227364Sadrian			break;
720227364Sadrian		} else {
721227364Sadrian			/*
722227364Sadrian			 * It's the first frame;
723227364Sadrian			 * set the aggregation limit based on the
724227364Sadrian			 * rate control decision that has been made.
725227364Sadrian			 */
726227364Sadrian			aggr_limit = ath_get_aggr_limit(sc, bf_first);
727227364Sadrian		}
728227364Sadrian
729227364Sadrian		/* Set this early just so things don't get confused */
730227364Sadrian		bf->bf_next = NULL;
731227364Sadrian
732227364Sadrian		/*
733227364Sadrian		 * If the frame doesn't have a sequence number that we're
734227364Sadrian		 * tracking in the BAW (eg NULL QOS data frame), we can't
735227364Sadrian		 * aggregate it. Stop the aggregation process; the sender
736227364Sadrian		 * can then TX what's in the list thus far and then
737227364Sadrian		 * TX the frame individually.
738227364Sadrian		 */
739227364Sadrian		if (! bf->bf_state.bfs_dobaw) {
740227364Sadrian			status = ATH_AGGR_NONAGGR;
741227364Sadrian			break;
742227364Sadrian		}
743227364Sadrian
744227364Sadrian		/*
745227364Sadrian		 * If any of the rates are non-HT, this packet
746227364Sadrian		 * can't be aggregated.
747227364Sadrian		 * XXX TODO: add a bf_state flag which gets marked
748227364Sadrian		 * if any active rate is non-HT.
749227364Sadrian		 */
750227364Sadrian
751227364Sadrian		/*
752227364Sadrian		 * do not exceed aggregation limit
753227364Sadrian		 */
754227364Sadrian		al_delta = ATH_AGGR_DELIM_SZ + bf->bf_state.bfs_pktlen;
755227364Sadrian		if (nframes &&
756227364Sadrian		    (aggr_limit < (al + bpad + al_delta + prev_al))) {
757227364Sadrian			status = ATH_AGGR_LIMITED;
758227364Sadrian			break;
759227364Sadrian		}
760227364Sadrian
761227364Sadrian		/*
762233970Sadrian		 * If RTS/CTS is set on the first frame, enforce
763233970Sadrian		 * the RTS aggregate limit.
764233970Sadrian		 */
765233970Sadrian		if (bf_first->bf_state.bfs_txflags &
766233970Sadrian		    (HAL_TXDESC_CTSENA | HAL_TXDESC_RTSENA)) {
767233970Sadrian			if (nframes &&
768233970Sadrian			   (sc->sc_rts_aggr_limit <
769233970Sadrian			     (al + bpad + al_delta + prev_al))) {
770233970Sadrian				status = ATH_AGGR_8K_LIMITED;
771233970Sadrian				break;
772233970Sadrian			}
773233970Sadrian		}
774233970Sadrian
775233970Sadrian		/*
776227364Sadrian		 * Do not exceed subframe limit.
777227364Sadrian		 */
778227364Sadrian		if ((nframes + prev_frames) >= MIN((h_baw),
779227364Sadrian		    IEEE80211_AMPDU_SUBFRAME_DEFAULT)) {
780227364Sadrian			status = ATH_AGGR_LIMITED;
781227364Sadrian			break;
782227364Sadrian		}
783227364Sadrian
784227364Sadrian		/*
785233970Sadrian		 * If the current frame has an RTS/CTS configuration
786233988Sadrian		 * that differs from the first frame, override the
787233988Sadrian		 * subsequent frame with this config.
788233970Sadrian		 */
789246536Sadrian		if (bf != bf_first) {
790246536Sadrian			bf->bf_state.bfs_txflags &=
791246536Sadrian			    ~ (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA);
792246536Sadrian			bf->bf_state.bfs_txflags |=
793246536Sadrian			    bf_first->bf_state.bfs_txflags &
794246536Sadrian			    (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA);
795246536Sadrian		}
796233970Sadrian
797233970Sadrian		/*
798233227Sadrian		 * If the packet has a sequence number, do not
799233227Sadrian		 * step outside of the block-ack window.
800233227Sadrian		 */
801233227Sadrian		if (! BAW_WITHIN(tap->txa_start, tap->txa_wnd,
802233227Sadrian		    SEQNO(bf->bf_state.bfs_seqno))) {
803233227Sadrian			status = ATH_AGGR_BAW_CLOSED;
804233227Sadrian			break;
805233227Sadrian		}
806233227Sadrian
807233227Sadrian		/*
808227364Sadrian		 * this packet is part of an aggregate.
809227364Sadrian		 */
810241336Sadrian		ATH_TID_REMOVE(tid, bf, bf_list);
811227364Sadrian
812227364Sadrian		/* The TID lock is required for the BAW update */
813227364Sadrian		ath_tx_addto_baw(sc, an, tid, bf);
814227364Sadrian		bf->bf_state.bfs_addedbaw = 1;
815227364Sadrian
816227364Sadrian		/*
817227364Sadrian		 * XXX enforce ACK for aggregate frames (this needs to be
818227364Sadrian		 * XXX handled more gracefully?
819227364Sadrian		 */
820233966Sadrian		if (bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) {
821227364Sadrian			device_printf(sc->sc_dev,
822227364Sadrian			    "%s: HAL_TXDESC_NOACK set for an aggregate frame?\n",
823227364Sadrian			    __func__);
824233966Sadrian			bf->bf_state.bfs_txflags &= (~HAL_TXDESC_NOACK);
825227364Sadrian		}
826227364Sadrian
827227364Sadrian		/*
828227364Sadrian		 * Add the now owned buffer (which isn't
829227364Sadrian		 * on the software TXQ any longer) to our
830227364Sadrian		 * aggregate frame list.
831227364Sadrian		 */
832227364Sadrian		TAILQ_INSERT_TAIL(bf_q, bf, bf_list);
833227364Sadrian		nframes ++;
834227364Sadrian
835227364Sadrian		/* Completion handler */
836227364Sadrian		bf->bf_comp = ath_tx_aggr_comp;
837227364Sadrian
838227364Sadrian		/*
839227364Sadrian		 * add padding for previous frame to aggregation length
840227364Sadrian		 */
841227364Sadrian		al += bpad + al_delta;
842227364Sadrian
843227364Sadrian		/*
844227364Sadrian		 * Calculate delimiters needed for the current frame
845227364Sadrian		 */
846227364Sadrian		bf->bf_state.bfs_ndelim =
847227364Sadrian		    ath_compute_num_delims(sc, bf_first,
848227364Sadrian		    bf->bf_state.bfs_pktlen);
849227364Sadrian
850227364Sadrian		/*
851227364Sadrian		 * Calculate the padding needed from this set of delimiters,
852227364Sadrian		 * used when calculating if the next frame will fit in
853227364Sadrian		 * the aggregate.
854227364Sadrian		 */
855227364Sadrian		bpad = PADBYTES(al_delta) + (bf->bf_state.bfs_ndelim << 2);
856227364Sadrian
857227364Sadrian		/*
858227364Sadrian		 * Chain the buffers together
859227364Sadrian		 */
860227364Sadrian		if (bf_prev)
861227364Sadrian			bf_prev->bf_next = bf;
862227364Sadrian		bf_prev = bf;
863227364Sadrian
864227364Sadrian		/*
865250665Sadrian		 * If we're leaking frames, just return at this point;
866250665Sadrian		 * we've queued a single frame and we don't want to add
867250665Sadrian		 * any more.
868227364Sadrian		 */
869250665Sadrian		if (tid->an->an_leak_count) {
870250665Sadrian			status = ATH_AGGR_LEAK_CLOSED;
871250665Sadrian			break;
872250665Sadrian		}
873227364Sadrian
874227364Sadrian#if 0
875227364Sadrian		/*
876227364Sadrian		 * terminate aggregation on a small packet boundary
877227364Sadrian		 */
878227364Sadrian		if (bf->bf_state.bfs_pktlen < ATH_AGGR_MINPLEN) {
879227364Sadrian			status = ATH_AGGR_SHORTPKT;
880227364Sadrian			break;
881227364Sadrian		}
882227364Sadrian#endif
883227364Sadrian
884227364Sadrian	}
885227364Sadrian
886227364Sadrianfinish:
887227364Sadrian	/*
888227364Sadrian	 * Just in case the list was empty when we tried to
889227364Sadrian	 * dequeue a packet ..
890227364Sadrian	 */
891227364Sadrian	if (bf_first) {
892227364Sadrian		bf_first->bf_state.bfs_al = al;
893227364Sadrian		bf_first->bf_state.bfs_nframes = nframes;
894227364Sadrian	}
895227364Sadrian	return status;
896227364Sadrian}
897