Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c
39566 views
1
/*-
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5
* Copyright (c) 2002-2008 Atheros Communications, Inc.
6
*
7
* Permission to use, copy, modify, and/or distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
*/
19
#include "opt_ah.h"
20
21
#include "ah.h"
22
#include "ah_desc.h"
23
#include "ah_internal.h"
24
25
#include "ar5416/ar5416.h"
26
#include "ar5416/ar5416reg.h"
27
#include "ar5416/ar5416phy.h"
28
#include "ar5416/ar5416desc.h"
29
30
/*
31
* Stop transmit on the specified queue
32
*/
33
HAL_BOOL
34
ar5416StopTxDma(struct ath_hal *ah, u_int q)
35
{
36
#define STOP_DMA_TIMEOUT 4000 /* us */
37
#define STOP_DMA_ITER 100 /* us */
38
u_int i;
39
40
HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues);
41
42
HALASSERT(AH5212(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE);
43
44
OS_REG_WRITE(ah, AR_Q_TXD, 1 << q);
45
for (i = STOP_DMA_TIMEOUT/STOP_DMA_ITER; i != 0; i--) {
46
if (ar5212NumTxPending(ah, q) == 0)
47
break;
48
OS_DELAY(STOP_DMA_ITER);
49
}
50
#ifdef AH_DEBUG
51
if (i == 0) {
52
HALDEBUG(ah, HAL_DEBUG_ANY,
53
"%s: queue %u DMA did not stop in 400 msec\n", __func__, q);
54
HALDEBUG(ah, HAL_DEBUG_ANY,
55
"%s: QSTS 0x%x Q_TXE 0x%x Q_TXD 0x%x Q_CBR 0x%x\n", __func__,
56
OS_REG_READ(ah, AR_QSTS(q)), OS_REG_READ(ah, AR_Q_TXE),
57
OS_REG_READ(ah, AR_Q_TXD), OS_REG_READ(ah, AR_QCBRCFG(q)));
58
HALDEBUG(ah, HAL_DEBUG_ANY,
59
"%s: Q_MISC 0x%x Q_RDYTIMECFG 0x%x Q_RDYTIMESHDN 0x%x\n",
60
__func__, OS_REG_READ(ah, AR_QMISC(q)),
61
OS_REG_READ(ah, AR_QRDYTIMECFG(q)),
62
OS_REG_READ(ah, AR_Q_RDYTIMESHDN));
63
}
64
#endif /* AH_DEBUG */
65
66
/* ar5416 and up can kill packets at the PCU level */
67
if (ar5212NumTxPending(ah, q)) {
68
uint32_t j;
69
70
HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
71
"%s: Num of pending TX Frames %d on Q %d\n",
72
__func__, ar5212NumTxPending(ah, q), q);
73
74
/* Kill last PCU Tx Frame */
75
/* TODO - save off and restore current values of Q1/Q2? */
76
for (j = 0; j < 2; j++) {
77
uint32_t tsfLow = OS_REG_READ(ah, AR_TSF_L32);
78
OS_REG_WRITE(ah, AR_QUIET2,
79
SM(10, AR_QUIET2_QUIET_DUR));
80
OS_REG_WRITE(ah, AR_QUIET_PERIOD, 100);
81
OS_REG_WRITE(ah, AR_NEXT_QUIET, tsfLow >> 10);
82
OS_REG_SET_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
83
84
if ((OS_REG_READ(ah, AR_TSF_L32)>>10) == (tsfLow>>10))
85
break;
86
87
HALDEBUG(ah, HAL_DEBUG_ANY,
88
"%s: TSF moved while trying to set quiet time "
89
"TSF: 0x%08x\n", __func__, tsfLow);
90
HALASSERT(j < 1); /* TSF shouldn't count twice or reg access is taking forever */
91
}
92
93
OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
94
95
/* Allow the quiet mechanism to do its work */
96
OS_DELAY(200);
97
OS_REG_CLR_BIT(ah, AR_TIMER_MODE, AR_TIMER_MODE_QUIET);
98
99
/* Verify the transmit q is empty */
100
for (i = STOP_DMA_TIMEOUT/STOP_DMA_ITER; i != 0; i--) {
101
if (ar5212NumTxPending(ah, q) == 0)
102
break;
103
OS_DELAY(STOP_DMA_ITER);
104
}
105
if (i == 0) {
106
HALDEBUG(ah, HAL_DEBUG_ANY,
107
"%s: Failed to stop Tx DMA in %d msec after killing"
108
" last frame\n", __func__, STOP_DMA_TIMEOUT / 1000);
109
}
110
OS_REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_CHAN_IDLE);
111
}
112
113
OS_REG_WRITE(ah, AR_Q_TXD, 0);
114
return (i != 0);
115
#undef STOP_DMA_ITER
116
#undef STOP_DMA_TIMEOUT
117
}
118
119
#define VALID_KEY_TYPES \
120
((1 << HAL_KEY_TYPE_CLEAR) | (1 << HAL_KEY_TYPE_WEP)|\
121
(1 << HAL_KEY_TYPE_AES) | (1 << HAL_KEY_TYPE_TKIP))
122
#define isValidKeyType(_t) ((1 << (_t)) & VALID_KEY_TYPES)
123
124
#define set11nTries(_series, _index) \
125
(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
126
127
#define set11nRate(_series, _index) \
128
(SM((_series)[_index].Rate, AR_XmitRate##_index))
129
130
#define set11nPktDurRTSCTS(_series, _index) \
131
(SM((_series)[_index].PktDuration, AR_PacketDur##_index) |\
132
((_series)[_index].RateFlags & HAL_RATESERIES_RTS_CTS ?\
133
AR_RTSCTSQual##_index : 0))
134
135
#define set11nRateFlags(_series, _index) \
136
((_series)[_index].RateFlags & HAL_RATESERIES_2040 ? AR_2040_##_index : 0) \
137
|((_series)[_index].RateFlags & HAL_RATESERIES_HALFGI ? AR_GI##_index : 0) \
138
|((_series)[_index].RateFlags & HAL_RATESERIES_STBC ? AR_STBC##_index : 0) \
139
|SM((_series)[_index].ChSel, AR_ChainSel##_index)
140
141
/*
142
* Descriptor Access Functions
143
*/
144
145
#define VALID_PKT_TYPES \
146
((1<<HAL_PKT_TYPE_NORMAL)|(1<<HAL_PKT_TYPE_ATIM)|\
147
(1<<HAL_PKT_TYPE_PSPOLL)|(1<<HAL_PKT_TYPE_PROBE_RESP)|\
148
(1<<HAL_PKT_TYPE_BEACON)|(1<<HAL_PKT_TYPE_AMPDU))
149
#define isValidPktType(_t) ((1<<(_t)) & VALID_PKT_TYPES)
150
#define VALID_TX_RATES \
151
((1<<0x0b)|(1<<0x0f)|(1<<0x0a)|(1<<0x0e)|(1<<0x09)|(1<<0x0d)|\
152
(1<<0x08)|(1<<0x0c)|(1<<0x1b)|(1<<0x1a)|(1<<0x1e)|(1<<0x19)|\
153
(1<<0x1d)|(1<<0x18)|(1<<0x1c)|(1<<0x01)|(1<<0x02)|(1<<0x03)|\
154
(1<<0x04)|(1<<0x05)|(1<<0x06)|(1<<0x07)|(1<<0x00))
155
/* NB: accept HT rates */
156
#define isValidTxRate(_r) ((1<<((_r) & 0x7f)) & VALID_TX_RATES)
157
158
static inline int
159
ar5416RateToRateTable(struct ath_hal *ah, uint8_t rate, HAL_BOOL is_ht40)
160
{
161
162
/*
163
* Handle the non-MCS rates
164
*/
165
switch (rate) {
166
case /* 1 Mb */ 0x1b:
167
case /* 1 MbS*/ 0x1b | 0x4:
168
return (AH5416(ah)->ah_ratesArray[rate1l]);
169
case /* 2 Mb */ 0x1a:
170
return (AH5416(ah)->ah_ratesArray[rate2l]);
171
case /* 2 MbS*/ 0x1a | 0x4:
172
return (AH5416(ah)->ah_ratesArray[rate2s]);
173
case /* 5.5 Mb */ 0x19:
174
return (AH5416(ah)->ah_ratesArray[rate5_5l]);
175
case /* 5.5 MbS*/ 0x19 | 0x4:
176
return (AH5416(ah)->ah_ratesArray[rate5_5s]);
177
case /* 11 Mb */ 0x18:
178
return (AH5416(ah)->ah_ratesArray[rate11l]);
179
case /* 11 MbS*/ 0x18 | 0x4:
180
return (AH5416(ah)->ah_ratesArray[rate11s]);
181
}
182
183
/* OFDM rates */
184
switch (rate) {
185
case /* 6 Mb */ 0x0b:
186
return (AH5416(ah)->ah_ratesArray[rate6mb]);
187
case /* 9 Mb */ 0x0f:
188
return (AH5416(ah)->ah_ratesArray[rate9mb]);
189
case /* 12 Mb */ 0x0a:
190
return (AH5416(ah)->ah_ratesArray[rate12mb]);
191
case /* 18 Mb */ 0x0e:
192
return (AH5416(ah)->ah_ratesArray[rate18mb]);
193
case /* 24 Mb */ 0x09:
194
return (AH5416(ah)->ah_ratesArray[rate24mb]);
195
case /* 36 Mb */ 0x0d:
196
return (AH5416(ah)->ah_ratesArray[rate36mb]);
197
case /* 48 Mb */ 0x08:
198
return (AH5416(ah)->ah_ratesArray[rate48mb]);
199
case /* 54 Mb */ 0x0c:
200
return (AH5416(ah)->ah_ratesArray[rate54mb]);
201
}
202
203
/*
204
* Handle HT20/HT40 - we only have to do MCS0-7;
205
* there's no stream differences.
206
*/
207
if ((rate & 0x80) && is_ht40) {
208
return (AH5416(ah)->ah_ratesArray[rateHt40_0 + (rate & 0x7)]);
209
} else if (rate & 0x80) {
210
return (AH5416(ah)->ah_ratesArray[rateHt20_0 + (rate & 0x7)]);
211
}
212
213
/* XXX default (eg XR, bad bad person!) */
214
return (AH5416(ah)->ah_ratesArray[rate6mb]);
215
}
216
217
/*
218
* Return the TX power to be used for the given rate/chains/TX power.
219
*
220
* There are a bunch of tweaks to make to a given TX power based on
221
* the current configuration, so...
222
*/
223
static uint16_t
224
ar5416GetTxRatePower(struct ath_hal *ah, uint8_t rate, uint8_t tx_chainmask,
225
uint16_t txPower, HAL_BOOL is_ht40)
226
{
227
int n_txpower, max_txpower;
228
const int cck_ofdm_delta = 2;
229
#define EEP_MINOR(_ah) \
230
(AH_PRIVATE(_ah)->ah_eeversion & AR5416_EEP_VER_MINOR_MASK)
231
#define IS_EEP_MINOR_V2(_ah) (EEP_MINOR(_ah) >= AR5416_EEP_MINOR_VER_2)
232
233
/* Take a copy ; we may underflow and thus need to clamp things */
234
n_txpower = txPower;
235
236
/* HT40? Need to adjust the TX power by this */
237
if (is_ht40)
238
n_txpower += AH5416(ah)->ah_ht40PowerIncForPdadc;
239
240
/*
241
* Merlin? Offset the target TX power offset - it defaults to
242
* starting at -5.0dBm, but that can change!
243
*
244
* Kiwi/Kite? Always -5.0dBm offset.
245
*/
246
if (AR_SREV_KIWI_10_OR_LATER(ah)) {
247
n_txpower -= (AR5416_PWR_TABLE_OFFSET_DB * 2);
248
} else if (AR_SREV_MERLIN_20_OR_LATER(ah)) {
249
int8_t pwr_table_offset = 0;
250
/* This is in dBm, convert to 1/2 dBm */
251
(void) ath_hal_eepromGet(ah, AR_EEP_PWR_TABLE_OFFSET,
252
&pwr_table_offset);
253
n_txpower -= (pwr_table_offset * 2);
254
}
255
256
/*
257
* If Open-loop TX power control is used, the CCK rates need
258
* to be offset by that.
259
*
260
* Rates: 2S, 2L, 1S, 1L, 5.5S, 5.5L
261
*
262
* XXX Odd, we don't have a PHY table entry for long preamble
263
* 1mbit CCK?
264
*/
265
if (AR_SREV_MERLIN_20_OR_LATER(ah) &&
266
ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) {
267
if (rate == 0x19 || rate == 0x1a || rate == 0x1b ||
268
rate == (0x19 | 0x04) || rate == (0x1a | 0x04) ||
269
rate == (0x1b | 0x04)) {
270
n_txpower -= cck_ofdm_delta;
271
}
272
}
273
274
/*
275
* We're now offset by the same amount that the static maximum
276
* PHY power tables are. So, clamp the value based on that rate.
277
*/
278
max_txpower = ar5416RateToRateTable(ah, rate, is_ht40);
279
#if 0
280
ath_hal_printf(ah, "%s: n_txpower = %d, max_txpower = %d, "
281
"rate = 0x%x , is_ht40 = %d\n",
282
__func__,
283
n_txpower,
284
max_txpower,
285
rate,
286
is_ht40);
287
#endif
288
n_txpower = MIN(max_txpower, n_txpower);
289
290
/*
291
* We don't have to offset the TX power for two or three
292
* chain operation here - it's done by the AR_PHY_POWER_TX_SUB
293
* register setting via the EEPROM.
294
*
295
* So for vendors that programmed the maximum target power assuming
296
* that 2/3 chains are always on, things will just plain work.
297
* (They won't reach that target power if only one chain is on, but
298
* that's a different problem.)
299
*/
300
301
/* Over/underflow? Adjust */
302
if (n_txpower < 0)
303
n_txpower = 0;
304
else if (n_txpower > 63)
305
n_txpower = 63;
306
307
/*
308
* For some odd reason the AR9160 with txpower=0 results in a
309
* much higher (max?) TX power. So, if it's a chipset before
310
* AR9220/AR9280, just clamp the minimum value at 1.
311
*/
312
if ((! AR_SREV_MERLIN_10_OR_LATER(ah)) && (n_txpower == 0))
313
n_txpower = 1;
314
315
return (n_txpower);
316
#undef EEP_MINOR
317
#undef IS_EEP_MINOR_V2
318
}
319
320
HAL_BOOL
321
ar5416SetupTxDesc(struct ath_hal *ah, struct ath_desc *ds,
322
u_int pktLen,
323
u_int hdrLen,
324
HAL_PKT_TYPE type,
325
u_int txPower,
326
u_int txRate0, u_int txTries0,
327
u_int keyIx,
328
u_int antMode,
329
u_int flags,
330
u_int rtsctsRate,
331
u_int rtsctsDuration,
332
u_int compicvLen,
333
u_int compivLen,
334
u_int comp)
335
{
336
#define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
337
struct ar5416_desc *ads = AR5416DESC(ds);
338
struct ath_hal_5416 *ahp = AH5416(ah);
339
340
(void) hdrLen;
341
342
HALASSERT(txTries0 != 0);
343
HALASSERT(isValidPktType(type));
344
HALASSERT(isValidTxRate(txRate0));
345
HALASSERT((flags & RTSCTS) != RTSCTS);
346
/* XXX validate antMode */
347
348
txPower = (txPower + AH5212(ah)->ah_txPowerIndexOffset);
349
if (txPower > 63)
350
txPower = 63;
351
352
/*
353
* XXX For now, just assume that this isn't a HT40 frame.
354
* It'll get over-ridden by the multi-rate TX power setup.
355
*/
356
if (AH5212(ah)->ah_tpcEnabled) {
357
txPower = ar5416GetTxRatePower(ah, txRate0,
358
ahp->ah_tx_chainmask,
359
txPower,
360
AH_FALSE);
361
}
362
363
ads->ds_ctl0 = (pktLen & AR_FrameLen)
364
| (txPower << AR_XmitPower_S)
365
| (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
366
| (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
367
| (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0)
368
;
369
ads->ds_ctl1 = (type << AR_FrameType_S)
370
| (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0)
371
| (flags & HAL_TXDESC_HWTS ? AR_InsertTS : 0)
372
;
373
ads->ds_ctl2 = SM(txTries0, AR_XmitDataTries0)
374
| (flags & HAL_TXDESC_DURENA ? AR_DurUpdateEn : 0)
375
;
376
ads->ds_ctl3 = (txRate0 << AR_XmitRate0_S)
377
;
378
ads->ds_ctl4 = 0;
379
ads->ds_ctl5 = 0;
380
ads->ds_ctl6 = 0;
381
ads->ds_ctl7 = SM(ahp->ah_tx_chainmask, AR_ChainSel0)
382
| SM(ahp->ah_tx_chainmask, AR_ChainSel1)
383
| SM(ahp->ah_tx_chainmask, AR_ChainSel2)
384
| SM(ahp->ah_tx_chainmask, AR_ChainSel3)
385
;
386
ads->ds_ctl8 = SM(0, AR_AntCtl0);
387
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
388
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
389
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
390
391
if (keyIx != HAL_TXKEYIX_INVALID) {
392
/* XXX validate key index */
393
ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
394
ads->ds_ctl0 |= AR_DestIdxValid;
395
ads->ds_ctl6 |= SM(ahp->ah_keytype[keyIx], AR_EncrType);
396
}
397
if (flags & RTSCTS) {
398
if (!isValidTxRate(rtsctsRate)) {
399
HALDEBUG(ah, HAL_DEBUG_ANY,
400
"%s: invalid rts/cts rate 0x%x\n",
401
__func__, rtsctsRate);
402
return AH_FALSE;
403
}
404
/* XXX validate rtsctsDuration */
405
ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
406
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0)
407
;
408
ads->ds_ctl7 |= (rtsctsRate << AR_RTSCTSRate_S);
409
}
410
411
/*
412
* Set the TX antenna to 0 for Kite
413
* To preserve existing behaviour, also set the TPC bits to 0;
414
* when TPC is enabled these should be filled in appropriately.
415
*
416
* XXX TODO: when doing TPC, set the TX power up appropriately?
417
*/
418
if (AR_SREV_KITE(ah)) {
419
ads->ds_ctl8 = SM(0, AR_AntCtl0);
420
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
421
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
422
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
423
}
424
return AH_TRUE;
425
#undef RTSCTS
426
}
427
428
HAL_BOOL
429
ar5416SetupXTxDesc(struct ath_hal *ah, struct ath_desc *ds,
430
u_int txRate1, u_int txTries1,
431
u_int txRate2, u_int txTries2,
432
u_int txRate3, u_int txTries3)
433
{
434
struct ar5416_desc *ads = AR5416DESC(ds);
435
436
if (txTries1) {
437
HALASSERT(isValidTxRate(txRate1));
438
ads->ds_ctl2 |= SM(txTries1, AR_XmitDataTries1);
439
ads->ds_ctl3 |= (txRate1 << AR_XmitRate1_S);
440
}
441
if (txTries2) {
442
HALASSERT(isValidTxRate(txRate2));
443
ads->ds_ctl2 |= SM(txTries2, AR_XmitDataTries2);
444
ads->ds_ctl3 |= (txRate2 << AR_XmitRate2_S);
445
}
446
if (txTries3) {
447
HALASSERT(isValidTxRate(txRate3));
448
ads->ds_ctl2 |= SM(txTries3, AR_XmitDataTries3);
449
ads->ds_ctl3 |= (txRate3 << AR_XmitRate3_S);
450
}
451
return AH_TRUE;
452
}
453
454
/*
455
* XXX TODO: Figure out if AR_InsertTS is required on all sub-frames
456
* of a TX descriptor.
457
*/
458
HAL_BOOL
459
ar5416FillTxDesc(struct ath_hal *ah, struct ath_desc *ds,
460
HAL_DMA_ADDR *bufAddrList, uint32_t *segLenList, u_int descId,
461
u_int qcuId, HAL_BOOL firstSeg, HAL_BOOL lastSeg,
462
const struct ath_desc *ds0)
463
{
464
struct ar5416_desc *ads = AR5416DESC(ds);
465
uint32_t segLen = segLenList[0];
466
467
HALASSERT((segLen &~ AR_BufLen) == 0);
468
469
ds->ds_data = bufAddrList[0];
470
471
if (firstSeg) {
472
/*
473
* First descriptor, don't clobber xmit control data
474
* setup by ar5212SetupTxDesc.
475
*/
476
ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
477
} else if (lastSeg) { /* !firstSeg && lastSeg */
478
/*
479
* Last descriptor in a multi-descriptor frame,
480
* copy the multi-rate transmit parameters from
481
* the first frame for processing on completion.
482
*/
483
ads->ds_ctl1 = segLen;
484
#ifdef AH_NEED_DESC_SWAP
485
ads->ds_ctl0 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl0)
486
& AR_TxIntrReq;
487
ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
488
ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
489
/* ctl6 - we only need encrtype; the rest are blank */
490
ads->ds_ctl6 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType);
491
#else
492
ads->ds_ctl0 = AR5416DESC_CONST(ds0)->ds_ctl0 & AR_TxIntrReq;
493
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
494
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
495
/* ctl6 - we only need encrtype; the rest are blank */
496
ads->ds_ctl6 = AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType;
497
#endif
498
} else { /* !firstSeg && !lastSeg */
499
/*
500
* Intermediate descriptor in a multi-descriptor frame.
501
*/
502
#ifdef AH_NEED_DESC_SWAP
503
ads->ds_ctl0 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl0)
504
& AR_TxIntrReq;
505
ads->ds_ctl6 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType);
506
#else
507
ads->ds_ctl0 = AR5416DESC_CONST(ds0)->ds_ctl0 & AR_TxIntrReq;
508
ads->ds_ctl6 = AR5416DESC_CONST(ds0)->ds_ctl6 & AR_EncrType;
509
#endif
510
ads->ds_ctl1 = segLen | AR_TxMore;
511
ads->ds_ctl2 = 0;
512
ads->ds_ctl3 = 0;
513
}
514
/* XXX only on last descriptor? */
515
OS_MEMZERO(ads->u.tx.status, sizeof(ads->u.tx.status));
516
return AH_TRUE;
517
}
518
519
/*
520
* NB: cipher is no longer used, it's calculated.
521
*/
522
HAL_BOOL
523
ar5416ChainTxDesc(struct ath_hal *ah, struct ath_desc *ds,
524
HAL_DMA_ADDR *bufAddrList,
525
uint32_t *segLenList,
526
u_int pktLen,
527
u_int hdrLen,
528
HAL_PKT_TYPE type,
529
u_int keyIx,
530
HAL_CIPHER cipher,
531
uint8_t delims,
532
HAL_BOOL firstSeg,
533
HAL_BOOL lastSeg,
534
HAL_BOOL lastAggr)
535
{
536
struct ar5416_desc *ads = AR5416DESC(ds);
537
uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
538
struct ath_hal_5416 *ahp = AH5416(ah);
539
u_int segLen = segLenList[0];
540
541
int isaggr = 0;
542
uint32_t last_aggr = 0;
543
544
(void) hdrLen;
545
(void) ah;
546
547
HALASSERT((segLen &~ AR_BufLen) == 0);
548
ds->ds_data = bufAddrList[0];
549
550
HALASSERT(isValidPktType(type));
551
if (type == HAL_PKT_TYPE_AMPDU) {
552
type = HAL_PKT_TYPE_NORMAL;
553
isaggr = 1;
554
if (lastAggr == AH_FALSE)
555
last_aggr = AR_MoreAggr;
556
}
557
558
/*
559
* Since this function is called before any of the other
560
* descriptor setup functions (at least in this particular
561
* 802.11n aggregation implementation), always bzero() the
562
* descriptor. Previously this would be done for all but
563
* the first segment.
564
* XXX TODO: figure out why; perhaps I'm using this slightly
565
* XXX incorrectly.
566
*/
567
OS_MEMZERO(ds->ds_hw, AR5416_DESC_TX_CTL_SZ);
568
569
/*
570
* Note: VEOL should only be for the last descriptor in the chain.
571
*/
572
ads->ds_ctl0 = (pktLen & AR_FrameLen);
573
574
/*
575
* For aggregates:
576
* + IsAggr must be set for all descriptors of all subframes of
577
* the aggregate
578
* + MoreAggr must be set for all descriptors of all subframes
579
* of the aggregate EXCEPT the last subframe;
580
* + MoreAggr must be _CLEAR_ for all descrpitors of the last
581
* subframe of the aggregate.
582
*/
583
ads->ds_ctl1 = (type << AR_FrameType_S)
584
| (isaggr ? (AR_IsAggr | last_aggr) : 0);
585
586
ads->ds_ctl2 = 0;
587
ads->ds_ctl3 = 0;
588
if (keyIx != HAL_TXKEYIX_INVALID) {
589
/* XXX validate key index */
590
ads->ds_ctl1 |= SM(keyIx, AR_DestIdx);
591
ads->ds_ctl0 |= AR_DestIdxValid;
592
}
593
594
ads->ds_ctl6 |= SM(ahp->ah_keytype[keyIx], AR_EncrType);
595
if (isaggr) {
596
ads->ds_ctl6 |= SM(delims, AR_PadDelim);
597
}
598
599
if (firstSeg) {
600
ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
601
} else if (lastSeg) { /* !firstSeg && lastSeg */
602
ads->ds_ctl0 = 0;
603
ads->ds_ctl1 |= segLen;
604
} else { /* !firstSeg && !lastSeg */
605
/*
606
* Intermediate descriptor in a multi-descriptor frame.
607
*/
608
ads->ds_ctl0 = 0;
609
ads->ds_ctl1 |= segLen | AR_TxMore;
610
}
611
ds_txstatus[0] = ds_txstatus[1] = 0;
612
ds_txstatus[9] &= ~AR_TxDone;
613
614
return AH_TRUE;
615
}
616
617
HAL_BOOL
618
ar5416SetupFirstTxDesc(struct ath_hal *ah, struct ath_desc *ds,
619
u_int aggrLen, u_int flags, u_int txPower,
620
u_int txRate0, u_int txTries0, u_int antMode,
621
u_int rtsctsRate, u_int rtsctsDuration)
622
{
623
#define RTSCTS (HAL_TXDESC_RTSENA|HAL_TXDESC_CTSENA)
624
struct ar5416_desc *ads = AR5416DESC(ds);
625
struct ath_hal_5212 *ahp = AH5212(ah);
626
627
HALASSERT(txTries0 != 0);
628
HALASSERT(isValidTxRate(txRate0));
629
HALASSERT((flags & RTSCTS) != RTSCTS);
630
/* XXX validate antMode */
631
632
txPower = (txPower + ahp->ah_txPowerIndexOffset );
633
if(txPower > 63) txPower=63;
634
635
ads->ds_ctl0 |= (txPower << AR_XmitPower_S)
636
| (flags & HAL_TXDESC_VEOL ? AR_VEOL : 0)
637
| (flags & HAL_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
638
| (flags & HAL_TXDESC_INTREQ ? AR_TxIntrReq : 0);
639
ads->ds_ctl1 |= (flags & HAL_TXDESC_NOACK ? AR_NoAck : 0);
640
ads->ds_ctl2 |= SM(txTries0, AR_XmitDataTries0);
641
ads->ds_ctl3 |= (txRate0 << AR_XmitRate0_S);
642
ads->ds_ctl7 = SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel0)
643
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel1)
644
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel2)
645
| SM(AH5416(ah)->ah_tx_chainmask, AR_ChainSel3);
646
647
/* NB: no V1 WAR */
648
ads->ds_ctl8 = SM(0, AR_AntCtl0);
649
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
650
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
651
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
652
653
ads->ds_ctl6 &= ~(0xffff);
654
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
655
656
if (flags & RTSCTS) {
657
/* XXX validate rtsctsDuration */
658
ads->ds_ctl0 |= (flags & HAL_TXDESC_CTSENA ? AR_CTSEnable : 0)
659
| (flags & HAL_TXDESC_RTSENA ? AR_RTSEnable : 0);
660
}
661
662
/*
663
* Set the TX antenna to 0 for Kite
664
* To preserve existing behaviour, also set the TPC bits to 0;
665
* when TPC is enabled these should be filled in appropriately.
666
*/
667
if (AR_SREV_KITE(ah)) {
668
ads->ds_ctl8 = SM(0, AR_AntCtl0);
669
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(0, AR_XmitPower1);
670
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(0, AR_XmitPower2);
671
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(0, AR_XmitPower3);
672
}
673
674
return AH_TRUE;
675
#undef RTSCTS
676
}
677
678
HAL_BOOL
679
ar5416SetupLastTxDesc(struct ath_hal *ah, struct ath_desc *ds,
680
const struct ath_desc *ds0)
681
{
682
struct ar5416_desc *ads = AR5416DESC(ds);
683
684
ads->ds_ctl1 &= ~AR_MoreAggr;
685
ads->ds_ctl6 &= ~AR_PadDelim;
686
687
/* hack to copy rate info to last desc for later processing */
688
#ifdef AH_NEED_DESC_SWAP
689
ads->ds_ctl2 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl2);
690
ads->ds_ctl3 = __bswap32(AR5416DESC_CONST(ds0)->ds_ctl3);
691
#else
692
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
693
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
694
#endif
695
return AH_TRUE;
696
}
697
698
#ifdef AH_NEED_DESC_SWAP
699
/* Swap transmit descriptor */
700
static __inline void
701
ar5416SwapTxDesc(struct ath_desc *ds)
702
{
703
ds->ds_data = __bswap32(ds->ds_data);
704
ds->ds_ctl0 = __bswap32(ds->ds_ctl0);
705
ds->ds_ctl1 = __bswap32(ds->ds_ctl1);
706
ds->ds_hw[0] = __bswap32(ds->ds_hw[0]);
707
ds->ds_hw[1] = __bswap32(ds->ds_hw[1]);
708
ds->ds_hw[2] = __bswap32(ds->ds_hw[2]);
709
ds->ds_hw[3] = __bswap32(ds->ds_hw[3]);
710
}
711
#endif
712
713
/*
714
* Processing of HW TX descriptor.
715
*/
716
HAL_STATUS
717
ar5416ProcTxDesc(struct ath_hal *ah,
718
struct ath_desc *ds, struct ath_tx_status *ts)
719
{
720
struct ar5416_desc *ads = AR5416DESC(ds);
721
uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
722
723
#ifdef AH_NEED_DESC_SWAP
724
if ((ds_txstatus[9] & __bswap32(AR_TxDone)) == 0)
725
return HAL_EINPROGRESS;
726
ar5416SwapTxDesc(ds);
727
#else
728
if ((ds_txstatus[9] & AR_TxDone) == 0)
729
return HAL_EINPROGRESS;
730
#endif
731
732
/* Update software copies of the HW status */
733
ts->ts_seqnum = MS(ds_txstatus[9], AR_SeqNum);
734
ts->ts_tstamp = AR_SendTimestamp(ds_txstatus);
735
ts->ts_tid = MS(ds_txstatus[9], AR_TxTid);
736
737
ts->ts_status = 0;
738
if (ds_txstatus[1] & AR_ExcessiveRetries)
739
ts->ts_status |= HAL_TXERR_XRETRY;
740
if (ds_txstatus[1] & AR_Filtered)
741
ts->ts_status |= HAL_TXERR_FILT;
742
if (ds_txstatus[1] & AR_FIFOUnderrun)
743
ts->ts_status |= HAL_TXERR_FIFO;
744
if (ds_txstatus[9] & AR_TxOpExceeded)
745
ts->ts_status |= HAL_TXERR_XTXOP;
746
if (ds_txstatus[1] & AR_TxTimerExpired)
747
ts->ts_status |= HAL_TXERR_TIMER_EXPIRED;
748
749
ts->ts_flags = 0;
750
if (ds_txstatus[0] & AR_TxBaStatus) {
751
ts->ts_flags |= HAL_TX_BA;
752
ts->ts_ba_low = AR_BaBitmapLow(ds_txstatus);
753
ts->ts_ba_high = AR_BaBitmapHigh(ds_txstatus);
754
}
755
if (ds->ds_ctl1 & AR_IsAggr)
756
ts->ts_flags |= HAL_TX_AGGR;
757
if (ds_txstatus[1] & AR_DescCfgErr)
758
ts->ts_flags |= HAL_TX_DESC_CFG_ERR;
759
if (ds_txstatus[1] & AR_TxDataUnderrun)
760
ts->ts_flags |= HAL_TX_DATA_UNDERRUN;
761
if (ds_txstatus[1] & AR_TxDelimUnderrun)
762
ts->ts_flags |= HAL_TX_DELIM_UNDERRUN;
763
764
/*
765
* Extract the transmit rate used and mark the rate as
766
* ``alternate'' if it wasn't the series 0 rate.
767
*/
768
ts->ts_finaltsi = MS(ds_txstatus[9], AR_FinalTxIdx);
769
switch (ts->ts_finaltsi) {
770
case 0:
771
ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate0);
772
break;
773
case 1:
774
ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate1);
775
break;
776
case 2:
777
ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate2);
778
break;
779
case 3:
780
ts->ts_rate = MS(ads->ds_ctl3, AR_XmitRate3);
781
break;
782
}
783
784
ts->ts_rssi = MS(ds_txstatus[5], AR_TxRSSICombined);
785
ts->ts_rssi_ctl[0] = MS(ds_txstatus[0], AR_TxRSSIAnt00);
786
ts->ts_rssi_ctl[1] = MS(ds_txstatus[0], AR_TxRSSIAnt01);
787
ts->ts_rssi_ctl[2] = MS(ds_txstatus[0], AR_TxRSSIAnt02);
788
ts->ts_rssi_ext[0] = MS(ds_txstatus[5], AR_TxRSSIAnt10);
789
ts->ts_rssi_ext[1] = MS(ds_txstatus[5], AR_TxRSSIAnt11);
790
ts->ts_rssi_ext[2] = MS(ds_txstatus[5], AR_TxRSSIAnt12);
791
ts->ts_evm0 = AR_TxEVM0(ds_txstatus);
792
ts->ts_evm1 = AR_TxEVM1(ds_txstatus);
793
ts->ts_evm2 = AR_TxEVM2(ds_txstatus);
794
795
ts->ts_shortretry = MS(ds_txstatus[1], AR_RTSFailCnt);
796
ts->ts_longretry = MS(ds_txstatus[1], AR_DataFailCnt);
797
/*
798
* The retry count has the number of un-acked tries for the
799
* final series used. When doing multi-rate retry we must
800
* fixup the retry count by adding in the try counts for
801
* each series that was fully-processed. Beware that this
802
* takes values from the try counts in the final descriptor.
803
* These are not required by the hardware. We assume they
804
* are placed there by the driver as otherwise we have no
805
* access and the driver can't do the calculation because it
806
* doesn't know the descriptor format.
807
*/
808
switch (ts->ts_finaltsi) {
809
case 3: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries2);
810
case 2: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries1);
811
case 1: ts->ts_longretry += MS(ads->ds_ctl2, AR_XmitDataTries0);
812
}
813
814
/*
815
* These fields are not used. Zero these to preserve compatibility
816
* with existing drivers.
817
*/
818
ts->ts_virtcol = MS(ads->ds_ctl1, AR_VirtRetryCnt);
819
ts->ts_antenna = 0; /* We don't switch antennas on Owl*/
820
821
/* handle tx trigger level changes internally */
822
if ((ts->ts_status & HAL_TXERR_FIFO) ||
823
(ts->ts_flags & (HAL_TX_DATA_UNDERRUN | HAL_TX_DELIM_UNDERRUN)))
824
ar5212UpdateTxTrigLevel(ah, AH_TRUE);
825
826
return HAL_OK;
827
}
828
829
HAL_BOOL
830
ar5416SetGlobalTxTimeout(struct ath_hal *ah, u_int tu)
831
{
832
struct ath_hal_5416 *ahp = AH5416(ah);
833
834
if (tu > 0xFFFF) {
835
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad global tx timeout %u\n",
836
__func__, tu);
837
/* restore default handling */
838
ahp->ah_globaltxtimeout = (u_int) -1;
839
return AH_FALSE;
840
}
841
OS_REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
842
ahp->ah_globaltxtimeout = tu;
843
return AH_TRUE;
844
}
845
846
u_int
847
ar5416GetGlobalTxTimeout(struct ath_hal *ah)
848
{
849
return MS(OS_REG_READ(ah, AR_GTXTO), AR_GTXTO_TIMEOUT_LIMIT);
850
}
851
852
#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f)
853
static const u_int8_t baDurationDelta[] = {
854
24, // 0: BPSK
855
12, // 1: QPSK 1/2
856
12, // 2: QPSK 3/4
857
4, // 3: 16-QAM 1/2
858
4, // 4: 16-QAM 3/4
859
4, // 5: 64-QAM 2/3
860
4, // 6: 64-QAM 3/4
861
4, // 7: 64-QAM 5/6
862
24, // 8: BPSK
863
12, // 9: QPSK 1/2
864
12, // 10: QPSK 3/4
865
4, // 11: 16-QAM 1/2
866
4, // 12: 16-QAM 3/4
867
4, // 13: 64-QAM 2/3
868
4, // 14: 64-QAM 3/4
869
4, // 15: 64-QAM 5/6
870
};
871
872
void
873
ar5416Set11nRateScenario(struct ath_hal *ah, struct ath_desc *ds,
874
u_int durUpdateEn, u_int rtsctsRate,
875
HAL_11N_RATE_SERIES series[], u_int nseries, u_int flags)
876
{
877
struct ar5416_desc *ads = AR5416DESC(ds);
878
uint32_t ds_ctl0;
879
880
HALASSERT(nseries == 4);
881
(void)nseries;
882
883
/*
884
* Only one of RTS and CTS enable must be set.
885
* If a frame has both set, just do RTS protection -
886
* that's enough to satisfy legacy protection.
887
*/
888
if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
889
ds_ctl0 = ads->ds_ctl0;
890
891
if (flags & HAL_TXDESC_RTSENA) {
892
ds_ctl0 &= ~AR_CTSEnable;
893
ds_ctl0 |= AR_RTSEnable;
894
} else {
895
ds_ctl0 &= ~AR_RTSEnable;
896
ds_ctl0 |= AR_CTSEnable;
897
}
898
899
ads->ds_ctl0 = ds_ctl0;
900
} else {
901
ads->ds_ctl0 =
902
(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
903
}
904
905
ads->ds_ctl2 = set11nTries(series, 0)
906
| set11nTries(series, 1)
907
| set11nTries(series, 2)
908
| set11nTries(series, 3)
909
| (durUpdateEn ? AR_DurUpdateEn : 0);
910
911
ads->ds_ctl3 = set11nRate(series, 0)
912
| set11nRate(series, 1)
913
| set11nRate(series, 2)
914
| set11nRate(series, 3);
915
916
ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
917
| set11nPktDurRTSCTS(series, 1);
918
919
ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
920
| set11nPktDurRTSCTS(series, 3);
921
922
ads->ds_ctl7 = set11nRateFlags(series, 0)
923
| set11nRateFlags(series, 1)
924
| set11nRateFlags(series, 2)
925
| set11nRateFlags(series, 3)
926
| SM(rtsctsRate, AR_RTSCTSRate);
927
928
/*
929
* Doing per-packet TPC - update the TX power for the first
930
* field; program in the other series.
931
*/
932
if (AH5212(ah)->ah_tpcEnabled) {
933
uint32_t ds_ctl0;
934
uint16_t txPower;
935
936
/* Modify the tx power field for rate 0 */
937
txPower = ar5416GetTxRatePower(ah, series[0].Rate,
938
series[0].ChSel,
939
series[0].tx_power_cap,
940
!! (series[0].RateFlags & HAL_RATESERIES_2040));
941
ds_ctl0 = ads->ds_ctl0 & ~AR_XmitPower;
942
ds_ctl0 |= (txPower << AR_XmitPower_S);
943
ads->ds_ctl0 = ds_ctl0;
944
945
/*
946
* Override the whole descriptor field for each TX power.
947
*
948
* This will need changing if we ever support antenna control
949
* programming.
950
*/
951
txPower = ar5416GetTxRatePower(ah, series[1].Rate,
952
series[1].ChSel,
953
series[1].tx_power_cap,
954
!! (series[1].RateFlags & HAL_RATESERIES_2040));
955
ads->ds_ctl9 = SM(0, AR_AntCtl1) | SM(txPower, AR_XmitPower1);
956
957
txPower = ar5416GetTxRatePower(ah, series[2].Rate,
958
series[2].ChSel,
959
series[2].tx_power_cap,
960
!! (series[2].RateFlags & HAL_RATESERIES_2040));
961
ads->ds_ctl10 = SM(0, AR_AntCtl2) | SM(txPower, AR_XmitPower2);
962
963
txPower = ar5416GetTxRatePower(ah, series[3].Rate,
964
series[3].ChSel,
965
series[3].tx_power_cap,
966
!! (series[3].RateFlags & HAL_RATESERIES_2040));
967
ads->ds_ctl11 = SM(0, AR_AntCtl3) | SM(txPower, AR_XmitPower3);
968
}
969
}
970
971
/*
972
* Note: this should be called before calling ar5416SetBurstDuration()
973
* (if it is indeed called) in order to ensure that the burst duration
974
* is correctly updated with the BA delta workaround.
975
*/
976
void
977
ar5416Set11nAggrFirst(struct ath_hal *ah, struct ath_desc *ds, u_int aggrLen,
978
u_int numDelims)
979
{
980
struct ar5416_desc *ads = AR5416DESC(ds);
981
uint32_t flags;
982
uint32_t burstDur;
983
uint8_t rate;
984
985
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
986
987
ads->ds_ctl6 &= ~(AR_AggrLen | AR_PadDelim);
988
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
989
ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
990
991
if (! AR_SREV_MERLIN_10_OR_LATER(ah)) {
992
/*
993
* XXX It'd be nice if I were passed in the rate scenario
994
* at this point..
995
*/
996
rate = MS(ads->ds_ctl3, AR_XmitRate0);
997
flags = ads->ds_ctl0 & (AR_CTSEnable | AR_RTSEnable);
998
/*
999
* WAR - MAC assumes normal ACK time instead of
1000
* block ACK while computing packet duration.
1001
* Add this delta to the burst duration in the descriptor.
1002
*/
1003
if (flags && (ads->ds_ctl1 & AR_IsAggr)) {
1004
burstDur = baDurationDelta[HT_RC_2_MCS(rate)];
1005
ads->ds_ctl2 &= ~(AR_BurstDur);
1006
ads->ds_ctl2 |= SM(burstDur, AR_BurstDur);
1007
}
1008
}
1009
}
1010
1011
void
1012
ar5416Set11nAggrMiddle(struct ath_hal *ah, struct ath_desc *ds, u_int numDelims)
1013
{
1014
struct ar5416_desc *ads = AR5416DESC(ds);
1015
uint32_t *ds_txstatus = AR5416_DS_TXSTATUS(ah,ads);
1016
1017
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
1018
1019
ads->ds_ctl6 &= ~AR_PadDelim;
1020
ads->ds_ctl6 |= SM(numDelims, AR_PadDelim);
1021
ads->ds_ctl6 &= ~AR_AggrLen;
1022
1023
/*
1024
* Clear the TxDone status here, may need to change
1025
* func name to reflect this
1026
*/
1027
ds_txstatus[9] &= ~AR_TxDone;
1028
}
1029
1030
void
1031
ar5416Set11nAggrLast(struct ath_hal *ah, struct ath_desc *ds)
1032
{
1033
struct ar5416_desc *ads = AR5416DESC(ds);
1034
1035
ads->ds_ctl1 |= AR_IsAggr;
1036
ads->ds_ctl1 &= ~AR_MoreAggr;
1037
ads->ds_ctl6 &= ~AR_PadDelim;
1038
}
1039
1040
void
1041
ar5416Clr11nAggr(struct ath_hal *ah, struct ath_desc *ds)
1042
{
1043
struct ar5416_desc *ads = AR5416DESC(ds);
1044
1045
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
1046
ads->ds_ctl6 &= ~AR_PadDelim;
1047
ads->ds_ctl6 &= ~AR_AggrLen;
1048
}
1049
1050
void
1051
ar5416Set11nVirtualMoreFrag(struct ath_hal *ah, struct ath_desc *ds,
1052
u_int vmf)
1053
{
1054
struct ar5416_desc *ads = AR5416DESC(ds);
1055
if (vmf)
1056
ads->ds_ctl0 |= AR_VirtMoreFrag;
1057
else
1058
ads->ds_ctl0 &= ~AR_VirtMoreFrag;
1059
}
1060
1061
/*
1062
* Program the burst duration, with the included BA delta if it's
1063
* applicable.
1064
*/
1065
void
1066
ar5416Set11nBurstDuration(struct ath_hal *ah, struct ath_desc *ds,
1067
u_int burstDuration)
1068
{
1069
struct ar5416_desc *ads = AR5416DESC(ds);
1070
uint32_t burstDur = 0;
1071
uint8_t rate;
1072
1073
if (! AR_SREV_MERLIN_10_OR_LATER(ah)) {
1074
/*
1075
* XXX It'd be nice if I were passed in the rate scenario
1076
* at this point..
1077
*/
1078
rate = MS(ads->ds_ctl3, AR_XmitDataTries0);
1079
/*
1080
* WAR - MAC assumes normal ACK time instead of
1081
* block ACK while computing packet duration.
1082
* Add this delta to the burst duration in the descriptor.
1083
*/
1084
if (ads->ds_ctl1 & AR_IsAggr) {
1085
burstDur = baDurationDelta[HT_RC_2_MCS(rate)];
1086
}
1087
}
1088
1089
ads->ds_ctl2 &= ~AR_BurstDur;
1090
ads->ds_ctl2 |= SM(burstDur + burstDuration, AR_BurstDur);
1091
}
1092
1093
/*
1094
* Retrieve the rate table from the given TX completion descriptor
1095
*/
1096
HAL_BOOL
1097
ar5416GetTxCompletionRates(struct ath_hal *ah, const struct ath_desc *ds0, int *rates, int *tries)
1098
{
1099
const struct ar5416_desc *ads = AR5416DESC_CONST(ds0);
1100
1101
rates[0] = MS(ads->ds_ctl3, AR_XmitRate0);
1102
rates[1] = MS(ads->ds_ctl3, AR_XmitRate1);
1103
rates[2] = MS(ads->ds_ctl3, AR_XmitRate2);
1104
rates[3] = MS(ads->ds_ctl3, AR_XmitRate3);
1105
1106
tries[0] = MS(ads->ds_ctl2, AR_XmitDataTries0);
1107
tries[1] = MS(ads->ds_ctl2, AR_XmitDataTries1);
1108
tries[2] = MS(ads->ds_ctl2, AR_XmitDataTries2);
1109
tries[3] = MS(ads->ds_ctl2, AR_XmitDataTries3);
1110
1111
return AH_TRUE;
1112
}
1113
1114
/*
1115
* TX queue management routines - AR5416 and later chipsets
1116
*/
1117
1118
/*
1119
* Allocate and initialize a tx DCU/QCU combination.
1120
*/
1121
int
1122
ar5416SetupTxQueue(struct ath_hal *ah, HAL_TX_QUEUE type,
1123
const HAL_TXQ_INFO *qInfo)
1124
{
1125
struct ath_hal_5212 *ahp = AH5212(ah);
1126
HAL_TX_QUEUE_INFO *qi;
1127
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
1128
int q, defqflags;
1129
1130
/* by default enable OK+ERR+DESC+URN interrupts */
1131
defqflags = HAL_TXQ_TXOKINT_ENABLE
1132
| HAL_TXQ_TXERRINT_ENABLE
1133
| HAL_TXQ_TXDESCINT_ENABLE
1134
| HAL_TXQ_TXURNINT_ENABLE;
1135
/* XXX move queue assignment to driver */
1136
switch (type) {
1137
case HAL_TX_QUEUE_BEACON:
1138
q = pCap->halTotalQueues-1; /* highest priority */
1139
defqflags |= HAL_TXQ_DBA_GATED
1140
| HAL_TXQ_CBR_DIS_QEMPTY
1141
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
1142
| HAL_TXQ_BACKOFF_DISABLE;
1143
break;
1144
case HAL_TX_QUEUE_CAB:
1145
q = pCap->halTotalQueues-2; /* next highest priority */
1146
defqflags |= HAL_TXQ_DBA_GATED
1147
| HAL_TXQ_CBR_DIS_QEMPTY
1148
| HAL_TXQ_CBR_DIS_BEMPTY
1149
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
1150
| HAL_TXQ_BACKOFF_DISABLE;
1151
break;
1152
case HAL_TX_QUEUE_PSPOLL:
1153
q = 1; /* lowest priority */
1154
defqflags |= HAL_TXQ_DBA_GATED
1155
| HAL_TXQ_CBR_DIS_QEMPTY
1156
| HAL_TXQ_CBR_DIS_BEMPTY
1157
| HAL_TXQ_ARB_LOCKOUT_GLOBAL
1158
| HAL_TXQ_BACKOFF_DISABLE;
1159
break;
1160
case HAL_TX_QUEUE_UAPSD:
1161
q = pCap->halTotalQueues-3; /* nextest highest priority */
1162
if (ahp->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE) {
1163
HALDEBUG(ah, HAL_DEBUG_ANY,
1164
"%s: no available UAPSD tx queue\n", __func__);
1165
return -1;
1166
}
1167
break;
1168
case HAL_TX_QUEUE_DATA:
1169
for (q = 0; q < pCap->halTotalQueues; q++)
1170
if (ahp->ah_txq[q].tqi_type == HAL_TX_QUEUE_INACTIVE)
1171
break;
1172
if (q == pCap->halTotalQueues) {
1173
HALDEBUG(ah, HAL_DEBUG_ANY,
1174
"%s: no available tx queue\n", __func__);
1175
return -1;
1176
}
1177
break;
1178
default:
1179
HALDEBUG(ah, HAL_DEBUG_ANY,
1180
"%s: bad tx queue type %u\n", __func__, type);
1181
return -1;
1182
}
1183
1184
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: queue %u\n", __func__, q);
1185
1186
qi = &ahp->ah_txq[q];
1187
if (qi->tqi_type != HAL_TX_QUEUE_INACTIVE) {
1188
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: tx queue %u already active\n",
1189
__func__, q);
1190
return -1;
1191
}
1192
OS_MEMZERO(qi, sizeof(HAL_TX_QUEUE_INFO));
1193
qi->tqi_type = type;
1194
if (qInfo == AH_NULL) {
1195
qi->tqi_qflags = defqflags;
1196
qi->tqi_aifs = INIT_AIFS;
1197
qi->tqi_cwmin = HAL_TXQ_USEDEFAULT; /* NB: do at reset */
1198
qi->tqi_cwmax = INIT_CWMAX;
1199
qi->tqi_shretry = INIT_SH_RETRY;
1200
qi->tqi_lgretry = INIT_LG_RETRY;
1201
qi->tqi_physCompBuf = 0;
1202
} else {
1203
qi->tqi_physCompBuf = qInfo->tqi_compBuf;
1204
(void) ar5212SetTxQueueProps(ah, q, qInfo);
1205
}
1206
/* NB: must be followed by ar5212ResetTxQueue */
1207
return q;
1208
}
1209
1210
/*
1211
* Update the h/w interrupt registers to reflect a tx q's configuration.
1212
*/
1213
static void
1214
setTxQInterrupts(struct ath_hal *ah, HAL_TX_QUEUE_INFO *qi)
1215
{
1216
struct ath_hal_5212 *ahp = AH5212(ah);
1217
1218
HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1219
"%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n", __func__,
1220
ahp->ah_txOkInterruptMask, ahp->ah_txErrInterruptMask,
1221
ahp->ah_txDescInterruptMask, ahp->ah_txEolInterruptMask,
1222
ahp->ah_txUrnInterruptMask);
1223
1224
OS_REG_WRITE(ah, AR_IMR_S0,
1225
SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
1226
| SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC)
1227
);
1228
OS_REG_WRITE(ah, AR_IMR_S1,
1229
SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
1230
| SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL)
1231
);
1232
OS_REG_RMW_FIELD(ah, AR_IMR_S2,
1233
AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
1234
}
1235
1236
/*
1237
* Set the retry, aifs, cwmin/max, readyTime regs for specified queue
1238
* Assumes:
1239
* phwChannel has been set to point to the current channel
1240
*/
1241
#define TU_TO_USEC(_tu) ((_tu) << 10)
1242
HAL_BOOL
1243
ar5416ResetTxQueue(struct ath_hal *ah, u_int q)
1244
{
1245
struct ath_hal_5212 *ahp = AH5212(ah);
1246
HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
1247
const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan;
1248
HAL_TX_QUEUE_INFO *qi;
1249
uint32_t cwMin, chanCwMin, qmisc, dmisc;
1250
1251
if (q >= pCap->halTotalQueues) {
1252
HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid queue num %u\n",
1253
__func__, q);
1254
return AH_FALSE;
1255
}
1256
qi = &ahp->ah_txq[q];
1257
if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1258
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: inactive queue %u\n",
1259
__func__, q);
1260
return AH_TRUE; /* XXX??? */
1261
}
1262
1263
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: reset queue %u\n", __func__, q);
1264
1265
if (qi->tqi_cwmin == HAL_TXQ_USEDEFAULT) {
1266
/*
1267
* Select cwmin according to channel type.
1268
* NB: chan can be NULL during attach
1269
*/
1270
if (chan && IEEE80211_IS_CHAN_B(chan))
1271
chanCwMin = INIT_CWMIN_11B;
1272
else
1273
chanCwMin = INIT_CWMIN;
1274
/* make sure that the CWmin is of the form (2^n - 1) */
1275
for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1)
1276
;
1277
} else
1278
cwMin = qi->tqi_cwmin;
1279
1280
/* set cwMin/Max and AIFS values */
1281
OS_REG_WRITE(ah, AR_DLCL_IFS(q),
1282
SM(cwMin, AR_D_LCL_IFS_CWMIN)
1283
| SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
1284
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
1285
1286
/* Set retry limit values */
1287
OS_REG_WRITE(ah, AR_DRETRY_LIMIT(q),
1288
SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
1289
| SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
1290
| SM(qi->tqi_lgretry, AR_D_RETRY_LIMIT_FR_LG)
1291
| SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
1292
);
1293
1294
/* NB: always enable early termination on the QCU */
1295
qmisc = AR_Q_MISC_DCU_EARLY_TERM_REQ
1296
| SM(AR_Q_MISC_FSP_ASAP, AR_Q_MISC_FSP);
1297
1298
/* NB: always enable DCU to wait for next fragment from QCU */
1299
dmisc = AR_D_MISC_FRAG_WAIT_EN;
1300
1301
/* Enable exponential backoff window */
1302
dmisc |= AR_D_MISC_BKOFF_PERSISTENCE;
1303
1304
/*
1305
* The chip reset default is to use a DCU backoff threshold of 0x2.
1306
* Restore this when programming the DCU MISC register.
1307
*/
1308
dmisc |= 0x2;
1309
1310
/* multiqueue support */
1311
if (qi->tqi_cbrPeriod) {
1312
OS_REG_WRITE(ah, AR_QCBRCFG(q),
1313
SM(qi->tqi_cbrPeriod,AR_Q_CBRCFG_CBR_INTERVAL)
1314
| SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_CBR_OVF_THRESH));
1315
qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_CBR;
1316
if (qi->tqi_cbrOverflowLimit)
1317
qmisc |= AR_Q_MISC_CBR_EXP_CNTR_LIMIT;
1318
}
1319
1320
if (qi->tqi_readyTime && (qi->tqi_type != HAL_TX_QUEUE_CAB)) {
1321
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
1322
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT)
1323
| AR_Q_RDYTIMECFG_ENA);
1324
}
1325
1326
OS_REG_WRITE(ah, AR_DCHNTIME(q),
1327
SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR)
1328
| (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
1329
1330
if (qi->tqi_readyTime &&
1331
(qi->tqi_qflags & HAL_TXQ_RDYTIME_EXP_POLICY_ENABLE))
1332
qmisc |= AR_Q_MISC_RDYTIME_EXP_POLICY;
1333
if (qi->tqi_qflags & HAL_TXQ_DBA_GATED)
1334
qmisc = (qmisc &~ AR_Q_MISC_FSP) | AR_Q_MISC_FSP_DBA_GATED;
1335
if (MS(qmisc, AR_Q_MISC_FSP) != AR_Q_MISC_FSP_ASAP) {
1336
/*
1337
* These are meangingful only when not scheduled asap.
1338
*/
1339
if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_BEMPTY)
1340
qmisc |= AR_Q_MISC_CBR_INCR_DIS0;
1341
else
1342
qmisc &= ~AR_Q_MISC_CBR_INCR_DIS0;
1343
if (qi->tqi_qflags & HAL_TXQ_CBR_DIS_QEMPTY)
1344
qmisc |= AR_Q_MISC_CBR_INCR_DIS1;
1345
else
1346
qmisc &= ~AR_Q_MISC_CBR_INCR_DIS1;
1347
}
1348
1349
if (qi->tqi_qflags & HAL_TXQ_BACKOFF_DISABLE)
1350
dmisc |= AR_D_MISC_POST_FR_BKOFF_DIS;
1351
if (qi->tqi_qflags & HAL_TXQ_FRAG_BURST_BACKOFF_ENABLE)
1352
dmisc |= AR_D_MISC_FRAG_BKOFF_EN;
1353
if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_GLOBAL)
1354
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
1355
AR_D_MISC_ARB_LOCKOUT_CNTRL);
1356
else if (qi->tqi_qflags & HAL_TXQ_ARB_LOCKOUT_INTRA)
1357
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR,
1358
AR_D_MISC_ARB_LOCKOUT_CNTRL);
1359
if (qi->tqi_qflags & HAL_TXQ_IGNORE_VIRTCOL)
1360
dmisc |= SM(AR_D_MISC_VIR_COL_HANDLING_IGNORE,
1361
AR_D_MISC_VIR_COL_HANDLING);
1362
if (qi->tqi_qflags & HAL_TXQ_SEQNUM_INC_DIS)
1363
dmisc |= AR_D_MISC_SEQ_NUM_INCR_DIS;
1364
1365
/*
1366
* Fillin type-dependent bits. Most of this can be
1367
* removed by specifying the queue parameters in the
1368
* driver; it's here for backwards compatibility.
1369
*/
1370
switch (qi->tqi_type) {
1371
case HAL_TX_QUEUE_BEACON: /* beacon frames */
1372
qmisc |= AR_Q_MISC_FSP_DBA_GATED
1373
| AR_Q_MISC_BEACON_USE
1374
| AR_Q_MISC_CBR_INCR_DIS1;
1375
1376
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
1377
AR_D_MISC_ARB_LOCKOUT_CNTRL)
1378
| AR_D_MISC_BEACON_USE
1379
| AR_D_MISC_POST_FR_BKOFF_DIS;
1380
break;
1381
case HAL_TX_QUEUE_CAB: /* CAB frames */
1382
/*
1383
* No longer Enable AR_Q_MISC_RDYTIME_EXP_POLICY,
1384
* There is an issue with the CAB Queue
1385
* not properly refreshing the Tx descriptor if
1386
* the TXE clear setting is used.
1387
*/
1388
qmisc |= AR_Q_MISC_FSP_DBA_GATED
1389
| AR_Q_MISC_CBR_INCR_DIS1
1390
| AR_Q_MISC_CBR_INCR_DIS0;
1391
HALDEBUG(ah, HAL_DEBUG_TXQUEUE, "%s: CAB: tqi_readyTime = %d\n",
1392
__func__, qi->tqi_readyTime);
1393
if (qi->tqi_readyTime) {
1394
HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1395
"%s: using tqi_readyTime\n", __func__);
1396
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
1397
SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_INT) |
1398
AR_Q_RDYTIMECFG_ENA);
1399
} else {
1400
int value;
1401
/*
1402
* NB: don't set default ready time if driver
1403
* has explicitly specified something. This is
1404
* here solely for backwards compatibility.
1405
*/
1406
/*
1407
* XXX for now, hard-code a CAB interval of 70%
1408
* XXX of the total beacon interval.
1409
*
1410
* XXX This keeps Merlin and later based MACs
1411
* XXX quite a bit happier (stops stuck beacons,
1412
* XXX which I gather is because of such a long
1413
* XXX cabq time.)
1414
*/
1415
value = (ahp->ah_beaconInterval * 50 / 100)
1416
- ah->ah_config.ah_additional_swba_backoff
1417
- ah->ah_config.ah_sw_beacon_response_time
1418
+ ah->ah_config.ah_dma_beacon_response_time;
1419
/*
1420
* XXX Ensure it isn't too low - nothing lower
1421
* XXX than 10 TU
1422
*/
1423
if (value < 10)
1424
value = 10;
1425
HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1426
"%s: defaulting to rdytime = %d uS\n",
1427
__func__, value);
1428
OS_REG_WRITE(ah, AR_QRDYTIMECFG(q),
1429
SM(TU_TO_USEC(value), AR_Q_RDYTIMECFG_INT) |
1430
AR_Q_RDYTIMECFG_ENA);
1431
}
1432
dmisc |= SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
1433
AR_D_MISC_ARB_LOCKOUT_CNTRL);
1434
break;
1435
case HAL_TX_QUEUE_PSPOLL:
1436
qmisc |= AR_Q_MISC_CBR_INCR_DIS1;
1437
break;
1438
case HAL_TX_QUEUE_UAPSD:
1439
dmisc |= AR_D_MISC_POST_FR_BKOFF_DIS;
1440
break;
1441
default: /* NB: silence compiler */
1442
break;
1443
}
1444
1445
OS_REG_WRITE(ah, AR_QMISC(q), qmisc);
1446
OS_REG_WRITE(ah, AR_DMISC(q), dmisc);
1447
1448
/* Setup compression scratchpad buffer */
1449
/*
1450
* XXX: calling this asynchronously to queue operation can
1451
* cause unexpected behavior!!!
1452
*/
1453
if (qi->tqi_physCompBuf) {
1454
HALASSERT(qi->tqi_type == HAL_TX_QUEUE_DATA ||
1455
qi->tqi_type == HAL_TX_QUEUE_UAPSD);
1456
OS_REG_WRITE(ah, AR_Q_CBBS, (80 + 2*q));
1457
OS_REG_WRITE(ah, AR_Q_CBBA, qi->tqi_physCompBuf);
1458
OS_REG_WRITE(ah, AR_Q_CBC, HAL_COMP_BUF_MAX_SIZE/1024);
1459
OS_REG_WRITE(ah, AR_Q0_MISC + 4*q,
1460
OS_REG_READ(ah, AR_Q0_MISC + 4*q)
1461
| AR_Q_MISC_QCU_COMP_EN);
1462
}
1463
1464
/*
1465
* Always update the secondary interrupt mask registers - this
1466
* could be a new queue getting enabled in a running system or
1467
* hw getting re-initialized during a reset!
1468
*
1469
* Since we don't differentiate between tx interrupts corresponding
1470
* to individual queues - secondary tx mask regs are always unmasked;
1471
* tx interrupts are enabled/disabled for all queues collectively
1472
* using the primary mask reg
1473
*/
1474
if (qi->tqi_qflags & HAL_TXQ_TXOKINT_ENABLE)
1475
ahp->ah_txOkInterruptMask |= 1 << q;
1476
else
1477
ahp->ah_txOkInterruptMask &= ~(1 << q);
1478
if (qi->tqi_qflags & HAL_TXQ_TXERRINT_ENABLE)
1479
ahp->ah_txErrInterruptMask |= 1 << q;
1480
else
1481
ahp->ah_txErrInterruptMask &= ~(1 << q);
1482
if (qi->tqi_qflags & HAL_TXQ_TXDESCINT_ENABLE)
1483
ahp->ah_txDescInterruptMask |= 1 << q;
1484
else
1485
ahp->ah_txDescInterruptMask &= ~(1 << q);
1486
if (qi->tqi_qflags & HAL_TXQ_TXEOLINT_ENABLE)
1487
ahp->ah_txEolInterruptMask |= 1 << q;
1488
else
1489
ahp->ah_txEolInterruptMask &= ~(1 << q);
1490
if (qi->tqi_qflags & HAL_TXQ_TXURNINT_ENABLE)
1491
ahp->ah_txUrnInterruptMask |= 1 << q;
1492
else
1493
ahp->ah_txUrnInterruptMask &= ~(1 << q);
1494
setTxQInterrupts(ah, qi);
1495
1496
return AH_TRUE;
1497
}
1498
#undef TU_TO_USEC
1499
1500